From 4a47f88a755eef8f9b49a1e0d0777d2752e71a46 Mon Sep 17 00:00:00 2001 From: TheLynk Date: Wed, 12 Nov 2025 03:38:30 +0100 Subject: [PATCH 01/45] Add Shuffle Roll (V1) TODO New model for items --- .../vanilla-behavior/GIVanillaBehavior.h | 9 +++++++++ .../3drando/hint_list/hint_list_item.cpp | 2 ++ .../randomizer/3drando/item_pool.cpp | 4 ++++ soh/soh/Enhancements/randomizer/draw.cpp | 18 ++++++++++++++++++ soh/soh/Enhancements/randomizer/draw.h | 1 + .../Enhancements/randomizer/hook_handlers.cpp | 3 +++ soh/soh/Enhancements/randomizer/item_list.cpp | 5 ++++- soh/soh/Enhancements/randomizer/logic.cpp | 16 ++++++++++++++-- .../randomizer/option_descriptions.cpp | 1 + soh/soh/Enhancements/randomizer/randomizer.cpp | 6 +++++- .../Enhancements/randomizer/randomizerTypes.h | 3 +++ .../Enhancements/randomizer/randomizer_inf.h | 1 + soh/soh/Enhancements/randomizer/savefile.cpp | 4 ++++ soh/soh/Enhancements/randomizer/settings.cpp | 3 +++ .../actors/ovl_player_actor/z_player.c | 6 ++++++ 15 files changed, 78 insertions(+), 4 deletions(-) diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index fe437907a2e..bbf4ba9454d 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -316,6 +316,15 @@ typedef enum { // ``` // #### `args` // - None + VB_ROLL, + + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - None + VB_CRAWL_SPEED_ENTER, // #### `result` diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp index c74c0ff23b9..98b59c7c6c4 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp @@ -2100,6 +2100,8 @@ void StaticData::HintTable_Init_Item() { { CustomMessage("a master unlocker", /*german*/ "ein Meisterentsperrer", /*french*/ "un Kit de Déverrouillage") }); // /*spanish*/un desbloqueador maestro + hintTextTable[RHT_ROLL] = HintText(CustomMessage("the ability to roll", /*german*/"!!!", /*french*/"!!!")); + //RANDOTODO if these are ever used for anything other than name, they want abscure and ambiguous hints hintTextTable[RHT_QUIVER_INF] = HintText(CustomMessage("an infinite Quiver", /*german*/"der unendliche Köcher", /*french*/"un Carquois Infini")); diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index e8cab933f58..a8fee2800ee 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -591,6 +591,10 @@ void GenerateItemPool() { AddItemToMainPool(RG_PROGRESSIVE_SCALE); } + if (ctx->GetOption(RSK_SHUFFLE_ROLL)) { + AddItemToMainPool(RG_ROLL); + } + if (ctx->GetOption(RSK_SHUFFLE_BEEHIVES)) { // 32 total beehive locations AddItemToPool(PendingJunkPool, RG_RED_RUPEE, 23); diff --git a/soh/soh/Enhancements/randomizer/draw.cpp b/soh/soh/Enhancements/randomizer/draw.cpp index b17718b6518..539df574c6e 100644 --- a/soh/soh/Enhancements/randomizer/draw.cpp +++ b/soh/soh/Enhancements/randomizer/draw.cpp @@ -34,6 +34,7 @@ extern "C" { #include "overlays/ovl_Boss_Sst/ovl_Boss_Sst.h" #include "objects/object_tw/object_tw.h" #include "objects/object_ganon2/object_ganon2.h" +#include "objects/object_vase/object_vase.h" extern PlayState* gPlayState; extern SaveContext gSaveContext; } @@ -1109,6 +1110,23 @@ extern "C" void Randomizer_DrawBronzeScale(PlayState* play, GetItemEntry* getIte CLOSE_DISPS(play->state.gfxCtx); } +extern "C" void Randomizer_DrawKneePads(PlayState* play, GetItemEntry* getItemEntry) { + OPEN_DISPS(play->state.gfxCtx); + + Gfx_SetupDL_25Opa(play->state.gfxCtx); + Matrix_Translate(-30, -20, 0, MTXMODE_APPLY); + Matrix_Scale(0.03f, 0.01f, 0.03f, MTXMODE_APPLY); + gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_MODELVIEW | G_MTX_LOAD); + gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gUnusedVaseDL); + + Gfx_SetupDL_25Opa(play->state.gfxCtx); + Matrix_Translate(0, 600, 900, MTXMODE_APPLY); + gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_MODELVIEW | G_MTX_LOAD); + gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gUnusedVaseDL); + + CLOSE_DISPS(play->state.gfxCtx); +} + extern "C" void Randomizer_DrawFishingPoleGI(PlayState* play, GetItemEntry* getItemEntry) { Vec3f pos; OPEN_DISPS(play->state.gfxCtx); diff --git a/soh/soh/Enhancements/randomizer/draw.h b/soh/soh/Enhancements/randomizer/draw.h index 8483a7bf966..b8a20ac561a 100644 --- a/soh/soh/Enhancements/randomizer/draw.h +++ b/soh/soh/Enhancements/randomizer/draw.h @@ -21,6 +21,7 @@ void Randomizer_DrawTriforcePiece(PlayState* play, GetItemEntry getItemEntry); void Randomizer_DrawTriforcePieceGI(PlayState* play, GetItemEntry getItemEntry); void Randomizer_DrawOcarinaButton(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawBronzeScale(PlayState* play, GetItemEntry* getItemEntry); +void Randomizer_DrawKneePads(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawFishingPoleGI(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawSkeletonKey(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawMysteryItem(PlayState* play, GetItemEntry* getItemEntry); diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 82a9336fad0..971805635b0 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -795,6 +795,9 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l va_copy(args, originalArgs); switch (id) { + case VB_ROLL: + *should = !RAND_GET_OPTION(RSK_SHUFFLE_ROLL) || Flags_GetRandomizerInf(RAND_INF_CAN_ROLL); + break; case VB_ALLOW_ENTRANCE_CS_FOR_EITHER_AGE: { s32 entranceIndex = va_arg(args, s32); diff --git a/soh/soh/Enhancements/randomizer/item_list.cpp b/soh/soh/Enhancements/randomizer/item_list.cpp index 3f6535c8326..21e801ed43c 100644 --- a/soh/soh/Enhancements/randomizer/item_list.cpp +++ b/soh/soh/Enhancements/randomizer/item_list.cpp @@ -349,9 +349,12 @@ void Rando::StaticData::InitItemTable() { itemTable[RG_OCARINA_C_RIGHT_BUTTON] = Item(RG_OCARINA_C_RIGHT_BUTTON, Text{ "Ocarina C Right Button", "Touche C-Droit de l'Ocarina", "C-Rechts-Taste der Okarina" }, ITEMTYPE_ITEM, GI_MAP, true, LOGIC_OCARINA_C_RIGHT_BUTTON, RHT_OCARINA_C_RIGHT_BUTTON, RG_OCARINA_C_RIGHT_BUTTON, OBJECT_GI_MAP, GID_STONE_OF_AGONY, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_OCARINA_C_RIGHT_BUTTON].SetCustomDrawFunc(Randomizer_DrawOcarinaButton); - itemTable[RG_BRONZE_SCALE] = Item(RG_BRONZE_SCALE, Text{ "Bronze Scale", "Écaille de Bronze", "Bronzene Schuppe" }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, LOGIC_PROGRESSIVE_WALLET, RHT_BRONZE_SCALE, RG_BRONZE_SCALE, OBJECT_GI_SCALE, GID_SCALE_SILVER, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_BRONZE_SCALE] = Item(RG_BRONZE_SCALE, Text{ "Bronze Scale", "Écaille de Bronze", "Bronzene Schuppe" }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, LOGIC_NONE, RHT_BRONZE_SCALE, RG_BRONZE_SCALE, OBJECT_GI_SCALE, GID_SCALE_SILVER, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_BRONZE_SCALE].SetCustomDrawFunc(Randomizer_DrawBronzeScale); + itemTable[RG_ROLL] = Item(RG_ROLL, Text{ "Roll", "TODO", "TODO" }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, LOGIC_NONE, RHT_ROLL, RG_ROLL, OBJECT_GI_SCALE, GID_SCALE_SILVER, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_ROLL].SetCustomDrawFunc(Randomizer_DrawKneePads); + itemTable[RG_BOMBCHU_BAG] = Item(RG_BOMBCHU_BAG, Text{ "Bombchu Bag", "Sac de Missiles Teigneux", "Krabbelminentasche" }, ITEMTYPE_ITEM, RG_BOMBCHU_BAG, true, LOGIC_BOMBCHUS, RHT_BOMBCHU_BAG, RG_BOMBCHU_BAG, OBJECT_GI_BOMB_2, GID_BOMBCHU, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_BOMBCHU_BAG].SetCustomDrawFunc(Randomizer_DrawBombchuBag); diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index 26e30492f9d..4bfd3a8bd2d 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -222,6 +222,8 @@ bool Logic::HasItem(RandomizerGet itemName) { return CurrentUpgrade(UPG_SCALE) >= 1; case RG_GOLDEN_SCALE: return CurrentUpgrade(UPG_SCALE) >= 2; + case RG_ROLL: + return CheckRandoInf(RAND_INF_CAN_ROLL); case RG_POCKET_EGG: return CheckRandoInf(RAND_INF_ADULT_TRADES_HAS_POCKET_EGG); case RG_COJIRO: @@ -376,6 +378,8 @@ bool Logic::CanUse(RandomizerGet itemName) { return HasItem(RG_CHILD_WALLET); // as long as you have enough rubies case RG_EPONA: return IsAdult && CanUse(RG_EPONAS_SONG); + case RG_ROLL: + return IsChild && IsAdult; // possible crash ici // Bottle Items case RG_BOTTLE_WITH_BUGS: @@ -1157,7 +1161,7 @@ bool Logic::CanBreakPots() { } bool Logic::CanBreakCrates() { - return true; + return HasItem(RG_ROLL) || CanUse(RG_MEGATON_HAMMER) || CanUse(RG_BOMB_BAG) || CanUse(RG_BOMBCHU_5); } bool Logic::CanBreakSmallCrates() { @@ -1165,7 +1169,7 @@ bool Logic::CanBreakSmallCrates() { } bool Logic::CanBonkTrees() { - return true; + return HasItem(RG_ROLL); } bool Logic::HasExplosives() { @@ -1575,6 +1579,9 @@ void Logic::ApplyItemEffect(Item& item, bool state) { case RG_CLAIM_CHECK: SetRandoInf(randoGet - RG_COJIRO + RAND_INF_ADULT_TRADES_HAS_COJIRO, state); break; + case RG_ROLL: + SetRandoInf(RAND_INF_CAN_ROLL, state); + break; case RG_PROGRESSIVE_HOOKSHOT: { uint8_t i; for (i = 0; i < 3; i++) { @@ -2312,6 +2319,11 @@ void Logic::Reset(bool resetSaveContext /*= true*/) { SetRandoInf(RAND_INF_CAN_SWIM, true); } + // If we're not shuffling roll, we start with it + if (ctx->GetOption(RSK_SHUFFLE_ROLL).Is(false)) { + SetRandoInf(RAND_INF_CAN_ROLL, true); + } + // If we're not shuffling child's wallet, we start with it if (ctx->GetOption(RSK_SHUFFLE_CHILD_WALLET).Is(false)) { SetRandoInf(RAND_INF_HAS_WALLET, true); diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp index c544d3b2904..c28d4d26444 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -253,6 +253,7 @@ void Settings::CreateOptionDescriptions() { "\n" "If you enter a water entrance without swim you will be respawned on land to prevent infinite death loops.\n" "If you void out in Water Temple you will immediately be kicked out to prevent a softlock."; + mOptionDescriptions[RSK_SHUFFLE_ROLL] = "Shuffles the ability to use roll into the item pool."; mOptionDescriptions[RSK_SHUFFLE_WEIRD_EGG] = "Shuffles the Weird Egg from Malon in to the item pool. Enabling " "\"Skip Child Zelda\" disables this feature.\n" "\n" diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index cac735121ef..f18d16cb7b2 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -5488,7 +5488,7 @@ CustomMessage Randomizer::GetGoronMessage(u16 index) { void Randomizer::CreateCustomMessages() { // RANDTODO: Translate into french and german and replace GIMESSAGE_UNTRANSLATED // with GIMESSAGE(getItemID, itemID, english, german, french). - const std::array getItemMessages = { { + const std::array getItemMessages = { { GIMESSAGE(RG_GREG_RUPEE, ITEM_MASK_GORON, "You found %gGreg%w!", "%gGreg%w! Du hast ihn&wirklich gefunden!", "Félicitation! Vous avez trouvé %gGreg%w!"), GIMESSAGE(RG_MASTER_SWORD, ITEM_SWORD_MASTER, "You found the %gMaster Sword%w!", @@ -5812,6 +5812,9 @@ void Randomizer::CreateCustomMessages() { GIMESSAGE(RG_BRONZE_SCALE, ITEM_SCALE_SILVER, "You got the %rBronze Scale%w!&The power of buoyancy is yours!", "Du hast die %rBronzene Schuppe%w&erhalten! Die Fähigkeit zu&Schwimmen ist nun dein!", "Vous obtenez l'%rÉcaille de Bronze%w!&Le pouvoir de la flottabilité est&à vous!"), + GIMESSAGE(RG_ROLL, ITEM_SCALE_SILVER, "You got the %rAbility to Roll%w!&", + "TODO", + "Vous obtenez la %rCapacité à faire des roulade%w!"), GIMESSAGE(RG_FISHING_POLE, ITEM_FISHING_POLE, "You found a lost %rFishing Pole%w!&Time to hit the pond!", "Du hast eine verlorene %rAngelrute%w&gefunden!&Zeit, im Teich&zu angeln!", "Vous obtenez une %rCanne à pêche%w&perdue!&Il est temps d'aller à %gl'étang%w!"), @@ -5982,6 +5985,7 @@ extern "C" u8 Return_Item_Entry(GetItemEntry itemEntry, u8 returnItem); std::map randomizerGetToRandInf = { { RG_FISHING_POLE, RAND_INF_FISHING_POLE_FOUND }, { RG_BRONZE_SCALE, RAND_INF_CAN_SWIM }, + { RG_ROLL, RAND_INF_CAN_ROLL }, { RG_QUIVER_INF, RAND_INF_HAS_INFINITE_QUIVER }, { RG_BOMB_BAG_INF, RAND_INF_HAS_INFINITE_BOMB_BAG }, { RG_BULLET_BAG_INF, RAND_INF_HAS_INFINITE_BULLET_BAG }, diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index f589e82c134..9f930282e3c 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -4193,6 +4193,7 @@ typedef enum { RG_HINT, RG_TYCOON_WALLET, RG_BRONZE_SCALE, + RG_ROLL, RG_CHILD_WALLET, RG_BOMBCHU_BAG, RG_QUIVER_INF, @@ -5390,6 +5391,7 @@ typedef enum { RHT_OCARINA_C_LEFT_BUTTON, RHT_OCARINA_C_RIGHT_BUTTON, RHT_BRONZE_SCALE, + RHT_ROLL, RHT_FISHING_POLE, RHT_SKELETON_KEY, RHT_EPONA, @@ -5967,6 +5969,7 @@ typedef enum { RSK_SHUFFLE_OCARINA, RSK_SHUFFLE_OCARINA_BUTTONS, RSK_SHUFFLE_SWIM, + RSK_SHUFFLE_ROLL, RSK_STARTING_DEKU_SHIELD, RSK_STARTING_KOKIRI_SWORD, RSK_STARTING_MASTER_SWORD, diff --git a/soh/soh/Enhancements/randomizer/randomizer_inf.h b/soh/soh/Enhancements/randomizer/randomizer_inf.h index 8742805a6f2..147e107266c 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_inf.h +++ b/soh/soh/Enhancements/randomizer/randomizer_inf.h @@ -1064,6 +1064,7 @@ DEFINE_RAND_INF(RAND_INF_LLR_TREE) DEFINE_RAND_INF(RAND_INF_CAUGHT_LOACH) DEFINE_RAND_INF(RAND_INF_CAN_SWIM) +DEFINE_RAND_INF(RAND_INF_CAN_ROLL) DEFINE_RAND_INF(RAND_INF_HAS_WALLET) diff --git a/soh/soh/Enhancements/randomizer/savefile.cpp b/soh/soh/Enhancements/randomizer/savefile.cpp index 106cecb11a4..a8fd6c0d2de 100644 --- a/soh/soh/Enhancements/randomizer/savefile.cpp +++ b/soh/soh/Enhancements/randomizer/savefile.cpp @@ -263,6 +263,10 @@ extern "C" void Randomizer_InitSaveFile() { Flags_SetRandomizerInf(RAND_INF_CAN_SWIM); } + if (Randomizer_GetSettingValue(RSK_SHUFFLE_ROLL) == RO_GENERIC_OFF) { + Flags_SetRandomizerInf(RAND_INF_CAN_ROLL); + } + if (Randomizer_GetSettingValue(RSK_SHUFFLE_CHILD_WALLET) == RO_GENERIC_OFF) { Flags_SetRandomizerInf(RAND_INF_HAS_WALLET); } diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index a7dbb38d6c9..f299240e4e7 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -214,6 +214,7 @@ void Settings::CreateOptions() { OPT_BOOL(RSK_SHUFFLE_OCARINA, "Shuffle Ocarinas", CVAR_RANDOMIZER_SETTING("ShuffleOcarinas"), mOptionDescriptions[RSK_SHUFFLE_OCARINA]); OPT_BOOL(RSK_SHUFFLE_OCARINA_BUTTONS, "Shuffle Ocarina Buttons", CVAR_RANDOMIZER_SETTING("ShuffleOcarinaButtons"), mOptionDescriptions[RSK_SHUFFLE_OCARINA_BUTTONS]); OPT_BOOL(RSK_SHUFFLE_SWIM, "Shuffle Swim", CVAR_RANDOMIZER_SETTING("ShuffleSwim"), mOptionDescriptions[RSK_SHUFFLE_SWIM]); + OPT_BOOL(RSK_SHUFFLE_ROLL, "Shuffle Roll", CVAR_RANDOMIZER_SETTING("ShuffleRoll"), mOptionDescriptions[RSK_SHUFFLE_ROLL]); OPT_BOOL(RSK_SHUFFLE_WEIRD_EGG, "Shuffle Weird Egg", CVAR_RANDOMIZER_SETTING("ShuffleWeirdEgg"), mOptionDescriptions[RSK_SHUFFLE_WEIRD_EGG]); OPT_BOOL(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD, "Shuffle Gerudo Membership Card", CVAR_RANDOMIZER_SETTING("ShuffleGerudoToken"), mOptionDescriptions[RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD]); OPT_U8(RSK_SHUFFLE_POTS, "Shuffle Pots", {"Off", "Dungeons", "Overworld", "All Pots"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShufflePots"), mOptionDescriptions[RSK_SHUFFLE_POTS], WidgetType::Combobox, RO_SHUFFLE_POTS_OFF); @@ -1261,6 +1262,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_OCARINA], &mOptions[RSK_SHUFFLE_OCARINA_BUTTONS], &mOptions[RSK_SHUFFLE_SWIM], + &mOptions[RSK_SHUFFLE_ROLL], &mOptions[RSK_SHUFFLE_WEIRD_EGG], &mOptions[RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD], &mOptions[RSK_SHUFFLE_FISHING_POLE], @@ -1564,6 +1566,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_OCARINA], &mOptions[RSK_SHUFFLE_OCARINA_BUTTONS], &mOptions[RSK_SHUFFLE_SWIM], + &mOptions[RSK_SHUFFLE_ROLL], &mOptions[RSK_SHUFFLE_WEIRD_EGG], &mOptions[RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD], &mOptions[RSK_SHUFFLE_MERCHANTS], 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 7da8447c03a..32995130075 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -6301,11 +6301,17 @@ s32 func_8083BBA0(Player* this, PlayState* play) { } void Player_SetupRoll(Player* this, PlayState* play) { + if (!GameInteractor_Should(VB_ROLL, true)) { + return false; + } + + else { Player_SetupAction(play, this, Player_Action_Roll, 0); LinkAnimation_PlayOnceSetSpeed(play, &this->skelAnime, GET_PLAYER_ANIM(PLAYER_ANIMGROUP_landing_roll, this->modelAnimType), 1.25f * sWaterSpeedFactor); gSaveContext.ship.stats.count[COUNT_ROLLS]++; + } } s32 Player_TryRoll(Player* this, PlayState* play) { From 782ca3eb91e7f3adf21d38a5cab5ade86ca634de Mon Sep 17 00:00:00 2001 From: TheLynk Date: Wed, 12 Nov 2025 03:45:33 +0100 Subject: [PATCH 02/45] Clang Format --- soh/soh/Enhancements/randomizer/randomizer.cpp | 3 +-- soh/src/overlays/actors/ovl_player_actor/z_player.c | 10 +++++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index f18d16cb7b2..2808eb929cb 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -5812,8 +5812,7 @@ void Randomizer::CreateCustomMessages() { GIMESSAGE(RG_BRONZE_SCALE, ITEM_SCALE_SILVER, "You got the %rBronze Scale%w!&The power of buoyancy is yours!", "Du hast die %rBronzene Schuppe%w&erhalten! Die Fähigkeit zu&Schwimmen ist nun dein!", "Vous obtenez l'%rÉcaille de Bronze%w!&Le pouvoir de la flottabilité est&à vous!"), - GIMESSAGE(RG_ROLL, ITEM_SCALE_SILVER, "You got the %rAbility to Roll%w!&", - "TODO", + GIMESSAGE(RG_ROLL, ITEM_SCALE_SILVER, "You got the %rAbility to Roll%w!&", "TODO", "Vous obtenez la %rCapacité à faire des roulade%w!"), GIMESSAGE(RG_FISHING_POLE, ITEM_FISHING_POLE, "You found a lost %rFishing Pole%w!&Time to hit the pond!", "Du hast eine verlorene %rAngelrute%w&gefunden!&Zeit, im Teich&zu angeln!", 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 32995130075..bc356610943 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -6306,11 +6306,11 @@ void Player_SetupRoll(Player* this, PlayState* play) { } else { - Player_SetupAction(play, this, Player_Action_Roll, 0); - LinkAnimation_PlayOnceSetSpeed(play, &this->skelAnime, - GET_PLAYER_ANIM(PLAYER_ANIMGROUP_landing_roll, this->modelAnimType), - 1.25f * sWaterSpeedFactor); - gSaveContext.ship.stats.count[COUNT_ROLLS]++; + Player_SetupAction(play, this, Player_Action_Roll, 0); + LinkAnimation_PlayOnceSetSpeed(play, &this->skelAnime, + GET_PLAYER_ANIM(PLAYER_ANIMGROUP_landing_roll, this->modelAnimType), + 1.25f * sWaterSpeedFactor); + gSaveContext.ship.stats.count[COUNT_ROLLS]++; } } From aedcc5314ad2483fdada98a5e8f1b27bf9ba1c2b Mon Sep 17 00:00:00 2001 From: TheLynk Date: Wed, 12 Nov 2025 05:15:12 +0100 Subject: [PATCH 03/45] New Model For Roll --- soh/soh/Enhancements/randomizer/draw.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/draw.cpp b/soh/soh/Enhancements/randomizer/draw.cpp index 539df574c6e..c72a2c7e853 100644 --- a/soh/soh/Enhancements/randomizer/draw.cpp +++ b/soh/soh/Enhancements/randomizer/draw.cpp @@ -1112,16 +1112,16 @@ extern "C" void Randomizer_DrawBronzeScale(PlayState* play, GetItemEntry* getIte extern "C" void Randomizer_DrawKneePads(PlayState* play, GetItemEntry* getItemEntry) { OPEN_DISPS(play->state.gfxCtx); - - Gfx_SetupDL_25Opa(play->state.gfxCtx); - Matrix_Translate(-30, -20, 0, MTXMODE_APPLY); - Matrix_Scale(0.03f, 0.01f, 0.03f, MTXMODE_APPLY); - gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_MODELVIEW | G_MTX_LOAD); - gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gUnusedVaseDL); - + Gfx_SetupDL_25Opa(play->state.gfxCtx); - Matrix_Translate(0, 600, 900, MTXMODE_APPLY); - gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_MODELVIEW | G_MTX_LOAD); + + // Objet central qui roule - réduit de 20% avec centrage ajusté + Matrix_Translate(21.0f, 0.0f, 0.0f, MTXMODE_APPLY); + Matrix_RotateZ(1.57f, MTXMODE_APPLY); + Matrix_RotateY(play->gameplayFrames * 0.15f, MTXMODE_APPLY); + Matrix_Scale(0.018f, 0.018f, 0.018f, MTXMODE_APPLY); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), + G_MTX_MODELVIEW | G_MTX_LOAD); gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gUnusedVaseDL); CLOSE_DISPS(play->state.gfxCtx); From 4ec43088afd29e8369f82301708ff60e25147904 Mon Sep 17 00:00:00 2001 From: TheLynk Date: Wed, 12 Nov 2025 05:29:02 +0100 Subject: [PATCH 04/45] Rename Custom Model in Code --- soh/soh/Enhancements/randomizer/draw.cpp | 6 +++--- soh/soh/Enhancements/randomizer/draw.h | 2 +- soh/soh/Enhancements/randomizer/item_list.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/draw.cpp b/soh/soh/Enhancements/randomizer/draw.cpp index c72a2c7e853..b02116614ec 100644 --- a/soh/soh/Enhancements/randomizer/draw.cpp +++ b/soh/soh/Enhancements/randomizer/draw.cpp @@ -1110,11 +1110,11 @@ extern "C" void Randomizer_DrawBronzeScale(PlayState* play, GetItemEntry* getIte CLOSE_DISPS(play->state.gfxCtx); } -extern "C" void Randomizer_DrawKneePads(PlayState* play, GetItemEntry* getItemEntry) { +extern "C" void Randomizer_DrawRollAbility(PlayState* play, GetItemEntry* getItemEntry) { OPEN_DISPS(play->state.gfxCtx); - + Gfx_SetupDL_25Opa(play->state.gfxCtx); - + // Objet central qui roule - réduit de 20% avec centrage ajusté Matrix_Translate(21.0f, 0.0f, 0.0f, MTXMODE_APPLY); Matrix_RotateZ(1.57f, MTXMODE_APPLY); diff --git a/soh/soh/Enhancements/randomizer/draw.h b/soh/soh/Enhancements/randomizer/draw.h index b8a20ac561a..10013952361 100644 --- a/soh/soh/Enhancements/randomizer/draw.h +++ b/soh/soh/Enhancements/randomizer/draw.h @@ -21,7 +21,7 @@ void Randomizer_DrawTriforcePiece(PlayState* play, GetItemEntry getItemEntry); void Randomizer_DrawTriforcePieceGI(PlayState* play, GetItemEntry getItemEntry); void Randomizer_DrawOcarinaButton(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawBronzeScale(PlayState* play, GetItemEntry* getItemEntry); -void Randomizer_DrawKneePads(PlayState* play, GetItemEntry* getItemEntry); +void Randomizer_DrawRollAbility(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawFishingPoleGI(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawSkeletonKey(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawMysteryItem(PlayState* play, GetItemEntry* getItemEntry); diff --git a/soh/soh/Enhancements/randomizer/item_list.cpp b/soh/soh/Enhancements/randomizer/item_list.cpp index 21e801ed43c..75fd13aa20c 100644 --- a/soh/soh/Enhancements/randomizer/item_list.cpp +++ b/soh/soh/Enhancements/randomizer/item_list.cpp @@ -353,7 +353,7 @@ void Rando::StaticData::InitItemTable() { itemTable[RG_BRONZE_SCALE].SetCustomDrawFunc(Randomizer_DrawBronzeScale); itemTable[RG_ROLL] = Item(RG_ROLL, Text{ "Roll", "TODO", "TODO" }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, LOGIC_NONE, RHT_ROLL, RG_ROLL, OBJECT_GI_SCALE, GID_SCALE_SILVER, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); - itemTable[RG_ROLL].SetCustomDrawFunc(Randomizer_DrawKneePads); + itemTable[RG_ROLL].SetCustomDrawFunc(Randomizer_DrawRollAbility); itemTable[RG_BOMBCHU_BAG] = Item(RG_BOMBCHU_BAG, Text{ "Bombchu Bag", "Sac de Missiles Teigneux", "Krabbelminentasche" }, ITEMTYPE_ITEM, RG_BOMBCHU_BAG, true, LOGIC_BOMBCHUS, RHT_BOMBCHU_BAG, RG_BOMBCHU_BAG, OBJECT_GI_BOMB_2, GID_BOMBCHU, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_BOMBCHU_BAG].SetCustomDrawFunc(Randomizer_DrawBombchuBag); From 4c3b5a7bb12e2b48982b0f3904568a2f4d7b63f3 Mon Sep 17 00:00:00 2001 From: TheLynk Date: Wed, 12 Nov 2025 05:50:19 +0100 Subject: [PATCH 05/45] Add more translation --- .../randomizer/3drando/hint_list/hint_list_item.cpp | 2 +- soh/soh/Enhancements/randomizer/logic.cpp | 2 +- soh/soh/Enhancements/randomizer/randomizer.cpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp index 98b59c7c6c4..b3c12b9b0b4 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp @@ -2100,7 +2100,7 @@ void StaticData::HintTable_Init_Item() { { CustomMessage("a master unlocker", /*german*/ "ein Meisterentsperrer", /*french*/ "un Kit de Déverrouillage") }); // /*spanish*/un desbloqueador maestro - hintTextTable[RHT_ROLL] = HintText(CustomMessage("the ability to roll", /*german*/"!!!", /*french*/"!!!")); + hintTextTable[RHT_ROLL] = HintText(CustomMessage("the ability to roll", /*german*/"la capacité de faire roulade", /*french*/"die Fähigkeit zu rollen")); //RANDOTODO if these are ever used for anything other than name, they want abscure and ambiguous hints hintTextTable[RHT_QUIVER_INF] = HintText(CustomMessage("an infinite Quiver", /*german*/"der unendliche Köcher", /*french*/"un Carquois Infini")); diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index 4bfd3a8bd2d..4dcbe86425d 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -379,7 +379,7 @@ bool Logic::CanUse(RandomizerGet itemName) { case RG_EPONA: return IsAdult && CanUse(RG_EPONAS_SONG); case RG_ROLL: - return IsChild && IsAdult; // possible crash ici + return IsChild && IsAdult; // Bottle Items case RG_BOTTLE_WITH_BUGS: diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 2808eb929cb..215c3d73681 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -5812,8 +5812,8 @@ void Randomizer::CreateCustomMessages() { GIMESSAGE(RG_BRONZE_SCALE, ITEM_SCALE_SILVER, "You got the %rBronze Scale%w!&The power of buoyancy is yours!", "Du hast die %rBronzene Schuppe%w&erhalten! Die Fähigkeit zu&Schwimmen ist nun dein!", "Vous obtenez l'%rÉcaille de Bronze%w!&Le pouvoir de la flottabilité est&à vous!"), - GIMESSAGE(RG_ROLL, ITEM_SCALE_SILVER, "You got the %rAbility to Roll%w!&", "TODO", - "Vous obtenez la %rCapacité à faire des roulade%w!"), + GIMESSAGE(RG_ROLL, ITEM_SCALE_SILVER, "You got the %rAbility to Roll%w!&", + "Du hast die Fähigkeit, %rzu&würfeln!&", "Vous obtenez la %rCapacité à faire&des roulade%w!"), GIMESSAGE(RG_FISHING_POLE, ITEM_FISHING_POLE, "You found a lost %rFishing Pole%w!&Time to hit the pond!", "Du hast eine verlorene %rAngelrute%w&gefunden!&Zeit, im Teich&zu angeln!", "Vous obtenez une %rCanne à pêche%w&perdue!&Il est temps d'aller à %gl'étang%w!"), From c78f3e25cb139b41af20c2ce5b46df6ec0ee2f1e Mon Sep 17 00:00:00 2001 From: TheLynk Date: Wed, 12 Nov 2025 06:06:56 +0100 Subject: [PATCH 06/45] Tweak Translation --- soh/soh/Enhancements/randomizer/item_list.cpp | 2 +- soh/soh/Enhancements/randomizer/option_descriptions.cpp | 2 +- soh/soh/Enhancements/randomizer/randomizer.cpp | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/item_list.cpp b/soh/soh/Enhancements/randomizer/item_list.cpp index 75fd13aa20c..bee59e5f3a6 100644 --- a/soh/soh/Enhancements/randomizer/item_list.cpp +++ b/soh/soh/Enhancements/randomizer/item_list.cpp @@ -352,7 +352,7 @@ void Rando::StaticData::InitItemTable() { itemTable[RG_BRONZE_SCALE] = Item(RG_BRONZE_SCALE, Text{ "Bronze Scale", "Écaille de Bronze", "Bronzene Schuppe" }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, LOGIC_NONE, RHT_BRONZE_SCALE, RG_BRONZE_SCALE, OBJECT_GI_SCALE, GID_SCALE_SILVER, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_BRONZE_SCALE].SetCustomDrawFunc(Randomizer_DrawBronzeScale); - itemTable[RG_ROLL] = Item(RG_ROLL, Text{ "Roll", "TODO", "TODO" }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, LOGIC_NONE, RHT_ROLL, RG_ROLL, OBJECT_GI_SCALE, GID_SCALE_SILVER, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_ROLL] = Item(RG_ROLL, Text{ "Roll", "Rouler", "Rolle" }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, LOGIC_NONE, RHT_ROLL, RG_ROLL, OBJECT_GI_SCALE, GID_SCALE_SILVER, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_ROLL].SetCustomDrawFunc(Randomizer_DrawRollAbility); itemTable[RG_BOMBCHU_BAG] = Item(RG_BOMBCHU_BAG, Text{ "Bombchu Bag", "Sac de Missiles Teigneux", "Krabbelminentasche" }, ITEMTYPE_ITEM, RG_BOMBCHU_BAG, true, LOGIC_BOMBCHUS, RHT_BOMBCHU_BAG, RG_BOMBCHU_BAG, OBJECT_GI_BOMB_2, GID_BOMBCHU, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp index c28d4d26444..5ec69f8d7cf 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -253,7 +253,7 @@ void Settings::CreateOptionDescriptions() { "\n" "If you enter a water entrance without swim you will be respawned on land to prevent infinite death loops.\n" "If you void out in Water Temple you will immediately be kicked out to prevent a softlock."; - mOptionDescriptions[RSK_SHUFFLE_ROLL] = "Shuffles the ability to use roll into the item pool."; + mOptionDescriptions[RSK_SHUFFLE_ROLL] = "Shuffles the ability do a roll into the item pool."; mOptionDescriptions[RSK_SHUFFLE_WEIRD_EGG] = "Shuffles the Weird Egg from Malon in to the item pool. Enabling " "\"Skip Child Zelda\" disables this feature.\n" "\n" diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 215c3d73681..9e39d768334 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -5812,8 +5812,9 @@ void Randomizer::CreateCustomMessages() { GIMESSAGE(RG_BRONZE_SCALE, ITEM_SCALE_SILVER, "You got the %rBronze Scale%w!&The power of buoyancy is yours!", "Du hast die %rBronzene Schuppe%w&erhalten! Die Fähigkeit zu&Schwimmen ist nun dein!", "Vous obtenez l'%rÉcaille de Bronze%w!&Le pouvoir de la flottabilité est&à vous!"), - GIMESSAGE(RG_ROLL, ITEM_SCALE_SILVER, "You got the %rAbility to Roll%w!&", - "Du hast die Fähigkeit, %rzu&würfeln!&", "Vous obtenez la %rCapacité à faire&des roulade%w!"), + GIMESSAGE(RG_ROLL, ITEM_SCALE_SILVER, "You got the %rAbility do a roll%w!", + "Du hast die Fähigkeit, %reinen Wurf&zu machen%w!", + "Vous obtenez la %rCapacité à faire&des roulade%w!"), GIMESSAGE(RG_FISHING_POLE, ITEM_FISHING_POLE, "You found a lost %rFishing Pole%w!&Time to hit the pond!", "Du hast eine verlorene %rAngelrute%w&gefunden!&Zeit, im Teich&zu angeln!", "Vous obtenez une %rCanne à pêche%w&perdue!&Il est temps d'aller à %gl'étang%w!"), From b61e3bf1cca906fa85aa3747bd6e96dbf3e53c5d Mon Sep 17 00:00:00 2001 From: TheLynk <44308308+TheLynk@users.noreply.github.com> Date: Wed, 12 Nov 2025 17:16:10 +0100 Subject: [PATCH 07/45] Update soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Philip Dubé --- .../game-interactor/vanilla-behavior/GIVanillaBehavior.h | 1 - 1 file changed, 1 deletion(-) diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index bbf4ba9454d..dddfcaab0a1 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -324,7 +324,6 @@ typedef enum { // ``` // #### `args` // - None - VB_CRAWL_SPEED_ENTER, // #### `result` From 3d9c729157cd78c2d11f80345ba2b4f8c422afaa Mon Sep 17 00:00:00 2001 From: TheLynk Date: Wed, 12 Nov 2025 17:38:24 +0100 Subject: [PATCH 08/45] Tweak code | Thx @serprex --- soh/soh/Enhancements/randomizer/logic.cpp | 2 +- soh/src/overlays/actors/ovl_player_actor/z_player.c | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index 4dcbe86425d..bc3c2caca0f 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -379,7 +379,7 @@ bool Logic::CanUse(RandomizerGet itemName) { case RG_EPONA: return IsAdult && CanUse(RG_EPONAS_SONG); case RG_ROLL: - return IsChild && IsAdult; + return HasItem(RG_ROLL); // Bottle Items case RG_BOTTLE_WITH_BUGS: 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 bc356610943..b4be8d00e4c 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -6301,11 +6301,7 @@ s32 func_8083BBA0(Player* this, PlayState* play) { } void Player_SetupRoll(Player* this, PlayState* play) { - if (!GameInteractor_Should(VB_ROLL, true)) { - return false; - } - - else { + if (GameInteractor_Should(VB_ROLL, true)) { Player_SetupAction(play, this, Player_Action_Roll, 0); LinkAnimation_PlayOnceSetSpeed(play, &this->skelAnime, GET_PLAYER_ANIM(PLAYER_ANIMGROUP_landing_roll, this->modelAnimType), From b2b6e3b70369dbf5204ba30b450f0706491c765c Mon Sep 17 00:00:00 2001 From: TheLynk <44308308+TheLynk@users.noreply.github.com> Date: Wed, 12 Nov 2025 18:52:46 +0100 Subject: [PATCH 09/45] Update soh/soh/Enhancements/randomizer/logic.cpp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Philip Dubé --- soh/soh/Enhancements/randomizer/logic.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index bc3c2caca0f..7df8163b289 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -378,9 +378,6 @@ bool Logic::CanUse(RandomizerGet itemName) { return HasItem(RG_CHILD_WALLET); // as long as you have enough rubies case RG_EPONA: return IsAdult && CanUse(RG_EPONAS_SONG); - case RG_ROLL: - return HasItem(RG_ROLL); - // Bottle Items case RG_BOTTLE_WITH_BUGS: return Get(LOGIC_BUG_SHRUB) || Get(LOGIC_WANDERING_BUGS) || Get(LOGIC_BUG_ROCK) || Get(LOGIC_BUGS_ACCESS); From e1d4cf0c25fbce67b3edc79aea313c3dd6b6ac73 Mon Sep 17 00:00:00 2001 From: TheLynk Date: Thu, 13 Nov 2025 15:06:50 +0100 Subject: [PATCH 10/45] Fix translation --- .../randomizer/3drando/hint_list/hint_list_item.cpp | 2 +- soh/soh/Enhancements/randomizer/randomizer.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp index b3c12b9b0b4..ebe67bc25b0 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp @@ -2100,7 +2100,7 @@ void StaticData::HintTable_Init_Item() { { CustomMessage("a master unlocker", /*german*/ "ein Meisterentsperrer", /*french*/ "un Kit de Déverrouillage") }); // /*spanish*/un desbloqueador maestro - hintTextTable[RHT_ROLL] = HintText(CustomMessage("the ability to roll", /*german*/"la capacité de faire roulade", /*french*/"die Fähigkeit zu rollen")); + hintTextTable[RHT_ROLL] = HintText(CustomMessage("the ability to roll", /*german*/"die Fähigkeit zu rollen", /*french*/"la capacité de faire des roulades")); //RANDOTODO if these are ever used for anything other than name, they want abscure and ambiguous hints hintTextTable[RHT_QUIVER_INF] = HintText(CustomMessage("an infinite Quiver", /*german*/"der unendliche Köcher", /*french*/"un Carquois Infini")); diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 9e39d768334..d1be2103b1a 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -5814,7 +5814,7 @@ void Randomizer::CreateCustomMessages() { "Vous obtenez l'%rÉcaille de Bronze%w!&Le pouvoir de la flottabilité est&à vous!"), GIMESSAGE(RG_ROLL, ITEM_SCALE_SILVER, "You got the %rAbility do a roll%w!", "Du hast die Fähigkeit, %reinen Wurf&zu machen%w!", - "Vous obtenez la %rCapacité à faire&des roulade%w!"), + "Vous obtenez la %rCapacité de faire&des roulades%w!"), GIMESSAGE(RG_FISHING_POLE, ITEM_FISHING_POLE, "You found a lost %rFishing Pole%w!&Time to hit the pond!", "Du hast eine verlorene %rAngelrute%w&gefunden!&Zeit, im Teich&zu angeln!", "Vous obtenez une %rCanne à pêche%w&perdue!&Il est temps d'aller à %gl'étang%w!"), From 82b00c2d71cf84595c60c354b13bb8098c8700f9 Mon Sep 17 00:00:00 2001 From: TheLynk Date: Mon, 17 Nov 2025 16:23:08 +0100 Subject: [PATCH 11/45] Re Add All the branch (but no Shuffle Silver Rupee) | V1.0 --- .../Cheats/NoLikeLikeItemSteal.cpp | 17 ++ soh/soh/Enhancements/DropThrowOnlyActors.cpp | 17 ++ soh/soh/Enhancements/ExtraTraps.cpp | 221 +++++++++++++++++- soh/soh/Enhancements/QoL/ResetNaviTimer.cpp | 2 +- .../Enhancements/debugger/debugSaveEditor.cpp | 1 - .../vanilla-behavior/GIVanillaBehavior.h | 32 +++ soh/soh/Enhancements/gameplaystats.cpp | 2 +- .../hint_list/hint_list_exclude_overworld.cpp | 9 + .../3drando/hint_list/hint_list_item.cpp | 4 + .../randomizer/3drando/item_pool.cpp | 21 ++ .../Enhancements/randomizer/ShuffleTrees.cpp | 158 ++++++++++--- soh/soh/Enhancements/randomizer/context.cpp | 1 + soh/soh/Enhancements/randomizer/draw.cpp | 31 ++- soh/soh/Enhancements/randomizer/draw.h | 2 + .../Enhancements/randomizer/hook_handlers.cpp | 46 ++++ soh/soh/Enhancements/randomizer/item_list.cpp | 25 +- soh/soh/Enhancements/randomizer/location.cpp | 9 + soh/soh/Enhancements/randomizer/location.h | 4 + .../randomizer/location_access.cpp | 49 ++-- .../Enhancements/randomizer/location_access.h | 4 +- .../dungeons/bottom_of_the_well.cpp | 32 +-- .../location_access/dungeons/deku_tree.cpp | 24 +- .../dungeons/dodongos_cavern.cpp | 24 +- .../location_access/dungeons/fire_temple.cpp | 52 ++--- .../dungeons/forest_temple.cpp | 58 ++--- .../dungeons/ganons_castle.cpp | 54 ++--- .../dungeons/gerudo_training_ground.cpp | 76 +++--- .../location_access/dungeons/ice_cavern.cpp | 16 +- .../dungeons/jabujabus_belly.cpp | 28 +-- .../dungeons/shadow_temple.cpp | 72 +++--- .../dungeons/spirit_temple.cpp | 94 ++++---- .../location_access/dungeons/water_temple.cpp | 36 +-- .../overworld/death_mountain_crater.cpp | 18 +- .../overworld/death_mountain_trail.cpp | 20 +- .../overworld/desert_colossus.cpp | 12 +- .../overworld/gerudo_fortress.cpp | 2 +- .../overworld/gerudo_valley.cpp | 14 +- .../location_access/overworld/goron_city.cpp | 6 +- .../location_access/overworld/graveyard.cpp | 20 +- .../overworld/haunted_wasteland.cpp | 2 +- .../overworld/hyrule_field.cpp | 64 ++++- .../location_access/overworld/kakariko.cpp | 4 +- .../overworld/kokiri_forest.cpp | 36 +-- .../location_access/overworld/lake_hylia.cpp | 14 +- .../location_access/overworld/lost_woods.cpp | 25 +- .../location_access/overworld/market.cpp | 22 +- .../overworld/sacred_forest_meadow.cpp | 2 +- .../overworld/zoras_domain.cpp | 2 +- .../overworld/zoras_fountain.cpp | 8 +- .../location_access/overworld/zoras_river.cpp | 2 +- soh/soh/Enhancements/randomizer/logic.cpp | 58 ++++- soh/soh/Enhancements/randomizer/logic.h | 2 +- .../randomizer/option_descriptions.cpp | 8 + .../Enhancements/randomizer/randomizer.cpp | 112 ++++++++- .../Enhancements/randomizer/randomizerTypes.h | 87 +++++++ .../randomizer/randomizer_check_tracker.cpp | 5 +- .../Enhancements/randomizer/randomizer_inf.h | 76 ++++++ .../randomizer/randomizer_item_tracker.cpp | 121 ++++++++++ soh/soh/Enhancements/randomizer/savefile.cpp | 31 +++ soh/soh/Enhancements/randomizer/settings.cpp | 13 +- soh/soh/SohGui/SohMenuEnhancements.cpp | 18 ++ soh/src/overlays/actors/ovl_En_Rr/z_en_rr.c | 136 +++++------ .../actors/ovl_En_Wood02/z_en_wood02.c | 12 +- .../actors/ovl_player_actor/z_player.c | 2 +- 64 files changed, 1646 insertions(+), 529 deletions(-) create mode 100644 soh/soh/Enhancements/Cheats/NoLikeLikeItemSteal.cpp create mode 100644 soh/soh/Enhancements/DropThrowOnlyActors.cpp diff --git a/soh/soh/Enhancements/Cheats/NoLikeLikeItemSteal.cpp b/soh/soh/Enhancements/Cheats/NoLikeLikeItemSteal.cpp new file mode 100644 index 00000000000..825ecbe1bfb --- /dev/null +++ b/soh/soh/Enhancements/Cheats/NoLikeLikeItemSteal.cpp @@ -0,0 +1,17 @@ +#include +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ShipInit.hpp" + +extern "C" { +#include "macros.h" +} + +static constexpr int32_t CVAR_NOLIKELIKEITEMSTEAL_DEFAULT = 0; +#define CVAR_NOLIKELIKEITEMSTEAL_NAME CVAR_CHEAT("NoLikeLikeItemSteal") +#define CVAR_NOLIKELIKEITEMSTEAL_VALUE CVarGetInteger(CVAR_NOLIKELIKEITEMSTEAL_NAME, CVAR_NOLIKELIKEITEMSTEAL_DEFAULT) + +void RegisterNoLikeLikeItemSteal() { + COND_VB_SHOULD(VB_LIKE_LIKE_STEAL_EQUIPMENT, CVAR_NOLIKELIKEITEMSTEAL_VALUE, { *should = false; }); +} + +static RegisterShipInitFunc initFunc(RegisterNoLikeLikeItemSteal, { CVAR_NOLIKELIKEITEMSTEAL_NAME }); \ No newline at end of file diff --git a/soh/soh/Enhancements/DropThrowOnlyActors.cpp b/soh/soh/Enhancements/DropThrowOnlyActors.cpp new file mode 100644 index 00000000000..260f1f183d8 --- /dev/null +++ b/soh/soh/Enhancements/DropThrowOnlyActors.cpp @@ -0,0 +1,17 @@ +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ShipInit.hpp" + +void OnAllowThrowOnlyDrop(void* actor) { + Actor* thisx = (Actor*)actor; + if (CVarGetInteger(CVAR_ENHANCEMENT("DropThrowOnlyObjects"), 0)) { + thisx->flags &= ~ACTOR_FLAG_THROW_ONLY; + } else { + thisx->flags |= ACTOR_FLAG_THROW_ONLY; + } +} + +void RegisterAllowThrowOnlyDrop() { + GameInteractor::Instance->RegisterGameHook(OnAllowThrowOnlyDrop); +} + +static RegisterShipInitFunc initFunc(RegisterAllowThrowOnlyDrop, { CVAR_ENHANCEMENT("DropThrowOnlyObjects") }); \ No newline at end of file diff --git a/soh/soh/Enhancements/ExtraTraps.cpp b/soh/soh/Enhancements/ExtraTraps.cpp index 155b1af713e..19f8142a8c7 100644 --- a/soh/soh/Enhancements/ExtraTraps.cpp +++ b/soh/soh/Enhancements/ExtraTraps.cpp @@ -4,6 +4,8 @@ #include "soh/Enhancements/randomizer/3drando/random.hpp" #include "soh/Notification/Notification.h" #include "soh/OTRGlobals.h" +#include "soh/SohGui/ImGuiUtils.h" +#include "soh/SaveManager.h" extern "C" { #include "variables.h" @@ -11,6 +13,8 @@ extern "C" { #include "macros.h" extern PlayState* gPlayState; GetItemEntry ItemTable_RetrieveEntry(s16 modIndex, s16 getItemID); +GetItemID RetrieveGetItemIDFromItemID(ItemID itemID); +RandomizerGet RetrieveRandomizerGetFromItemID(ItemID itemID); } #define CVAR_EXTRA_TRAPS_NAME CVAR_ENHANCEMENT("ExtraTraps.Enabled") @@ -28,19 +32,49 @@ typedef enum { ADD_AMMO_TRAP, ADD_KILL_TRAP, ADD_TELEPORT_TRAP, + ADD_POCKET_TRAP, + ADD_PERMADEATH_TRAP, ADD_TRAP_MAX } AltTrapType; static AltTrapType roll = ADD_TRAP_MAX; static int statusTimer = -1; static int eventTimer = -1; +static int permaDeathTimer = -1; +bool shouldFileDelete = false; const char* altTrapTypeCvars[] = { - CVAR_ENHANCEMENT("ExtraTraps.Ice"), CVAR_ENHANCEMENT("ExtraTraps.Burn"), - CVAR_ENHANCEMENT("ExtraTraps.Shock"), CVAR_ENHANCEMENT("ExtraTraps.Knockback"), - CVAR_ENHANCEMENT("ExtraTraps.Speed"), CVAR_ENHANCEMENT("ExtraTraps.Bomb"), - CVAR_ENHANCEMENT("ExtraTraps.Void"), CVAR_ENHANCEMENT("ExtraTraps.Ammo"), - CVAR_ENHANCEMENT("ExtraTraps.Kill"), CVAR_ENHANCEMENT("ExtraTraps.Teleport"), + CVAR_ENHANCEMENT("ExtraTraps.Ice"), CVAR_ENHANCEMENT("ExtraTraps.Burn"), + CVAR_ENHANCEMENT("ExtraTraps.Shock"), CVAR_ENHANCEMENT("ExtraTraps.Knockback"), + CVAR_ENHANCEMENT("ExtraTraps.Speed"), CVAR_ENHANCEMENT("ExtraTraps.Bomb"), + CVAR_ENHANCEMENT("ExtraTraps.Void"), CVAR_ENHANCEMENT("ExtraTraps.Ammo"), + CVAR_ENHANCEMENT("ExtraTraps.Kill"), CVAR_ENHANCEMENT("ExtraTraps.Teleport"), + CVAR_ENHANCEMENT("ExtraTraps.Pocket"), CVAR_ENHANCEMENT("ExtraTraps.Permadeath"), +}; + +static std::unordered_map itemToQuestMap = { + { ITEM_MEDALLION_FOREST, QUEST_MEDALLION_FOREST }, + { ITEM_MEDALLION_FIRE, QUEST_MEDALLION_FIRE }, + { ITEM_MEDALLION_WATER, QUEST_MEDALLION_WATER }, + { ITEM_MEDALLION_SPIRIT, QUEST_MEDALLION_SPIRIT }, + { ITEM_MEDALLION_SHADOW, QUEST_MEDALLION_SHADOW }, + { ITEM_MEDALLION_LIGHT, QUEST_MEDALLION_LIGHT }, + { ITEM_SONG_MINUET, QUEST_SONG_MINUET }, + { ITEM_SONG_BOLERO, QUEST_SONG_BOLERO }, + { ITEM_SONG_SERENADE, QUEST_SONG_SERENADE }, + { ITEM_SONG_REQUIEM, QUEST_SONG_REQUIEM }, + { ITEM_SONG_NOCTURNE, QUEST_SONG_NOCTURNE }, + { ITEM_SONG_PRELUDE, QUEST_SONG_PRELUDE }, + { ITEM_SONG_LULLABY, QUEST_SONG_LULLABY }, + { ITEM_SONG_EPONA, QUEST_SONG_EPONA }, + { ITEM_SONG_SARIA, QUEST_SONG_SARIA }, + { ITEM_SONG_SUN, QUEST_SONG_SUN }, + { ITEM_SONG_TIME, QUEST_SONG_TIME }, + { ITEM_SONG_STORMS, QUEST_SONG_STORMS }, + { ITEM_KOKIRI_EMERALD, QUEST_KOKIRI_EMERALD }, + { ITEM_GORON_RUBY, QUEST_GORON_RUBY }, + { ITEM_ZORA_SAPPHIRE, QUEST_ZORA_SAPPHIRE }, + { ITEM_GERUDO_CARD, QUEST_GERUDO_CARD }, }; std::vector getEnabledAddTraps() { @@ -60,11 +94,149 @@ std::vector getEnabledAddTraps() { return enabledAddTraps; }; +void TriggerVoidOut() { + Player* player = GET_PLAYER(gPlayState); + + Audio_PlaySoundGeneral(NA_SE_EN_BUBLE_LAUGH, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); + + // Hyrule Castle: Very likely to fall through floor, so we force a specific entrance + if (gPlayState->sceneNum == SCENE_HYRULE_CASTLE || gPlayState->sceneNum == SCENE_OUTSIDE_GANONS_CASTLE) { + gPlayState->nextEntranceIndex = ENTR_CASTLE_GROUNDS_SOUTH_EXIT; + } else { + gSaveContext.respawnFlag = 1; + gPlayState->nextEntranceIndex = gSaveContext.entranceIndex; + + // Preserve the player's position and orientation + gSaveContext.respawn[RESPAWN_MODE_DOWN].entranceIndex = gPlayState->nextEntranceIndex; + gSaveContext.respawn[RESPAWN_MODE_DOWN].roomIndex = gPlayState->roomCtx.curRoom.num; + gSaveContext.respawn[RESPAWN_MODE_DOWN].pos = player->actor.world.pos; + gSaveContext.respawn[RESPAWN_MODE_DOWN].yaw = player->actor.shape.rot.y; + + if (gPlayState->roomCtx.curRoom.behaviorType2 < 4) { + gSaveContext.respawn[RESPAWN_MODE_DOWN].playerParams = 0x0DFF; + } else { + // Scenes with static backgrounds use a special camera we need to preserve + Camera* camera = GET_ACTIVE_CAM(gPlayState); + s16 camId = camera->camDataIdx; + gSaveContext.respawn[RESPAWN_MODE_DOWN].playerParams = 0x0D00 | camId; + } + } + + gPlayState->transitionTrigger = TRANS_TRIGGER_START; + gPlayState->transitionType = TRANS_TYPE_INSTANT; + gSaveContext.nextTransitionType = TRANS_TYPE_FADE_BLACK_FAST; +} + +void ExecutePocketTrap() { + std::vector currentLoadout; + + for (auto& items : itemMapping) { + if (INV_CONTENT(items.second.id) == items.second.id) { + currentLoadout.push_back(items.second.id); + continue; + } + auto questItem = itemToQuestMap.find( + (ItemID)items.second.id); // std::find(itemToQuestMap.begin(), itemToQuestMap.end(), items.second.id); + if (questItem == itemToQuestMap.end()) { + continue; + } + if (CHECK_QUEST_ITEM(questItem->second)) { + currentLoadout.push_back(items.second.id); + continue; + } + } + + if (currentLoadout.size() == 0) { + GameInteractor::RawAction::FreezePlayer(); + return; + } + + RandomizerGet rgItem = RG_NONE; + + uint32_t roll = Random(0, currentLoadout.size() - 1); + if (currentLoadout[roll] >= ITEM_SONG_MINUET) { + rgItem = RetrieveRandomizerGetFromItemID((ItemID)currentLoadout[roll]); + } else { + GetItemID getItemId = RetrieveGetItemIDFromItemID((ItemID)currentLoadout[roll]); + for (auto& randoGet : Rando::StaticData::GetItemTable()) { + if (randoGet.GetItemID() == getItemId) { + rgItem = randoGet.GetRandomizerGet(); + break; + } + } + } + + if (rgItem == RG_NONE) { + GameInteractor::RawAction::FreezePlayer(); + return; + } + + for (auto& check : Rando::StaticData::GetLocationTable()) { + if (Rando::Context::GetInstance()->GetItemLocation(check.GetRandomizerCheck())->GetPlacedRandomizerGet() == + rgItem) { + if (check.GetRandomizerCheck() == RC_UNKNOWN_CHECK || check.GetRandomizerCheck() == RC_LINKS_POCKET) { + GameInteractor::RawAction::FreezePlayer(); + return; + } + switch (check.GetActorID()) { + case ACTOR_EN_BOX: + GameInteractor::RawAction::UnsetSceneFlag(check.GetScene(), FLAG_SCENE_TREASURE, + check.GetActorParams() & 0x1F); + break; + default: + if (check.GetCollectionCheck().type != SPOILER_CHK_NONE) { + switch (check.GetCollectionCheck().type) { + case SPOILER_CHK_ITEM_GET_INF: + Flags_UnsetItemGetInf(check.GetCollectionCheck().flag); + break; + case SPOILER_CHK_RANDOMIZER_INF: + Flags_UnsetRandomizerInf((RandomizerInf)check.GetCollectionCheck().flag); + break; + case SPOILER_CHK_EVENT_CHK_INF: + Flags_UnsetEventInf(check.GetCollectionCheck().flag); + break; + case SPOILER_CHK_CHEST: + GameInteractor::RawAction::UnsetSceneFlag(check.GetScene(), FLAG_SCENE_TREASURE, + check.GetCollectionCheck().flag); + break; + case SPOILER_CHK_COLLECTABLE: + GameInteractor::RawAction::UnsetSceneFlag(check.GetScene(), FLAG_SCENE_COLLECTIBLE, + check.GetCollectionCheck().flag); + break; + case SPOILER_CHK_INF_TABLE: + Flags_UnsetInfTable(check.GetCollectionCheck().flag); + break; + default: + GameInteractor::RawAction::FreezePlayer(); + return; + } + } + break; + } + + Rando::Context::GetInstance()->GetItemLocation(check.GetRandomizerCheck())->SetCheckStatus(RCSHOW_SEEN); + INV_CONTENT(currentLoadout[roll]) = ITEM_NONE; + break; + } + } + + Notification::Emit({ .itemIcon = (const char*)gItemIcons[currentLoadout[roll]], + .prefix = "You've lost your", + .prefixColor = UIWidgets::ColorValues.at(UIWidgets::Colors::White), + .message = Rando::StaticData::RetrieveItem(rgItem).GetName().english.c_str(), + .messageColor = UIWidgets::ColorValues.at(UIWidgets::Colors::Green), + .suffix = ". I remember seeing it somewhere...", + .suffixColor = UIWidgets::ColorValues.at(UIWidgets::Colors::White) }); + + TriggerVoidOut(); +} + static void RollRandomTrap(uint32_t seed) { uint32_t finalSeed = seed + (IS_RANDO ? Rando::Context::GetInstance()->GetSeed() : static_cast(gSaveContext.ship.stats.fileCreatedAt)); Random_Init(finalSeed); - + // roll = ADD_PERMADEATH_TRAP; roll = RandomElement(getEnabledAddTraps()); switch (roll) { case ADD_ICE_TRAP: @@ -104,6 +276,18 @@ static void RollRandomTrap(uint32_t seed) { case ADD_TELEPORT_TRAP: eventTimer = 3; break; + case ADD_POCKET_TRAP: + ExecutePocketTrap(); + break; + case ADD_PERMADEATH_TRAP: + permaDeathTimer = 180; + shouldFileDelete = true; + Notification::Emit({ .itemIcon = (const char*)gItemIcons[ITEM_BOMB], + .message = "Collect a Check or Perma Death executes in ", + .messageColor = UIWidgets::ColorValues.at(UIWidgets::Colors::White), + .suffix = "60 seconds.", + .suffixColor = UIWidgets::ColorValues.at(UIWidgets::Colors::Red) }); + break; default: break; } @@ -168,6 +352,17 @@ static void OnPlayerUpdate() { break; } } + if (permaDeathTimer == 0) { + if (shouldFileDelete) { + SaveManager::Instance->DeleteZeldaFile(gSaveContext.fileNum); + std::reinterpret_pointer_cast( + Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Console")) + ->Dispatch("reset"); + } + } + if (permaDeathTimer >= 0) { + permaDeathTimer--; + } if (statusTimer >= 0) { statusTimer--; } @@ -196,6 +391,20 @@ void RegisterExtraTraps() { GameInteractor::RawAction::FreezePlayer(); } }); + + COND_HOOK(OnFlagSet, CVAR_EXTRA_TRAPS_NAME, [](int16_t flagType, int16_t flag) { + SPDLOG_INFO("Flag Set Here {}", std::to_string(flagType).c_str()); + if (flagType != FLAG_SCENE_CLEAR) { + shouldFileDelete = false; + } + }); + + COND_HOOK(OnSceneFlagSet, CVAR_EXTRA_TRAPS_NAME, [](int16_t sceneNum, int16_t flagType, int16_t flag) { + SPDLOG_INFO("Scene Flag Set Here {}", std::to_string(flagType).c_str()); + if (flagType != FLAG_SCENE_CLEAR) { + shouldFileDelete = false; + } + }); } static RegisterShipInitFunc initFunc(RegisterExtraTraps, { CVAR_EXTRA_TRAPS_NAME }); diff --git a/soh/soh/Enhancements/QoL/ResetNaviTimer.cpp b/soh/soh/Enhancements/QoL/ResetNaviTimer.cpp index b3048be538f..6f88067757c 100644 --- a/soh/soh/Enhancements/QoL/ResetNaviTimer.cpp +++ b/soh/soh/Enhancements/QoL/ResetNaviTimer.cpp @@ -14,4 +14,4 @@ static void RegisterResetNaviTimer() { COND_HOOK(OnSceneInit, CVAR_RESET_NAVI_VALUE, [](int32_t) { gSaveContext.naviTimer = 0; }); } -static RegisterShipInitFunc initFunc(RegisterResetNaviTimer, { CVAR_RESET_NAVI_NAME }); +static RegisterShipInitFunc initFunc(RegisterResetNaviTimer, { CVAR_RESET_NAVI_NAME }); \ No newline at end of file diff --git a/soh/soh/Enhancements/debugger/debugSaveEditor.cpp b/soh/soh/Enhancements/debugger/debugSaveEditor.cpp index 463f900e0d4..d7eceb82973 100644 --- a/soh/soh/Enhancements/debugger/debugSaveEditor.cpp +++ b/soh/soh/Enhancements/debugger/debugSaveEditor.cpp @@ -1726,7 +1726,6 @@ void SaveEditorWindow::DrawElement() { DrawPlayerTab(); ImGui::EndTabItem(); } - ImGui::EndTabBar(); } diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index fe437907a2e..5ce333e5484 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -244,6 +244,14 @@ typedef enum { // - `*EnPoField` VB_BOTTLE_BIG_POE, + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `*ObjWood02` + VB_BUSH_DROP_ITEM, + // #### `result` // ```c // ((this->actor.params == DNS_TYPE_HEART_PIECE) && (Flags_GetItemGetInf(ITEMGETINF_DEKU_SCRUB_HEART_PIECE))) || @@ -1378,6 +1386,14 @@ typedef enum { // - `*EnOkarinaTag` VB_OKARINA_TAG_COMPLETED, + // #### `result` + // ```c + // this->getItemId != GI_NONE + // ``` + // #### `args` + // - `None` + VB_OPEN_CHEST, + // #### `result` // ```c // CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD) @@ -2236,6 +2252,14 @@ typedef enum { // - `*Actor` VB_RECIEVE_FALL_DAMAGE, + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `*EnRr` + VB_LIKE_LIKE_DROP_COLLECTIBLE, + // #### `result` // ```c // true @@ -2244,6 +2268,14 @@ typedef enum { // - `*EnRr` VB_LIKE_LIKE_GRAB_PLAYER, + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `*EnRr` + VB_LIKE_LIKE_STEAL_EQUIPMENT, + // #### `result` // ```c // entry != NULL diff --git a/soh/soh/Enhancements/gameplaystats.cpp b/soh/soh/Enhancements/gameplaystats.cpp index ca360543fa4..ade699a3cc1 100644 --- a/soh/soh/Enhancements/gameplaystats.cpp +++ b/soh/soh/Enhancements/gameplaystats.cpp @@ -446,7 +446,7 @@ void DrawGameplayStatsHeader() { // if tag is empty (not a release build) if (gGitCommitTag[0] == 0) { GameplayStatsRow("Git Branch:", (char*)gGitBranch); - GameplayStatsRow("Git Commit Hash:", (char*)gGitCommitHash); + GameplayStatsRow("Version : 1.0 | Git Commit Hash:", (char*)gGitCommitHash); } else { GameplayStatsRow("Build Version:", (char*)gBuildVersion); } 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 0c40dfdb9c4..487c761584b 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 @@ -2126,6 +2126,15 @@ void StaticData::HintTable_Init_Exclude_Overworld() { HintText(CustomMessage("They say that a #tree in Lon Lon Ranch# contains #[[1]]#.", /*german*/ "", /*french*/ "Selon moi, un #arbre au Ranch Lon Lon# cache #[[1]]#.", { QM_RED, QM_GREEN })); + + hintTextTable[RHT_BUSH_HYRULE_FIELD] = + HintText(CustomMessage("They say that a #bush in Hyrle Field# contains #[[1]]#.", + /*german*/ "", + /*french*/ "Selon moi, un #buisson dans la Plaine d'Hyrule# cache #[[1]]#.", { QM_RED, QM_GREEN })); + hintTextTable[RHT_BUSH_ZORAS_FOUNTAIN] = + HintText(CustomMessage("They say that a #bush in Zora's Fountain# contains #[[1]]#.", + /*german*/ "", + /*french*/ "Selon moi, un #buisson à la Fontaine Zora# cache #[[1]]#.", { QM_RED, QM_GREEN })); // clang-format on } } // namespace Rando diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp index c74c0ff23b9..471362e30e7 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp @@ -1964,6 +1964,8 @@ void StaticData::HintTable_Init_Item() { CustomMessage("a gold fragment", /*german*/"ein Goldfragment", /*french*/"un fragment d'or")}); // /*spanish*/un fragmento dorado + hintTextTable[RHT_BEAN_SOUL] = HintText(CustomMessage("a bean soul", TODO_TRANSLATE, TODO_TRANSLATE)); + hintTextTable[RHT_GOHMA_SOUL] = HintText(CustomMessage("the soul of Gohma", /*german*/"Gohmas Seele", /*french*/"l'Âme de Gohma"), { CustomMessage("something webbed", /*german*/"etwas Verwobenes", /*french*/"un truc entoilé") @@ -2100,6 +2102,8 @@ void StaticData::HintTable_Init_Item() { { CustomMessage("a master unlocker", /*german*/ "ein Meisterentsperrer", /*french*/ "un Kit de Déverrouillage") }); // /*spanish*/un desbloqueador maestro + hintTextTable[RHT_OPEN_CHEST] = HintText(CustomMessage("the ability to open chests", /*german*/"!!!", /*french*/"!!!")); + //RANDOTODO if these are ever used for anything other than name, they want abscure and ambiguous hints hintTextTable[RHT_QUIVER_INF] = HintText(CustomMessage("an infinite Quiver", /*german*/"der unendliche Köcher", /*french*/"un Carquois Infini")); diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index ea6123b24c9..75089f210e9 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -578,6 +578,10 @@ void GenerateItemPool() { AddItemToMainPool(RG_PROGRESSIVE_SCALE); } + if (ctx->GetOption(RSK_SHUFFLE_OPEN_CHEST)) { + AddItemToMainPool(RG_OPEN_CHEST); + } + if (ctx->GetOption(RSK_SHUFFLE_BEEHIVES)) { // 32 total beehive locations AddItemToPool(PendingJunkPool, RG_RED_RUPEE, 23); @@ -598,6 +602,10 @@ void GenerateItemPool() { PlaceItemsForType(RCTYPE_NLTREE, treesActive, false); } + // Shuffle Bushes + bool bushesActive = (bool)ctx->GetOption(RSK_SHUFFLE_BUSHES); + PlaceItemsForType(RCTYPE_BUSH, bushesActive, false); + // Shuffle Crates bool overworldCratesActive = ctx->GetOption(RSK_SHUFFLE_CRATES).Is(RO_SHUFFLE_CRATES_OVERWORLD) || ctx->GetOption(RSK_SHUFFLE_CRATES).Is(RO_SHUFFLE_CRATES_ALL); @@ -745,6 +753,19 @@ void GenerateItemPool() { ctx->PlaceItemInLocation(RC_KAK_100_GOLD_SKULLTULA_REWARD, RG_HUGE_RUPEE, false, true); } + if (ctx->GetOption(RSK_SHUFFLE_BEAN_SOULS)) { + AddItemToMainPool(RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL); + AddItemToMainPool(RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL); + AddItemToMainPool(RG_DESERT_COLOSSUS_BEAN_SOUL); + AddItemToMainPool(RG_GERUDO_VALLEY_BEAN_SOUL); + AddItemToMainPool(RG_GRAVEYARD_BEAN_SOUL); + AddItemToMainPool(RG_KOKIRI_FOREST_BEAN_SOUL); + AddItemToMainPool(RG_LAKE_HYLIA_BEAN_SOUL); + AddItemToMainPool(RG_LOST_WOODS_BRIDGE_BEAN_SOUL); + AddItemToMainPool(RG_LOST_WOODS_BEAN_SOUL); + AddItemToMainPool(RG_ZORAS_RIVER_BEAN_SOUL); + } + if (ctx->GetOption(RSK_SHUFFLE_BOSS_SOULS)) { AddItemToMainPool(RG_GOHMA_SOUL); AddItemToMainPool(RG_KING_DODONGO_SOUL); diff --git a/soh/soh/Enhancements/randomizer/ShuffleTrees.cpp b/soh/soh/Enhancements/randomizer/ShuffleTrees.cpp index 14cb9c7b1d2..cf301c8c26c 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleTrees.cpp +++ b/soh/soh/Enhancements/randomizer/ShuffleTrees.cpp @@ -36,50 +36,45 @@ static Gfx* D_80B3BF70[] = { extern void EnItem00_DrawRandomizedItem(EnItem00* enItem00, PlayState* play); uint8_t EnWood02_RandomizerHoldsItem(EnWood02* treeActor, PlayState* play) { - const auto treeIdentity = ObjectExtension::GetInstance().Get(&treeActor->actor); - if (treeIdentity == nullptr) { - return false; - } - // Don't pull randomized item if tree isn't randomized or is already checked - return IS_RANDO && Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_TREES).Get() && - !Flags_GetRandomizerInf(treeIdentity->randomizerInf) && treeIdentity->randomizerCheck != RC_UNKNOWN_CHECK; + const auto treeIdentity = ObjectExtension::GetInstance().Get(&treeActor->actor); + return treeIdentity != nullptr && treeIdentity->randomizerCheck != RC_UNKNOWN_CHECK && + treeIdentity->randomizerInf != RAND_INF_MAX && !Flags_GetRandomizerInf(treeIdentity->randomizerInf); } extern "C" void EnWood02_RandomizerDraw(Actor* thisx, PlayState* play) { GetItemCategory getItemCategory; - GetItemEntry smallCrateItem; + GetItemEntry treeItem; auto treeActor = (EnWood02*)thisx; - int csmc = CVarGetInteger(CVAR_ENHANCEMENT("ChestSizeAndTextureMatchContents"), CSMC_DISABLED); - int requiresStoneAgony = CVarGetInteger(CVAR_ENHANCEMENT("ChestSizeDependsStoneOfAgony"), 0); - - int isVanilla = - csmc == CSMC_DISABLED || csmc == CSMC_SIZE || (requiresStoneAgony && !CHECK_QUEST_ITEM(QUEST_STONE_OF_AGONY)); const auto treeIdentity = ObjectExtension::GetInstance().Get(&treeActor->actor); - if (treeIdentity == nullptr) { + if (treeIdentity == nullptr || treeIdentity->randomizerCheck == RC_UNKNOWN_CHECK) { return; } - if (isVanilla || treeIdentity == nullptr || treeIdentity->randomizerCheck == RC_UNKNOWN_CHECK) { + int csmc = CVarGetInteger(CVAR_ENHANCEMENT("ChestSizeAndTextureMatchContents"), CSMC_DISABLED); + int requiresStoneAgony = CVarGetInteger(CVAR_ENHANCEMENT("ChestSizeDependsStoneOfAgony"), 0); + int isVanilla = + csmc == CSMC_DISABLED || csmc == CSMC_SIZE || (requiresStoneAgony && !CHECK_QUEST_ITEM(QUEST_STONE_OF_AGONY)); + + if (isVanilla) { getItemCategory = ITEM_CATEGORY_JUNK; } else { - smallCrateItem = Rando::Context::GetInstance()->GetFinalGIEntry(treeIdentity->randomizerCheck, true, GI_NONE); - getItemCategory = smallCrateItem.getItemCategory; + treeItem = Rando::Context::GetInstance()->GetFinalGIEntry(treeIdentity->randomizerCheck, true, GI_NONE); + getItemCategory = treeItem.getItemCategory; // If they have bombchus, don't consider the bombchu item major if (INV_CONTENT(ITEM_BOMBCHU) == ITEM_BOMBCHU && - ((smallCrateItem.modIndex == MOD_RANDOMIZER && smallCrateItem.getItemId == RG_PROGRESSIVE_BOMBCHUS) || - (smallCrateItem.modIndex == MOD_NONE && - (smallCrateItem.getItemId == GI_BOMBCHUS_5 || smallCrateItem.getItemId == GI_BOMBCHUS_10 || - smallCrateItem.getItemId == GI_BOMBCHUS_20)))) { + ((treeItem.modIndex == MOD_RANDOMIZER && treeItem.getItemId == RG_PROGRESSIVE_BOMBCHUS) || + (treeItem.modIndex == MOD_NONE && + (treeItem.getItemId == GI_BOMBCHUS_5 || treeItem.getItemId == GI_BOMBCHUS_10 || + treeItem.getItemId == GI_BOMBCHUS_20)))) { getItemCategory = ITEM_CATEGORY_JUNK; // If it's a bottle and they already have one, consider the item lesser - } else if ((smallCrateItem.modIndex == MOD_RANDOMIZER && - smallCrateItem.getItemId >= RG_BOTTLE_WITH_RED_POTION && - smallCrateItem.getItemId <= RG_BOTTLE_WITH_POE) || - (smallCrateItem.modIndex == MOD_NONE && - (smallCrateItem.getItemId == GI_BOTTLE || smallCrateItem.getItemId == GI_MILK_BOTTLE))) { + } else if ((treeItem.modIndex == MOD_RANDOMIZER && treeItem.getItemId >= RG_BOTTLE_WITH_RED_POTION && + treeItem.getItemId <= RG_BOTTLE_WITH_POE) || + (treeItem.modIndex == MOD_NONE && + (treeItem.getItemId == GI_BOTTLE || treeItem.getItemId == GI_MILK_BOTTLE))) { if (gSaveContext.inventory.items[SLOT_BOTTLE_1] != ITEM_NONE) { getItemCategory = ITEM_CATEGORY_LESSER; } @@ -110,7 +105,7 @@ extern "C" void EnWood02_RandomizerDraw(Actor* thisx, PlayState* play) { break; case ITEM_CATEGORY_LESSER: Matrix_Scale(0.1, 0.05, 0.1, MTXMODE_APPLY); - switch (smallCrateItem.itemId) { + switch (treeItem.itemId) { case ITEM_HEART_PIECE: case ITEM_HEART_PIECE_2: case ITEM_HEART_CONTAINER: @@ -133,7 +128,7 @@ extern "C" void EnWood02_RandomizerDraw(Actor* thisx, PlayState* play) { void EnWood02_RandomizerSpawnCollectible(EnWood02* treeActor, PlayState* play) { const auto treeIdentity = ObjectExtension::GetInstance().Get(&treeActor->actor); - if (treeIdentity == nullptr) { + if (treeIdentity == nullptr || treeIdentity->randomizerCheck == RC_UNKNOWN_CHECK) { return; } @@ -152,26 +147,33 @@ void EnWood02_RandomizerSpawnCollectible(EnWood02* treeActor, PlayState* play) { void EnWood02_RandomizerInit(void* actorRef) { EnWood02* treeActor = static_cast(actorRef); - if (treeActor->actor.params <= WOOD_TREE_KAKARIKO_ADULT) { + if ((treeActor->actor.params <= WOOD_TREE_KAKARIKO_ADULT && + Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_TREES).Get()) || + (treeActor->actor.params > WOOD_TREE_KAKARIKO_ADULT && + treeActor->actor.params <= WOOD_BUSH_BLACK_LARGE_SPAWNED && + Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_BUSHES).Get())) { auto treeIdentity = OTRGlobals::Instance->gRandomizer->IdentifyTree( gPlayState->sceneNum, (s16)treeActor->actor.world.pos.x, (s16)treeActor->actor.world.pos.z); - ObjectExtension::GetInstance().Set(actorRef, std::move(treeIdentity)); + if (treeIdentity.randomizerInf != RAND_INF_MAX && treeIdentity.randomizerCheck != RC_UNKNOWN_CHECK) { + ObjectExtension::GetInstance().Set(actorRef, std::move(treeIdentity)); + } } } void RegisterShuffleTrees() { - bool shouldRegister = IS_RANDO && Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_TREES).Get(); + bool shouldRegisterTree = IS_RANDO && Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_TREES).Get(); + bool shouldRegisterBush = IS_RANDO && Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_BUSHES).Get(); - COND_ID_HOOK(OnActorInit, ACTOR_EN_WOOD02, shouldRegister, EnWood02_RandomizerInit); + COND_ID_HOOK(OnActorInit, ACTOR_EN_WOOD02, shouldRegisterTree || shouldRegisterBush, EnWood02_RandomizerInit); - COND_VB_SHOULD(VB_TREE_SETUP_DRAW, shouldRegister, { + COND_VB_SHOULD(VB_TREE_SETUP_DRAW, shouldRegisterTree || shouldRegisterBush, { EnWood02* treeActor = va_arg(args, EnWood02*); if (EnWood02_RandomizerHoldsItem(treeActor, gPlayState)) { EnWood02_RandomizerDraw(&treeActor->actor, gPlayState); } }); - COND_VB_SHOULD(VB_TREE_DROP_ITEM, shouldRegister, { + COND_VB_SHOULD(VB_TREE_DROP_ITEM, shouldRegisterTree, { EnWood02* treeActor = va_arg(args, EnWood02*); if (EnWood02_RandomizerHoldsItem(treeActor, gPlayState)) { EnWood02_RandomizerSpawnCollectible(treeActor, gPlayState); @@ -188,6 +190,25 @@ void RegisterShuffleTrees() { *should = false; } }); + + COND_VB_SHOULD(VB_BUSH_DROP_ITEM, shouldRegisterBush, { + EnWood02* treeActor = va_arg(args, EnWood02*); + if (EnWood02_RandomizerHoldsItem(treeActor, gPlayState)) { + const auto treeIdentity = ObjectExtension::GetInstance().Get(&treeActor->actor); + if (treeIdentity == nullptr || treeIdentity->randomizerCheck == RC_UNKNOWN_CHECK) { + return; + } + + EnItem00* item00 = + (EnItem00*)Item_DropCollectible2(gPlayState, &treeActor->actor.world.pos, ITEM00_SOH_DUMMY); + item00->randoInf = treeIdentity->randomizerInf; + item00->itemEntry = + Rando::Context::GetInstance()->GetFinalGIEntry(treeIdentity->randomizerCheck, true, GI_NONE); + item00->actor.draw = (ActorFunc)EnItem00_DrawRandomizedItem; + treeIdentity->randomizerCheck = RC_UNKNOWN_CHECK; + treeActor->unk_14C = -0x15; + } + }); } void Rando::StaticData::RegisterTreeLocations() { @@ -201,7 +222,7 @@ void Rando::StaticData::RegisterTreeLocations() { locationTable[RC_HC_NEAR_GUARDS_TREE_4] = Location::Tree(RC_HC_NEAR_GUARDS_TREE_4, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(421, 1397), "Tree Near Guards 4", RHT_TREE_HYRULE_CASTLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_NEAR_GUARDS_TREE_4)); locationTable[RC_HC_NEAR_GUARDS_TREE_5] = Location::Tree(RC_HC_NEAR_GUARDS_TREE_5, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(-73, 1459), "Tree Near Guards 5", RHT_TREE_HYRULE_CASTLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_NEAR_GUARDS_TREE_5)); locationTable[RC_HC_NEAR_GUARDS_TREE_6] = Location::Tree(RC_HC_NEAR_GUARDS_TREE_6, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(1494, 2108), "Tree Near Guards 6", RHT_TREE_HYRULE_CASTLE, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_NEAR_GUARDS_TREE_6)); - locationTable[RC_HC_SKULLTULA_TREE] = Location::Tree(RC_HC_SKULLTULA_TREE, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(-145, 2961), "HC GS Tree", RHT_TREE_HYRULE_CASTLE, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_SKULLTULA_TREE)); + locationTable[RC_HC_SKULLTULA_TREE] = Location::Tree(RC_HC_SKULLTULA_TREE, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(-145, 2961), "GS Tree", RHT_TREE_HYRULE_CASTLE, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_SKULLTULA_TREE)); locationTable[RC_HC_GROTTO_TREE] = Location::Tree(RC_HC_GROTTO_TREE, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(924, 872), "Tree Near Storms Grotto", RHT_TREE_HYRULE_CASTLE, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_GROTTO_TREE)); locationTable[RC_HC_NL_TREE_1] = Location::NLTree(RC_HC_NL_TREE_1, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(-331, 1438), "NL Tree Near Guards 1", RHT_TREE_HYRULE_CASTLE, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_NL_TREE_1)); locationTable[RC_HC_NL_TREE_2] = Location::NLTree(RC_HC_NL_TREE_2, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(1022, 1444), "NL Tree Near Guards 2", RHT_TREE_HYRULE_CASTLE, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_NL_TREE_2)); @@ -257,9 +278,74 @@ void Rando::StaticData::RegisterTreeLocations() { locationTable[RC_ZR_TREE] = Location::Tree(RC_ZR_TREE, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(-1690, 554), "Tree in Zoras River", RHT_TREE_ZORAS_RIVER, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_TREE)); locationTable[RC_KAK_TREE] = Location::Tree(RC_KAK_TREE, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, TWO_ACTOR_PARAMS(-860, 522), "Kakariko GS Tree", RHT_TREE_KAKARIKO, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_TREE)); locationTable[RC_LLR_TREE] = Location::Tree(RC_LLR_TREE, RCQUEST_BOTH, RCAREA_LON_LON_RANCH, SCENE_LON_LON_RANCH, TWO_ACTOR_PARAMS(1309, -2241), "Lon Lon Ranch GS Tree", RHT_TREE_LON_LON_RANCH, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LLR_TREE)); + + locationTable[RC_HF_BUSH_NEAR_LAKE_1] = Location::Bush(RC_HF_BUSH_NEAR_LAKE_1, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-3506,13460), "Bush Near Lake 1", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_BUSH_NEAR_LAKE_1)); + locationTable[RC_HF_BUSH_NEAR_LAKE_2] = Location::Bush(RC_HF_BUSH_NEAR_LAKE_2, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-3907,13119), "Bush Near Lake 2", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_BUSH_NEAR_LAKE_2)); + locationTable[RC_HF_BUSH_NEAR_LAKE_3] = Location::Bush(RC_HF_BUSH_NEAR_LAKE_3, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-4106,13520), "Bush Near Lake 3", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_BUSH_NEAR_LAKE_3)); + locationTable[RC_HF_BUSH_NEAR_LAKE_4] = Location::Bush(RC_HF_BUSH_NEAR_LAKE_4, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-4407,13320), "Bush Near Lake 4", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_BUSH_NEAR_LAKE_4)); + locationTable[RC_HF_BUSH_NEAR_LAKE_5] = Location::Bush(RC_HF_BUSH_NEAR_LAKE_5, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-4486,13920), "Bush Near Lake 5", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_BUSH_NEAR_LAKE_5)); + locationTable[RC_HF_BUSH_NEAR_LAKE_6] = Location::Bush(RC_HF_BUSH_NEAR_LAKE_6, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-4722,12732), "Bush Near Lake 6", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_BUSH_NEAR_LAKE_6)); + locationTable[RC_HF_BUSH_NEAR_LAKE_7] = Location::Bush(RC_HF_BUSH_NEAR_LAKE_7, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-4723,13392), "Bush Near Lake 7", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_BUSH_NEAR_LAKE_7)); + locationTable[RC_HF_BUSH_NEAR_LAKE_8] = Location::Bush(RC_HF_BUSH_NEAR_LAKE_8, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-5123,12391), "Bush Near Lake 8", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_BUSH_NEAR_LAKE_8)); + locationTable[RC_HF_BUSH_NEAR_LAKE_9] = Location::Bush(RC_HF_BUSH_NEAR_LAKE_9, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-5322,12792), "Bush Near Lake 9", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_BUSH_NEAR_LAKE_9)); + locationTable[RC_HF_BUSH_NEAR_LAKE_10] = Location::Bush(RC_HF_BUSH_NEAR_LAKE_10, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-5623,12592), "Bush Near Lake 10", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_BUSH_NEAR_LAKE_10)); + locationTable[RC_HF_BUSH_NEAR_LAKE_11] = Location::Bush(RC_HF_BUSH_NEAR_LAKE_11, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-5702,13192), "Bush Near Lake 11", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_BUSH_NEAR_LAKE_11)); + locationTable[RC_HF_NORTHERN_BUSH_1] = Location::Bush(RC_HF_NORTHERN_BUSH_1, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-4710,1381), "Northern Bush 1", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NORTHERN_BUSH_1)); + locationTable[RC_HF_NORTHERN_BUSH_2] = Location::Bush(RC_HF_NORTHERN_BUSH_2, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-4711,2041), "Northern Bush 2", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NORTHERN_BUSH_2)); + locationTable[RC_HF_NORTHERN_BUSH_3] = Location::Bush(RC_HF_NORTHERN_BUSH_3, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-5111,1040), "Northern Bush 3", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NORTHERN_BUSH_3)); + locationTable[RC_HF_NORTHERN_BUSH_4] = Location::Bush(RC_HF_NORTHERN_BUSH_4, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-5310,1441), "Northern Bush 4", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NORTHERN_BUSH_4)); + locationTable[RC_HF_NORTHERN_BUSH_5] = Location::Bush(RC_HF_NORTHERN_BUSH_5, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-5611,1241), "Northern Bush 5", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NORTHERN_BUSH_5)); + locationTable[RC_HF_NORTHERN_BUSH_6] = Location::Bush(RC_HF_NORTHERN_BUSH_6, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-5690,1841), "Northern Bush 6", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NORTHERN_BUSH_6)); + locationTable[RC_HF_CHILD_NORTHERN_BUSH_1] = Location::Bush(RC_HF_CHILD_NORTHERN_BUSH_1, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-3621,-303), "Child Northern Bush 1", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_NORTHERN_BUSH_1)); + locationTable[RC_HF_CHILD_NORTHERN_BUSH_2] = Location::Bush(RC_HF_CHILD_NORTHERN_BUSH_2, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-3622,356), "Child Northern Bush 2", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_NORTHERN_BUSH_2)); + locationTable[RC_HF_CHILD_NORTHERN_BUSH_3] = Location::Bush(RC_HF_CHILD_NORTHERN_BUSH_3, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-4022,-644), "Child Northern Bush 3", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_NORTHERN_BUSH_3)); + locationTable[RC_HF_CHILD_NORTHERN_BUSH_4] = Location::Bush(RC_HF_CHILD_NORTHERN_BUSH_4, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-4221,-243), "Child Northern Bush 4", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_NORTHERN_BUSH_4)); + locationTable[RC_HF_CHILD_NORTHERN_BUSH_5] = Location::Bush(RC_HF_CHILD_NORTHERN_BUSH_5, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-4522,-443), "Child Northern Bush 5", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_NORTHERN_BUSH_5)); + locationTable[RC_HF_CHILD_NORTHERN_BUSH_6] = Location::Bush(RC_HF_CHILD_NORTHERN_BUSH_6, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-4601,156), "Child Northern Bush 6", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_NORTHERN_BUSH_6)); + locationTable[RC_HF_CHILD_NORTHERN_BUSH_7] = Location::Bush(RC_HF_CHILD_NORTHERN_BUSH_7, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-4634,-284), "Child Northern Bush 7", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_NORTHERN_BUSH_7)); + locationTable[RC_HF_CHILD_NORTHERN_BUSH_8] = Location::Bush(RC_HF_CHILD_NORTHERN_BUSH_8, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-4713,315), "Child Northern Bush 8", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_NORTHERN_BUSH_8)); + locationTable[RC_HF_CHILD_NORTHERN_BUSH_9] = Location::Bush(RC_HF_CHILD_NORTHERN_BUSH_9, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-5014,115), "Child Northern Bush 9", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_NORTHERN_BUSH_9)); + locationTable[RC_HF_CHILD_NORTHERN_BUSH_10] = Location::Bush(RC_HF_CHILD_NORTHERN_BUSH_10, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-5213,516), "Child Northern Bush 10", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_NORTHERN_BUSH_10)); + locationTable[RC_HF_CHILD_NORTHERN_BUSH_11] = Location::Bush(RC_HF_CHILD_NORTHERN_BUSH_11, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-5614,175), "Child Northern Bush 11", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_NORTHERN_BUSH_11)); + locationTable[RC_HF_BUSH_BY_ROCKY_PATH_1] = Location::Bush(RC_HF_BUSH_BY_ROCKY_PATH_1, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-5792,7022), "Bush By Rocky Path 1", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_BUSH_BY_ROCKY_PATH_1)); + locationTable[RC_HF_BUSH_BY_ROCKY_PATH_2] = Location::Bush(RC_HF_BUSH_BY_ROCKY_PATH_2, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-5793,7682), "Bush By Rocky Path 2", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_BUSH_BY_ROCKY_PATH_2)); + locationTable[RC_HF_BUSH_BY_ROCKY_PATH_3] = Location::Bush(RC_HF_BUSH_BY_ROCKY_PATH_3, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-6193,6681), "Bush By Rocky Path 3", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_BUSH_BY_ROCKY_PATH_3)); + locationTable[RC_HF_BUSH_BY_ROCKY_PATH_4] = Location::Bush(RC_HF_BUSH_BY_ROCKY_PATH_4, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-6392,7082), "Bush By Rocky Path 4", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_BUSH_BY_ROCKY_PATH_4)); + locationTable[RC_HF_BUSH_BY_ROCKY_PATH_5] = Location::Bush(RC_HF_BUSH_BY_ROCKY_PATH_5, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-6693,6882), "Bush By Rocky Path 5", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_BUSH_BY_ROCKY_PATH_5)); + locationTable[RC_HF_BUSH_BY_ROCKY_PATH_6] = Location::Bush(RC_HF_BUSH_BY_ROCKY_PATH_6, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-6772,7482), "Bush By Rocky Path 6", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_BUSH_BY_ROCKY_PATH_6)); + locationTable[RC_HF_SOUTHERN_BUSH_1] = Location::Bush(RC_HF_SOUTHERN_BUSH_1, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-270,12633), "Southern Bush 1", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHERN_BUSH_1)); + locationTable[RC_HF_SOUTHERN_BUSH_2] = Location::Bush(RC_HF_SOUTHERN_BUSH_2, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-349,13233), "Southern Bush 2", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHERN_BUSH_2)); + locationTable[RC_HF_SOUTHERN_BUSH_3] = Location::Bush(RC_HF_SOUTHERN_BUSH_3, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(2,11473), "Southern Bush 3", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHERN_BUSH_3)); + locationTable[RC_HF_SOUTHERN_BUSH_4] = Location::Bush(RC_HF_SOUTHERN_BUSH_4, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(229,12432), "Southern Bush 4", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHERN_BUSH_4)); + locationTable[RC_HF_SOUTHERN_BUSH_5] = Location::Bush(RC_HF_SOUTHERN_BUSH_5, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(30,12833), "Southern Bush 5", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHERN_BUSH_5)); + locationTable[RC_HF_SOUTHERN_BUSH_6] = Location::Bush(RC_HF_SOUTHERN_BUSH_6, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(382,11073), "Southern Bush 6", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHERN_BUSH_6)); + locationTable[RC_HF_SOUTHERN_BUSH_7] = Location::Bush(RC_HF_SOUTHERN_BUSH_7, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(581,10672), "Southern Bush 7", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHERN_BUSH_7)); + locationTable[RC_HF_SOUTHERN_BUSH_8] = Location::Bush(RC_HF_SOUTHERN_BUSH_8, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(629,13433), "Southern Bush 8", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHERN_BUSH_8)); + locationTable[RC_HF_SOUTHERN_BUSH_9] = Location::Bush(RC_HF_SOUTHERN_BUSH_9, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(630,12773), "Southern Bush 9", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHERN_BUSH_9)); + locationTable[RC_HF_SOUTHERN_BUSH_10] = Location::Bush(RC_HF_SOUTHERN_BUSH_10, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(81,10873), "Southern Bush 10", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHERN_BUSH_10)); + locationTable[RC_HF_SOUTHERN_BUSH_11] = Location::Bush(RC_HF_SOUTHERN_BUSH_11, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(981,11673), "Southern Bush 11", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHERN_BUSH_11)); + locationTable[RC_HF_SOUTHERN_BUSH_12] = Location::Bush(RC_HF_SOUTHERN_BUSH_12, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(982,11013), "Southern Bush 12", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHERN_BUSH_12)); + locationTable[RC_HF_CHILD_SOUTHERN_BUSH_1] = Location::Bush(RC_HF_CHILD_SOUTHERN_BUSH_1, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-873,13221), "Child Southern Bush 1", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_SOUTHERN_BUSH_1)); + locationTable[RC_HF_CHILD_SOUTHERN_BUSH_2] = Location::Bush(RC_HF_CHILD_SOUTHERN_BUSH_2, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-874,13881), "Child Southern Bush 2", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_SOUTHERN_BUSH_2)); + locationTable[RC_HF_CHILD_SOUTHERN_BUSH_3] = Location::Bush(RC_HF_CHILD_SOUTHERN_BUSH_3, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(1009,11961), "Child Southern Bush 3", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_SOUTHERN_BUSH_3)); + locationTable[RC_HF_CHILD_SOUTHERN_BUSH_4] = Location::Bush(RC_HF_CHILD_SOUTHERN_BUSH_4, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(1310,12161), "Child Southern Bush 4", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_SOUTHERN_BUSH_4)); + locationTable[RC_HF_CHILD_SOUTHERN_BUSH_5] = Location::Bush(RC_HF_CHILD_SOUTHERN_BUSH_5, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(1509,11760), "Child Southern Bush 5", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_SOUTHERN_BUSH_5)); + locationTable[RC_HF_CHILD_SOUTHERN_BUSH_6] = Location::Bush(RC_HF_CHILD_SOUTHERN_BUSH_6, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(1909,12761), "Child Southern Bush 6", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_SOUTHERN_BUSH_6)); + locationTable[RC_HF_CHILD_SOUTHERN_BUSH_7] = Location::Bush(RC_HF_CHILD_SOUTHERN_BUSH_7, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(1910,12101), "Child Southern Bush 7", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_SOUTHERN_BUSH_7)); + locationTable[RC_HF_CHILD_SOUTHERN_BUSH_8] = Location::Bush(RC_HF_CHILD_SOUTHERN_BUSH_8, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(930,12561), "Child Southern Bush 8", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_SOUTHERN_BUSH_8)); + locationTable[RC_HF_CHILD_SOUTHERN_BUSH_9] = Location::Bush(RC_HF_CHILD_SOUTHERN_BUSH_9, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-1274,12880), "Child Southern Bush 9", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_SOUTHERN_BUSH_9)); + locationTable[RC_HF_CHILD_SOUTHERN_BUSH_10] = Location::Bush(RC_HF_CHILD_SOUTHERN_BUSH_10, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-1473,13281), "Child Southern Bush 10", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_SOUTHERN_BUSH_10)); + locationTable[RC_HF_CHILD_SOUTHERN_BUSH_11] = Location::Bush(RC_HF_CHILD_SOUTHERN_BUSH_11, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-1774,13081), "Child Southern Bush 11", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_SOUTHERN_BUSH_11)); + locationTable[RC_HF_CHILD_SOUTHERN_BUSH_12] = Location::Bush(RC_HF_CHILD_SOUTHERN_BUSH_12, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-1853,13681), "Child Southern Bush 12", RHT_BUSH_HYRULE_FIELD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_SOUTHERN_BUSH_12)); + locationTable[RC_ZF_BUSH_1] = Location::Bush(RC_ZF_BUSH_1, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(167,2514), "Bush 1", RHT_BUSH_ZORAS_FOUNTAIN, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_BUSH_1)); + locationTable[RC_ZF_BUSH_2] = Location::Bush(RC_ZF_BUSH_2, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(394,2510), "Bush 2", RHT_BUSH_ZORAS_FOUNTAIN, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_BUSH_2)); + locationTable[RC_ZF_BUSH_3] = Location::Bush(RC_ZF_BUSH_3, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(231,2406), "Bush 3", RHT_BUSH_ZORAS_FOUNTAIN, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_BUSH_3)); + locationTable[RC_ZF_BUSH_4] = Location::Bush(RC_ZF_BUSH_4, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(544,2373), "Bush 4", RHT_BUSH_ZORAS_FOUNTAIN, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_BUSH_4)); + locationTable[RC_ZF_BUSH_5] = Location::Bush(RC_ZF_BUSH_5, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(386,2265), "Bush 5", RHT_BUSH_ZORAS_FOUNTAIN, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_BUSH_5)); + locationTable[RC_ZF_BUSH_6] = Location::Bush(RC_ZF_BUSH_6, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(551,2184), "Bush 6", RHT_BUSH_ZORAS_FOUNTAIN, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_BUSH_6)); // clang-format on } -static ObjectExtension::Register RegisterPotIdentity; +static ObjectExtension::Register RegisterTreeIdentity; static RegisterShipInitFunc registerShuffleTrees(RegisterShuffleTrees, { "IS_RANDO" }); static RegisterShipInitFunc registerTreeLocations(Rando::StaticData::RegisterTreeLocations); diff --git a/soh/soh/Enhancements/randomizer/context.cpp b/soh/soh/Enhancements/randomizer/context.cpp index ef680862556..07d823c6f9f 100644 --- a/soh/soh/Enhancements/randomizer/context.cpp +++ b/soh/soh/Enhancements/randomizer/context.cpp @@ -203,6 +203,7 @@ void Context::GenerateLocationPool() { (location.GetRCType() == RCTYPE_TREE && !mOptions[RSK_SHUFFLE_TREES]) || (location.GetRCType() == RCTYPE_NLTREE && (!mOptions[RSK_SHUFFLE_TREES] || mOptions[RSK_LOGIC_RULES].IsNot(RO_LOGIC_NO_LOGIC))) || + (location.GetRCType() == RCTYPE_BUSH && !mOptions[RSK_SHUFFLE_BUSHES]) || (location.GetRCType() == RCTYPE_FREESTANDING && mOptions[RSK_SHUFFLE_FREESTANDING].Is(RO_SHUFFLE_FREESTANDING_OFF)) || (location.GetRCType() == RCTYPE_BEEHIVE && !mOptions[RSK_SHUFFLE_BEEHIVES])) { diff --git a/soh/soh/Enhancements/randomizer/draw.cpp b/soh/soh/Enhancements/randomizer/draw.cpp index b17718b6518..25e9f060e60 100644 --- a/soh/soh/Enhancements/randomizer/draw.cpp +++ b/soh/soh/Enhancements/randomizer/draw.cpp @@ -28,12 +28,14 @@ extern "C" { #include "objects/object_bv/object_bv.h" #include "objects/object_gnd/object_gnd.h" #include "objects/object_fd/object_fd.h" +#include "objects/object_mamenoki/object_mamenoki.h" #include "objects/object_mo/object_mo.h" #include "objects/object_sst/object_sst.h" #include "overlays/actors/ovl_Boss_Goma/z_boss_goma.h" #include "overlays/ovl_Boss_Sst/ovl_Boss_Sst.h" #include "objects/object_tw/object_tw.h" #include "objects/object_ganon2/object_ganon2.h" + extern PlayState* gPlayState; extern SaveContext gSaveContext; } @@ -116,6 +118,17 @@ extern "C" void Randomizer_DrawSmallKey(PlayState* play, GetItemEntry* getItemEn CLOSE_DISPS(play->state.gfxCtx); } +extern "C" void Randomizer_DrawBeanSprout(PlayState* play, GetItemEntry* getItemEntry) { + OPEN_DISPS(play->state.gfxCtx); + + Gfx_SetupDL_25Opa(play->state.gfxCtx); + Matrix_Scale(0.3f, 0.3f, 0.3f, MTXMODE_APPLY); + gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_MODELVIEW | G_MTX_LOAD); + gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gMagicBeanSeedlingDL); + + CLOSE_DISPS(play->state.gfxCtx); +} + extern "C" void Randomizer_DrawMap(PlayState* play, GetItemEntry* getItemEntry) { s16 color_slot = getItemEntry->drawItemId - RG_DEKU_TREE_MAP; s16 colors[12][3] = { @@ -1109,6 +1122,22 @@ extern "C" void Randomizer_DrawBronzeScale(PlayState* play, GetItemEntry* getIte CLOSE_DISPS(play->state.gfxCtx); } +extern "C" void Randomizer_DrawOpenChest(PlayState* play, GetItemEntry* getItemEntry) { + OPEN_DISPS(play->state.gfxCtx); + + Gfx_SetupDL_25Opa(play->state.gfxCtx); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), + G_MTX_MODELVIEW | G_MTX_LOAD); + + gDPSetGrayscaleColor(POLY_OPA_DISP++, 255, 255, 255, 255); + gSPGrayscale(POLY_OPA_DISP++, true); + gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gGiSmallKeyDL); + gSPGrayscale(POLY_OPA_DISP++, false); + + CLOSE_DISPS(play->state.gfxCtx); +} + extern "C" void Randomizer_DrawFishingPoleGI(PlayState* play, GetItemEntry* getItemEntry) { Vec3f pos; OPEN_DISPS(play->state.gfxCtx); @@ -1221,4 +1250,4 @@ extern "C" void Randomizer_DrawOverworldKey(PlayState* play, GetItemEntry* getIt gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gHouseKeyDL); CLOSE_DISPS(play->state.gfxCtx); -} +} \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/draw.h b/soh/soh/Enhancements/randomizer/draw.h index 8483a7bf966..3adad3899ad 100644 --- a/soh/soh/Enhancements/randomizer/draw.h +++ b/soh/soh/Enhancements/randomizer/draw.h @@ -14,6 +14,7 @@ void Randomizer_DrawMap(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawCompass(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawKeyRing(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawBossKey(PlayState* play, GetItemEntry* getItemEntry); +void Randomizer_DrawBeanSprout(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawBossSoul(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawDoubleDefense(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawMasterSword(PlayState* play, GetItemEntry* getItemEntry); @@ -21,6 +22,7 @@ void Randomizer_DrawTriforcePiece(PlayState* play, GetItemEntry getItemEntry); void Randomizer_DrawTriforcePieceGI(PlayState* play, GetItemEntry getItemEntry); void Randomizer_DrawOcarinaButton(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawBronzeScale(PlayState* play, GetItemEntry* getItemEntry); +void Randomizer_DrawOpenChest(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawFishingPoleGI(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawSkeletonKey(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawMysteryItem(PlayState* play, GetItemEntry* getItemEntry); diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 82a9336fad0..4fdc39cc3df 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -863,6 +863,9 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l case VB_MIDO_CONSIDER_DEKU_TREE_DEAD: *should = Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_KOKIRI_EMERALD_DEKU_TREE_DEAD); break; + case VB_OPEN_CHEST: + *should = *should && Flags_GetRandomizerInf(RAND_INF_CAN_OPEN_CHEST); + break; case VB_OPEN_KOKIRI_FOREST: *should = Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_KOKIRI_EMERALD_DEKU_TREE_DEAD) || RAND_GET_OPTION(RSK_FOREST) != RO_CLOSED_FOREST_ON; @@ -2173,6 +2176,49 @@ void RandomizerOnActorInitHandler(void* actorRef) { return; } + if (RAND_GET_OPTION(RSK_SHUFFLE_BEAN_SOULS)) { + if (actor->id == ACTOR_OBJ_BEAN) { + RandomizerInf currentBeanSoulRandInf = RAND_INF_MAX; + switch (gPlayState->sceneNum) { + case SCENE_DEATH_MOUNTAIN_CRATER: + currentBeanSoulRandInf = RAND_INF_DEATH_MOUNTAIN_CRATER_BEAN_SOUL; + break; + case SCENE_DEATH_MOUNTAIN_TRAIL: + currentBeanSoulRandInf = RAND_INF_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL; + break; + case SCENE_DESERT_COLOSSUS: + currentBeanSoulRandInf = RAND_INF_DESERT_COLOSSUS_BEAN_SOUL; + break; + case SCENE_GERUDO_VALLEY: + currentBeanSoulRandInf = RAND_INF_GERUDO_VALLEY_BEAN_SOUL; + break; + case SCENE_GRAVEYARD: + currentBeanSoulRandInf = RAND_INF_GRAVEYARD_BEAN_SOUL; + break; + case SCENE_KOKIRI_FOREST: + currentBeanSoulRandInf = RAND_INF_KOKIRI_FOREST_BEAN_SOUL; + break; + case SCENE_LAKE_HYLIA: + currentBeanSoulRandInf = RAND_INF_LAKE_HYLIA_BEAN_SOUL; + break; + case SCENE_LOST_WOODS: + if ((actor->params & 0x3F) == 4) { + currentBeanSoulRandInf = RAND_INF_LOST_WOODS_BRIDGE_BEAN_SOUL; + } else { + currentBeanSoulRandInf = RAND_INF_LOST_WOODS_BEAN_SOUL; + } + break; + case SCENE_ZORAS_RIVER: + currentBeanSoulRandInf = RAND_INF_ZORAS_RIVER_BEAN_SOUL; + break; + } + if (currentBeanSoulRandInf != RAND_INF_MAX && !Flags_GetRandomizerInf(currentBeanSoulRandInf)) { + Actor_Kill(actor); + return; + } + } + } + // If child is in the adult shooting gallery or adult in the child shooting gallery, then despawn the shooting // gallery man if (actor->id == ACTOR_EN_SYATEKI_MAN && RAND_GET_OPTION(RSK_SHUFFLE_INTERIOR_ENTRANCES) && diff --git a/soh/soh/Enhancements/randomizer/item_list.cpp b/soh/soh/Enhancements/randomizer/item_list.cpp index 3f6535c8326..e3882732faf 100644 --- a/soh/soh/Enhancements/randomizer/item_list.cpp +++ b/soh/soh/Enhancements/randomizer/item_list.cpp @@ -317,6 +317,26 @@ void Rando::StaticData::InitItemTable() { itemTable[RG_BUY_RED_POTION_40] = Item(RG_BUY_RED_POTION_40, Text{ "Buy Red Potion [40]", "Acheter: Potion Rouge [40]", "Rotes Elixier kaufen [40]" }, ITEMTYPE_SHOP, GI_POTION_RED, false, LOGIC_NONE, RHT_BOTTLE_WITH_RED_POTION, ITEM_POTION_RED, OBJECT_GI_LIQUID, GID_POTION_RED, 0x43, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, false, 40); itemTable[RG_BUY_RED_POTION_50] = Item(RG_BUY_RED_POTION_50, Text{ "Buy Red Potion [50]", "Acheter: Potion Rouge [50]", "Rotes Elixier kaufen [50]" }, ITEMTYPE_SHOP, GI_POTION_RED, false, LOGIC_NONE, RHT_BOTTLE_WITH_RED_POTION, ITEM_POTION_RED, OBJECT_GI_LIQUID, GID_POTION_RED, 0x43, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, false, 50); // Misc. + itemTable[RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL] = Item(RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL, Text{ "Death Mountain Crater Bean Soul" }, ITEMTYPE_ITEM, 0xE0, true, LOGIC_NONE, RHT_BEAN_SOUL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL, OBJECT_GI_BEAN, GID_BEAN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL].SetCustomDrawFunc(Randomizer_DrawBeanSprout); + itemTable[RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL] = Item(RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL, Text{ "Death Mountain Trail Bean Soul" }, ITEMTYPE_ITEM, 0xE0, true, LOGIC_NONE, RHT_BEAN_SOUL, RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL, OBJECT_GI_BEAN, GID_BEAN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL].SetCustomDrawFunc(Randomizer_DrawBeanSprout); + itemTable[RG_DESERT_COLOSSUS_BEAN_SOUL] = Item(RG_DESERT_COLOSSUS_BEAN_SOUL, Text{ "Desert Colossus Bean Soul" }, ITEMTYPE_ITEM, 0xE0, true, LOGIC_NONE, RHT_BEAN_SOUL, RG_DESERT_COLOSSUS_BEAN_SOUL, OBJECT_GI_BEAN, GID_BEAN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_DESERT_COLOSSUS_BEAN_SOUL].SetCustomDrawFunc(Randomizer_DrawBeanSprout); + itemTable[RG_GERUDO_VALLEY_BEAN_SOUL] = Item(RG_GERUDO_VALLEY_BEAN_SOUL, Text{ "Gerudo Valley Bean Soul" }, ITEMTYPE_ITEM, 0xE0, true, LOGIC_NONE, RHT_BEAN_SOUL, RG_GERUDO_VALLEY_BEAN_SOUL, OBJECT_GI_BEAN, GID_BEAN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_GERUDO_VALLEY_BEAN_SOUL].SetCustomDrawFunc(Randomizer_DrawBeanSprout); + itemTable[RG_GRAVEYARD_BEAN_SOUL] = Item(RG_GRAVEYARD_BEAN_SOUL, Text{ "Graveyard Bean Soul" }, ITEMTYPE_ITEM, 0xE0, true, LOGIC_NONE, RHT_BEAN_SOUL, RG_GRAVEYARD_BEAN_SOUL, OBJECT_GI_BEAN, GID_BEAN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_GRAVEYARD_BEAN_SOUL].SetCustomDrawFunc(Randomizer_DrawBeanSprout); + itemTable[RG_KOKIRI_FOREST_BEAN_SOUL] = Item(RG_KOKIRI_FOREST_BEAN_SOUL, Text{ "Kokiri Forest Bean Soul" }, ITEMTYPE_ITEM, 0xE0, true, LOGIC_NONE, RHT_BEAN_SOUL, RG_KOKIRI_FOREST_BEAN_SOUL, OBJECT_GI_BEAN, GID_BEAN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_KOKIRI_FOREST_BEAN_SOUL].SetCustomDrawFunc(Randomizer_DrawBeanSprout); + itemTable[RG_LAKE_HYLIA_BEAN_SOUL] = Item(RG_LAKE_HYLIA_BEAN_SOUL, Text{ "Lake Hylia Bean Soul" }, ITEMTYPE_ITEM, 0xE0, true, LOGIC_NONE, RHT_BEAN_SOUL, RG_LAKE_HYLIA_BEAN_SOUL, OBJECT_GI_BEAN, GID_BEAN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_LAKE_HYLIA_BEAN_SOUL].SetCustomDrawFunc(Randomizer_DrawBeanSprout); + itemTable[RG_LOST_WOODS_BRIDGE_BEAN_SOUL] = Item(RG_LOST_WOODS_BRIDGE_BEAN_SOUL, Text{ "Lost Woods Bridge Bean Soul" }, ITEMTYPE_ITEM, 0xE0, true, LOGIC_NONE, RHT_BEAN_SOUL, RG_LOST_WOODS_BRIDGE_BEAN_SOUL, OBJECT_GI_BEAN, GID_BEAN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_LOST_WOODS_BRIDGE_BEAN_SOUL].SetCustomDrawFunc(Randomizer_DrawBeanSprout); + itemTable[RG_LOST_WOODS_BEAN_SOUL] = Item(RG_LOST_WOODS_BEAN_SOUL, Text{ "Lost Woods Bean Soul" }, ITEMTYPE_ITEM, 0xE0, true, LOGIC_NONE, RHT_BEAN_SOUL, RG_LOST_WOODS_BEAN_SOUL, OBJECT_GI_BEAN, GID_BEAN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_LOST_WOODS_BEAN_SOUL].SetCustomDrawFunc(Randomizer_DrawBeanSprout); + itemTable[RG_ZORAS_RIVER_BEAN_SOUL] = Item(RG_ZORAS_RIVER_BEAN_SOUL, Text{ "Zora's River Bean Soul" }, ITEMTYPE_ITEM, 0xE0, true, LOGIC_NONE, RHT_BEAN_SOUL, RG_ZORAS_RIVER_BEAN_SOUL, OBJECT_GI_BEAN, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_ZORAS_RIVER_BEAN_SOUL].SetCustomDrawFunc(Randomizer_DrawBeanSprout); itemTable[RG_GOHMA_SOUL] = Item(RG_GOHMA_SOUL, Text{ "Gohma's Soul", "Âme de Gohma", "Gohmas Seele" }, ITEMTYPE_ITEM, 0xE0, true, LOGIC_CAN_SUMMON_GOHMA, RHT_GOHMA_SOUL, RG_GOHMA_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_GOHMA_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul); itemTable[RG_KING_DODONGO_SOUL] = Item(RG_KING_DODONGO_SOUL, Text{ "King Dodongo's Soul", "Âme du Roi Dodongo", "König Dodongos Seele" }, ITEMTYPE_ITEM, 0xE1, true, LOGIC_CAN_SUMMON_KINGDODONGO, RHT_KING_DODONGO_SOUL, RG_KING_DODONGO_SOUL, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); @@ -349,9 +369,12 @@ void Rando::StaticData::InitItemTable() { itemTable[RG_OCARINA_C_RIGHT_BUTTON] = Item(RG_OCARINA_C_RIGHT_BUTTON, Text{ "Ocarina C Right Button", "Touche C-Droit de l'Ocarina", "C-Rechts-Taste der Okarina" }, ITEMTYPE_ITEM, GI_MAP, true, LOGIC_OCARINA_C_RIGHT_BUTTON, RHT_OCARINA_C_RIGHT_BUTTON, RG_OCARINA_C_RIGHT_BUTTON, OBJECT_GI_MAP, GID_STONE_OF_AGONY, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_OCARINA_C_RIGHT_BUTTON].SetCustomDrawFunc(Randomizer_DrawOcarinaButton); - itemTable[RG_BRONZE_SCALE] = Item(RG_BRONZE_SCALE, Text{ "Bronze Scale", "Écaille de Bronze", "Bronzene Schuppe" }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, LOGIC_PROGRESSIVE_WALLET, RHT_BRONZE_SCALE, RG_BRONZE_SCALE, OBJECT_GI_SCALE, GID_SCALE_SILVER, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_BRONZE_SCALE] = Item(RG_BRONZE_SCALE, Text{ "Bronze Scale", "Écaille de Bronze", "Bronzene Schuppe" }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, LOGIC_NONE, RHT_BRONZE_SCALE, RG_BRONZE_SCALE, OBJECT_GI_SCALE, GID_SCALE_SILVER, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_BRONZE_SCALE].SetCustomDrawFunc(Randomizer_DrawBronzeScale); + itemTable[RG_OPEN_CHEST] = Item(RG_OPEN_CHEST, Text{ "Open Chests", "!!!", "!!!" }, ITEMTYPE_ITEM, GI_KEY_SMALL, true, LOGIC_NONE, RHT_OPEN_CHEST, RG_OPEN_CHEST, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_OPEN_CHEST].SetCustomDrawFunc(Randomizer_DrawOpenChest); + itemTable[RG_BOMBCHU_BAG] = Item(RG_BOMBCHU_BAG, Text{ "Bombchu Bag", "Sac de Missiles Teigneux", "Krabbelminentasche" }, ITEMTYPE_ITEM, RG_BOMBCHU_BAG, true, LOGIC_BOMBCHUS, RHT_BOMBCHU_BAG, RG_BOMBCHU_BAG, OBJECT_GI_BOMB_2, GID_BOMBCHU, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_BOMBCHU_BAG].SetCustomDrawFunc(Randomizer_DrawBombchuBag); diff --git a/soh/soh/Enhancements/randomizer/location.cpp b/soh/soh/Enhancements/randomizer/location.cpp index 847ee9aa991..250af2cfb74 100644 --- a/soh/soh/Enhancements/randomizer/location.cpp +++ b/soh/soh/Enhancements/randomizer/location.cpp @@ -585,6 +585,15 @@ Rando::Location Rando::Location::NLTree(RandomizerCheck rc, RandomizerCheckQuest false, collectionCheck }; } +Rando::Location Rando::Location::Bush(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, + SceneID scene_, int32_t actorParams_, std::string&& shortName_, + RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, + SpoilerCollectionCheck collectionCheck) { + return { rc, quest_, RCTYPE_BUSH, area_, ACTOR_EN_WOOD02, + scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem, + false, collectionCheck }; +} + Rando::Location Rando::Location::HintStone(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, int32_t actorParams_, std::string&& shortName_) { return { rc, quest_, RCTYPE_GOSSIP_STONE, area_, ACTOR_EN_GS, diff --git a/soh/soh/Enhancements/randomizer/location.h b/soh/soh/Enhancements/randomizer/location.h index f118bdcda38..9556012204a 100644 --- a/soh/soh/Enhancements/randomizer/location.h +++ b/soh/soh/Enhancements/randomizer/location.h @@ -254,6 +254,10 @@ class Location { int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck); + static Location Bush(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, + int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey, + RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck); + static Location OtherHint(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, std::string&& shortName_, std::string&& spoilerName_); diff --git a/soh/soh/Enhancements/randomizer/location_access.cpp b/soh/soh/Enhancements/randomizer/location_access.cpp index 0f517aa3ff5..8b468544ea4 100644 --- a/soh/soh/Enhancements/randomizer/location_access.cpp +++ b/soh/soh/Enhancements/randomizer/location_access.cpp @@ -511,8 +511,25 @@ Rando::Entrance* Region::GetExit(RandomizerRegion exitToReturn) { return nullptr; } -bool Region::CanPlantBeanCheck() const { - return Rando::Context::GetInstance()->GetLogic()->GetAmmo(ITEM_BEAN) > 0 && BothAgesCheck(); +bool Region::CanPlantBeanCheck(RandomizerGet bean) const { + auto ctx = Rando::Context::GetInstance(); + auto logic = ctx->GetLogic(); + + if (!logic->HasItem(bean)) { + // Never available without soul + return false; + } else if (ctx->GetOption(RSK_SKIP_PLANTING_BEANS) && + !ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_BEANS_ONLY) && + !ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL)) { + // All planted when skip enabled & bean pack not shuffled + return true; + } else if (logic->GetAmmo(ITEM_BEAN) <= 0) { + // Need bean pack + return false; + } else { + // BothAgesCheck necessary when planting + return ctx->GetOption(RSK_SKIP_PLANTING_BEANS) || BothAgesCheck(); + } } bool Region::AllAccountedFor() const { @@ -681,49 +698,49 @@ bool MQSpiritSharedBrokenWallRoom(const RandomizerRegion region, ConditionFn con return areaTable[region].MQSpiritShared(condition, true, anyAge); } -bool BeanPlanted(const RandomizerRegion region) { +bool BeanPlanted(const RandomizerGet bean) { // swchFlag found using the Actor Viewer to get the Obj_Bean parameters & 0x3F // not tested with multiple OTRs, but can be automated similarly to GetDungeonSmallKeyDoors SceneID sceneID; uint8_t swchFlag; - switch (region) { - case RR_ZORAS_RIVER: + switch (bean) { + case RG_ZORAS_RIVER_BEAN_SOUL: sceneID = SceneID::SCENE_ZORAS_RIVER; swchFlag = 3; break; - case RR_THE_GRAVEYARD: + case RG_GRAVEYARD_BEAN_SOUL: sceneID = SceneID::SCENE_GRAVEYARD; swchFlag = 3; break; - case RR_KOKIRI_FOREST: + case RG_KOKIRI_FOREST_BEAN_SOUL: sceneID = SceneID::SCENE_KOKIRI_FOREST; swchFlag = 9; break; - case RR_THE_LOST_WOODS: + case RG_LOST_WOODS_BRIDGE_BEAN_SOUL: sceneID = SceneID::SCENE_LOST_WOODS; swchFlag = 4; break; - case RR_LW_BEYOND_MIDO: + case RG_LOST_WOODS_BEAN_SOUL: sceneID = SceneID::SCENE_LOST_WOODS; swchFlag = 18; break; - case RR_DEATH_MOUNTAIN_TRAIL: + case RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL: sceneID = SceneID::SCENE_DEATH_MOUNTAIN_TRAIL; swchFlag = 6; break; - case RR_LAKE_HYLIA: + case RG_LAKE_HYLIA_BEAN_SOUL: sceneID = SceneID::SCENE_LAKE_HYLIA; swchFlag = 1; break; - case RR_GERUDO_VALLEY: + case RG_GERUDO_VALLEY_BEAN_SOUL: sceneID = SceneID::SCENE_GERUDO_VALLEY; swchFlag = 3; break; - case RR_DMC_CENTRAL_LOCAL: + case RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL: sceneID = SceneID::SCENE_DEATH_MOUNTAIN_CRATER; swchFlag = 3; break; - case RR_DESERT_COLOSSUS: + case RG_DESERT_COLOSSUS_BEAN_SOUL: sceneID = SceneID::SCENE_DESERT_COLOSSUS; swchFlag = 24; break; @@ -747,8 +764,8 @@ bool BeanPlanted(const RandomizerRegion region) { return swch >> swchFlag & 1; } -bool CanPlantBean(const RandomizerRegion region) { - return areaTable[region].CanPlantBeanCheck() || BeanPlanted(region); +bool CanPlantBean(const RandomizerRegion region, const RandomizerGet bean) { + return areaTable[region].CanPlantBeanCheck(bean) || BeanPlanted(bean); } bool BothAges(const RandomizerRegion region) { diff --git a/soh/soh/Enhancements/randomizer/location_access.h b/soh/soh/Enhancements/randomizer/location_access.h index d55928eea85..83ba46a6f0e 100644 --- a/soh/soh/Enhancements/randomizer/location_access.h +++ b/soh/soh/Enhancements/randomizer/location_access.h @@ -210,7 +210,7 @@ class Region { return hereVal; } - bool CanPlantBeanCheck() const; + bool CanPlantBeanCheck(RandomizerGet bean) const; bool AllAccountedFor() const; bool MQSpiritShared(ConditionFn condition, bool IsBrokenWall, bool anyAge = false); @@ -227,7 +227,7 @@ bool Here(const RandomizerRegion region, condition); // RANDOTODO make a less stupid way to check own at either age than self referencing with this bool MQSpiritSharedStatueRoom(const RandomizerRegion region, ConditionFn condition, bool anyAge = false); bool MQSpiritSharedBrokenWallRoom(const RandomizerRegion region, ConditionFn condition, bool anyAge = false); -bool CanPlantBean(const RandomizerRegion region); +bool CanPlantBean(const RandomizerRegion region, RandomizerGet bean); bool BothAges(const RandomizerRegion region); bool ChildCanAccess(const RandomizerRegion region); bool AdultCanAccess(const RandomizerRegion region); diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/bottom_of_the_well.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/bottom_of_the_well.cpp index 62db2164acf..be95e626a6d 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/bottom_of_the_well.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/bottom_of_the_well.cpp @@ -31,12 +31,12 @@ void RegionTable_Init_BottomOfTheWell() { EventAccess(LOGIC_BOTW_LOWERED_WATER, []{return logic->CanUse(RG_ZELDAS_LULLABY);}), }, { //Locations - LOCATION(RC_BOTTOM_OF_THE_WELL_FRONT_LEFT_FAKE_WALL_CHEST, ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)), - LOCATION(RC_BOTTOM_OF_THE_WELL_RIGHT_BOTTOM_FAKE_WALL_CHEST, ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)), - LOCATION(RC_BOTTOM_OF_THE_WELL_FRONT_CENTER_BOMBABLE_CHEST, logic->HasExplosives()), - LOCATION(RC_BOTTOM_OF_THE_WELL_BACK_LEFT_BOMBABLE_CHEST, logic->HasExplosives() && (ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH))), - LOCATION(RC_BOTTOM_OF_THE_WELL_UNDERWATER_FRONT_CHEST, logic->Get(LOGIC_BOTW_LOWERED_WATER) || logic->CanOpenUnderwaterChest()), - LOCATION(RC_BOTTOM_OF_THE_WELL_UNDERWATER_LEFT_CHEST, logic->Get(LOGIC_BOTW_LOWERED_WATER) || logic->CanOpenUnderwaterChest()), + LOCATION(RC_BOTTOM_OF_THE_WELL_FRONT_LEFT_FAKE_WALL_CHEST, (ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_BOTTOM_OF_THE_WELL_RIGHT_BOTTOM_FAKE_WALL_CHEST, (ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_BOTTOM_OF_THE_WELL_FRONT_CENTER_BOMBABLE_CHEST, logic->HasExplosives() && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_BOTTOM_OF_THE_WELL_BACK_LEFT_BOMBABLE_CHEST, (logic->HasExplosives() && (ctx->GetTrickOption(RT_LENS_BOTW) && logic->HasItem(RG_OPEN_CHEST)) || (logic->CanUse(RG_LENS_OF_TRUTH) && logic->HasItem(RG_OPEN_CHEST)))), + LOCATION(RC_BOTTOM_OF_THE_WELL_UNDERWATER_FRONT_CHEST, (logic->Get(LOGIC_BOTW_LOWERED_WATER) || logic->CanOpenUnderwaterChest()) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_BOTTOM_OF_THE_WELL_UNDERWATER_LEFT_CHEST, (logic->Get(LOGIC_BOTW_LOWERED_WATER) || logic->CanOpenUnderwaterChest()) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_1, logic->CanBreakPots()), LOCATION(RC_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_2, logic->CanBreakPots()), LOCATION(RC_BOTTOM_OF_THE_WELL_UNDERWATER_POT, (logic->CanBreakPots() && logic->Get(LOGIC_BOTW_LOWERED_WATER)) || logic->CanUse(RG_BOOMERANG)), @@ -61,7 +61,7 @@ void RegionTable_Init_BottomOfTheWell() { areaTable[RR_BOTW_MIDDLE] = Region("Bottom of the Well Middle", SCENE_BOTTOM_OF_THE_WELL, {}, { //Locations //You can just barely pass the spider on the right side without damage or items, but it's probably tight enough to count as as a trick - LOCATION(RC_BOTTOM_OF_THE_WELL_CENTER_SKULLTULA_CHEST, logic->CanPassEnemy(RE_BIG_SKULLTULA) || logic->TakeDamage()), + LOCATION(RC_BOTTOM_OF_THE_WELL_CENTER_SKULLTULA_CHEST, (logic->CanPassEnemy(RE_BIG_SKULLTULA) || logic->TakeDamage()) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_BOTW_PERIMETER, []{return ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH);}), @@ -91,7 +91,7 @@ void RegionTable_Init_BottomOfTheWell() { //Passing through this area needs lens, but entering doesn't, so that the fire keese can be killed without crossing the pits if enemy drops are ever shuffled areaTable[RR_BOTW_HIDDEN_PITS_ROOM] = Region("Bottom of the Well Hidden Pits Room", SCENE_BOTTOM_OF_THE_WELL, {}, { //Locations - LOCATION(RC_BOTTOM_OF_THE_WELL_FIRE_KEESE_CHEST, ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)), + LOCATION(RC_BOTTOM_OF_THE_WELL_FIRE_KEESE_CHEST, (ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_BOTTOM_OF_THE_WELL_FIRE_KEESE_POT_1, logic->CanBreakPots() && (ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH))), }, { //Exits @@ -103,7 +103,7 @@ void RegionTable_Init_BottomOfTheWell() { areaTable[RR_BOTW_LOCKED_CAGE] = Region("Bottom of the Well Locked Cage", SCENE_BOTTOM_OF_THE_WELL, {}, { //Locations - LOCATION(RC_BOTTOM_OF_THE_WELL_LIKE_LIKE_CHEST, true), + LOCATION(RC_BOTTOM_OF_THE_WELL_LIKE_LIKE_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_BOTTOM_OF_THE_WELL_GS_LIKE_LIKE_CAGE, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)), }, { //Exits @@ -112,7 +112,7 @@ void RegionTable_Init_BottomOfTheWell() { areaTable[RR_BOTW_PIT_CAGE] = Region("Bottom of the Well Pit Cage", SCENE_BOTTOM_OF_THE_WELL, {}, { //Locations - LOCATION(RC_BOTTOM_OF_THE_WELL_COMPASS_CHEST, true), + LOCATION(RC_BOTTOM_OF_THE_WELL_COMPASS_CHEST, logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_BOTW_PERIMETER, []{return ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH);}), @@ -178,8 +178,8 @@ void RegionTable_Init_BottomOfTheWell() { areaTable[RR_BOTW_DEAD_HAND_ROOM] = Region("Bottom of the Well Dead Hand Room", SCENE_BOTTOM_OF_THE_WELL, {}, { //Locations - LOCATION(RC_BOTTOM_OF_THE_WELL_LENS_OF_TRUTH_CHEST, logic->CanKillEnemy(RE_DEAD_HAND)), - LOCATION(RC_BOTTOM_OF_THE_WELL_INVISIBLE_CHEST, (ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_BOTTOM_OF_THE_WELL_LENS_OF_TRUTH_CHEST, logic->CanKillEnemy(RE_DEAD_HAND) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_BOTTOM_OF_THE_WELL_INVISIBLE_CHEST, (ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_BOTW_NEAR_BOSS_UPPER, []{return logic->CanKillEnemy(RE_DEAD_HAND);}), @@ -238,7 +238,7 @@ void RegionTable_Init_BottomOfTheWell() { areaTable[RR_BOTW_B3_CHEST_AREA] = Region("Bottom of the Well B3 Chest Area", SCENE_BOTTOM_OF_THE_WELL, {}, { //Locations - LOCATION(RC_BOTTOM_OF_THE_WELL_MAP_CHEST, true), + LOCATION(RC_BOTTOM_OF_THE_WELL_MAP_CHEST, logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_BOTW_B3_OOZE, []{return Here(RR_BOTW_B3_CHEST_AREA, []{return logic->BlastOrSmash();});}), @@ -293,7 +293,7 @@ void RegionTable_Init_BottomOfTheWell() { areaTable[RR_BOTW_MQ_MIDDLE] = Region("Bottom of the Well MQ Middle", SCENE_BOTTOM_OF_THE_WELL, {}, { //Locations - LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_MAP_CHEST, true), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_MAP_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_1, logic->CanBreakPots()), LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_2, logic->CanBreakPots()), LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_3, logic->CanBreakPots()), @@ -398,7 +398,7 @@ void RegionTable_Init_BottomOfTheWell() { areaTable[RR_BOTW_MQ_DEAD_HAND_ROOM] = Region("Bottom of the Well MQ Dead Hand Room", SCENE_BOTTOM_OF_THE_WELL, {}, { //Locations - LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_COMPASS_CHEST, logic->CanKillEnemy(RE_DEAD_HAND)), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_COMPASS_CHEST, logic->CanKillEnemy(RE_DEAD_HAND) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_FREESTANDING_KEY, logic->HasExplosives() || (ctx->GetTrickOption(RT_BOTW_MQ_DEADHAND_KEY) && logic->CanUse(RG_BOOMERANG))), LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_GRASS_1, logic->CanCutShrubs()), LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_GRASS_2, logic->CanCutShrubs()), @@ -425,7 +425,7 @@ void RegionTable_Init_BottomOfTheWell() { areaTable[RR_BOTW_MQ_B3_PLATFORM] = Region("Bottom of the Well MQ B3 Platform", SCENE_BOTTOM_OF_THE_WELL, {}, { //Locations //Assumes RR_BOTW_MQ_B3 access - LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_LENS_OF_TRUTH_CHEST, logic->CanPassEnemy(RE_REDEAD)), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_LENS_OF_TRUTH_CHEST, logic->CanPassEnemy(RE_REDEAD) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_BOTW_MQ_B3, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp index 6dde5698d66..916d00a736d 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp @@ -22,7 +22,7 @@ void RegionTable_Init_DekuTree() { EventAccess(LOGIC_DEKU_BABA_NUTS, []{return logic->CanGetDekuBabaNuts();}), }, { //Locations - LOCATION(RC_DEKU_TREE_MAP_CHEST, true), + LOCATION(RC_DEKU_TREE_MAP_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_DEKU_TREE_LOBBY_LOWER_HEART, true), LOCATION(RC_DEKU_TREE_LOBBY_UPPER_HEART, logic->CanPassEnemy(RE_BIG_SKULLTULA)), LOCATION(RC_DEKU_TREE_LOBBY_GRASS_1, logic->CanCutShrubs()), @@ -48,8 +48,8 @@ void RegionTable_Init_DekuTree() { areaTable[RR_DEKU_TREE_SLINGSHOT_ROOM] = Region("Deku Tree Slingshot Room", SCENE_DEKU_TREE, {}, { //Locations - LOCATION(RC_DEKU_TREE_SLINGSHOT_CHEST, true), - LOCATION(RC_DEKU_TREE_SLINGSHOT_ROOM_SIDE_CHEST, true), + LOCATION(RC_DEKU_TREE_SLINGSHOT_CHEST, logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_DEKU_TREE_SLINGSHOT_ROOM_SIDE_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_DEKU_TREE_SLINGSHOT_GRASS_1, logic->CanCutShrubs() && logic->CanReflectNuts()), LOCATION(RC_DEKU_TREE_SLINGSHOT_GRASS_2, logic->CanCutShrubs() && logic->CanReflectNuts()), LOCATION(RC_DEKU_TREE_SLINGSHOT_GRASS_3, logic->CanCutShrubs() && logic->CanReflectNuts()), @@ -65,8 +65,8 @@ void RegionTable_Init_DekuTree() { EventAccess(LOGIC_DEKU_BABA_NUTS, []{return logic->CanGetDekuBabaNuts();}), }, { //Locations - LOCATION(RC_DEKU_TREE_COMPASS_CHEST, true), - LOCATION(RC_DEKU_TREE_COMPASS_ROOM_SIDE_CHEST, true), + LOCATION(RC_DEKU_TREE_COMPASS_CHEST, logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_DEKU_TREE_COMPASS_ROOM_SIDE_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_DEKU_TREE_GS_COMPASS_ROOM, logic->CanAttack()), LOCATION(RC_DEKU_TREE_COMPASS_GRASS_1, logic->CanCutShrubs()), LOCATION(RC_DEKU_TREE_COMPASS_GRASS_2, logic->CanCutShrubs()), @@ -82,7 +82,7 @@ void RegionTable_Init_DekuTree() { EventAccess(LOGIC_DEKU_BABA_NUTS, []{return logic->CanGetDekuBabaNuts();}), }, { //Locations - LOCATION(RC_DEKU_TREE_BASEMENT_CHEST, true), + LOCATION(RC_DEKU_TREE_BASEMENT_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_DEKU_TREE_GS_BASEMENT_GATE, logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_SHORT_JUMPSLASH)), LOCATION(RC_DEKU_TREE_GS_BASEMENT_VINES, logic->CanKillEnemy(RE_GOLD_SKULLTULA, ctx->GetTrickOption(RT_DEKU_MQ_COMPASS_GS) ? ED_SHORT_JUMPSLASH : ED_BOMB_THROW)), LOCATION(RC_DEKU_TREE_BASEMENT_GRASS_1, logic->CanCutShrubs()), @@ -215,7 +215,7 @@ void RegionTable_Init_DekuTree() { areaTable[RR_DEKU_TREE_MQ_2F] = Region("Deku Tree MQ 2F", SCENE_DEKU_TREE, {}, { //Locations - LOCATION(RC_DEKU_TREE_MQ_MAP_CHEST, true), + LOCATION(RC_DEKU_TREE_MQ_MAP_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_DEKU_TREE_MQ_GS_LOBBY, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)), LOCATION(RC_DEKU_TREE_MQ_LOBBY_HEART, true), LOCATION(RC_DEKU_TREE_MQ_LOBBY_GRASS_6, logic->CanCutShrubs()), @@ -237,8 +237,8 @@ void RegionTable_Init_DekuTree() { }, { //Locations //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_CHEST, logic->CanKillEnemy(RE_DEKU_BABA) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_DEKU_TREE_MQ_SLINGSHOT_ROOM_BACK_CHEST, (logic->HasFireSourceWithTorch() || (logic->IsAdult && logic->CanUse(RG_FAIRY_BOW))) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_DEKU_TREE_MQ_SLINGSHOT_ROOM_HEART, true), LOCATION(RC_DEKU_TREE_MQ_SLINGSHOT_GRASS_1, logic->CanCutShrubs()), LOCATION(RC_DEKU_TREE_MQ_SLINGSHOT_GRASS_2, logic->CanCutShrubs()), @@ -272,7 +272,7 @@ void RegionTable_Init_DekuTree() { areaTable[RR_DEKU_TREE_MQ_COMPASS_ROOM] = Region("Deku Tree MQ Compass Room", SCENE_DEKU_TREE, {}, { //Locations - LOCATION(RC_DEKU_TREE_MQ_COMPASS_CHEST, true), + LOCATION(RC_DEKU_TREE_MQ_BASEMENT_CHEST, (logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW)) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_DEKU_TREE_MQ_COMPASS_GRASS_1, logic->CanCutShrubs()), LOCATION(RC_DEKU_TREE_MQ_COMPASS_GRASS_2, logic->CanCutShrubs()), LOCATION(RC_DEKU_TREE_MQ_COMPASS_GRASS_3, logic->CanCutShrubs()), @@ -334,7 +334,7 @@ void RegionTable_Init_DekuTree() { EventAccess(LOGIC_DEKU_TREE_MQ_WATER_ROOM_TORCHES, []{return logic->CanUse(RG_FIRE_ARROWS) || (logic->CanUse(RG_STICKS) && (ctx->GetTrickOption(RT_DEKU_MQ_LOG) || (logic->IsChild && logic->CanShield())));}), }, { //Locations - LOCATION(RC_DEKU_TREE_MQ_BEFORE_SPINNING_LOG_CHEST, true), + LOCATION(RC_DEKU_TREE_MQ_BEFORE_SPINNING_LOG_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_DEKU_TREE_MQ_BASEMENT_SPIKE_ROLLER_FRONT_GRASS_1, logic->CanCutShrubs()), LOCATION(RC_DEKU_TREE_MQ_BASEMENT_SPIKE_ROLLER_FRONT_GRASS_2, logic->CanCutShrubs()), LOCATION(RC_DEKU_TREE_MQ_BASEMENT_SPIKE_ROLLER_FRONT_GRASS_3, logic->CanCutShrubs()), @@ -351,7 +351,7 @@ void RegionTable_Init_DekuTree() { }, { //Locations //it blocks the chest while stunned unless you stun it from afar while it's slightly off the ground - LOCATION(RC_DEKU_TREE_MQ_AFTER_SPINNING_LOG_CHEST, logic->CanUse(RG_SONG_OF_TIME) && logic->CanPassEnemy(RE_BIG_SKULLTULA)), + LOCATION(RC_DEKU_TREE_MQ_AFTER_SPINNING_LOG_CHEST, logic->CanUse(RG_SONG_OF_TIME) && logic->CanPassEnemy(RE_BIG_SKULLTULA) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_DEKU_TREE_MQ_BASEMENT_SPIKE_ROLLER_BACK_GRASS_1, logic->CanCutShrubs()), LOCATION(RC_DEKU_TREE_MQ_BASEMENT_SPIKE_ROLLER_BACK_GRASS_2, logic->CanCutShrubs()), }, { diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp index c21a7a33eb8..114c30eed80 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp @@ -27,7 +27,7 @@ void RegionTable_Init_DodongosCavern() { EventAccess(LOGIC_GOSSIP_STONE_FAIRY, []{return (Here(RR_DODONGOS_CAVERN_LOBBY, []{return logic->CanBreakMudWalls();}) || logic->HasItem(RG_GORONS_BRACELET)) && logic->CallGossipFairy();}), }, { //Locations - LOCATION(RC_DODONGOS_CAVERN_MAP_CHEST, logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET);), + LOCATION(RC_DODONGOS_CAVERN_MAP_CHEST, (logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET)) && logic->HasItem(RG_OPEN_CHEST);), LOCATION(RC_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY, logic->CanStunDeku() || logic->HasItem(RG_GORONS_BRACELET)), LOCATION(RC_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY, Here(RR_DODONGOS_CAVERN_LOBBY, []{return logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET);}) && logic->CallGossipFairy()), LOCATION(RC_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG, Here(RR_DODONGOS_CAVERN_LOBBY, []{return logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET);}) && logic->CanUse(RG_SONG_OF_STORMS)), @@ -146,7 +146,7 @@ void RegionTable_Init_DodongosCavern() { areaTable[RR_DODONGOS_CAVERN_COMPASS_ROOM] = Region("Dodongos Cavern Compass Room", SCENE_DODONGOS_CAVERN, {}, { //Locations - LOCATION(RC_DODONGOS_CAVERN_COMPASS_CHEST, true), + LOCATION(RC_DODONGOS_CAVERN_COMPASS_CHEST, logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_DODONGOS_CAVERN_STAIRS_LOWER, []{return logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET);}), @@ -160,7 +160,7 @@ void RegionTable_Init_DodongosCavern() { areaTable[RR_DODONGOS_CAVERN_BOMB_ROOM_LOWER] = Region("Dodongos Cavern Bomb Room Lower", SCENE_DODONGOS_CAVERN, {}, { //Locations - LOCATION(RC_DODONGOS_CAVERN_BOMB_FLOWER_PLATFORM_CHEST, true), + LOCATION(RC_DODONGOS_CAVERN_BOMB_FLOWER_PLATFORM_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_DODONGOS_CAVERN_BLADE_ROOM_HEART, true), LOCATION(RC_DODONGOS_CAVERN_FIRST_BRIDGE_GRASS, logic->CanCutShrubs()), LOCATION(RC_DODONGOS_CAVERN_BLADE_GRASS, logic->CanCutShrubs()), @@ -224,7 +224,7 @@ void RegionTable_Init_DodongosCavern() { areaTable[RR_DODONGOS_CAVERN_BOMB_ROOM_UPPER] = Region("Dodongos Cavern Bomb Room Upper", SCENE_DODONGOS_CAVERN, {}, { //Locations - LOCATION(RC_DODONGOS_CAVERN_BOMB_BAG_CHEST, true), + LOCATION(RC_DODONGOS_CAVERN_BOMB_BAG_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_DODONGOS_CAVERN_BLADE_POT_1, logic->CanBreakPots()), LOCATION(RC_DODONGOS_CAVERN_BLADE_POT_2, logic->CanBreakPots()), }, { @@ -240,7 +240,7 @@ void RegionTable_Init_DodongosCavern() { EventAccess(LOGIC_DC_LIFT_PLATFORM, []{return true;}), }, { //Locations - LOCATION(RC_DODONGOS_CAVERN_END_OF_BRIDGE_CHEST, logic->CanBreakMudWalls()), + LOCATION(RC_DODONGOS_CAVERN_END_OF_BRIDGE_CHEST, logic->CanBreakMudWalls() && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_DODONGOS_CAVERN_LOBBY, []{return true;}), @@ -284,7 +284,7 @@ void RegionTable_Init_DodongosCavern() { areaTable[RR_DODONGOS_CAVERN_MQ_LOBBY] = Region("Dodongos Cavern MQ Lobby", SCENE_DODONGOS_CAVERN, {}, { //Locations - LOCATION(RC_DODONGOS_CAVERN_MQ_MAP_CHEST, logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET)), + LOCATION(RC_DODONGOS_CAVERN_MQ_MAP_CHEST, (logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET)) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR, logic->CanStunDeku()), LOCATION(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT, logic->CanStunDeku()), }, { @@ -381,7 +381,7 @@ void RegionTable_Init_DodongosCavern() { areaTable[RR_DODONGOS_CAVERN_MQ_DODONGO_ROOM] = Region("Dodongos Cavern MQ Dodongo Room", SCENE_DODONGOS_CAVERN, {}, { //Locations - LOCATION(RC_DODONGOS_CAVERN_MQ_COMPASS_CHEST, logic->CanKillEnemy(RE_DODONGO) || logic->HasItem(RG_GORONS_BRACELET)), + LOCATION(RC_DODONGOS_CAVERN_MQ_COMPASS_CHEST, (logic->CanKillEnemy(RE_DODONGO) || logic->HasItem(RG_GORONS_BRACELET)) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_DODONGOS_CAVERN_MQ_COMPASS_GRASS_1, logic->CanCutShrubs()), LOCATION(RC_DODONGOS_CAVERN_MQ_COMPASS_GRASS_2, logic->CanCutShrubs()), LOCATION(RC_DODONGOS_CAVERN_MQ_COMPASS_GRASS_3, logic->CanCutShrubs()), @@ -422,7 +422,7 @@ void RegionTable_Init_DodongosCavern() { areaTable[RR_DODONGOS_CAVERN_MQ_LARVAE_ROOM] = Region("Dodongos Cavern MQ Larvae Room", SCENE_DODONGOS_CAVERN, {}, { //Locations - LOCATION(RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CHEST, true), //implied logic->CanKillEnemy(RE_GOHMA_LARVA) based on entry reqs with a trick to kill with nuts + LOCATION(RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CHEST, logic->HasItem(RG_OPEN_CHEST)), //implied logic->CanKillEnemy(RE_GOHMA_LARVA) based on entry reqs with a trick to kill with nuts LOCATION(RC_DODONGOS_CAVERN_MQ_GS_LARVAE_ROOM, logic->CanBreakCrates()), //implied logic->CanKillEnemy(RE_GOLD_SKULTULLA) based on entry reqs. Add crate logic when BONKO is added LOCATION(RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_1, logic->CanBreakCrates()), LOCATION(RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_2, logic->CanBreakCrates()), @@ -467,7 +467,7 @@ void RegionTable_Init_DodongosCavern() { EventAccess(LOGIC_DC_MQ_CLEAR_UPPER_LOBBY_ROCKS, []{return logic->CanDetonateUprightBombFlower() || logic->CanUse(RG_MEGATON_HAMMER);}), }, { //Locations - LOCATION(RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_CHEST, true), + LOCATION(RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_CORNER_POT, logic->CanBreakPots()), LOCATION(RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_MIDDLE_POT, logic->CanBreakPots()), }, { @@ -501,7 +501,7 @@ void RegionTable_Init_DodongosCavern() { areaTable[RR_DODONGOS_CAVERN_MQ_POES_ROOM] = Region("Dodongos Cavern MQ Poes Room", SCENE_DODONGOS_CAVERN, {}, { //Locations - LOCATION(RC_DODONGOS_CAVERN_MQ_BOMB_BAG_CHEST, true), //If you can get to the locked part of POES_ROOM without a way to open it or passing the chest, this will need it's own room + LOCATION(RC_DODONGOS_CAVERN_MQ_BOMB_BAG_CHEST, logic->HasItem(RG_OPEN_CHEST)), //If you can get to the locked part of POES_ROOM without a way to open it or passing the chest, this will need it's own room LOCATION(RC_DODONGOS_CAVERN_MQ_GS_SCRUB_ROOM, (Here(RR_DODONGOS_CAVERN_MQ_POES_ROOM, []{return logic->CanDetonateBombFlowers() || logic->HasItem(RG_GORONS_BRACELET);}) && //could be a seperate room if it gets busy logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG, true))), //Implies you can avoid/kill the enemies with what you use on the skull, if this assumption is broken, add //&& (Here(RR_DODONGOS_CAVERN_MQ_POES_ROOM, []{return logic->CanKillEnemy(RE_FIRE_KEESE) && logic->CanKillEnemy(RE_MAD_SCRUB);}) || (logic->CanAvoidEnemy(RE_FIRE_KEESE) && logic->CanAvoidEnemy(RE_MAD_SCRUB))) @@ -556,7 +556,7 @@ void RegionTable_Init_DodongosCavern() { EventAccess(LOGIC_DC_MQ_BEHIND_FIRE_SWITCH, []{return logic->CanDetonateBombFlowers();}), }, { //Locations - LOCATION(RC_DODONGOS_CAVERN_MQ_UNDER_GRAVE_CHEST, true), //pulling the grave isn't required, as you can open the chest through it + LOCATION(RC_DODONGOS_CAVERN_MQ_UNDER_GRAVE_CHEST, logic->HasItem(RG_OPEN_CHEST)), //pulling the grave isn't required, as you can open the chest through it LOCATION(RC_DODONGOS_CAVERN_MQ_GS_BACK_AREA, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)), LOCATION(RC_DODONGOS_CAVERN_MQ_BACKROOM_POT_1, logic->CanBreakPots()), LOCATION(RC_DODONGOS_CAVERN_MQ_BACKROOM_POT_2, logic->CanBreakPots()), @@ -608,7 +608,7 @@ void RegionTable_Init_DodongosCavern() { && logic->CanKillEnemy(RE_KING_DODONGO);}), }, { // Locations - LOCATION(RC_DODONGOS_CAVERN_BOSS_ROOM_CHEST, true), + LOCATION(RC_DODONGOS_CAVERN_BOSS_ROOM_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_DODONGOS_CAVERN_KING_DODONGO_HEART, logic->Get(LOGIC_DODONGOS_CAVERN_CLEAR)), LOCATION(RC_KING_DODONGO, logic->Get(LOGIC_DODONGOS_CAVERN_CLEAR)), }, { diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp index d7ae81645f1..8bc76124fd9 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp @@ -30,7 +30,7 @@ void RegionTable_Init_FireTemple() { EventAccess(LOGIC_FAIRY_POT, []{return logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT);}), }, { //Locations - LOCATION(RC_FIRE_TEMPLE_NEAR_BOSS_CHEST, true), + LOCATION(RC_FIRE_TEMPLE_NEAR_BOSS_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_FIRE_TEMPLE_NEAR_BOSS_POT_1, (logic->CanBreakPots() && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT)))), LOCATION(RC_FIRE_TEMPLE_NEAR_BOSS_POT_2, (logic->CanBreakPots() && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT)))), LOCATION(RC_FIRE_TEMPLE_NEAR_BOSS_POT_3, (logic->CanBreakPots() && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT)))), @@ -58,7 +58,7 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_LOOP_FLARE_DANCER] = Region("Fire Temple Loop Flare Dancer", SCENE_FIRE_TEMPLE, {}, { //Locations - LOCATION(RC_FIRE_TEMPLE_FLARE_DANCER_CHEST, (logic->HasExplosives() || logic->CanUse(RG_MEGATON_HAMMER)) && (logic->IsAdult || logic->CanGroundJump())), + LOCATION(RC_FIRE_TEMPLE_FLARE_DANCER_CHEST, (logic->HasExplosives() || logic->CanUse(RG_MEGATON_HAMMER)) && (logic->IsAdult || logic->CanGroundJump()) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_FIRE_TEMPLE_LOOP_TILES, []{return true;}), @@ -76,7 +76,7 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_LOOP_GORON_ROOM] = Region("Fire Temple Loop Goron Room", SCENE_FIRE_TEMPLE, {}, { //Locations - LOCATION(RC_FIRE_TEMPLE_BOSS_KEY_CHEST, true), + LOCATION(RC_FIRE_TEMPLE_BOSS_KEY_CHEST, logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_FIRE_TEMPLE_LOOP_HAMMER_SWITCH, []{return logic->Get(LOGIC_FIRE_LOOP_SWITCH);}), @@ -105,7 +105,7 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_BIG_LAVA_ROOM_NORTH_GORON] = Region("Fire Temple Big Lava Room North Goron", SCENE_FIRE_TEMPLE, {}, { //Locations - LOCATION(RC_FIRE_TEMPLE_BIG_LAVA_ROOM_LOWER_OPEN_DOOR_CHEST, true), + LOCATION(RC_FIRE_TEMPLE_BIG_LAVA_ROOM_LOWER_OPEN_DOOR_CHEST, logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_FIRE_TEMPLE_BIG_LAVA_ROOM, []{return true;}), @@ -122,7 +122,7 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_BIG_LAVA_ROOM_SOUTH_GORON] = Region("Fire Temple Big Lava Room South Goron", SCENE_FIRE_TEMPLE, {}, { //Locations - LOCATION(RC_FIRE_TEMPLE_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST, true), + LOCATION(RC_FIRE_TEMPLE_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST, logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_FIRE_TEMPLE_BIG_LAVA_ROOM, []{return true;}), @@ -149,7 +149,7 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_SHORTCUT_CLIMB] = Region("Fire Temple Shortcut Climb", SCENE_FIRE_TEMPLE, {}, { //Locations - LOCATION(RC_FIRE_TEMPLE_BOULDER_MAZE_SHORTCUT_CHEST, true), + LOCATION(RC_FIRE_TEMPLE_BOULDER_MAZE_SHORTCUT_CHEST, logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_FIRE_TEMPLE_SHORTCUT_ROOM, []{return true;}), @@ -158,7 +158,7 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_BOULDER_MAZE_LOWER] = Region("Fire Temple Boulder Maze Lower", SCENE_FIRE_TEMPLE, {}, { //Locations - LOCATION(RC_FIRE_TEMPLE_BOULDER_MAZE_LOWER_CHEST, true), + LOCATION(RC_FIRE_TEMPLE_BOULDER_MAZE_LOWER_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_FIRE_TEMPLE_GS_BOULDER_MAZE, logic->HasExplosives() && (logic->IsAdult || logic->HookshotOrBoomerang())), }, { //Exits @@ -170,7 +170,7 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_BOULDER_MAZE_LOWER_SIDE_ROOM] = Region("Fire Temple Boulder Maze Lower Side Room", SCENE_FIRE_TEMPLE, {}, { //Locations - LOCATION(RC_FIRE_TEMPLE_BOULDER_MAZE_SIDE_ROOM_CHEST, true), + LOCATION(RC_FIRE_TEMPLE_BOULDER_MAZE_SIDE_ROOM_CHEST, logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_LOWER, []{return true;}), @@ -204,7 +204,7 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_MAP_AREA] = Region("Fire Temple Map Region", SCENE_FIRE_TEMPLE, {}, { //Locations - LOCATION(RC_FIRE_TEMPLE_MAP_CHEST, true), + LOCATION(RC_FIRE_TEMPLE_MAP_CHEST, logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_FIRE_TEMPLE_EAST_CENTRAL_ROOM, []{return true;}), @@ -212,7 +212,7 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_BOULDER_MAZE_UPPER] = Region("Fire Temple Boulder Maze Upper", SCENE_FIRE_TEMPLE, {}, { //Locations - LOCATION(RC_FIRE_TEMPLE_BOULDER_MAZE_UPPER_CHEST, true), + LOCATION(RC_FIRE_TEMPLE_BOULDER_MAZE_UPPER_CHEST, logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_FIRE_TEMPLE_SHORTCUT_CLIMB, []{return logic->HasExplosives();}), @@ -273,7 +273,7 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_FIRE_MAZE_SIDE_ROOM] = Region("Fire Temple Fire Maze Side Room", SCENE_FIRE_TEMPLE, {}, { //Locations - LOCATION(RC_FIRE_TEMPLE_COMPASS_CHEST, true), + LOCATION(RC_FIRE_TEMPLE_COMPASS_CHEST, logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_ROOM, []{return true;}), @@ -288,7 +288,7 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_WEST_CENTRAL_UPPER] = Region("Fire Temple West Central Upper", SCENE_FIRE_TEMPLE, {}, { //Locations - LOCATION(RC_FIRE_TEMPLE_HIGHEST_GORON_CHEST, (logic->CanUse(RG_SONG_OF_TIME) || ctx->GetTrickOption(RT_RUSTED_SWITCHES)) && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_FIRE_TEMPLE_HIGHEST_GORON_CHEST, (logic->CanUse(RG_SONG_OF_TIME) || ctx->GetTrickOption(RT_RUSTED_SWITCHES)) && logic->CanUse(RG_MEGATON_HAMMER) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_FIRE_TEMPLE_BOSS_ENTRYWAY, []{return false;}), @@ -323,7 +323,7 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_WEST_PEAK] = Region("Fire Temple West Peak", SCENE_FIRE_TEMPLE, {}, { //Locations - LOCATION(RC_FIRE_TEMPLE_MEGATON_HAMMER_CHEST, true), + LOCATION(RC_FIRE_TEMPLE_MEGATON_HAMMER_CHEST, logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_FIRE_TEMPLE_WEST_CENTRAL_UPPER, []{return logic->TakeDamage();}), @@ -373,7 +373,7 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_MQ_MAP_ROOM_SOUTH] = Region("Fire Temple MQ Map Room South", SCENE_FIRE_TEMPLE, {}, { //Locations - LOCATION(RC_FIRE_TEMPLE_MQ_MAP_ROOM_SIDE_CHEST, logic->CanKillEnemy(RE_LIKE_LIKE)), + LOCATION(RC_FIRE_TEMPLE_MQ_MAP_ROOM_SIDE_CHEST, logic->CanKillEnemy(RE_LIKE_LIKE) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_FIRE_TEMPLE_MQ_FIRST_ROOM_LOWER, []{return Here(RR_FIRE_TEMPLE_MQ_FIRST_ROOM_LOWER, []{return logic->CanKillEnemy(RE_LIKE_LIKE);});}), @@ -411,7 +411,7 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_MQ_LOWER_FLARE_DANCER] = Region("Fire Temple MQ Lower Flare Dancer", SCENE_FIRE_TEMPLE, {}, { //Locations - LOCATION(RC_FIRE_TEMPLE_MQ_MEGATON_HAMMER_CHEST, (logic->IsAdult || logic->CanUse(RG_HOOKSHOT)) && Here(RR_FIRE_TEMPLE_MQ_LOWER_FLARE_DANCER, []{return logic->CanKillEnemy(RE_FLARE_DANCER);})), + LOCATION(RC_FIRE_TEMPLE_MQ_MEGATON_HAMMER_CHEST, (logic->IsAdult || logic->CanUse(RG_HOOKSHOT)) && Here(RR_FIRE_TEMPLE_MQ_LOWER_FLARE_DANCER, []{return logic->CanKillEnemy(RE_FLARE_DANCER);}) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_FIRE_TEMPLE_MQ_IRON_KNUCKLE_ROOM, []{return true;}), @@ -429,7 +429,7 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_MQ_MAP_ROOM_CAGE] = Region("Fire Temple MQ Map Room Cage", SCENE_FIRE_TEMPLE, {}, { //Locations - LOCATION(RC_FIRE_TEMPLE_MQ_MAP_CHEST, true), + LOCATION(RC_FIRE_TEMPLE_MQ_MAP_CHEST, logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_FIRE_TEMPLE_MQ_MAP_ROOM_NORTH, []{return logic->Get(LOGIC_FIRE_OPENED_LOWEST_GORON_CAGE);}), @@ -439,7 +439,7 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_MQ_NEAR_BOSS_ROOM] = Region("Fire Temple MQ Near Boss Room", SCENE_FIRE_TEMPLE, {}, { //Locations //If we're using the south torch as the initial torch, or using FAs, we either have to cross to the north to remove the crate, or use a trick to ignore it - LOCATION(RC_FIRE_TEMPLE_MQ_NEAR_BOSS_CHEST, logic->FireTimer() > 25 && ctx->GetTrickOption(RT_FIRE_MQ_NEAR_BOSS) && (logic->CanUse(RG_FIRE_ARROWS) || (logic->IsAdult && logic->CanUse(RG_DINS_FIRE) && logic->CanUse(RG_FAIRY_BOW)))), + LOCATION(RC_FIRE_TEMPLE_MQ_NEAR_BOSS_CHEST, logic->FireTimer() > 25 && ctx->GetTrickOption(RT_FIRE_MQ_NEAR_BOSS) && (logic->CanUse(RG_FIRE_ARROWS) || (logic->IsAdult && logic->CanUse(RG_DINS_FIRE) && logic->CanUse(RG_FAIRY_BOW))) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_1, logic->FireTimer() > 25 && logic->CanBreakCrates()), LOCATION(RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_2, logic->FireTimer() > 25 && logic->CanBreakCrates()), @@ -462,7 +462,7 @@ void RegionTable_Init_FireTemple() { //Fairies cannot be used for this as it is time sensetive, and NL is only useful with sticks as it disables other magic while in use, so it's tunic or raw damage taking ability. //testing tells me you take 3 ticks of lava damage, which is 12 internal damage or 3/4 of a heart at x1 damage multiplier, performing this run //logic->EffectiveHealth() works in half hearts for whatever reason, meaning this needs a deeper refactor to be perfect, but it should be good enough for now - LOCATION(RC_FIRE_TEMPLE_MQ_NEAR_BOSS_CHEST, logic->CanUse(RG_FIRE_ARROWS) || (logic->CanUse(RG_DINS_FIRE) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_LONGSHOT) || (logic->IsAdult && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_GORON_TUNIC) || logic->EffectiveHealth() >= 2 || (logic->CanUse(RG_NAYRUS_LOVE) && logic->CanUse(RG_STICKS))))))), + LOCATION(RC_FIRE_TEMPLE_MQ_NEAR_BOSS_CHEST, (logic->CanUse(RG_FIRE_ARROWS) || (logic->CanUse(RG_DINS_FIRE) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_LONGSHOT) || (logic->IsAdult && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_GORON_TUNIC) || logic->EffectiveHealth() >= 2 || (logic->CanUse(RG_NAYRUS_LOVE) && logic->CanUse(RG_STICKS))))))) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_1, logic->CanBreakPots()), LOCATION(RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_2, logic->CanBreakPots()), LOCATION(RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_1, logic->FireTimer() > 25 && logic->CanBreakCrates()), @@ -479,7 +479,7 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM] = Region("Fire Temple MQ Big Lava Room", SCENE_FIRE_TEMPLE, {}, { //Locations //I'm currently assuming the oversight version of RT_FIRE_MQ_BK_CHEST for the fire timer logic - LOCATION(RC_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST, logic->FireTimer() >= 40 && logic->HasFireSource() && logic->HasExplosives() && (logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && ctx->GetTrickOption(RT_FIRE_MQ_BLOCKED_CHEST)))), + LOCATION(RC_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST, logic->FireTimer() >= 40 && logic->HasFireSource() && logic->HasExplosives() && (logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && ctx->GetTrickOption(RT_FIRE_MQ_BLOCKED_CHEST))) && logic->HasItem(RG_OPEN_CHEST)), //implies CanGetEnemyDrop(RE_GOLD_SKULLTULA) LOCATION(RC_FIRE_TEMPLE_MQ_GS_BIG_LAVA_ROOM_OPEN_DOOR, logic->FireTimer() >= 20 && logic->CanUse(RG_MEGATON_HAMMER)), LOCATION(RC_FIRE_TEMPLE_MQ_LAVA_ROOM_NORTH_POT, logic->CanBreakPots()), @@ -498,7 +498,7 @@ void RegionTable_Init_FireTemple() { EventAccess(LOGIC_FAIRY_POT, []{return logic->CanUse(RG_HOOKSHOT);}), }, { //Locations - LOCATION(RC_FIRE_TEMPLE_MQ_BOSS_KEY_CHEST, logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_FIRE_TEMPLE_MQ_BOSS_KEY_CHEST, logic->CanUse(RG_HOOKSHOT) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_1, logic->HookshotOrBoomerang()), LOCATION(RC_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_2, logic->HookshotOrBoomerang()), }, { @@ -528,7 +528,7 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_MQ_LOWER_MAZE] = Region("Fire Temple MQ Lower Maze", SCENE_FIRE_TEMPLE, {}, { //Locations //Check handled on both floors - LOCATION(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_SIDE_ROOM_CHEST, logic->HasExplosives() && ctx->GetTrickOption(RT_FIRE_MQ_MAZE_SIDE_ROOM)), + LOCATION(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_SIDE_ROOM_CHEST, logic->HasExplosives() && ctx->GetTrickOption(RT_FIRE_MQ_MAZE_SIDE_ROOM) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_FIRE_TEMPLE_MQ_BIG_TORCH_ROOM, []{return true;}), @@ -540,7 +540,7 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_MQ_LOWER_MAZE_CRATE_CAGE] = Region("Fire Temple MQ Lower Maze Crate Cage", SCENE_FIRE_TEMPLE, {}, { //Locations - LOCATION(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CHEST, true), + LOCATION(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CRATE_1, logic->CanBreakCrates()), LOCATION(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CRATE_2, logic->CanBreakCrates()), LOCATION(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CRATE_3, logic->CanBreakCrates()), @@ -565,14 +565,14 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_MQ_UPPER_MAZE_BOX_CAGE] = Region("Fire Temple MQ Upper Maze Box Cage", SCENE_FIRE_TEMPLE, {}, { //Locations - LOCATION(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CHEST, true), + LOCATION(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CRATE_1, logic->CanBreakCrates()), LOCATION(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CRATE_2, logic->CanBreakCrates()), LOCATION(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CRATE_3, logic->CanBreakCrates()), LOCATION(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_SMALL_CRATE_1, logic->CanBreakSmallCrates()), LOCATION(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_SMALL_CRATE_2, logic->CanBreakSmallCrates()), //Assumes maze access - LOCATION(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_SIDE_ROOM_CHEST, logic->HasExplosives()), + LOCATION(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_SIDE_ROOM_CHEST, logic->HasExplosives() && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_FIRE_TEMPLE_MQ_UPPER_MAZE, []{return true;}), @@ -589,7 +589,7 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_MQ_MAZE_SHORTCUT_CAGE] = Region("Fire Temple MQ Maze Shortcut Cage", SCENE_FIRE_TEMPLE, {}, { //Locations - LOCATION(RC_FIRE_TEMPLE_MQ_COMPASS_CHEST, logic->Get(LOGIC_FIRE_OPENED_UPPER_SHORTCUT);), + LOCATION(RC_FIRE_TEMPLE_MQ_COMPASS_CHEST, logic->Get(LOGIC_FIRE_OPENED_UPPER_SHORTCUT) && logic->HasItem(RG_OPEN_CHEST);), LOCATION(RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_1, logic->Get(LOGIC_FIRE_OPENED_UPPER_SHORTCUT) && logic->CanBreakCrates()), LOCATION(RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_2, logic->Get(LOGIC_FIRE_OPENED_UPPER_SHORTCUT) && logic->CanBreakCrates()), LOCATION(RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_3, logic->Get(LOGIC_FIRE_OPENED_UPPER_SHORTCUT) && logic->CanBreakCrates()), @@ -716,7 +716,7 @@ void RegionTable_Init_FireTemple() { //Locations //This requires nothing in N64 logic, but is tight enough to need rollspam with the one-point on which is stricter than I would normally consider in logic //Child basically needs the scarecrow or a bunny hood though due to a worse ledge grab. - LOCATION(RC_FIRE_TEMPLE_MQ_CHEST_ON_FIRE, logic->IsAdult || logic->CanUse(RG_SCARECROW)), + LOCATION(RC_FIRE_TEMPLE_MQ_CHEST_ON_FIRE, (logic->IsAdult || logic->CanUse(RG_SCARECROW)) && logic->HasItem(RG_OPEN_CHEST)), }, { //The dropdown here is unusual in that it hits 1 of 3 locations: RR_FIRE_TEMPLE_MQ_SOUTH_FIRE_MAZE, RR_FIRE_TEMPLE_MQ_FIRE_MAZE_PLATFORMS and the section of RR_FIRE_TEMPLE_MQ_FIRE_MAZE_PLATFORMS with the hammer switch //Using this dropdown is in N64 logic elsewhere, but not here, probably because it requires good foreknowlege to determine where to land diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp index a4a0563cfba..3f2f20893aa 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp @@ -18,7 +18,7 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_FIRST_ROOM] = Region("Forest Temple First Room", SCENE_FOREST_TEMPLE, {}, { //Locations - LOCATION(RC_FOREST_TEMPLE_FIRST_ROOM_CHEST, true), + LOCATION(RC_FOREST_TEMPLE_FIRST_ROOM_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_FOREST_TEMPLE_GS_FIRST_ROOM, (logic->IsAdult && logic->CanUse(RG_BOMB_BAG)) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOMBCHU_5) || logic->CanUse(RG_DINS_FIRE) || (ctx->GetTrickOption(RT_FOREST_FIRST_GS) && (logic->CanJumpslashExceptHammer() || (logic->IsChild && logic->CanUse(RG_BOMB_BAG))))), }, { //Exits @@ -67,7 +67,7 @@ void RegionTable_Init_ForestTemple() { EventAccess(LOGIC_FAIRY_POT, []{return true;}), }, { //Locations - LOCATION(RC_FOREST_TEMPLE_FIRST_STALFOS_CHEST, logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2)), + LOCATION(RC_FOREST_TEMPLE_FIRST_STALFOS_CHEST, logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_FOREST_TEMPLE_LOWER_STALFOS_POT_1, logic->CanBreakPots()), LOCATION(RC_FOREST_TEMPLE_LOWER_STALFOS_POT_2, logic->CanBreakPots()), }, { @@ -116,7 +116,7 @@ void RegionTable_Init_ForestTemple() { EventAccess(LOGIC_DEKU_BABA_NUTS, []{return logic->CanGetDekuBabaNuts();}), }, { //Locations - LOCATION(RC_FOREST_TEMPLE_RAISED_ISLAND_COURTYARD_CHEST, logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_FOREST_TEMPLE_RAISED_ISLAND_COURTYARD_CHEST, logic->CanUse(RG_HOOKSHOT) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_FOREST_TEMPLE_GS_RAISED_ISLAND_COURTYARD, logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_FOREST_OUTDOORS_EAST_GS) && logic->CanUse(RG_BOOMERANG))), }, { //Exits @@ -132,7 +132,7 @@ void RegionTable_Init_ForestTemple() { EventAccess(LOGIC_DEKU_BABA_NUTS, []{return logic->CanGetDekuBabaNuts();}), }, { //Locations - LOCATION(RC_FOREST_TEMPLE_RAISED_ISLAND_COURTYARD_CHEST, logic->IsAdult && ctx->GetTrickOption(RT_FOREST_OUTDOORS_LEDGE) && logic->CanUse(RG_HOVER_BOOTS)), + LOCATION(RC_FOREST_TEMPLE_RAISED_ISLAND_COURTYARD_CHEST, logic->IsAdult && ctx->GetTrickOption(RT_FOREST_OUTDOORS_LEDGE) && logic->CanUse(RG_HOVER_BOOTS) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_FOREST_TEMPLE_NE_OUTDOORS_LOWER, []{return true;}), @@ -143,7 +143,7 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_MAP_ROOM] = Region("Forest Temple Map Room", SCENE_FOREST_TEMPLE, {}, { //Locations - LOCATION(RC_FOREST_TEMPLE_MAP_CHEST, logic->CanKillEnemy(RE_BLUE_BUBBLE)), + LOCATION(RC_FOREST_TEMPLE_MAP_CHEST, logic->CanKillEnemy(RE_BLUE_BUBBLE) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_FOREST_TEMPLE_NW_OUTDOORS_LOWER, []{return Here(RR_FOREST_TEMPLE_MAP_ROOM, []{return logic->CanKillEnemy(RE_BLUE_BUBBLE);});}), @@ -152,7 +152,7 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_SEWER] = Region("Forest Temple Sewer", SCENE_FOREST_TEMPLE, {}, { //Locations - LOCATION(RC_FOREST_TEMPLE_WELL_CHEST, logic->CanOpenUnderwaterChest() && logic->WaterTimer() >= 8), + LOCATION(RC_FOREST_TEMPLE_WELL_CHEST, logic->CanOpenUnderwaterChest() && logic->WaterTimer() >= 8 && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_FOREST_TEMPLE_WELL_WEST_HEART, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8), LOCATION(RC_FOREST_TEMPLE_WELL_EAST_HEART, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8), }, { @@ -163,7 +163,7 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_DRAINED_SEWER] = Region("Forest Temple Drained Well", SCENE_FOREST_TEMPLE, {}, { //Locations - LOCATION(RC_FOREST_TEMPLE_WELL_CHEST, true), + LOCATION(RC_FOREST_TEMPLE_WELL_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_FOREST_TEMPLE_WELL_WEST_HEART, true), LOCATION(RC_FOREST_TEMPLE_WELL_EAST_HEART, true), }, { @@ -179,7 +179,7 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_FLOORMASTER_ROOM] = Region("Forest Temple Floormaster Room", SCENE_FOREST_TEMPLE, {}, { //Locations - LOCATION(RC_FOREST_TEMPLE_FLOORMASTER_CHEST, logic->CanDamage()), + LOCATION(RC_FOREST_TEMPLE_FLOORMASTER_CHEST, logic->CanDamage() && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_FOREST_TEMPLE_NW_OUTDOORS_UPPER, []{return true;}), @@ -193,7 +193,7 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_BLOCK_PUSH_ROOM] = Region("Forest Temple Block Push Room", SCENE_FOREST_TEMPLE, {}, { //Locations - LOCATION(RC_FOREST_TEMPLE_EYE_SWITCH_CHEST, logic->HasItem(RG_GORONS_BRACELET) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT))), + LOCATION(RC_FOREST_TEMPLE_EYE_SWITCH_CHEST, logic->HasItem(RG_GORONS_BRACELET) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT)) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_FOREST_TEMPLE_WEST_CORRIDOR, []{return true;}), @@ -210,7 +210,7 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_NW_CORRIDOR_STRAIGHTENED] = Region("Forest Temple NW Corridor Straightened", SCENE_FOREST_TEMPLE, {}, { //Locations - LOCATION(RC_FOREST_TEMPLE_BOSS_KEY_CHEST, true), + LOCATION(RC_FOREST_TEMPLE_BOSS_KEY_CHEST, logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_FOREST_TEMPLE_BELOW_BOSS_KEY_CHEST, []{return true;}), @@ -222,7 +222,7 @@ void RegionTable_Init_ForestTemple() { EventAccess(LOGIC_FOREST_JOELLE, []{return logic->CanUse(RG_FAIRY_BOW);}), }, { //Locations - LOCATION(RC_FOREST_TEMPLE_RED_POE_CHEST, logic->Get(LOGIC_FOREST_JOELLE)), + LOCATION(RC_FOREST_TEMPLE_RED_POE_CHEST, logic->Get(LOGIC_FOREST_JOELLE) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_FOREST_TEMPLE_NW_CORRIDOR_TWISTED, []{return logic->SmallKeys(SCENE_FOREST_TEMPLE, 3);}), @@ -231,7 +231,7 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_UPPER_STALFOS] = Region("Forest Temple Upper Stalfos", SCENE_FOREST_TEMPLE, {}, { //Locations - LOCATION(RC_FOREST_TEMPLE_BOW_CHEST, logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 3)), + LOCATION(RC_FOREST_TEMPLE_BOW_CHEST, logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 3) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_FOREST_TEMPLE_UPPER_STALFOS_POT_1, logic->CanBreakPots()), LOCATION(RC_FOREST_TEMPLE_UPPER_STALFOS_POT_2, logic->CanBreakPots()), LOCATION(RC_FOREST_TEMPLE_UPPER_STALFOS_POT_3, logic->CanBreakPots()), @@ -247,7 +247,7 @@ void RegionTable_Init_ForestTemple() { EventAccess(LOGIC_FOREST_BETH, []{return logic->CanUse(RG_FAIRY_BOW);}), }, { //Locations - LOCATION(RC_FOREST_TEMPLE_BLUE_POE_CHEST, logic->Get(LOGIC_FOREST_BETH)), + LOCATION(RC_FOREST_TEMPLE_BLUE_POE_CHEST, logic->Get(LOGIC_FOREST_BETH) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_FOREST_TEMPLE_BLUE_POE_POT_1, logic->CanBreakPots()), LOCATION(RC_FOREST_TEMPLE_BLUE_POE_POT_2, logic->CanBreakPots()), LOCATION(RC_FOREST_TEMPLE_BLUE_POE_POT_3, logic->CanBreakPots()), @@ -282,8 +282,8 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_FALLING_ROOM] = Region("Forest Temple Falling Room", SCENE_FOREST_TEMPLE, {}, { //Locations LOCATION(RC_FOREST_TEMPLE_GS_RAISED_ISLAND_COURTYARD, logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_DINS_FIRE) || logic->HasExplosives()), - LOCATION(RC_FOREST_TEMPLE_FALLING_CEILING_ROOM_CHEST, true), - LOCATION(RC_FOREST_TEMPLE_RAISED_ISLAND_COURTYARD_CHEST, true), + LOCATION(RC_FOREST_TEMPLE_FALLING_CEILING_ROOM_CHEST, logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_FOREST_TEMPLE_RAISED_ISLAND_COURTYARD_CHEST, logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_FOREST_TEMPLE_NE_OUTDOORS_LOWER, []{return true;}), @@ -311,7 +311,7 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_BOSS_REGION] = Region("Forest Temple Boss Region", SCENE_FOREST_TEMPLE, {}, { //Locations - LOCATION(RC_FOREST_TEMPLE_BASEMENT_CHEST, true), + LOCATION(RC_FOREST_TEMPLE_BASEMENT_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_FOREST_TEMPLE_GS_BASEMENT, logic->HookshotOrBoomerang()), }, { //Exits @@ -325,7 +325,7 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_MQ_LOBBY] = Region("Forest Temple MQ Lobby", SCENE_FOREST_TEMPLE, {}, { //Locations - LOCATION(RC_FOREST_TEMPLE_MQ_FIRST_ROOM_CHEST, logic->CanPassEnemy(RE_BIG_SKULLTULA, ED_SHORT_JUMPSLASH, false) || logic->CanUse(RG_HOVER_BOOTS)), + LOCATION(RC_FOREST_TEMPLE_MQ_FIRST_ROOM_CHEST, (logic->CanPassEnemy(RE_BIG_SKULLTULA, ED_SHORT_JUMPSLASH, false) || logic->CanUse(RG_HOVER_BOOTS)) && logic->HasItem(RG_OPEN_CHEST)), //Implies CanPassEnemy(RE_BIG_SKULLTULA) LOCATION(RC_FOREST_TEMPLE_MQ_GS_FIRST_HALLWAY, logic->HookshotOrBoomerang()), }, { @@ -361,7 +361,7 @@ void RegionTable_Init_ForestTemple() { EventAccess(LOGIC_FOREST_CLEAR_BETWEEN_JOELLE_AND_BETH, []{return logic->CanKillEnemy(RE_WOLFOS);}), }, { //Locations - LOCATION(RC_FOREST_TEMPLE_MQ_WOLFOS_CHEST, logic->Get(LOGIC_FOREST_CLEAR_BETWEEN_JOELLE_AND_BETH)), + LOCATION(RC_FOREST_TEMPLE_MQ_WOLFOS_CHEST, logic->Get(LOGIC_FOREST_CLEAR_BETWEEN_JOELLE_AND_BETH) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_FOREST_TEMPLE_MQ_WOLFOS_POT_1, logic->CanBreakPots()), LOCATION(RC_FOREST_TEMPLE_MQ_WOLFOS_POT_2, logic->CanBreakPots()), }, { @@ -400,7 +400,7 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_MQ_UPPER_BLOCK_PUZZLE] = Region("Forest Temple MQ After Block Puzzle", SCENE_FOREST_TEMPLE, {}, { //Locations - LOCATION(RC_FOREST_TEMPLE_MQ_BOSS_KEY_CHEST, logic->SmallKeys(SCENE_FOREST_TEMPLE, 3)), + LOCATION(RC_FOREST_TEMPLE_MQ_BOSS_KEY_CHEST, logic->SmallKeys(SCENE_FOREST_TEMPLE, 3) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_FOREST_TEMPLE_MQ_STRAIGHT_HALLWAY, []{return logic->SmallKeys(SCENE_FOREST_TEMPLE, 3);}), @@ -414,7 +414,7 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_MQ_STRAIGHT_HALLWAY] = Region("Forest Temple MQ Straight Hallway", SCENE_FOREST_TEMPLE, {}, { //Locations - LOCATION(RC_FOREST_TEMPLE_MQ_BOSS_KEY_CHEST, logic->SmallKeys(SCENE_FOREST_TEMPLE, 3)), + LOCATION(RC_FOREST_TEMPLE_MQ_BOSS_KEY_CHEST, logic->SmallKeys(SCENE_FOREST_TEMPLE, 3) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_FOREST_TEMPLE_MQ_FLOORMASTER_ROOM, []{return true;}), @@ -429,7 +429,7 @@ void RegionTable_Init_ForestTemple() { EventAccess(LOGIC_FOREST_CAN_TWIST_HALLWAY, []{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) && logic->HasItem(RG_OPEN_CHEST)), 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), @@ -462,7 +462,7 @@ void RegionTable_Init_ForestTemple() { EventAccess(LOGIC_DEKU_BABA_NUTS, []{return logic->CanGetDekuBabaNuts();}), }, { //Locations - LOCATION(RC_FOREST_TEMPLE_MQ_WELL_CHEST, logic->CanHitEyeTargets() || (logic->CanOpenUnderwaterChest() && logic->WaterTimer() >= 8)), + LOCATION(RC_FOREST_TEMPLE_MQ_WELL_CHEST, (logic->CanHitEyeTargets() || (logic->CanOpenUnderwaterChest() && logic->WaterTimer() >= 8)) && logic->HasItem(RG_OPEN_CHEST)), 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))), @@ -478,7 +478,7 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_MQ_OUTDOORS_TOP_LEDGES] = Region("Forest Temple MQ Outdoors Top Ledges", SCENE_FOREST_TEMPLE, {}, { //Locations - LOCATION(RC_FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_UPPER_CHEST, true), + LOCATION(RC_FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_UPPER_CHEST, logic->HasItem(RG_OPEN_CHEST)), //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)))))), }, { @@ -491,7 +491,7 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_MQ_NE_OUTDOORS_LEDGE] = Region("Forest Temple MQ NE Outdoors Ledge", SCENE_FOREST_TEMPLE, {}, { //Locations - LOCATION(RC_FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_LOWER_CHEST, true), + LOCATION(RC_FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_LOWER_CHEST, logic->HasItem(RG_OPEN_CHEST)), }, { //Exits //Skipping swim here is non-trival, needs a roll-jump. If a swim lock is added it's probably wise to copy deku baba events here @@ -504,7 +504,7 @@ void RegionTable_Init_ForestTemple() { EventAccess(LOGIC_FOREST_JOELLE, []{return logic->CanUse(RG_FAIRY_BOW);}), }, { //Locations - LOCATION(RC_FOREST_TEMPLE_MQ_MAP_CHEST, logic->Get(LOGIC_FOREST_JOELLE)), + LOCATION(RC_FOREST_TEMPLE_MQ_MAP_CHEST, logic->Get(LOGIC_FOREST_JOELLE) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_FOREST_TEMPLE_MQ_UPPER_BLOCK_PUZZLE, []{return logic->SmallKeys(SCENE_FOREST_TEMPLE, 4);}), @@ -517,7 +517,7 @@ void RegionTable_Init_ForestTemple() { EventAccess(LOGIC_FOREST_CLEAR_BETWEEN_JOELLE_AND_BETH, []{return logic->CanKillEnemy(RE_WOLFOS);}), }, { //Locations - LOCATION(RC_FOREST_TEMPLE_MQ_BOW_CHEST, logic->Get(LOGIC_FOREST_CLEAR_BETWEEN_JOELLE_AND_BETH) && logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 3)), + LOCATION(RC_FOREST_TEMPLE_MQ_BOW_CHEST, logic->Get(LOGIC_FOREST_CLEAR_BETWEEN_JOELLE_AND_BETH) && logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 3) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_1, logic->CanBreakPots()), LOCATION(RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_2, logic->CanBreakPots()), LOCATION(RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_3, logic->CanBreakPots()), @@ -533,7 +533,7 @@ void RegionTable_Init_ForestTemple() { EventAccess(LOGIC_FOREST_BETH, []{return logic->CanUse(RG_FAIRY_BOW);}), }, { //Locations - LOCATION(RC_FOREST_TEMPLE_MQ_COMPASS_CHEST, logic->Get(LOGIC_FOREST_BETH)), + LOCATION(RC_FOREST_TEMPLE_MQ_COMPASS_CHEST, logic->Get(LOGIC_FOREST_BETH) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_FOREST_TEMPLE_MQ_BLUE_POE_POT_1, logic->CanBreakPots()), LOCATION(RC_FOREST_TEMPLE_MQ_BLUE_POE_POT_2, logic->CanBreakPots()), LOCATION(RC_FOREST_TEMPLE_MQ_BLUE_POE_POT_3, logic->CanBreakPots()), @@ -561,7 +561,7 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_MQ_FALLING_ROOM] = Region("Forest Temple MQ Falling Room", SCENE_FOREST_TEMPLE, {}, { //Locations - LOCATION(RC_FOREST_TEMPLE_MQ_FALLING_CEILING_ROOM_CHEST, true), + LOCATION(RC_FOREST_TEMPLE_MQ_FALLING_CEILING_ROOM_CHEST, logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_FOREST_TEMPLE_MQ_NE_OUTDOORS_LEDGE, []{return true;}), @@ -587,7 +587,7 @@ void RegionTable_Init_ForestTemple() { EventAccess(LOGIC_FOREST_OPEN_BOSS_CORRIDOR, []{return logic->CanHitEyeTargets();}), }, { //Locations - LOCATION(RC_FOREST_TEMPLE_MQ_BASEMENT_CHEST, true), + LOCATION(RC_FOREST_TEMPLE_MQ_BASEMENT_CHEST, logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_FOREST_TEMPLE_MQ_CENTRAL_AREA, []{return logic->Get(LOGIC_FOREST_MEG);}), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp index 3f52a231cf6..d27d981e732 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp @@ -57,7 +57,7 @@ void RegionTable_Init_GanonsCastle() { EventAccess(LOGIC_FOREST_TRIAL_CLEAR, []{return logic->CanUse(RG_LIGHT_ARROWS) && (logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_DINS_FIRE));}), }, { //Locations - LOCATION(RC_GANONS_CASTLE_FOREST_TRIAL_CHEST, logic->CanKillEnemy(RE_WOLFOS)), + LOCATION(RC_GANONS_CASTLE_FOREST_TRIAL_CHEST, logic->CanKillEnemy(RE_WOLFOS) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_GANONS_CASTLE_FOREST_TRIAL_POT_1, logic->CanBreakPots() && (logic->CanUse(RG_FIRE_ARROWS) || (logic->CanUse(RG_DINS_FIRE) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT))))), LOCATION(RC_GANONS_CASTLE_FOREST_TRIAL_POT_2, logic->CanBreakPots() && (logic->CanUse(RG_FIRE_ARROWS) || (logic->CanUse(RG_DINS_FIRE) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT))))), }, {}); @@ -79,8 +79,8 @@ void RegionTable_Init_GanonsCastle() { EventAccess(LOGIC_WATER_TRIAL_CLEAR, []{return logic->BlueFire() && logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_LIGHT_ARROWS);}), }, { //Locations - LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_LEFT_CHEST, true), - LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_RIGHT_CHEST, true), + LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_LEFT_CHEST, logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_RIGHT_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_POT_1, logic->CanBreakPots() && logic->BlueFire() && logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_POT_2, logic->CanBreakPots() && logic->BlueFire() && logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_POT_3, logic->CanBreakPots() && logic->BlueFire() && logic->CanKillEnemy(RE_FREEZARD)), @@ -91,8 +91,8 @@ void RegionTable_Init_GanonsCastle() { EventAccess(LOGIC_SHADOW_TRIAL_CLEAR, []{return logic->CanUse(RG_LIGHT_ARROWS) && 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))))));}), }, { //Locations - LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_FRONT_CHEST, logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_SONG_OF_TIME) || logic->IsChild), - LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_GOLDEN_GAUNTLETS_CHEST, logic->CanUse(RG_FIRE_ARROWS) || (logic->CanUse(RG_LONGSHOT) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_DINS_FIRE)))), + LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_FRONT_CHEST, (logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_SONG_OF_TIME) || logic->IsChild) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_GOLDEN_GAUNTLETS_CHEST, (logic->CanUse(RG_FIRE_ARROWS) || (logic->CanUse(RG_LONGSHOT) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_DINS_FIRE)))) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_POT_1, logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_LONGSHOT)), 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))))))), @@ -108,8 +108,8 @@ void RegionTable_Init_GanonsCastle() { EventAccess(LOGIC_SPIRIT_TRIAL_CLEAR, []{return logic->CanUse(RG_LIGHT_ARROWS) && (logic->CanUse(RG_MIRROR_SHIELD) || ctx->GetOption(RSK_SUNLIGHT_ARROWS)) && (logic->CanUse(RG_BOMBCHU_5) || (ctx->GetTrickOption(RT_HOOKSHOT_EXTENSION) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT)))) && ((ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) && logic->CanJumpslashExceptHammer()) || logic->CanUse(RG_HOOKSHOT));}), }, { //Locations - LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_CRYSTAL_SWITCH_CHEST, (ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) || logic->CanUse(RG_HOOKSHOT)) && (logic->CanJumpslashExceptHammer() || (logic->CanUse(RG_BOMBCHU_5) || (ctx->GetTrickOption(RT_HOOKSHOT_EXTENSION) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT)))))), - 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_HOOKSHOT_EXTENSION) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT)))) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_CRYSTAL_SWITCH_CHEST, (ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) || logic->CanUse(RG_HOOKSHOT)) && (logic->CanJumpslashExceptHammer() || (logic->CanUse(RG_BOMBCHU_5) || (ctx->GetTrickOption(RT_HOOKSHOT_EXTENSION) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT))))) && logic->HasItem(RG_OPEN_CHEST)), + 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_HOOKSHOT_EXTENSION) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT)))) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasItem(RG_OPEN_CHEST)), 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) || (ctx->GetTrickOption(RT_HOOKSHOT_EXTENSION) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT)))) && 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) || (ctx->GetTrickOption(RT_HOOKSHOT_EXTENSION) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT)))) && 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_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)), @@ -121,14 +121,14 @@ void RegionTable_Init_GanonsCastle() { EventAccess(LOGIC_LIGHT_TRIAL_CLEAR, []{return logic->CanUse(RG_LIGHT_ARROWS) && (logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanGroundJump())) && logic->SmallKeys(SCENE_INSIDE_GANONS_CASTLE, 2) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH));}), }, { //Locations - LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_FIRST_LEFT_CHEST, true), - LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_SECOND_LEFT_CHEST, true), - LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_THIRD_LEFT_CHEST, true), - LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_FIRST_RIGHT_CHEST, true), - LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_SECOND_RIGHT_CHEST, true), - LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_THIRD_RIGHT_CHEST, true), - LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_INVISIBLE_ENEMIES_CHEST, ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH)), - LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_LULLABY_CHEST, logic->CanUse(RG_ZELDAS_LULLABY) && logic->SmallKeys(SCENE_INSIDE_GANONS_CASTLE, 1)), + LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_FIRST_LEFT_CHEST, logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_SECOND_LEFT_CHEST, logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_THIRD_LEFT_CHEST, logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_FIRST_RIGHT_CHEST, logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_SECOND_RIGHT_CHEST, logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_THIRD_RIGHT_CHEST, logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_INVISIBLE_ENEMIES_CHEST, (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_LULLABY_CHEST, logic->CanUse(RG_ZELDAS_LULLABY) && logic->SmallKeys(SCENE_INSIDE_GANONS_CASTLE, 1) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_BOULDER_POT_1, logic->CanBreakPots() && logic->SmallKeys(SCENE_INSIDE_GANONS_CASTLE, 2)), LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_POT_1, logic->CanBreakPots() && (logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanGroundJump())) && logic->SmallKeys(SCENE_INSIDE_GANONS_CASTLE, 2) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH))), LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_POT_2, logic->CanBreakPots() && (logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanGroundJump())) && logic->SmallKeys(SCENE_INSIDE_GANONS_CASTLE, 2) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH))), @@ -196,8 +196,8 @@ void RegionTable_Init_GanonsCastle() { //If it is ever possible to warp into the RR_GANONS_CASTLE_MQ_FOREST_TRIAL_FINAL_ROOM, this needs splitting up as the requirements to reach things from the other side are more complex areaTable[RR_GANONS_CASTLE_MQ_FOREST_TRIAL_BEAMOS_ROOM] = Region("Ganon's Castle MQ Forest Trial Beamos Room", SCENE_INSIDE_GANONS_CASTLE, {}, { //Locations - LOCATION(RC_GANONS_CASTLE_MQ_FOREST_TRIAL_EYE_SWITCH_CHEST, logic->CanHitEyeTargets()), - LOCATION(RC_GANONS_CASTLE_MQ_FOREST_TRIAL_FROZEN_EYE_SWITCH_CHEST, logic->HasFireSource()), + LOCATION(RC_GANONS_CASTLE_MQ_FOREST_TRIAL_EYE_SWITCH_CHEST, logic->CanHitEyeTargets() && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GANONS_CASTLE_MQ_FOREST_TRIAL_FROZEN_EYE_SWITCH_CHEST, logic->HasFireSource() && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_GANONS_CASTLE_MQ_FOREST_TRIAL_STALFOS_ROOM, []{return true;}), @@ -238,7 +238,7 @@ void RegionTable_Init_GanonsCastle() { EventAccess(LOGIC_BLUE_FIRE_ACCESS, []{return logic->CanJumpslash() || logic->HasExplosives();}), }, { //Locations - LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_CHEST, logic->BlueFire()), + LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_CHEST, logic->BlueFire() && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_HEART, logic->BlueFire()), }, { //Exits @@ -279,7 +279,7 @@ void RegionTable_Init_GanonsCastle() { EventAccess(LOGIC_SHADOW_TRIAL_FIRST_CHEST, []{return logic->CanUse(RG_FAIRY_BOW);}), }, { //Locations - LOCATION(RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_BOMB_FLOWER_CHEST, logic->Get(LOGIC_SHADOW_TRIAL_FIRST_CHEST)), + LOCATION(RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_BOMB_FLOWER_CHEST, logic->Get(LOGIC_SHADOW_TRIAL_FIRST_CHEST) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits //Hookshot here is possible but very tight, but it's basically never relevant @@ -341,7 +341,7 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_MQ_SPIRIT_TRIAL_BEFORE_SWITCH] = Region("Ganon's Castle MQ Spirit Trial Before Switch", SCENE_INSIDE_GANONS_CASTLE, {}, { //Locations - LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_FIRST_CHEST, logic->CanPassEnemy(RE_GREEN_BUBBLE)), + LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_FIRST_CHEST, logic->CanPassEnemy(RE_GREEN_BUBBLE) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_GANONS_CASTLE_MQ_SPIRIT_TRIAL_CHAIRS_ROOM, []{return true;}), @@ -350,12 +350,12 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_MQ_SPIRIT_TRIAL_AFTER_SWITCH] = Region("Ganon's Castle MQ Spirit Trial After Switch", SCENE_INSIDE_GANONS_CASTLE, {}, { //Locations - LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_INVISIBLE_CHEST, ctx->GetTrickOption(RT_LENS_GANON_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)), + LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_INVISIBLE_CHEST, (ctx->GetTrickOption(RT_LENS_GANON_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasItem(RG_OPEN_CHEST)), //better names for these would be nice. - LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_FRONT_LEFT_CHEST, (logic->CanUse(RG_FIRE_ARROWS) && logic->CanUse(RG_MIRROR_SHIELD)) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS))), - LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_LEFT_CHEST, (logic->CanUse(RG_FIRE_ARROWS) && logic->CanUse(RG_MIRROR_SHIELD)) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS))), - LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_GOLDEN_GAUNTLETS_CHEST, (logic->CanUse(RG_FIRE_ARROWS) && logic->CanUse(RG_MIRROR_SHIELD)) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS))), - LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_RIGHT_CHEST, (logic->CanUse(RG_FIRE_ARROWS) && logic->CanUse(RG_MIRROR_SHIELD)) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS))), + LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_FRONT_LEFT_CHEST, ((logic->CanUse(RG_FIRE_ARROWS) && logic->CanUse(RG_MIRROR_SHIELD)) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS))) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_LEFT_CHEST, ((logic->CanUse(RG_FIRE_ARROWS) && logic->CanUse(RG_MIRROR_SHIELD)) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS))) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_GOLDEN_GAUNTLETS_CHEST, ((logic->CanUse(RG_FIRE_ARROWS) && logic->CanUse(RG_MIRROR_SHIELD)) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS))) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_RIGHT_CHEST, ((logic->CanUse(RG_FIRE_ARROWS) && logic->CanUse(RG_MIRROR_SHIELD)) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS))) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_GANONS_CASTLE_MQ_SPIRIT_TRIAL_BEFORE_SWITCH, []{return Here(RR_GANONS_CASTLE_MQ_SPIRIT_TRIAL_AFTER_SWITCH, []{return logic->CanUse(RG_BOMBCHU_5);});}), @@ -384,7 +384,7 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_MQ_LIGHT_TRIAL_TRIFORCE_ROOM] = Region("Ganon's Castle MQ Light Trial Triforce Room", SCENE_INSIDE_GANONS_CASTLE, {}, { //Locations - LOCATION(RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_LULLABY_CHEST, logic->CanUse(RG_ZELDAS_LULLABY)), + LOCATION(RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_LULLABY_CHEST, logic->CanUse(RG_ZELDAS_LULLABY) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_GANONS_CASTLE_MQ_LIGHT_TRIAL_DINOLFOS_ROOM, []{return true;}), @@ -442,7 +442,7 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_TOWER_FLOOR_2] = Region("Ganon's Tower Floor 2", SCENE_GANONS_TOWER, {}, { //Locations - LOCATION(RC_GANONS_TOWER_BOSS_KEY_CHEST, logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2)), + LOCATION(RC_GANONS_TOWER_BOSS_KEY_CHEST, logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_GANONS_TOWER_FLOOR_1, []{return Here(RR_GANONS_TOWER_FLOOR_2, []{return logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2);});}), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp index 6d75dffb663..bcc95111f93 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp @@ -18,10 +18,10 @@ void RegionTable_Init_GerudoTrainingGround() { areaTable[RR_GERUDO_TRAINING_GROUND_LOBBY] = Region("Gerudo Training Ground Lobby", SCENE_GERUDO_TRAINING_GROUND, {}, { //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_LOBBY_LEFT_CHEST, logic->CanHitEyeTargets()), - LOCATION(RC_GERUDO_TRAINING_GROUND_LOBBY_RIGHT_CHEST, logic->CanHitEyeTargets()), - LOCATION(RC_GERUDO_TRAINING_GROUND_STALFOS_CHEST, logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2, true)), - LOCATION(RC_GERUDO_TRAINING_GROUND_BEAMOS_CHEST, logic->CanKillEnemy(RE_BEAMOS) && logic->CanKillEnemy(RE_DINOLFOS, ED_CLOSE, true, 2, true)), + LOCATION(RC_GERUDO_TRAINING_GROUND_LOBBY_LEFT_CHEST, logic->CanHitEyeTargets() && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GERUDO_TRAINING_GROUND_LOBBY_RIGHT_CHEST, logic->CanHitEyeTargets() && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GERUDO_TRAINING_GROUND_STALFOS_CHEST, logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2, true) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GERUDO_TRAINING_GROUND_BEAMOS_CHEST, logic->CanKillEnemy(RE_BEAMOS) && logic->CanKillEnemy(RE_DINOLFOS, ED_CLOSE, true, 2, true) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_GERUDO_TRAINING_GROUND_ENTRANCE_STORMS_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_GERUDO_TRAINING_GROUND_BEAMOS_SOUTH_HEART, true), LOCATION(RC_GERUDO_TRAINING_GROUND_BEAMOS_EAST_HEART, true), @@ -35,11 +35,11 @@ void RegionTable_Init_GerudoTrainingGround() { areaTable[RR_GERUDO_TRAINING_GROUND_CENTRAL_MAZE] = Region("Gerudo Training Ground Central Maze", SCENE_GERUDO_TRAINING_GROUND, {}, { //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_HIDDEN_CEILING_CHEST, logic->SmallKeys(SCENE_GERUDO_TRAINING_GROUND, 3) && (ctx->GetTrickOption(RT_LENS_GTG) || logic->CanUse(RG_LENS_OF_TRUTH))), - LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_FIRST_CHEST, logic->SmallKeys(SCENE_GERUDO_TRAINING_GROUND, 4)), - LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_SECOND_CHEST, logic->SmallKeys(SCENE_GERUDO_TRAINING_GROUND, 6)), - LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_THIRD_CHEST, logic->SmallKeys(SCENE_GERUDO_TRAINING_GROUND, 7)), - LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_FINAL_CHEST, logic->SmallKeys(SCENE_GERUDO_TRAINING_GROUND, 9)), + LOCATION(RC_GERUDO_TRAINING_GROUND_HIDDEN_CEILING_CHEST, logic->SmallKeys(SCENE_GERUDO_TRAINING_GROUND, 3) && (ctx->GetTrickOption(RT_LENS_GTG) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_FIRST_CHEST, logic->SmallKeys(SCENE_GERUDO_TRAINING_GROUND, 4) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_SECOND_CHEST, logic->SmallKeys(SCENE_GERUDO_TRAINING_GROUND, 6) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_THIRD_CHEST, logic->SmallKeys(SCENE_GERUDO_TRAINING_GROUND, 7) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_FINAL_CHEST, logic->SmallKeys(SCENE_GERUDO_TRAINING_GROUND, 9) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_GERUDO_TRAINING_GROUND_CENTRAL_MAZE_RIGHT, []{return logic->SmallKeys(SCENE_GERUDO_TRAINING_GROUND, 9);}), @@ -47,8 +47,8 @@ void RegionTable_Init_GerudoTrainingGround() { areaTable[RR_GERUDO_TRAINING_GROUND_CENTRAL_MAZE_RIGHT] = Region("Gerudo Training Ground Central Maze Right", SCENE_GERUDO_TRAINING_GROUND, {}, { //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_RIGHT_CENTRAL_CHEST, true), - LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_RIGHT_SIDE_CHEST, true), + LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_RIGHT_CENTRAL_CHEST, logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_RIGHT_SIDE_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_GERUDO_TRAINING_GROUND_FREESTANDING_KEY, true), }, { //Exits @@ -58,7 +58,7 @@ void RegionTable_Init_GerudoTrainingGround() { areaTable[RR_GERUDO_TRAINING_GROUND_LAVA_ROOM] = Region("Gerudo Training Ground Lava Room", SCENE_GERUDO_TRAINING_GROUND, {}, { //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_UNDERWATER_SILVER_RUPEE_CHEST, logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 24), + LOCATION(RC_GERUDO_TRAINING_GROUND_UNDERWATER_SILVER_RUPEE_CHEST, logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 24 && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_GERUDO_TRAINING_GROUND_CENTRAL_MAZE_RIGHT, []{return logic->CanUse(RG_SONG_OF_TIME) || logic->IsChild;}), @@ -67,8 +67,8 @@ void RegionTable_Init_GerudoTrainingGround() { areaTable[RR_GERUDO_TRAINING_GROUND_HAMMER_ROOM] = Region("Gerudo Training Ground Hammer Room", SCENE_GERUDO_TRAINING_GROUND, {}, { //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_HAMMER_ROOM_CLEAR_CHEST, logic->CanAttack()), - LOCATION(RC_GERUDO_TRAINING_GROUND_HAMMER_ROOM_SWITCH_CHEST, logic->CanUse(RG_MEGATON_HAMMER) || (logic->TakeDamage() && ctx->GetTrickOption(RT_FLAMING_CHESTS))), + LOCATION(RC_GERUDO_TRAINING_GROUND_HAMMER_ROOM_CLEAR_CHEST, logic->CanAttack() && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GERUDO_TRAINING_GROUND_HAMMER_ROOM_SWITCH_CHEST, (logic->CanUse(RG_MEGATON_HAMMER) || (logic->TakeDamage() && ctx->GetTrickOption(RT_FLAMING_CHESTS))) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_GERUDO_TRAINING_GROUND_EYE_STATUE_LOWER, []{return logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_FAIRY_BOW);}), @@ -77,7 +77,7 @@ void RegionTable_Init_GerudoTrainingGround() { areaTable[RR_GERUDO_TRAINING_GROUND_EYE_STATUE_LOWER] = Region("Gerudo Training Ground Eye Statue Lower", SCENE_GERUDO_TRAINING_GROUND, {}, { //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_EYE_STATUE_CHEST, logic->CanUse(RG_FAIRY_BOW)), + LOCATION(RC_GERUDO_TRAINING_GROUND_EYE_STATUE_CHEST, logic->CanUse(RG_FAIRY_BOW) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_GERUDO_TRAINING_GROUND_HAMMER_ROOM, []{return true;}), @@ -85,7 +85,7 @@ void RegionTable_Init_GerudoTrainingGround() { areaTable[RR_GERUDO_TRAINING_GROUND_EYE_STATUE_UPPER] = Region("Gerudo Training Ground Eye Statue Upper", SCENE_GERUDO_TRAINING_GROUND, {}, { //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_NEAR_SCARECROW_CHEST, logic->CanUse(RG_FAIRY_BOW)), + LOCATION(RC_GERUDO_TRAINING_GROUND_NEAR_SCARECROW_CHEST, logic->CanUse(RG_FAIRY_BOW) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_GERUDO_TRAINING_GROUND_EYE_STATUE_LOWER, []{return true;}), @@ -93,7 +93,7 @@ void RegionTable_Init_GerudoTrainingGround() { areaTable[RR_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_ROOM] = Region("Gerudo Training Ground Heavy Block Room", SCENE_GERUDO_TRAINING_GROUND, {}, { //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_BEFORE_HEAVY_BLOCK_CHEST, logic->CanKillEnemy(RE_WOLFOS, ED_CLOSE, true, 4, true)), + LOCATION(RC_GERUDO_TRAINING_GROUND_BEFORE_HEAVY_BLOCK_CHEST, logic->CanKillEnemy(RE_WOLFOS, ED_CLOSE, true, 4, true) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_GERUDO_TRAINING_GROUND_EYE_STATUE_UPPER, []{return (ctx->GetTrickOption(RT_LENS_GTG) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && (ctx->GetTrickOption(RT_GTG_FAKE_WALL) && logic->CanUse(RG_HOVER_BOOTS)) || logic->CanGroundJump()));}), @@ -102,10 +102,10 @@ void RegionTable_Init_GerudoTrainingGround() { areaTable[RR_GERUDO_TRAINING_GROUND_LIKE_LIKE_ROOM] = Region("Gerudo Training Ground Like Like Room", SCENE_GERUDO_TRAINING_GROUND, {}, { //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FIRST_CHEST, logic->CanJumpslashExceptHammer()), - LOCATION(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_SECOND_CHEST, logic->CanJumpslashExceptHammer()), - LOCATION(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_THIRD_CHEST, logic->CanJumpslashExceptHammer()), - LOCATION(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FOURTH_CHEST, logic->CanJumpslashExceptHammer()), + LOCATION(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FIRST_CHEST, logic->CanJumpslashExceptHammer() && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_SECOND_CHEST, logic->CanJumpslashExceptHammer() && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_THIRD_CHEST, logic->CanJumpslashExceptHammer() && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FOURTH_CHEST, logic->CanJumpslashExceptHammer() && logic->HasItem(RG_OPEN_CHEST)), }, {}); #pragma endregion @@ -114,10 +114,10 @@ void RegionTable_Init_GerudoTrainingGround() { areaTable[RR_GERUDO_TRAINING_GROUND_MQ_LOBBY] = Region("Gerudo Training Ground MQ Lobby", SCENE_GERUDO_TRAINING_GROUND, {}, { //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_CHEST, true), - LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_CHEST, true), - LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_FIRST_CHEST, true), - LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_SECOND_CHEST, true), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_CHEST, logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_CHEST, logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_FIRST_CHEST, logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_SECOND_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_1, logic->CanBreakPots()), LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_2, logic->CanBreakPots()), LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_1, logic->CanBreakPots()), @@ -134,7 +134,7 @@ void RegionTable_Init_GerudoTrainingGround() { areaTable[RR_GERUDO_TRAINING_GROUND_MQ_MAZE_HIDDEN_ROOM] = Region("Gerudo Training Ground MQ Maze Hidden Room", SCENE_GERUDO_TRAINING_GROUND, {}, { //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_HIDDEN_CEILING_CHEST, true), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_HIDDEN_CEILING_CHEST, logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_GERUDO_TRAINING_GROUND_MQ_LOBBY, []{return true;}), @@ -142,7 +142,7 @@ void RegionTable_Init_GerudoTrainingGround() { areaTable[RR_GERUDO_TRAINING_GROUND_MQ_MAZE_FIRST_LOCK] = Region("Gerudo Training Ground MQ Maze First Lock", SCENE_GERUDO_TRAINING_GROUND, {}, { //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_THIRD_CHEST, true), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_THIRD_CHEST, logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_GERUDO_TRAINING_GROUND_MQ_LOBBY, []{return logic->SmallKeys(SCENE_GERUDO_TRAINING_GROUND, 1);}), @@ -163,7 +163,7 @@ void RegionTable_Init_GerudoTrainingGround() { areaTable[RR_GERUDO_TRAINING_GROUND_MQ_SAND_ROOM] = Region("Gerudo Training Ground MQ Sand Room", SCENE_GERUDO_TRAINING_GROUND, {}, { //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_FIRST_IRON_KNUCKLE_CHEST, logic->CanKillEnemy(RE_IRON_KNUCKLE)), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_FIRST_IRON_KNUCKLE_CHEST, logic->CanKillEnemy(RE_IRON_KNUCKLE) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_GERUDO_TRAINING_GROUND_MQ_LOBBY, []{return true;}), @@ -182,7 +182,7 @@ void RegionTable_Init_GerudoTrainingGround() { }, { //Locations //implies logic->CanKillEnemy(RE_BIG_SKULLTULA) - LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_BEFORE_HEAVY_BLOCK_CHEST, logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2, true)), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_BEFORE_HEAVY_BLOCK_CHEST, logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2, true) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_GERUDO_TRAINING_GROUND_MQ_BEHIND_BLOCK, []{return Here(RR_GERUDO_TRAINING_GROUND_MQ_STALFOS_ROOM, []{return logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2, true);}) && logic->CanUse(RG_SILVER_GAUNTLETS);}), @@ -192,7 +192,7 @@ void RegionTable_Init_GerudoTrainingGround() { areaTable[RR_GERUDO_TRAINING_GROUND_MQ_BEHIND_BLOCK] = Region("Gerudo Training Ground MQ Behind Block", SCENE_GERUDO_TRAINING_GROUND, {}, { //Locations //implies logic->CanKillEnemy(RE_SPIKE) - LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_HEAVY_BLOCK_CHEST, logic->CanKillEnemy(RE_FREEZARD)), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_HEAVY_BLOCK_CHEST, logic->CanKillEnemy(RE_FREEZARD) && logic->HasItem(RG_OPEN_CHEST)), }, {}); areaTable[RR_GERUDO_TRAINING_GROUND_MQ_STATUE_ROOM_LEDGE] = Region("Gerudo Training Ground MQ Statue Room Ledge", SCENE_GERUDO_TRAINING_GROUND, {}, {}, { @@ -205,7 +205,7 @@ void RegionTable_Init_GerudoTrainingGround() { areaTable[RR_GERUDO_TRAINING_GROUND_MQ_MAGENTA_FIRE_ROOM] = Region("Gerudo Training Ground MQ Magenta Fire Room", SCENE_GERUDO_TRAINING_GROUND, {}, { //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_ICE_ARROWS_CHEST, logic->Get(LOGIC_GTG_MQ_MAZE_SWITCH)), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_ICE_ARROWS_CHEST, logic->Get(LOGIC_GTG_MQ_MAZE_SWITCH) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_GERUDO_TRAINING_GROUND_MQ_STATUE_ROOM_LEDGE, []{return true;}), @@ -213,7 +213,7 @@ void RegionTable_Init_GerudoTrainingGround() { areaTable[RR_GERUDO_TRAINING_GROUND_MQ_STATUE_ROOM] = Region("Gerudo Training Ground MQ Statue ROom", SCENE_GERUDO_TRAINING_GROUND, {}, { //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_EYE_STATUE_CHEST, logic->CanUse(RG_FAIRY_BOW)), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_EYE_STATUE_CHEST, logic->CanUse(RG_FAIRY_BOW) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_GERUDO_TRAINING_GROUND_MQ_STATUE_ROOM_LEDGE, []{return logic->CanUse(RG_LONGSHOT);}), @@ -223,8 +223,8 @@ void RegionTable_Init_GerudoTrainingGround() { areaTable[RR_GERUDO_TRAINING_GROUND_MQ_TORCH_SLUG_ROOM] = Region("Gerudo Training Ground MQ Torch Slug Room", SCENE_GERUDO_TRAINING_GROUND, {}, { //Locations //implies logic->CanKillEnemy(RE_TORCH_SLUG) - LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_SECOND_IRON_KNUCKLE_CHEST, logic->CanKillEnemy(RE_IRON_KNUCKLE)), - LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_FLAME_CIRCLE_CHEST, logic->CanHitSwitch(ED_BOMB_THROW)), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_SECOND_IRON_KNUCKLE_CHEST, logic->CanKillEnemy(RE_IRON_KNUCKLE) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_FLAME_CIRCLE_CHEST, logic->CanHitSwitch(ED_BOMB_THROW) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_GERUDO_TRAINING_GROUND_MQ_STATUE_ROOM, []{return Here(RR_GERUDO_TRAINING_GROUND_MQ_TORCH_SLUG_ROOM, []{return logic->CanKillEnemy(RE_IRON_KNUCKLE);});}), @@ -287,7 +287,7 @@ void RegionTable_Init_GerudoTrainingGround() { areaTable[RR_GERUDO_TRAINING_GROUND_MQ_UNDERWATER] = Region("Gerudo Training Ground MQ Underwater", SCENE_GERUDO_TRAINING_GROUND, {}, { //Locations //it is possible to snipe the stingers with bow or sling before dropping in, or just get really lucky, and avoid needing to take damage, but that might be trick worthy - LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_UNDERWATER_SILVER_RUPEE_CHEST, logic->HasFireSource() && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 24 && logic->HasItem(RG_BRONZE_SCALE) && logic->TakeDamage()), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_UNDERWATER_SILVER_RUPEE_CHEST, (logic->HasFireSource() && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 24 && logic->HasItem(RG_BRONZE_SCALE) && logic->TakeDamage()) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_GERUDO_TRAINING_GROUND_MQ_PLATFORMS_UNLIT_TORCH, []{return true;}), @@ -299,8 +299,8 @@ void RegionTable_Init_GerudoTrainingGround() { EventAccess(LOGIC_GTG_PLATFORM_SILVER_RUPEES, []{return logic->CanUse(RG_FIRE_ARROWS) && logic->CanUse(RG_HOVER_BOOTS);}), }, { //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT_CENTRAL_CHEST, true), - LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT_SIDE_CHEST, true), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT_CENTRAL_CHEST, logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT_SIDE_CHEST, logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_GERUDO_TRAINING_GROUND_MQ_LOBBY, []{return true;}), @@ -319,7 +319,7 @@ void RegionTable_Init_GerudoTrainingGround() { //is logic->CanKillEnemy(RE_DINOLFOS, ED_CLOSE, true, 2, true) && logic->CanKillEnemy(RE_ARMOS, ED_CLOSE, true, 1, true) broken down to exclude sticks, as it take too many to clear the room //Proper enemy kill room ammo logic is needed to handle this room //some combinations may be impossible without taking damage, keep an eye out for issues here - LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_DINOLFOS_CHEST, logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_FAIRY_BOW) || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT)))), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_DINOLFOS_CHEST, (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_FAIRY_BOW) || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT)))) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_GERUDO_TRAINING_GROUND_MQ_TORCH_SIDE_PLATFORMS, []{return Here(RR_GERUDO_TRAINING_GROUND_MQ_DINOLFOS_ROOM, []{return logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_FAIRY_BOW) || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT)));});}), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp index 666a31ffd5b..0e082ddaae9 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp @@ -48,7 +48,7 @@ void RegionTable_Init_IceCavern() { EventAccess(LOGIC_BLUE_FIRE_ACCESS, []{return true;}), }, { //Locations - LOCATION(RC_ICE_CAVERN_MAP_CHEST, logic->BlueFire()), + LOCATION(RC_ICE_CAVERN_MAP_CHEST, logic->BlueFire() && logic->HasItem(RG_OPEN_CHEST)), // very easy to break pot through ice LOCATION(RC_ICE_CAVERN_FROZEN_POT_1, (logic->CanBreakPots() && logic->BlueFire()) || logic->HasExplosives() || (ctx->GetTrickOption(RT_RUSTED_SWITCHES) && ((logic->CanStandingShield() && logic->CanUse(RG_KOKIRI_SWORD)) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MEGATON_HAMMER))) || @@ -66,7 +66,7 @@ void RegionTable_Init_IceCavern() { EventAccess(LOGIC_BLUE_FIRE_ACCESS, []{return true;}), }, { //Locations - LOCATION(RC_ICE_CAVERN_COMPASS_CHEST, logic->CanClearStalagmite() && logic->BlueFire()), + LOCATION(RC_ICE_CAVERN_COMPASS_CHEST, logic->CanClearStalagmite() && logic->BlueFire() && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_ICE_CAVERN_FREESTANDING_POH, logic->CanClearStalagmite() && logic->BlueFire()), // can skip blue fire with rang trick LOCATION(RC_ICE_CAVERN_GS_HEART_PIECE_ROOM, logic->HookshotOrBoomerang()), }, { @@ -104,8 +104,8 @@ void RegionTable_Init_IceCavern() { areaTable[RR_ICE_CAVERN_FINAL_ROOM] = Region("Ice Cavern Final Room", SCENE_ICE_CAVERN, {}, { //Locations - LOCATION(RC_ICE_CAVERN_IRON_BOOTS_CHEST, Here(RR_ICE_CAVERN_FINAL_ROOM, []{return logic->CanKillEnemy(RE_WOLFOS);})), - LOCATION(RC_SHEIK_IN_ICE_CAVERN, Here(RR_ICE_CAVERN_FINAL_ROOM, []{return logic->CanKillEnemy(RE_WOLFOS);})), // rando enables this for child + LOCATION(RC_ICE_CAVERN_IRON_BOOTS_CHEST, Here(RR_ICE_CAVERN_FINAL_ROOM, []{return logic->CanKillEnemy(RE_WOLFOS) && logic->HasItem(RG_OPEN_CHEST);})), + LOCATION(RC_SHEIK_IN_ICE_CAVERN, Here(RR_ICE_CAVERN_FINAL_ROOM, []{return logic->CanKillEnemy(RE_WOLFOS) && logic->HasItem(RG_OPEN_CHEST);})), // rando enables this for child }, { //Exits Entrance(RR_ICE_CAVERN_BEFORE_FINAL_ROOM, []{return Here(RR_ICE_CAVERN_FINAL_ROOM, []{return logic->CanKillEnemy(RE_WOLFOS);});}), @@ -165,7 +165,7 @@ void RegionTable_Init_IceCavern() { EventAccess(LOGIC_BLUE_FIRE_ACCESS, []{return logic->IsChild || logic->CanClearStalagmite();}), }, { //Locations - LOCATION(RC_ICE_CAVERN_MQ_MAP_CHEST, logic->BlueFire() && Here(RR_ICE_CAVERN_MQ_MAP_ROOM, []{return logic->CanHitSwitch();})), + LOCATION(RC_ICE_CAVERN_MQ_MAP_CHEST, logic->BlueFire() && Here(RR_ICE_CAVERN_MQ_MAP_ROOM, []{return logic->CanHitSwitch();}) && logic->HasItem(RG_OPEN_CHEST)), }, {}); areaTable[RR_ICE_CAVERN_MQ_SCARECROW_ROOM] = Region("Ice Cavern MQ Scarecrow Room", SCENE_ICE_CAVERN, { @@ -197,7 +197,7 @@ void RegionTable_Init_IceCavern() { EventAccess(LOGIC_BLUE_FIRE_ACCESS, []{return true;}), }, { //Locations - LOCATION(RC_ICE_CAVERN_MQ_COMPASS_CHEST, true), + LOCATION(RC_ICE_CAVERN_MQ_COMPASS_CHEST, logic->HasItem(RG_OPEN_CHEST)), //It is possible for child with master, BGS or sticks, or adult with BGS, to hit this switch through the ice with a crouchstab, but it's precise and unintuitive for a trick LOCATION(RC_ICE_CAVERN_MQ_FREESTANDING_POH, logic->HasExplosives()), // can get with rang trick //doing RT_ICE_MQ_RED_ICE_GS as child is untested, as I could not perform the trick reliably even as adult @@ -209,8 +209,8 @@ void RegionTable_Init_IceCavern() { areaTable[RR_ICE_CAVERN_MQ_STALFOS_ROOM] = Region("Ice Cavern MQ Stalfos Room", SCENE_ICE_CAVERN, {}, { //Locations - LOCATION(RC_ICE_CAVERN_MQ_IRON_BOOTS_CHEST, logic->CanKillEnemy(RE_STALFOS)), - LOCATION(RC_SHEIK_IN_ICE_CAVERN, logic->CanKillEnemy(RE_STALFOS)), // rando enables this for child + LOCATION(RC_ICE_CAVERN_MQ_IRON_BOOTS_CHEST, logic->CanKillEnemy(RE_STALFOS) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_SHEIK_IN_ICE_CAVERN, logic->CanKillEnemy(RE_STALFOS) && logic->HasItem(RG_OPEN_CHEST)), // rando enables this for child }, { //Exits Entrance(RR_ICE_CAVERN_MQ_WEST_CORRIDOR, []{return Here(RR_ICE_CAVERN_MQ_STALFOS_ROOM, []{return logic->CanKillEnemy(RE_STALFOS);});}), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/jabujabus_belly.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/jabujabus_belly.cpp index c473f676461..55357d5831a 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/jabujabus_belly.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/jabujabus_belly.cpp @@ -30,8 +30,8 @@ void RegionTable_Init_JabuJabusBelly() { //Locations LOCATION(RC_JABU_JABUS_BELLY_DEKU_SCRUB, logic->HasItem(RG_BRONZE_SCALE) && (logic->IsChild || logic->HasItem(RG_SILVER_SCALE) || ctx->GetTrickOption(RT_JABU_ALCOVE_JUMP_DIVE) || logic->CanUse(RG_IRON_BOOTS)) && logic->CanStunDeku()), //We can kill the Stingers with ruto - LOCATION(RC_JABU_JABUS_BELLY_BOOMERANG_CHEST, logic->Get(LOGIC_JABU_RUTO_IN_1F)), - LOCATION(RC_JABU_JABUS_BELLY_MAP_CHEST, logic->Get(LOGIC_JABU_WEST_TENTACLE)), + LOCATION(RC_JABU_JABUS_BELLY_BOOMERANG_CHEST, logic->Get(LOGIC_JABU_RUTO_IN_1F) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_JABU_JABUS_BELLY_MAP_CHEST, logic->Get(LOGIC_JABU_WEST_TENTACLE) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_JABU_JABUS_BELLY_PLATFORM_ROOM_SMALL_CRATE_1, logic->CanBreakSmallCrates()), LOCATION(RC_JABU_JABUS_BELLY_PLATFORM_ROOM_SMALL_CRATE_2, logic->CanBreakSmallCrates()), }, { @@ -97,7 +97,7 @@ void RegionTable_Init_JabuJabusBelly() { areaTable[RR_JABU_JABUS_BELLY_COMPASS_ROOM] = Region("Jabu Jabus Belly Compass Room", SCENE_JABU_JABU, {}, { //Locations //ruto could theoretically clear this room, but it's hard because of the timer and she doesn't appear with you when you respawn after failing, which would force a savewarp - LOCATION(RC_JABU_JABUS_BELLY_COMPASS_CHEST, logic->CanKillEnemy(RE_SHABOM)), + LOCATION(RC_JABU_JABUS_BELLY_COMPASS_CHEST, logic->CanKillEnemy(RE_SHABOM) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_JABU_JABUS_BELLY_MAIN, []{return Here(RR_JABU_JABUS_BELLY_COMPASS_ROOM, []{return logic->CanKillEnemy(RE_SHABOM);});}), @@ -171,8 +171,8 @@ void RegionTable_Init_JabuJabusBelly() { EventAccess(LOGIC_NUT_POT, []{return true;}), }, { //Locations - LOCATION(RC_JABU_JABUS_BELLY_MQ_MAP_CHEST, logic->BlastOrSmash()), - LOCATION(RC_JABU_JABUS_BELLY_MQ_FIRST_ROOM_SIDE_CHEST, logic->CanUse(RG_FAIRY_SLINGSHOT)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_MAP_CHEST, logic->BlastOrSmash() && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_FIRST_ROOM_SIDE_CHEST, logic->CanUse(RG_FAIRY_SLINGSHOT) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_1, logic->CanBreakPots()), LOCATION(RC_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_2, logic->CanBreakPots()), LOCATION(RC_JABU_JABUS_BELLY_MQ_FIRST_GRASS_1, logic->CanCutShrubs()), @@ -188,7 +188,7 @@ void RegionTable_Init_JabuJabusBelly() { EventAccess(LOGIC_JABU_MQ_LIFT_ROOM_COW, []{return logic->CanUse(RG_FAIRY_SLINGSHOT);}), }, { //Locations - LOCATION(RC_JABU_JABUS_BELLY_MQ_SECOND_ROOM_LOWER_CHEST, true), + LOCATION(RC_JABU_JABUS_BELLY_MQ_SECOND_ROOM_LOWER_CHEST, logic->HasItem(RG_OPEN_CHEST)), 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)), @@ -208,7 +208,7 @@ void RegionTable_Init_JabuJabusBelly() { EventAccess(LOGIC_JABU_MQ_HOLES_ROOM_DOOR, []{return true;}), }, { //Locations - LOCATION(RC_JABU_JABUS_BELLY_MQ_COMPASS_CHEST, logic->CanHitSwitch(ED_HOOKSHOT, true) || (ctx->GetTrickOption(RT_JABU_MQ_RANG_JUMP) && logic->CanUse(RG_BOOMERANG) && logic->HasItem(RG_BRONZE_SCALE))), + LOCATION(RC_JABU_JABUS_BELLY_MQ_COMPASS_CHEST, (logic->CanHitSwitch(ED_HOOKSHOT, true) || (ctx->GetTrickOption(RT_JABU_MQ_RANG_JUMP) && logic->CanUse(RG_BOOMERANG) && logic->HasItem(RG_BRONZE_SCALE))) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_JABU_JABUS_BELLY_MQ_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 @@ -222,8 +222,8 @@ void RegionTable_Init_JabuJabusBelly() { areaTable[RR_JABU_JABUS_BELLY_MQ_HOLES_ROOM] = Region("Jabu Jabus Belly MQ Holes Room", SCENE_JABU_JABU, {}, { //Locations - LOCATION(RC_JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_VINES_CHEST, logic->CanUse(RG_FAIRY_SLINGSHOT)), - LOCATION(RC_JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_SWITCHES_CHEST, logic->CanUse(RG_FAIRY_SLINGSHOT)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_VINES_CHEST, logic->CanUse(RG_FAIRY_SLINGSHOT) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_SWITCHES_CHEST, logic->CanUse(RG_FAIRY_SLINGSHOT) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_JABU_JABUS_BELLY_MQ_PIT_GRASS_1, logic->CanCutShrubs() && logic->HasExplosives()), LOCATION(RC_JABU_JABUS_BELLY_MQ_PIT_GRASS_2, logic->CanCutShrubs() && logic->HasExplosives()), LOCATION(RC_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_1, logic->CanCutShrubs()), @@ -240,9 +240,9 @@ void RegionTable_Init_JabuJabusBelly() { areaTable[RR_JABU_JABUS_BELLY_MQ_WATER_SWITCH_ROOM] = Region("Jabu Jabus Belly MQ Water Switch Room", SCENE_JABU_JABU, {}, { //Locations - LOCATION(RC_JABU_JABUS_BELLY_MQ_BOOMERANG_ROOM_SMALL_CHEST, true), + LOCATION(RC_JABU_JABUS_BELLY_MQ_BOOMERANG_ROOM_SMALL_CHEST, logic->HasItem(RG_OPEN_CHEST)), //Implies logic->CanKillEnemy(RE_LIKE_LIKE) && logic->CanKillEnemy(RE_STINGER). Without swim, jump from the song of time block to the vines. - LOCATION(RC_JABU_JABUS_BELLY_MQ_BOOMERANG_CHEST, logic->CanKillEnemy(RE_LIZALFOS)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_BOOMERANG_CHEST, logic->CanKillEnemy(RE_LIZALFOS) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_JABU_JABUS_BELLY_MQ_GS_BOOMERANG_CHEST_ROOM, (logic->CanUse(RG_SONG_OF_TIME) && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)) || (ctx->GetTrickOption(RT_JABU_MQ_SOT_GS) && logic->CanUse(RG_BOOMERANG))), LOCATION(RC_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_1, logic->CanBreakPots()), LOCATION(RC_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_2, logic->CanBreakPots()), @@ -261,7 +261,7 @@ void RegionTable_Init_JabuJabusBelly() { }, { //Locations //Implies CanKillEnemy(RE_LIKE_LIKE) - LOCATION(RC_JABU_JABUS_BELLY_MQ_FALLING_LIKE_LIKE_ROOM_CHEST, logic->CanUse(RG_FAIRY_SLINGSHOT)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_FALLING_LIKE_LIKE_ROOM_CHEST, logic->CanUse(RG_FAIRY_SLINGSHOT) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_1, logic->CanBreakPots()), LOCATION(RC_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_2, logic->CanBreakPots()), LOCATION(RC_JABU_JABUS_BELLY_MQ_FALLING_LIKE_LIKE_GRASS, logic->CanCutShrubs()), @@ -326,7 +326,7 @@ void RegionTable_Init_JabuJabusBelly() { areaTable[RR_JABU_JABUS_BELLY_MQ_LIFT_ROOM_EAST_LEDGE] = Region("Jabu Jabus Belly MQ Lift Room East Ledge", SCENE_JABU_JABU, {}, { //Locations - LOCATION(RC_JABU_JABUS_BELLY_MQ_SECOND_ROOM_UPPER_CHEST, logic->Get(LOGIC_JABU_MQ_LIFT_ROOM_COW)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_SECOND_ROOM_UPPER_CHEST, logic->Get(LOGIC_JABU_MQ_LIFT_ROOM_COW) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_JABU_JABUS_BELLY_MQ_LIFT_ROOM, []{return true;}), @@ -338,7 +338,7 @@ void RegionTable_Init_JabuJabusBelly() { EventAccess(LOGIC_FAIRY_POT, []{return true;}), }, { //Locations - LOCATION(RC_JABU_JABUS_BELLY_MQ_NEAR_BOSS_CHEST, logic->CanUse(RG_FAIRY_SLINGSHOT)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_NEAR_BOSS_CHEST, logic->CanUse(RG_FAIRY_SLINGSHOT) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_JABU_JABUS_BELLY_MQ_GS_NEAR_BOSS, logic->CanUse(RG_BOOMERANG) || (ctx->GetTrickOption(RT_JABU_NEAR_BOSS_RANGED) && logic->CanUse(RG_HOOKSHOT))), LOCATION(RC_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_POT_1, logic->CanBreakPots()), LOCATION(RC_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_GRASS_1, logic->CanCutShrubs()), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp index 8514d12be9e..c9253a47a72 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp @@ -65,7 +65,7 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_WHISPERING_WALLS_SIDE_ROOM] = Region("Shadow Temple Whispering Walls Side Room", SCENE_SHADOW_TEMPLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_MAP_CHEST, logic->CanKillEnemy(RE_REDEAD) && logic->CanKillEnemy(RE_KEESE)), + LOCATION(RC_SHADOW_TEMPLE_MAP_CHEST, logic->CanKillEnemy(RE_REDEAD) && logic->CanKillEnemy(RE_KEESE) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_SHADOW_TEMPLE_MAP_CHEST_POT_1, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_MAP_CHEST_POT_2, logic->CanBreakPots()), }, { @@ -75,7 +75,7 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_DEAD_HAND] = Region("Shadow Temple Dead Hand", SCENE_SHADOW_TEMPLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_HOVER_BOOTS_CHEST, logic->CanKillEnemy(RE_DEAD_HAND)), + LOCATION(RC_SHADOW_TEMPLE_HOVER_BOOTS_CHEST, logic->CanKillEnemy(RE_DEAD_HAND) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_SHADOW_TEMPLE_WHISPERING_WALLS_END, []{return Here(RR_SHADOW_TEMPLE_DEAD_HAND, []{return logic->CanKillEnemy(RE_DEAD_HAND);});}), @@ -94,7 +94,7 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_COMPASS_ROOM] = Region("Shadow Temple Compass Room", SCENE_SHADOW_TEMPLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_COMPASS_CHEST, logic->CanKillEnemy(RE_GIBDO)), + LOCATION(RC_SHADOW_TEMPLE_COMPASS_CHEST, logic->CanKillEnemy(RE_GIBDO) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_SHADOW_TEMPLE_FIRST_BEAMOS, []{return Here(RR_SHADOW_TEMPLE_COMPASS_ROOM, []{return logic->CanKillEnemy(RE_GIBDO);});}), @@ -102,7 +102,7 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_SPINNING_BLADES] = Region("Shadow Temple Spinning Blades", SCENE_SHADOW_TEMPLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_EARLY_SILVER_RUPEE_CHEST, (logic->IsAdult && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanGroundJump())) || logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_SHADOW_TEMPLE_EARLY_SILVER_RUPEE_CHEST, ((logic->IsAdult && logic->HasItem(RG_OPEN_CHEST)) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanGroundJump())) || logic->CanUse(RG_HOOKSHOT)), }, { //Exits Entrance(RR_SHADOW_TEMPLE_FIRST_BEAMOS, []{return true;}), @@ -148,7 +148,7 @@ void RegionTable_Init_ShadowTemple() { // See MQ for comments areaTable[RR_SHADOW_TEMPLE_STONE_UMBRELLA] = Region("Shadow Temple Stone Umbrella", SCENE_SHADOW_TEMPLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_LOWER_CHEST, true), + LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_LOWER_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG) || (logic->IsAdult && ctx->GetTrickOption(RT_GROUND_JUMP_HARD) && logic->CanGroundJump() && logic->CanJumpslash())), LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_1, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_2, logic->CanBreakPots()), @@ -161,8 +161,8 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_STONE_UMBRELLA_UPPER] = Region("Shadow Temple Stone Umbrella Upper", SCENE_SHADOW_TEMPLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_UPPER_CHEST, true), - LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_SWITCH_CHEST, true), + LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_UPPER_CHEST, logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_SWITCH_CHEST, logic->HasItem(RG_OPEN_CHEST)), //Assuming the known setup for RT_SHADOW_UMBRELLA_HOVER and RT_SHADOW_UMBRELLA_GS, probably possible without sword + shield. LOCATION(RC_SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM, ctx->GetTrickOption(RT_SHADOW_UMBRELLA_GS) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanStandingShield() && logic->CanUse(RG_MASTER_SWORD)), LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_3, logic->CanBreakPots()), @@ -180,8 +180,8 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_INVISIBLE_SPINNING_BLADES] = Region("Shadow Temple Invisible Spinning Blades", SCENE_SHADOW_TEMPLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_VISIBLE_CHEST, logic->CanKillEnemy(RE_LIKE_LIKE) && logic->CanKillEnemy(RE_KEESE)), - LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_INVISIBLE_CHEST, logic->CanKillEnemy(RE_LIKE_LIKE) && logic->CanKillEnemy(RE_KEESE) && (ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_VISIBLE_CHEST, logic->CanKillEnemy(RE_LIKE_LIKE) && logic->CanKillEnemy(RE_KEESE) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_INVISIBLE_CHEST, logic->CanKillEnemy(RE_LIKE_LIKE) && logic->HasItem(RG_OPEN_CHEST) && logic->CanKillEnemy(RE_KEESE) && (ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH))), LOCATION(RC_SHADOW_TEMPLE_GS_LIKE_LIKE_ROOM, Here(RR_SHADOW_TEMPLE_INVISIBLE_SPINNING_BLADES, []{return logic->CanKillEnemy(RE_LIKE_LIKE) && logic->CanKillEnemy(RE_KEESE);}) && ((logic->IsAdult && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_SHORT_JUMPSLASH)) || logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG))), //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)), @@ -193,7 +193,7 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_INVISIBLE_SPIKES] = Region("Shadow Temple Invisible Spikes", SCENE_SHADOW_TEMPLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_SPIKES_CHEST, logic->CanKillEnemy(RE_REDEAD) && (ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH) || logic->TakeDamage() || logic->CanUse(RG_GORON_TUNIC))), + LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_SPIKES_CHEST, logic->CanKillEnemy(RE_REDEAD) && logic->HasItem(RG_OPEN_CHEST) && (ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH) || logic->TakeDamage() || logic->CanUse(RG_GORON_TUNIC))), }, { //Exits Entrance(RR_SHADOW_TEMPLE_LOWER_HUGE_PIT_DOOR_LEDGE, []{return logic->SmallKeys(SCENE_SHADOW_TEMPLE, 2);}), @@ -237,7 +237,7 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_WIND_TUNNEL_HINT_ROOM] = Region("Shadow Temple Wind Tunnel Hint Room", SCENE_SHADOW_TEMPLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_WIND_HINT_CHEST, logic->CanKillEnemy(RE_REDEAD)), + LOCATION(RC_SHADOW_TEMPLE_WIND_HINT_CHEST, logic->CanKillEnemy(RE_REDEAD) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)), }, { //Exits @@ -246,8 +246,8 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_ROOM_TO_BOAT] = Region("Shadow Temple Room to Boat", SCENE_SHADOW_TEMPLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_ENEMY_CHEST, logic->CanKillEnemy(RE_GIBDO, ED_CLOSE, true, 2)), - LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_HIDDEN_CHEST, (ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasExplosives()), + LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_ENEMY_CHEST, logic->CanKillEnemy(RE_GIBDO, ED_CLOSE, true, 2) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_HIDDEN_CHEST, (ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasExplosives() && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_POT_1, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_POT_2, logic->CanBreakPots()), }, { @@ -312,7 +312,7 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_X_CROSS] = Region("Shadow Temple X-Cross", SCENE_SHADOW_TEMPLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_FLOORMASTER_CHEST, (ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanKillEnemy(RE_FLOORMASTER)), + LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_FLOORMASTER_CHEST, (ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanKillEnemy(RE_FLOORMASTER) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_SHADOW_TEMPLE_FLOORMASTER_POT_1, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_FLOORMASTER_POT_2, logic->CanBreakPots()), }, { @@ -330,8 +330,8 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_WOODEN_SPIKES] = Region("Shadow Temple Wooden Spikes", SCENE_SHADOW_TEMPLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_SPIKE_WALLS_LEFT_CHEST, logic->CanUse(RG_DINS_FIRE)), - LOCATION(RC_SHADOW_TEMPLE_BOSS_KEY_CHEST, logic->CanUse(RG_DINS_FIRE)), + LOCATION(RC_SHADOW_TEMPLE_SPIKE_WALLS_LEFT_CHEST, logic->CanUse(RG_DINS_FIRE) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_SHADOW_TEMPLE_BOSS_KEY_CHEST, logic->CanUse(RG_DINS_FIRE) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_SHADOW_TEMPLE_SPIKE_WALLS_POT_1, logic->CanBreakPots()), }, { //Exits @@ -405,7 +405,7 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_SIDE_ROOM] = Region("Shadow Temple MQ Whispering Walls Redeads", SCENE_SHADOW_TEMPLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_MQ_COMPASS_CHEST, logic->CanKillEnemy(RE_REDEAD)), + LOCATION(RC_SHADOW_TEMPLE_MQ_COMPASS_CHEST, logic->CanKillEnemy(RE_REDEAD) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_1, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_2, logic->CanBreakPots()), }, { @@ -415,7 +415,7 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_DEAD_HAND] = Region("Shadow Temple MQ Whispering Walls Dead Hand", SCENE_SHADOW_TEMPLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_MQ_HOVER_BOOTS_CHEST, logic->CanKillEnemy(RE_DEAD_HAND)), + LOCATION(RC_SHADOW_TEMPLE_MQ_HOVER_BOOTS_CHEST, logic->CanKillEnemy(RE_DEAD_HAND) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_END, []{return Here(RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_DEAD_HAND, []{return logic->CanKillEnemy(RE_DEAD_HAND);});}), @@ -435,7 +435,7 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_MQ_B2_GIBDO_ROOM] = Region("Shadow Temple MQ B2 Gibdo Room", SCENE_SHADOW_TEMPLE, {}, { //Locations //Doing this sets the shared flag for the glass in RR_SHADOW_TEMPLE_MQ_WHISPERING_WALLS, but doesn't seem to affect the chest - LOCATION(RC_SHADOW_TEMPLE_MQ_EARLY_GIBDOS_CHEST, logic->CanKillEnemy(RE_GIBDO) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_SHADOW_TEMPLE_MQ_EARLY_GIBDOS_CHEST, logic->CanKillEnemy(RE_GIBDO) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS, []{return Here(RR_SHADOW_TEMPLE_MQ_B2_GIBDO_ROOM, []{return logic->CanKillEnemy(RE_GIBDO);});}), @@ -443,7 +443,7 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_MQ_B2_SPINNING_BLADE_ROOM] = Region("Shadow Temple MQ B2 Spinning Blade Room", SCENE_SHADOW_TEMPLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_MQ_MAP_CHEST, logic->CanPassEnemy(RE_BIG_SKULLTULA) && (logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanGroundJump())))), + LOCATION(RC_SHADOW_TEMPLE_MQ_MAP_CHEST, (logic->CanPassEnemy(RE_BIG_SKULLTULA) && (logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanGroundJump())))) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS, []{return Here(RR_SHADOW_TEMPLE_MQ_B2_SPINNING_BLADE_ROOM, []{return logic->CanKillEnemy(RE_BIG_SKULLTULA) && (logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)));});}), @@ -452,7 +452,7 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_MQ_SHORTCUT_PATH] = Region("Shadow Temple MQ Shortcut Path", SCENE_SHADOW_TEMPLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_MQ_NEAR_SHIP_INVISIBLE_CHEST, ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)), + LOCATION(RC_SHADOW_TEMPLE_MQ_NEAR_SHIP_INVISIBLE_CHEST, (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_SHADOW_TEMPLE_MQ_B2_SPINNING_BLADE_ROOM, []{return logic->CanPassEnemy(RE_BIG_SKULLTULA);}), @@ -496,9 +496,9 @@ void RegionTable_Init_ShadowTemple() { //you take half a heart base from a spit out, double check EffectiveHealth when damage logic gets reworked //Child is too small to get hit by the blades doesn't need the trick or lens for dodging them LOCATION(RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_VISIBLE_CHEST, (logic->CanUse(RG_SONG_OF_TIME) || (ctx->GetTrickOption(RT_SHADOW_MQ_INVISIBLE_BLADES) && logic->EffectiveHealth() > 1)) && - (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))), + (ctx->GetTrickOption(RT_LENS_SHADOW_MQ_INVISIBLE_BLADES) || logic->IsChild || logic->CanUse(RG_NAYRUS_LOVE) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasItem(RG_OPEN_CHEST)), + 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)) && logic->HasItem(RG_OPEN_CHEST)), 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)), }, { @@ -508,7 +508,7 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_MQ_LOWER_HUGE_PIT] = Region("Shadow Temple MQ Lower Huge Pit", SCENE_SHADOW_TEMPLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_MQ_BEAMOS_SILVER_RUPEES_CHEST, logic->CanUse(RG_LONGSHOT)), + LOCATION(RC_SHADOW_TEMPLE_MQ_BEAMOS_SILVER_RUPEES_CHEST, logic->CanUse(RG_LONGSHOT) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_SHADOW_TEMPLE_MQ_B2_TO_B3_CORRIDOR_B3, []{return logic->CanUse(RG_LONGSHOT);}), @@ -524,7 +524,7 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_MQ_STONE_UMBRELLA_ROOM] = Region("Shadow Temple MQ Stone Umbrella Room", SCENE_SHADOW_TEMPLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_LOWER_CHEST, true), + LOCATION(RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_LOWER_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_SHADOW_TEMPLE_MQ_GS_FALLING_SPIKES_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG) || (logic->IsAdult && ctx->GetTrickOption(RT_GROUND_JUMP_HARD) && logic->CanGroundJump() && logic->CanJumpslash())), LOCATION(RC_SHADOW_TEMPLE_MQ_LOWER_UMBRELLA_WEST_POT, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_MQ_LOWER_UMBRELLA_EAST_POT, logic->CanBreakPots()), @@ -538,8 +538,8 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_MQ_UPPER_STONE_UMBRELLA] = Region("Shadow Temple MQ Upper Stone Umbrella", SCENE_SHADOW_TEMPLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_UPPER_CHEST, true), - LOCATION(RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_SWITCH_CHEST, true), + LOCATION(RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_UPPER_CHEST, logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_SWITCH_CHEST, logic->HasItem(RG_OPEN_CHEST)), //Assuming the known setup for RT_SHADOW_UMBRELLA_HOVER and RT_SHADOW_UMBRELLA_GS, probably possible without sword + shield. LOCATION(RC_SHADOW_TEMPLE_MQ_GS_FALLING_SPIKES_ROOM, ctx->GetTrickOption(RT_SHADOW_UMBRELLA_GS) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanStandingShield() && logic->CanUse(RG_MASTER_SWORD)), LOCATION(RC_SHADOW_TEMPLE_MQ_UPPER_UMBRELLA_NORTH_POT, logic->CanBreakPots()), @@ -561,7 +561,7 @@ void RegionTable_Init_ShadowTemple() { (logic->TakeDamage() || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_GORON_TUNIC));}), }, { //Locations - LOCATION(RC_SHADOW_TEMPLE_MQ_INVISIBLE_SPIKES_CHEST, logic->CanKillEnemy(RE_REDEAD) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->TakeDamage() || logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_SHADOW_TEMPLE_MQ_INVISIBLE_SPIKES_CHEST, logic->CanKillEnemy(RE_REDEAD) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->TakeDamage() || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_SHADOW_TEMPLE_MQ_LOWER_HUGE_PIT, []{return logic->SmallKeys(SCENE_SHADOW_TEMPLE, 3);}), @@ -579,7 +579,7 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_MQ_STALFOS_ROOM] = Region("Shadow Temple MQ Stalfos Room", SCENE_SHADOW_TEMPLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_MQ_STALFOS_ROOM_CHEST, logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2)), + LOCATION(RC_SHADOW_TEMPLE_MQ_STALFOS_ROOM_CHEST, logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_ROOM, []{return Here(RR_SHADOW_TEMPLE_MQ_STALFOS_ROOM, []{return logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2);});}), @@ -600,7 +600,7 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_MQ_WIND_HINT_ROOM] = Region("Shadow Temple MQ Wind Hint Room", SCENE_SHADOW_TEMPLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_MQ_WIND_HINT_CHEST, (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanPassEnemy(RE_REDEAD)), + LOCATION(RC_SHADOW_TEMPLE_MQ_WIND_HINT_CHEST, (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanPassEnemy(RE_REDEAD) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_SHADOW_TEMPLE_MQ_GS_WIND_HINT_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)), LOCATION(RC_SHADOW_TEMPLE_MQ_WIND_HINT_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)), }, { @@ -618,8 +618,8 @@ void RegionTable_Init_ShadowTemple() { EventAccess(LOGIC_NUT_POT, []{return true;}), }, { //Locations - LOCATION(RC_SHADOW_TEMPLE_MQ_AFTER_WIND_ENEMY_CHEST, logic->CanKillEnemy(RE_GIBDO)), - LOCATION(RC_SHADOW_TEMPLE_MQ_AFTER_WIND_HIDDEN_CHEST, logic->HasExplosives() && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_SHADOW_TEMPLE_MQ_AFTER_WIND_ENEMY_CHEST, logic->CanKillEnemy(RE_GIBDO) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_SHADOW_TEMPLE_MQ_AFTER_WIND_HIDDEN_CHEST, logic->HasExplosives() && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_SHADOW_TEMPLE_MQ_GS_AFTER_WIND, logic->HasExplosives()), LOCATION(RC_SHADOW_TEMPLE_MQ_BEFORE_BOAT_POT_1, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_MQ_BEFORE_BOAT_POT_2, logic->CanBreakPots()), @@ -706,7 +706,7 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_MQ_X_CROSS] = Region("Shadow Temple MQ X-Cross", SCENE_SHADOW_TEMPLE, {}, { //Locations //don't use CanDetonateUprightBombFlower as blue fire logic would need to account for player having multiple bottles & taking damage multiple times - LOCATION(RC_SHADOW_TEMPLE_MQ_BOMB_FLOWER_CHEST, (logic->CanUse(RG_LENS_OF_TRUTH) || ctx->GetTrickOption(RT_LENS_SHADOW_MQ_DEADHAND)) && logic->CanKillEnemy(RE_DEAD_HAND) && (logic->CanDetonateBombFlowers() || logic->HasItem(RG_GORONS_BRACELET))), + LOCATION(RC_SHADOW_TEMPLE_MQ_BOMB_FLOWER_CHEST, (logic->CanUse(RG_LENS_OF_TRUTH) || ctx->GetTrickOption(RT_LENS_SHADOW_MQ_DEADHAND)) && logic->CanKillEnemy(RE_DEAD_HAND) && (logic->CanDetonateBombFlowers() || logic->HasItem(RG_GORONS_BRACELET)) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_1, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_2, logic->CanBreakPots()), }, { @@ -724,8 +724,8 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_MQ_SPIKE_WALLS_ROOM] = Region("Shadow Temple MQ Spike Walls Room", SCENE_SHADOW_TEMPLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_MQ_SPIKE_WALLS_LEFT_CHEST, logic->CanUse(RG_DINS_FIRE)), - LOCATION(RC_SHADOW_TEMPLE_MQ_BOSS_KEY_CHEST, logic->CanUse(RG_DINS_FIRE)), + LOCATION(RC_SHADOW_TEMPLE_MQ_SPIKE_WALLS_LEFT_CHEST, logic->CanUse(RG_DINS_FIRE) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_SHADOW_TEMPLE_MQ_BOSS_KEY_CHEST, logic->CanUse(RG_DINS_FIRE) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_SHADOW_TEMPLE_MQ_SPIKE_BARICADE_POT, logic->CanBreakPots()), }, { //Exits diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp index 207b9c76f47..c49cd7a2d3e 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp @@ -32,8 +32,8 @@ void RegionTable_Init_SpiritTemple() { EventAccess(LOGIC_NUT_CRATE, []{return true;}), }, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_CHILD_BRIDGE_CHEST, (logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives() || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT))))), - LOCATION(RC_SPIRIT_TEMPLE_CHILD_EARLY_TORCHES_CHEST, (logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives() || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT)))) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_DINS_FIRE))), + LOCATION(RC_SPIRIT_TEMPLE_CHILD_BRIDGE_CHEST, (logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives() || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT)))) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_SPIRIT_TEMPLE_CHILD_EARLY_TORCHES_CHEST, (logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives() || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT)))) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_DINS_FIRE)) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_SPIRIT_TEMPLE_GS_METAL_FENCE, (logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives() || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT))))), LOCATION(RC_SPIRIT_TEMPLE_ANUBIS_POT_1, (logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives() || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT))))), LOCATION(RC_SPIRIT_TEMPLE_ANUBIS_POT_2, (logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives() || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT))))), @@ -48,8 +48,8 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_CHILD_CLIMB] = Region("Child Spirit Temple Climb", SCENE_SPIRIT_TEMPLE, {}, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_CHILD_CLIMB_NORTH_CHEST, logic->HasProjectile(HasProjectileAge::Both) || (logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 2) && logic->CanUse(RG_SILVER_GAUNTLETS) && logic->HasProjectile(HasProjectileAge::Adult)) || (logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 5) && logic->IsChild && logic->HasProjectile(HasProjectileAge::Child))), - LOCATION(RC_SPIRIT_TEMPLE_CHILD_CLIMB_EAST_CHEST, logic->HasProjectile(HasProjectileAge::Both) || (logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 2) && logic->CanUse(RG_SILVER_GAUNTLETS) && logic->HasProjectile(HasProjectileAge::Adult)) || (logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 5) && logic->IsChild && logic->HasProjectile(HasProjectileAge::Child))), + LOCATION(RC_SPIRIT_TEMPLE_CHILD_CLIMB_NORTH_CHEST, (logic->HasProjectile(HasProjectileAge::Both) || (logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 2) && logic->CanUse(RG_SILVER_GAUNTLETS) && logic->HasProjectile(HasProjectileAge::Adult)) || (logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 5) && logic->IsChild && logic->HasProjectile(HasProjectileAge::Child))) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_SPIRIT_TEMPLE_CHILD_CLIMB_EAST_CHEST, (logic->HasProjectile(HasProjectileAge::Both) || (logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 2) && logic->CanUse(RG_SILVER_GAUNTLETS) && logic->HasProjectile(HasProjectileAge::Adult)) || (logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 5) && logic->IsChild && logic->HasProjectile(HasProjectileAge::Child))) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_SPIRIT_TEMPLE_GS_SUN_ON_FLOOR_ROOM, logic->HasProjectile(HasProjectileAge::Both) || logic->CanUse(RG_DINS_FIRE) || (logic->TakeDamage() && (logic->CanJumpslashExceptHammer() || logic->HasProjectile(HasProjectileAge::Child))) || (logic->IsChild && logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 5) && logic->HasProjectile(HasProjectileAge::Child)) || @@ -62,10 +62,10 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_EARLY_ADULT] = Region("Early Adult Spirit Temple", SCENE_SPIRIT_TEMPLE, {}, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_COMPASS_CHEST, logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_ZELDAS_LULLABY)), - LOCATION(RC_SPIRIT_TEMPLE_EARLY_ADULT_RIGHT_CHEST, (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_BOMBCHU_5) || (logic->CanUse(RG_BOMB_BAG) && logic->IsAdult && ctx->GetTrickOption(RT_SPIRIT_LOWER_ADULT_SWITCH))) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanJumpslashExceptHammer())), - LOCATION(RC_SPIRIT_TEMPLE_FIRST_MIRROR_LEFT_CHEST, logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 3)), - LOCATION(RC_SPIRIT_TEMPLE_FIRST_MIRROR_RIGHT_CHEST, logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 3)), + LOCATION(RC_SPIRIT_TEMPLE_COMPASS_CHEST, logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_ZELDAS_LULLABY) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_SPIRIT_TEMPLE_EARLY_ADULT_RIGHT_CHEST, (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_BOMBCHU_5) || (logic->CanUse(RG_BOMB_BAG) && logic->IsAdult && ctx->GetTrickOption(RT_SPIRIT_LOWER_ADULT_SWITCH))) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanJumpslashExceptHammer()) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_SPIRIT_TEMPLE_FIRST_MIRROR_LEFT_CHEST, logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 3) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_SPIRIT_TEMPLE_FIRST_MIRROR_RIGHT_CHEST, logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 3) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_SPIRIT_TEMPLE_GS_BOULDER_ROOM, logic->CanUse(RG_SONG_OF_TIME) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_BOMBCHU_5) || (logic->CanUse(RG_BOMB_BAG) && ctx->GetTrickOption(RT_SPIRIT_LOWER_ADULT_SWITCH)))), LOCATION(RC_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_BOMBCHU_5) || (logic->CanUse(RG_BOMB_BAG) && logic->IsAdult && ctx->GetTrickOption(RT_SPIRIT_LOWER_ADULT_SWITCH))) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanJumpslash())), }, { @@ -75,16 +75,16 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_CENTRAL_CHAMBER] = Region("Spirit Temple Central Chamber", SCENE_SPIRIT_TEMPLE, {}, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_MAP_CHEST, ((logic->HasExplosives() || logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 2)) && - (logic->CanUse(RG_DINS_FIRE) || ((logic->CanUse(RG_FIRE_ARROWS) || ctx->GetTrickOption(RT_SPIRIT_MAP_CHEST)) && logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_STICKS) ))) || + LOCATION(RC_SPIRIT_TEMPLE_MAP_CHEST, (((logic->HasExplosives() || logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 2)) && + (logic->CanUse(RG_DINS_FIRE) || ((logic->CanUse(RG_FIRE_ARROWS) || ctx->GetTrickOption(RT_SPIRIT_MAP_CHEST)) && logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_STICKS)))) || (logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 5) && logic->HasExplosives() && logic->CanUse(RG_STICKS)) || - (logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 3) && (logic->CanUse(RG_FIRE_ARROWS) || (ctx->GetTrickOption(RT_SPIRIT_MAP_CHEST) && logic->CanUse(RG_FAIRY_BOW))) && logic->CanUse(RG_SILVER_GAUNTLETS))), - LOCATION(RC_SPIRIT_TEMPLE_SUN_BLOCK_ROOM_CHEST, ((logic->HasExplosives() || logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 2)) && - (logic->CanUse(RG_DINS_FIRE) || ((logic->CanUse(RG_FIRE_ARROWS) || ctx->GetTrickOption(RT_SPIRIT_SUN_CHEST)) && logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_STICKS) ))) || + (logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 3) && (logic->CanUse(RG_FIRE_ARROWS) || (ctx->GetTrickOption(RT_SPIRIT_MAP_CHEST) && logic->CanUse(RG_FAIRY_BOW))) && logic->CanUse(RG_SILVER_GAUNTLETS))) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_SPIRIT_TEMPLE_SUN_BLOCK_ROOM_CHEST, (((logic->HasExplosives() || logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 2)) && + (logic->CanUse(RG_DINS_FIRE) || ((logic->CanUse(RG_FIRE_ARROWS) || ctx->GetTrickOption(RT_SPIRIT_SUN_CHEST)) && logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_STICKS)))) || (logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 5) && logic->HasExplosives() && logic->CanUse(RG_STICKS)) || - (logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 3) && (logic->CanUse(RG_FIRE_ARROWS) || (ctx->GetTrickOption(RT_SPIRIT_SUN_CHEST) && logic->CanUse(RG_FAIRY_BOW))) && logic->CanUse(RG_SILVER_GAUNTLETS))), - LOCATION(RC_SPIRIT_TEMPLE_STATUE_ROOM_HAND_CHEST, logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 3) && logic->CanUse(RG_SILVER_GAUNTLETS) && logic->CanUse(RG_ZELDAS_LULLABY)), - LOCATION(RC_SPIRIT_TEMPLE_STATUE_ROOM_NORTHEAST_CHEST, logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 3) && logic->CanUse(RG_SILVER_GAUNTLETS) && logic->CanUse(RG_ZELDAS_LULLABY) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_SPIRIT_LOBBY_JUMP))), + (logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 3) && (logic->CanUse(RG_FIRE_ARROWS) || (ctx->GetTrickOption(RT_SPIRIT_SUN_CHEST) && logic->CanUse(RG_FAIRY_BOW))) && logic->CanUse(RG_SILVER_GAUNTLETS))) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_SPIRIT_TEMPLE_STATUE_ROOM_HAND_CHEST, logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 3) && logic->CanUse(RG_SILVER_GAUNTLETS) && logic->CanUse(RG_ZELDAS_LULLABY) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_SPIRIT_TEMPLE_STATUE_ROOM_NORTHEAST_CHEST, logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 3) && logic->CanUse(RG_SILVER_GAUNTLETS) && logic->CanUse(RG_ZELDAS_LULLABY) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_SPIRIT_LOBBY_JUMP)) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_SPIRIT_TEMPLE_GS_HALL_AFTER_SUN_BLOCK_ROOM, (logic->HasExplosives() && logic->CanUse(RG_BOOMERANG) && logic->CanUse(RG_HOOKSHOT)) || (logic->CanUse(RG_BOOMERANG) && logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 5) && logic->HasExplosives()) || (logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_SILVER_GAUNTLETS) && logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 2))), @@ -111,8 +111,8 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_OUTDOOR_HANDS] = Region("Spirit Temple Outdoor Hands", SCENE_SPIRIT_TEMPLE, {}, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST, (logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 3) && logic->CanUse(RG_LONGSHOT) && logic->HasExplosives()) || logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 5)), - LOCATION(RC_SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST, logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 4) && logic->CanUse(RG_SILVER_GAUNTLETS) && logic->HasExplosives()), + LOCATION(RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST, ((logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 3) && logic->CanUse(RG_LONGSHOT) && logic->HasExplosives()) || logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 5)) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST, logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 4) && logic->CanUse(RG_SILVER_GAUNTLETS) && logic->HasExplosives() && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_DESERT_COLOSSUS, []{return (logic->IsChild && logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 5)) || (logic->CanUse(RG_SILVER_GAUNTLETS) && ((logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 3) && logic->HasExplosives()) || logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 5)));}), @@ -120,9 +120,9 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_BEYOND_CENTRAL_LOCKED_DOOR] = Region("Spirit Temple Beyond Central Locked Door", SCENE_SPIRIT_TEMPLE, {}, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_NEAR_FOUR_ARMOS_CHEST, (logic->CanUse(RG_MIRROR_SHIELD) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS))) && logic->HasExplosives()), - LOCATION(RC_SPIRIT_TEMPLE_HALLWAY_LEFT_INVISIBLE_CHEST, (ctx->GetTrickOption(RT_LENS_SPIRIT) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasExplosives()), - LOCATION(RC_SPIRIT_TEMPLE_HALLWAY_RIGHT_INVISIBLE_CHEST, (ctx->GetTrickOption(RT_LENS_SPIRIT) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasExplosives()), + LOCATION(RC_SPIRIT_TEMPLE_NEAR_FOUR_ARMOS_CHEST, (logic->CanUse(RG_MIRROR_SHIELD) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS))) && logic->HasExplosives() && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_SPIRIT_TEMPLE_HALLWAY_LEFT_INVISIBLE_CHEST, (ctx->GetTrickOption(RT_LENS_SPIRIT) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasExplosives() && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_SPIRIT_TEMPLE_HALLWAY_RIGHT_INVISIBLE_CHEST, (ctx->GetTrickOption(RT_LENS_SPIRIT) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasExplosives() && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_SPIRIT_TEMPLE_BEAMOS_HALL_POT_1, logic->CanBreakPots()), LOCATION(RC_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY, logic->HasExplosives() && logic->CanUse(RG_SUNS_SONG)), }, { @@ -132,9 +132,9 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_BEYOND_FINAL_LOCKED_DOOR] = Region("Spirit Temple Beyond Final Locked Door", SCENE_SPIRIT_TEMPLE, {}, { //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->CanJumpslash() || logic->HasExplosives() || (ctx->GetTrickOption(RT_HOOKSHOT_EXTENSION) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_HOOKSHOT))))) || - (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))) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_SPIRIT_TEMPLE_TOPMOST_CHEST, ((logic->CanUse(RG_MIRROR_SHIELD) && (logic->CanJumpslash() || logic->HasExplosives() || (ctx->GetTrickOption(RT_HOOKSHOT_EXTENSION) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_HOOKSHOT))))) || + (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS))) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_SPIRIT_TEMPLE_ADULT_CLIMB_LEFT_HEART, logic->CanUse(RG_HOOKSHOT)), LOCATION(RC_SPIRIT_TEMPLE_ADULT_CLIMB_RIGHT_HEART, logic->CanUse(RG_HOOKSHOT)), }, { @@ -154,10 +154,10 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_MQ_LOBBY] = Region("Spirit Temple MQ Lobby", SCENE_SPIRIT_TEMPLE, {}, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_LEFT_CHEST, true), - LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_LEFT_CHEST, Here(RR_SPIRIT_TEMPLE_MQ_LOBBY, []{return logic->BlastOrSmash();}) && logic->CanHitEyeTargets()), - LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_RIGHT_CHEST, logic->CanHitSwitch(ED_BOOMERANG)), - LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_RIGHT_CHEST, logic->Get(LOGIC_SPIRIT_1F_SILVER_RUPEES)), + LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_LEFT_CHEST, logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_LEFT_CHEST, Here(RR_SPIRIT_TEMPLE_MQ_LOBBY, []{return logic->BlastOrSmash();}) && logic->CanHitEyeTargets() && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_RIGHT_CHEST, logic->CanHitSwitch(ED_BOOMERANG) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_RIGHT_CHEST, logic->Get(LOGIC_SPIRIT_1F_SILVER_RUPEES) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_1, logic->CanBreakPots()), LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_2, logic->CanBreakPots()), LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_3, logic->CanBreakPots()), @@ -175,7 +175,7 @@ void RegionTable_Init_SpiritTemple() { EventAccess(LOGIC_SPIRIT_MQ_CRAWL_BOULDER, []{return logic->CanUse(RG_BOMBCHU_5) || (ctx->GetTrickOption(RT_RUSTED_SWITCHES) && logic->CanUse(RG_MEGATON_HAMMER));}), }, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_HAMMER_SWITCH_CHEST, logic->Get(LOGIC_SPIRIT_MQ_TIME_TRAVEL_CHEST)), + LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_HAMMER_SWITCH_CHEST, logic->Get(LOGIC_SPIRIT_MQ_TIME_TRAVEL_CHEST) && logic->HasItem(RG_OPEN_CHEST)), 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()), @@ -222,7 +222,7 @@ void RegionTable_Init_SpiritTemple() { EventAccess(LOGIC_SPIRIT_MQ_MAP_ROOM_ENEMIES, []{return logic->CanKillEnemy(RE_ANUBIS) && logic->CanKillEnemy(RE_KEESE);}), }, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_MQ_MAP_ROOM_ENEMY_CHEST, logic->Get(LOGIC_SPIRIT_MQ_MAP_ROOM_ENEMIES)), + LOCATION(RC_SPIRIT_TEMPLE_MQ_MAP_ROOM_ENEMY_CHEST, logic->Get(LOGIC_SPIRIT_MQ_MAP_ROOM_ENEMIES) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits //Stalfos room blocks you in with fire until you kill the stalfos, which won't spawn from behind the fire @@ -235,7 +235,7 @@ void RegionTable_Init_SpiritTemple() { EventAccess(LOGIC_SPIRIT_MQ_MAP_ROOM_ENEMIES, []{return logic->CanKillEnemy(RE_ANUBIS) && logic->CanKillEnemy(RE_KEESE, ED_BOOMERANG);}), }, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_MQ_MAP_CHEST, true), + LOCATION(RC_SPIRIT_TEMPLE_MQ_MAP_CHEST, logic->HasItem(RG_OPEN_CHEST)), }, { //Exits //The bridge is a temp flag, so not a way to cross south to north in logic @@ -245,7 +245,7 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_MQ_WEST_1F_RUSTED_SWITCH] = Region("Spirit Temple MQ West 1F Rusted Switch", SCENE_SPIRIT_TEMPLE, { //Events - EventAccess(LOGIC_SPIRIT_MQ_TIME_TRAVEL_CHEST, []{return logic->CanUse(RG_MEGATON_HAMMER);}), + EventAccess(LOGIC_SPIRIT_MQ_TIME_TRAVEL_CHEST, []{return logic->CanUse(RG_MEGATON_HAMMER) && logic->HasItem(RG_OPEN_CHEST);}), EventAccess(LOGIC_SPIRIT_MQ_CRAWL_BOULDER, []{return logic->CanUse(RG_BOMBCHU_5) || (ctx->GetTrickOption(RT_RUSTED_SWITCHES) && logic->CanUse(RG_MEGATON_HAMMER));}), }, {}, { //Exits @@ -267,10 +267,10 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_MQ_BROKEN_WALL_ROOM] = Region("Spirit Temple MQ Broken Wall Room", SCENE_SPIRIT_TEMPLE, {}, { //Locations //Implies CanKillEnemy(RE_LIKE_LIKE) - LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_NORTH_CHEST, MQSpiritSharedBrokenWallRoom(RR_SPIRIT_TEMPLE_MQ_BROKEN_WALL_ROOM, []{return logic->CanKillEnemy(RE_BEAMOS);})), + LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_NORTH_CHEST, MQSpiritSharedBrokenWallRoom(RR_SPIRIT_TEMPLE_MQ_BROKEN_WALL_ROOM, []{return logic->CanKillEnemy(RE_BEAMOS);}) && logic->HasItem(RG_OPEN_CHEST)), //Sunlights only temp spawn this chest, which is unintuitive/a bug. //chest is only reachable as adult glitchlessly, so we can skip the shared in favour of IsAdult as adult access is always Certain - LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_SOUTH_CHEST, logic->IsAdult && (logic->HasExplosives() || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS))) && logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_SOUTH_CHEST, logic->IsAdult && (logic->HasExplosives() || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS))) && logic->CanUse(RG_HOOKSHOT) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_SPIRIT_TEMPLE_MQ_UNDER_LIKE_LIKE, []{return logic->CanHitSwitch();}), @@ -280,7 +280,7 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM] = Region("Spirit Temple MQ Statue Room", SCENE_SPIRIT_TEMPLE, {}, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_MQ_COMPASS_CHEST, MQSpiritSharedStatueRoom(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return logic->CanHitEyeTargets();})), + LOCATION(RC_SPIRIT_TEMPLE_MQ_COMPASS_CHEST, MQSpiritSharedStatueRoom(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return logic->CanHitEyeTargets();}) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_3F_EAST_POT, MQSpiritSharedStatueRoom(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return ((logic->IsAdult || logic->CanJumpslash()) && logic->CanUse(RG_BOOMERANG)) || ((logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_SONG_OF_TIME) || (logic->IsAdult && ctx->GetTrickOption(RT_SPIRIT_LOBBY_JUMP))) && logic->CanBreakPots());})), LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_3F_WEST_POT, MQSpiritSharedStatueRoom(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_SONG_OF_TIME) || (logic->IsAdult && ctx->GetTrickOption(RT_SPIRIT_LOBBY_JUMP)) && logic->CanBreakPots());})), LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_2F_CENTER_EAST_POT, MQSpiritSharedStatueRoom(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return logic->CanBreakPots();})), @@ -304,7 +304,7 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM] = Region("Spirit Temple MQ Sun Block Room", SCENE_SPIRIT_TEMPLE, {}, { //Locations //We don't need Shared here because If we are checking as child, universe 2 adult access needs nothing so it always passes, and if we are checking as adult, it is Certain Access - LOCATION(RC_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM_CHEST, true), + LOCATION(RC_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_SUN_BLOCK_ROOM, MQSpiritSharedStatueRoom(RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM, []{return logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_SPIRIT_MQ_SUN_BLOCK_GS) && logic->CanUse(RG_BOOMERANG));})), LOCATION(RC_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_1, MQSpiritSharedStatueRoom(RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM, []{return logic->CanBreakPots();})), LOCATION(RC_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_2, MQSpiritSharedStatueRoom(RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM, []{return logic->CanBreakPots();})), @@ -323,7 +323,7 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_MQ_SILVER_GAUNTLETS_HAND] = Region("Spirit Temple MQ Silver Gauntlets Hand", SCENE_SPIRIT_TEMPLE, {}, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST, true), + LOCATION(RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST, logic->HasItem(RG_OPEN_CHEST)), }, { //Exits //If it is ever relevent for 1 age to spawn the mirror shield chest for the other can longshot across, it needs an eventAccess @@ -342,7 +342,7 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_NORTH] = Region("Spirit Temple MQ Block Room North", SCENE_SPIRIT_TEMPLE, {}, { //Locations //Does not need to be shared as it's hard child locked, because adult pushing the block is a permanent flag that blocks the eye target and cannot be undone - LOCATION(RC_SPIRIT_TEMPLE_MQ_SILVER_BLOCK_HALLWAY_CHEST, logic->IsChild && logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 7) && logic->CanHitEyeTargets()), + LOCATION(RC_SPIRIT_TEMPLE_MQ_SILVER_BLOCK_HALLWAY_CHEST, logic->IsChild && logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 7) && logic->CanHitEyeTargets() && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits //if going to RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_SOUTH from here is ever relevant, there needs to be an event to handle the block @@ -351,8 +351,8 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM_EAST] = Region("Spirit Temple MQ Statue Room East", SCENE_SPIRIT_TEMPLE, {}, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_ROOM_LULLABY_CHEST, logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_ZELDAS_LULLABY) && (logic->CanJumpslash() || logic->CanUse(RG_HOVER_BOOTS))), - LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_ROOM_INVISIBLE_CHEST, (ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS))), + LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_ROOM_LULLABY_CHEST, logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_ZELDAS_LULLABY) && (logic->CanJumpslash() || logic->CanUse(RG_HOVER_BOOTS)) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_ROOM_INVISIBLE_CHEST, (ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS)) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return true;}), @@ -404,7 +404,7 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_MQ_LEEVER_ROOM] = Region("Spirit Temple MQ Leever Room", SCENE_SPIRIT_TEMPLE, {}, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_MQ_LEEVER_ROOM_CHEST, logic->CanKillEnemy(RE_PURPLE_LEEVER) && logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_SPIRIT_TEMPLE_MQ_LEEVER_ROOM_CHEST, logic->CanKillEnemy(RE_PURPLE_LEEVER) && logic->CanUse(RG_HOOKSHOT) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_LEEVER_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)), }, { //Exits @@ -420,7 +420,7 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_MQ_AFTER_SYMPHONY_ROOM] = Region("Spirit Temple MQ After Symphony Room", SCENE_SPIRIT_TEMPLE, {}, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM_CHEST, logic->CanPassEnemy(RE_BIG_SKULLTULA)), + LOCATION(RC_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM_CHEST, logic->CanPassEnemy(RE_BIG_SKULLTULA) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_SYMPHONY_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)), }, { //Exits @@ -429,7 +429,7 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_MQ_FOUR_BEAMOS_ROOM] = Region("Spirit Temple MQ Four Beamos Room", SCENE_SPIRIT_TEMPLE, {}, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_MQ_BEAMOS_ROOM_CHEST, logic->CanKillEnemy(RE_BEAMOS)), + LOCATION(RC_SPIRIT_TEMPLE_MQ_BEAMOS_ROOM_CHEST, logic->CanKillEnemy(RE_BEAMOS) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_SPIRIT_TEMPLE_MQ_BEAMOS_SMALL_CRATE, logic->CanKillEnemy(RE_BEAMOS) && logic->CanUse(RG_SONG_OF_TIME) && logic->CanBreakSmallCrates()), }, { //Exits @@ -440,7 +440,7 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_MQ_SOT_SUN_ROOM] = Region("Spirit Temple MQ SoT Sun Room", SCENE_SPIRIT_TEMPLE, {}, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_MQ_CHEST_SWITCH_CHEST, true), + LOCATION(RC_SPIRIT_TEMPLE_MQ_CHEST_SWITCH_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_SPIRIT_TEMPLE_MQ_DINALFOS_ROOM_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)), }, { //Exits @@ -463,7 +463,7 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_MQ_MIRROR_SHIELD_HAND] = Region("Spirit Temple MQ Mirror Shield Hand", SCENE_SPIRIT_TEMPLE, {}, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST, true), + LOCATION(RC_SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST, logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_SPIRIT_TEMPLE_MQ_SILVER_GAUNTLETS_HAND, []{return logic->CanUse(RG_LONGSHOT);}), @@ -473,7 +473,7 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_MQ_3F_GIBDO_ROOM] = Region("Spirit Temple MQ 3F Gibdo Room", SCENE_SPIRIT_TEMPLE, {}, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_MQ_BOSS_KEY_CHEST, true), + LOCATION(RC_SPIRIT_TEMPLE_MQ_BOSS_KEY_CHEST, logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_SPIRIT_TEMPLE_MQ_SOT_SUN_ROOM, []{return true;}), @@ -530,7 +530,7 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CAVE] = Region("Spirit Temple MQ Big Mirror Cave", SCENE_SPIRIT_TEMPLE, {}, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_MQ_MIRROR_PUZZLE_INVISIBLE_CHEST, ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)), + LOCATION(RC_SPIRIT_TEMPLE_MQ_MIRROR_PUZZLE_INVISIBLE_CHEST, (ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits //If it's ever relevant to longshot into head from lobby, this needs to be an event access diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp index aee55c972a4..3c8c6bf8fe8 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp @@ -55,7 +55,7 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_MAP_ROOM] = Region("Water Temple Map Room", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_MAP_CHEST, logic->CanKillEnemy(RE_SPIKE, ED_CLOSE, true, 3)), + LOCATION(RC_WATER_TEMPLE_MAP_CHEST, logic->CanKillEnemy(RE_SPIKE, ED_CLOSE, true, 3) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_WATER_TEMPLE_EAST_LOWER, []{return logic->CanKillEnemy(RE_SPIKE, ED_CLOSE, true, 3);}), @@ -63,7 +63,7 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_CRACKED_WALL] = Region("Water Temple Cracked Wall", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_CRACKED_WALL_CHEST, logic->HasExplosives()), + LOCATION(RC_WATER_TEMPLE_CRACKED_WALL_CHEST, logic->HasExplosives() && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_WATER_TEMPLE_EAST_LOWER, []{return true;}), @@ -71,7 +71,7 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_TORCH_ROOM] = Region("Water Temple Torch Room", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_TORCHES_CHEST, logic->CanKillEnemy(RE_SHELL_BLADE, ED_CLOSE, true, 3)), + LOCATION(RC_WATER_TEMPLE_TORCHES_CHEST, logic->CanKillEnemy(RE_SHELL_BLADE, ED_CLOSE, true, 3) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_WATER_TEMPLE_EAST_LOWER, []{return logic->CanKillEnemy(RE_SHELL_BLADE, ED_CLOSE, true, 3);}), @@ -124,7 +124,7 @@ void RegionTable_Init_WaterTemple() { EventAccess(LOGIC_FAIRY_POT, []{return true;}), }, { //Locations - LOCATION(RC_WATER_TEMPLE_BOSS_KEY_CHEST, true), + LOCATION(RC_WATER_TEMPLE_BOSS_KEY_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_WATER_TEMPLE_BOSS_KEY_POT_1, logic->CanBreakPots()), LOCATION(RC_WATER_TEMPLE_BOSS_KEY_POT_2, logic->CanBreakPots()), }, { @@ -152,7 +152,7 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_DRAGON_ROOM] = Region("Water Temple Dragon Room", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_DRAGON_CHEST, (logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_IRON_BOOTS)) || (((logic->IsAdult && ctx->GetTrickOption(RT_WATER_ADULT_DRAGON) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_BOMBCHU_5))) || (logic->IsChild && ctx->GetTrickOption(RT_WATER_CHILD_DRAGON) && (logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_BOMBCHU_5)))) && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS)))), + LOCATION(RC_WATER_TEMPLE_DRAGON_CHEST, ((logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_IRON_BOOTS)) || (((logic->IsAdult && ctx->GetTrickOption(RT_WATER_ADULT_DRAGON) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_BOMBCHU_5))) || (logic->IsChild && ctx->GetTrickOption(RT_WATER_CHILD_DRAGON) && (logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_BOMBCHU_5)))) && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS)))) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_WATER_TEMPLE_WEST_LOWER, []{return true;}), @@ -179,7 +179,7 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_CENTRAL_PILLAR_BASEMENT] = Region("Water Temple Central Pillar Basement", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_CENTRAL_PILLAR_CHEST, logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 40), + LOCATION(RC_WATER_TEMPLE_CENTRAL_PILLAR_CHEST, logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 40 && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_WATER_TEMPLE_CENTRAL_PILLAR_LOWER, []{return logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16;}), @@ -187,7 +187,7 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_EAST_MIDDLE] = Region("Water Temple East Middle", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_COMPASS_CHEST, logic->CanUseProjectile()), + LOCATION(RC_WATER_TEMPLE_COMPASS_CHEST, logic->CanUseProjectile() && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_WATER_TEMPLE_NEAR_COMPASS_POT_1, logic->CanBreakPots()), LOCATION(RC_WATER_TEMPLE_NEAR_COMPASS_POT_2, logic->CanBreakPots()), LOCATION(RC_WATER_TEMPLE_NEAR_COMPASS_POT_3, logic->CanBreakPots()), @@ -212,7 +212,7 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_BLOCK_CORRIDOR] = Region("Water Temple Block Corridor", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_CENTRAL_BOW_TARGET_CHEST, logic->HasItem(RG_GORONS_BRACELET) && (logic->Get(LOGIC_WATER_LOW_FROM_HIGH) || logic->Get(LOGIC_WATER_MIDDLE))), + LOCATION(RC_WATER_TEMPLE_CENTRAL_BOW_TARGET_CHEST, logic->HasItem(RG_GORONS_BRACELET) && (logic->Get(LOGIC_WATER_LOW_FROM_HIGH) || logic->Get(LOGIC_WATER_MIDDLE)) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_WATER_TEMPLE_CENTRAL_BOW_POT_1, logic->CanBreakPots() && logic->HasItem(RG_GORONS_BRACELET) && (logic->Get(LOGIC_WATER_LOW_FROM_HIGH) || logic->Get(LOGIC_WATER_MIDDLE))), LOCATION(RC_WATER_TEMPLE_CENTRAL_BOW_POT_2, logic->CanBreakPots() && logic->HasItem(RG_GORONS_BRACELET) && (logic->Get(LOGIC_WATER_LOW_FROM_HIGH) || logic->Get(LOGIC_WATER_MIDDLE))), }, { @@ -247,7 +247,7 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_LONGSHOT_ROOM] = Region("Water Temple Longshot Room", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_LONGSHOT_CHEST, true), + LOCATION(RC_WATER_TEMPLE_LONGSHOT_CHEST, logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_WATER_TEMPLE_DARK_LINK_ROOM, []{return true;}), @@ -256,7 +256,7 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_RIVER] = Region("Water Temple River", SCENE_WATER_TEMPLE, {}, { //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_RIVER_CHEST, logic->CanHitEyeTargets() && (logic->IsAdult || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT)) && logic->HasItem(RG_OPEN_CHEST)), 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()), @@ -264,7 +264,7 @@ void RegionTable_Init_WaterTemple() { 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)), - LOCATION(RC_WATER_TEMPLE_DRAGON_CHEST, logic->IsAdult && logic->CanUse(RG_FAIRY_BOW) && ((ctx->GetTrickOption(RT_WATER_ADULT_DRAGON) && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))) || ctx->GetTrickOption(RT_WATER_DRAGON_JUMP_DIVE))), + LOCATION(RC_WATER_TEMPLE_DRAGON_CHEST, logic->IsAdult && logic->CanUse(RG_FAIRY_BOW) && ((ctx->GetTrickOption(RT_WATER_ADULT_DRAGON) && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))) || ctx->GetTrickOption(RT_WATER_DRAGON_JUMP_DIVE)) && logic->HasItem(RG_OPEN_CHEST)), }, { //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));}), @@ -381,8 +381,8 @@ void RegionTable_Init_WaterTemple() { //EventAccess(LOGIC_WATER_LOW_FROM_MIDDLE, []{return false;}), }, { //Locations - LOCATION(RC_WATER_TEMPLE_MQ_MAP_CHEST, logic->MQWaterLevel(WL_HIGH) && logic->HasFireSource() && logic->CanUse(RG_HOOKSHOT)), - LOCATION(RC_WATER_TEMPLE_MQ_LONGSHOT_CHEST, (logic->MQWaterLevel(WL_MID) && logic->CanUse(RG_HOOKSHOT)) || (logic->MQWaterLevel(WL_HIGH_OR_MID) && logic->CanOpenUnderwaterChest())), + LOCATION(RC_WATER_TEMPLE_MQ_MAP_CHEST, logic->MQWaterLevel(WL_HIGH) && logic->HasFireSource() && logic->CanUse(RG_HOOKSHOT) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_WATER_TEMPLE_MQ_LONGSHOT_CHEST, ((logic->MQWaterLevel(WL_MID) && logic->CanUse(RG_HOOKSHOT)) || (logic->MQWaterLevel(WL_HIGH_OR_MID) && logic->CanOpenUnderwaterChest())) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_WATER_TEMPLE_MQ_LOWER_TORCHES_POT_1, (logic->MQWaterLevel(WL_LOW) && logic->CanBreakPots()) || (logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT) && logic->WaterTimer() >= 16)), LOCATION(RC_WATER_TEMPLE_MQ_LOWER_TORCHES_POT_2, (logic->MQWaterLevel(WL_LOW) && logic->CanBreakPots()) || (logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT) && logic->WaterTimer() >= 16)), }, { @@ -392,7 +392,7 @@ void RegionTable_Init_WaterTemple() { //Raising the targets by clearing this room achieves nothing logically because it requires WL_LOW to do and hookshot to use, which implies access to WL_MID and WL_HIGH already areaTable[RR_WATER_TEMPLE_MQ_EAST_TOWER_1F_ROOM] = Region("Water Temple MQ East Tower 1F Room", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_MQ_COMPASS_CHEST, logic->CanKillEnemy(RE_LIZALFOS) && logic->CanKillEnemy(RE_SPIKE)), + LOCATION(RC_WATER_TEMPLE_MQ_COMPASS_CHEST, logic->CanKillEnemy(RE_LIZALFOS) && logic->CanKillEnemy(RE_SPIKE) && logic->HasItem(RG_OPEN_CHEST)), }, { Entrance(RR_WATER_TEMPLE_MQ_EAST_TOWER, []{return true;}), }); @@ -449,7 +449,7 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_B1_FINAL] = Region("Water Temple MQ Central Pillar B1 Final", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_CHEST, logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_CHEST, logic->CanUse(RG_HOOKSHOT) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_1, logic->CanBreakCrates()), LOCATION(RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_2, logic->CanBreakCrates()), LOCATION(RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_3, logic->CanBreakCrates()), @@ -698,7 +698,7 @@ void RegionTable_Init_WaterTemple() { //Exits Entrance(RR_WATER_TEMPLE_MQ_DRAGON_ROOM_DOOR, []{return true;}), Entrance(RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_PIT, []{return true;}), - Entrance(RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_CHEST, []{return logic->CanHitSwitch() && Here(RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_SWITCH, []{return logic->CanUse(RG_DINS_FIRE);});}), + Entrance(RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_CHEST, []{return logic->CanHitSwitch() && Here(RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_SWITCH, []{return logic->CanUse(RG_DINS_FIRE);}) && logic->HasItem(RG_OPEN_CHEST);}), }); //this exists for the crates in preparation for clips through the grate @@ -717,7 +717,7 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_CHEST] = Region("Water Temple MQ Boss Key Room Chest", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_MQ_BOSS_KEY_CHEST, true), + LOCATION(RC_WATER_TEMPLE_MQ_BOSS_KEY_CHEST, logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_SWITCH, []{return logic->CanHitSwitch(ED_BOMB_THROW) || logic->CanUse(RG_HOVER_BOOTS);}), @@ -733,7 +733,7 @@ void RegionTable_Init_WaterTemple() { }, {}, { //Exits Entrance(RR_WATER_TEMPLE_MQ_MAIN, []{return logic->Get(LOGIC_WATER_MQ_B1_SWITCH) && (logic->MQWaterLevel(WL_LOW) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16));}), - Entrance(RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_CHEST, []{return logic->CanUse(RG_IRON_BOOTS) && logic->HasItem(RG_BRONZE_SCALE) && (logic->MQWaterLevel(WL_LOW) || logic->WaterTimer() >= 24);}) + Entrance(RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_CHEST, []{return logic->CanUse(RG_IRON_BOOTS) && logic->HasItem(RG_BRONZE_SCALE) && (logic->MQWaterLevel(WL_LOW) || logic->WaterTimer() >= 24) && logic->HasItem(RG_OPEN_CHEST);}) }); areaTable[RR_WATER_TEMPLE_MQ_TRIANGLE_TORCH_ROOM] = Region("Water Temple MQ Triangle Torch Room", SCENE_WATER_TEMPLE, {}, diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_crater.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_crater.cpp index 15e80d6c261..89b12ca2689 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_crater.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_crater.cpp @@ -66,7 +66,7 @@ void RegionTable_Init_DeathMountainCrater() { areaTable[RR_DMC_CENTRAL_NEARBY] = Region("DMC Central Nearby", SCENE_DEATH_MOUNTAIN_CRATER, {}, { //Locations - LOCATION(RC_DMC_VOLCANO_FREESTANDING_POH, logic->IsAdult && logic->Hearts() >= 3 && (CanPlantBean(RR_DMC_CENTRAL_LOCAL) || (ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS)))), + LOCATION(RC_DMC_VOLCANO_FREESTANDING_POH, logic->IsAdult && logic->Hearts() >= 3 && (CanPlantBean(RR_DMC_CENTRAL_LOCAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL) || (ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS)))), LOCATION(RC_SHEIK_IN_CRATER, logic->IsAdult && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), }, { //Exits @@ -75,10 +75,10 @@ void RegionTable_Init_DeathMountainCrater() { areaTable[RR_DMC_CENTRAL_LOCAL] = Region("DMC Central Local", SCENE_DEATH_MOUNTAIN_CRATER, { //Events - EventAccess(LOGIC_BEAN_PLANT_FAIRY, []{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->FireTimer() >= 8 || logic->Hearts() >= 3);}), + EventAccess(LOGIC_BEAN_PLANT_FAIRY, []{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->FireTimer() >= 8 || logic->Hearts() >= 3);}), }, { //Locations - LOCATION(RC_DMC_GS_BEAN_PATCH, (logic->FireTimer() >= 8 || logic->Hearts() >= 3) && logic->CanSpawnSoilSkull() && logic->CanAttack()), + LOCATION(RC_DMC_GS_BEAN_PATCH, (logic->FireTimer() >= 8 || logic->Hearts() >= 3) && logic->CanSpawnSoilSkull(RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL) && 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)), @@ -87,14 +87,14 @@ void RegionTable_Init_DeathMountainCrater() { 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)), - LOCATION(RC_DMC_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), - LOCATION(RC_DMC_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), - LOCATION(RC_DMC_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), + LOCATION(RC_DMC_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), + LOCATION(RC_DMC_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), + LOCATION(RC_DMC_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS) && (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_DMC_LOWER_NEARBY, []{return (logic->IsAdult && CanPlantBean(RR_DMC_CENTRAL_LOCAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT);}), + Entrance(RR_DMC_UPPER_NEARBY, []{return logic->IsAdult && CanPlantBean(RR_DMC_CENTRAL_LOCAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL);}), 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);}), }); @@ -109,7 +109,7 @@ void RegionTable_Init_DeathMountainCrater() { areaTable[RR_DMC_UPPER_GROTTO] = Region("DMC Upper Grotto", SCENE_GROTTOS, grottoEvents, { //Locations - LOCATION(RC_DMC_UPPER_GROTTO_CHEST, true), + LOCATION(RC_DMC_UPPER_GROTTO_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_DMC_UPPER_GROTTO_FISH, logic->HasBottle()), LOCATION(RC_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), LOCATION(RC_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_trail.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_trail.cpp index 42fa22cf946..e166842d64c 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_trail.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_trail.cpp @@ -7,25 +7,25 @@ void RegionTable_Init_DeathMountainTrail() { // clang-format off areaTable[RR_DEATH_MOUNTAIN_TRAIL] = Region("Death Mountain", SCENE_DEATH_MOUNTAIN_TRAIL, { //Events - EventAccess(LOGIC_BEAN_PLANT_FAIRY, []{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET));}), + EventAccess(LOGIC_BEAN_PLANT_FAIRY, []{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET));}), }, { //Locations - LOCATION(RC_DMT_CHEST, logic->BlastOrSmash() || (ctx->GetTrickOption(RT_DMT_BOMBABLE) && logic->IsChild && logic->HasItem(RG_GORONS_BRACELET))), - LOCATION(RC_DMT_FREESTANDING_POH, logic->TakeDamage() || logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && CanPlantBean(RR_DEATH_MOUNTAIN_TRAIL) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET)))), - LOCATION(RC_DMT_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET) || (ctx->GetTrickOption(RT_DMT_SOIL_GS) && (logic->TakeDamage() || logic->CanUse(RG_HOVER_BOOTS)) && logic->CanUse(RG_BOOMERANG)))), + LOCATION(RC_DMT_CHEST, (logic->BlastOrSmash() || (ctx->GetTrickOption(RT_DMT_BOMBABLE) && logic->IsChild && logic->HasItem(RG_GORONS_BRACELET))) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_DMT_FREESTANDING_POH, logic->TakeDamage() || logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && CanPlantBean(RR_DEATH_MOUNTAIN_TRAIL, RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET)))), + LOCATION(RC_DMT_GS_BEAN_PATCH, logic->CanSpawnSoilSkull(RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL) && (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_HOOKSHOT_EXTENSION) && 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->CanJumpslash())) && logic->CanGetNightTimeGS()), + LOCATION(RC_DMT_GS_ABOVE_DODONGOS_CAVERN, logic->IsAdult && logic->AtNight && (logic->CanUse(RG_MEGATON_HAMMER) || (ctx->GetTrickOption(RT_HOOKSHOT_EXTENSION) && logic->CanUse(RG_HOOKSHOT)) || (ctx->GetTrickOption(RT_DMT_BEAN_LOWER_GS) && CanPlantBean(RR_DEATH_MOUNTAIN_TRAIL, RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL)) || (ctx->GetTrickOption(RT_DMT_HOVERS_LOWER_GS) && logic->CanUse(RG_HOVER_BOOTS)) || (ctx->GetTrickOption(RT_DMT_JS_LOWER_GS) && logic->CanJumpslash())) && logic->CanGetNightTimeGS()), LOCATION(RC_DMT_BLUE_RUPEE, logic->IsChild && logic->BlastOrSmash()), LOCATION(RC_DMT_RED_RUPEE, logic->IsChild && logic->BlastOrSmash()), - LOCATION(RC_DMT_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET))), - LOCATION(RC_DMT_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET))), - LOCATION(RC_DMT_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET))), + LOCATION(RC_DMT_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET))), + LOCATION(RC_DMT_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET))), + LOCATION(RC_DMT_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET))), LOCATION(RC_DMT_FLAG_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)), }, { //Exits Entrance(RR_KAK_BEHIND_GATE, []{return true;}), Entrance(RR_GORON_CITY, []{return true;}), - Entrance(RR_DEATH_MOUNTAIN_SUMMIT, []{return Here(RR_DEATH_MOUNTAIN_TRAIL, []{return logic->BlastOrSmash();}) || (logic->IsAdult && ((CanPlantBean(RR_DEATH_MOUNTAIN_TRAIL) && logic->HasItem(RG_GORONS_BRACELET)) || (logic->CanUse(RG_HOVER_BOOTS) && ctx->GetTrickOption(RT_DMT_CLIMB_HOVERS))));}), + Entrance(RR_DEATH_MOUNTAIN_SUMMIT, []{return Here(RR_DEATH_MOUNTAIN_TRAIL, []{return logic->BlastOrSmash();}) || (logic->IsAdult && ((CanPlantBean(RR_DEATH_MOUNTAIN_TRAIL, RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL) && logic->HasItem(RG_GORONS_BRACELET)) || (logic->CanUse(RG_HOVER_BOOTS) && ctx->GetTrickOption(RT_DMT_CLIMB_HOVERS))));}), Entrance(RR_DODONGOS_CAVERN_ENTRYWAY, []{return logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET) || logic->IsAdult;}), Entrance(RR_DMT_STORMS_GROTTO, []{return logic->CanOpenStormsGrotto();}), }); @@ -82,7 +82,7 @@ void RegionTable_Init_DeathMountainTrail() { areaTable[RR_DMT_STORMS_GROTTO] = Region("DMT Storms Grotto", SCENE_GROTTOS, grottoEvents, { //Locations - LOCATION(RC_DMT_STORMS_GROTTO_CHEST, true), + LOCATION(RC_DMT_STORMS_GROTTO_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_DMT_STORMS_GROTTO_FISH, logic->HasBottle()), LOCATION(RC_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), LOCATION(RC_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/desert_colossus.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/desert_colossus.cpp index 6f639d53953..7af296dcb92 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/desert_colossus.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/desert_colossus.cpp @@ -11,13 +11,13 @@ void RegionTable_Init_DesertColossus() { EventAccess(LOGIC_BUG_ROCK, []{return true;}), }, { //Locations - LOCATION(RC_COLOSSUS_FREESTANDING_POH, logic->IsAdult && CanPlantBean(RR_DESERT_COLOSSUS)), - LOCATION(RC_COLOSSUS_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && logic->CanAttack()), + LOCATION(RC_COLOSSUS_FREESTANDING_POH, logic->IsAdult && CanPlantBean(RR_DESERT_COLOSSUS, RG_DESERT_COLOSSUS_BEAN_SOUL)), + LOCATION(RC_COLOSSUS_GS_BEAN_PATCH, logic->CanSpawnSoilSkull(RG_DESERT_COLOSSUS_BEAN_SOUL) && logic->CanAttack()), LOCATION(RC_COLOSSUS_GS_TREE, logic->IsAdult && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), - LOCATION(RC_COLOSSUS_GS_HILL, logic->IsAdult && ((CanPlantBean(RR_DESERT_COLOSSUS) && logic->CanAttack()) || logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_COLOSSUS_GS) && logic->CanUse(RG_HOOKSHOT))) && logic->CanGetNightTimeGS()), - LOCATION(RC_COLOSSUS_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), - LOCATION(RC_COLOSSUS_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), - LOCATION(RC_COLOSSUS_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_COLOSSUS_GS_HILL, logic->IsAdult && ((CanPlantBean(RR_DESERT_COLOSSUS, RG_DESERT_COLOSSUS_BEAN_SOUL) && logic->CanAttack()) || logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_COLOSSUS_GS) && logic->CanUse(RG_HOOKSHOT))) && logic->CanGetNightTimeGS()), + LOCATION(RC_COLOSSUS_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DESERT_COLOSSUS_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_COLOSSUS_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DESERT_COLOSSUS_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_COLOSSUS_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DESERT_COLOSSUS_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_COLOSSUS_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), LOCATION(RC_COLOSSUS_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_COLOSSUS_GOSSIP_STONE, true), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp index 15f75ab8dd4..f21ab3cc2f1 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp @@ -152,7 +152,7 @@ void RegionTable_Init_GerudoFortress() { areaTable[RR_GF_NEAR_CHEST] = Region("GF Near Chest", SCENE_GERUDOS_FORTRESS, {}, { //Locations - LOCATION(RC_GF_CHEST, true), + LOCATION(RC_GF_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_GF_GS_TOP_FLOOR, logic->IsAdult && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG) && logic->CanGetNightTimeGS()), }, { //Exits diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp index f613e969a0e..3a054692536 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp @@ -24,15 +24,15 @@ void RegionTable_Init_GerudoValley() { areaTable[RR_GV_UPPER_STREAM] = Region("GV Upper Stream", SCENE_GERUDO_VALLEY, { //Events EventAccess(LOGIC_GOSSIP_STONE_FAIRY, []{return logic->CallGossipFairy();}), - EventAccess(LOGIC_BEAN_PLANT_FAIRY, []{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS);}), + EventAccess(LOGIC_BEAN_PLANT_FAIRY, []{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_GERUDO_VALLEY_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS);}), }, { //Locations - LOCATION(RC_GV_WATERFALL_FREESTANDING_POH, logic->IsChild || logic->HasItem(RG_BRONZE_SCALE)),//can use cucco as child - LOCATION(RC_GV_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && logic->CanAttack()), + LOCATION(RC_GV_WATERFALL_FREESTANDING_POH, logic->IsChild || logic->HasItem(RG_BRONZE_SCALE) || CanPlantBean(RR_GV_UPPER_STREAM, RG_GERUDO_VALLEY_BEAN_SOUL)),//can use cucco as child + LOCATION(RC_GV_GS_BEAN_PATCH, logic->CanSpawnSoilSkull(RG_GERUDO_VALLEY_BEAN_SOUL) && logic->CanAttack()), LOCATION(RC_GV_COW, logic->IsChild && logic->CanUse(RG_EPONAS_SONG)), - LOCATION(RC_GV_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), - LOCATION(RC_GV_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), - LOCATION(RC_GV_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_GV_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_GERUDO_VALLEY_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_GV_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_GERUDO_VALLEY_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_GV_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_GERUDO_VALLEY_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_GV_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), LOCATION(RC_GV_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_GV_GOSSIP_STONE, true), @@ -68,7 +68,7 @@ void RegionTable_Init_GerudoValley() { areaTable[RR_GV_FORTRESS_SIDE] = Region("GV Fortress Side", SCENE_GERUDO_VALLEY, {}, { //Locations - LOCATION(RC_GV_CHEST, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GV_CHEST, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_GV_TRADE_SAW, logic->IsAdult && logic->CanUse(RG_POACHERS_SAW)), LOCATION(RC_GV_GS_BEHIND_TENT, logic->IsAdult && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), LOCATION(RC_GV_GS_PILLAR, logic->IsAdult && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/goron_city.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/goron_city.cpp index 2e4fa2fbe92..107106239a3 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/goron_city.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/goron_city.cpp @@ -18,9 +18,9 @@ void RegionTable_Init_GoronCity() { (ctx->GetTrickOption(RT_GC_LINK_GORON_DINS) && (logic->CanUse(RG_DINS_FIRE) || (ctx->GetTrickOption(RT_BLUE_FIRE_MUD_WALLS) && logic->CanUse(RG_BOTTLE_WITH_BLUE_FIRE)))));}), }, { //Locations - LOCATION(RC_GC_MAZE_LEFT_CHEST, logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_SILVER_GAUNTLETS) || (ctx->GetTrickOption(RT_GC_LEFTMOST) && logic->HasExplosives() && logic->CanUse(RG_HOVER_BOOTS))), - LOCATION(RC_GC_MAZE_CENTER_CHEST, logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)), - LOCATION(RC_GC_MAZE_RIGHT_CHEST, logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_LEFT_CHEST, (logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_SILVER_GAUNTLETS) || (ctx->GetTrickOption(RT_GC_LEFTMOST) && logic->HasExplosives() && logic->CanUse(RG_HOVER_BOOTS))) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GC_MAZE_CENTER_CHEST, (logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GC_MAZE_RIGHT_CHEST, (logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_GC_POT_FREESTANDING_POH, logic->IsChild && logic->Get(LOGIC_GORON_CITY_CHILD_FIRE) && (logic->CanUse(RG_BOMB_BAG) || (logic->HasItem(RG_GORONS_BRACELET) && ctx->GetTrickOption(RT_GC_POT_STRENGTH)) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_GC_POT)))), LOCATION(RC_GC_ROLLING_GORON_AS_CHILD, logic->IsChild && (logic->HasExplosives() || (logic->HasItem(RG_GORONS_BRACELET) && ctx->GetTrickOption(RT_GC_ROLLING_STRENGTH)))), LOCATION(RC_GC_ROLLING_GORON_AS_ADULT, logic->Get(LOGIC_GORON_CITY_STOP_ROLLING_GORON_AS_ADULT)), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp index 94a2c85c834..95046874fd0 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp @@ -13,13 +13,13 @@ void RegionTable_Init_Graveyard() { EventAccess(LOGIC_BORROW_BUNNY_HOOD, []{return logic->IsChild && logic->AtDay && logic->Get(LOGIC_BORROW_SPOOKY_MASK) && logic->HasItem(RG_CHILD_WALLET);}), }, { //Locations - LOCATION(RC_GRAVEYARD_FREESTANDING_POH, (((logic->IsAdult && CanPlantBean(RR_THE_GRAVEYARD)) || logic->CanUse(RG_LONGSHOT)) && logic->CanBreakCrates()) || (ctx->GetTrickOption(RT_GY_POH) && logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_GRAVEYARD_FREESTANDING_POH, (((logic->IsAdult && CanPlantBean(RR_THE_GRAVEYARD, RG_GRAVEYARD_BEAN_SOUL)) || logic->CanUse(RG_LONGSHOT)) && logic->CanBreakCrates()) || (ctx->GetTrickOption(RT_GY_POH) && logic->CanUse(RG_BOOMERANG))), LOCATION(RC_GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR, logic->HasItem(RG_CHILD_WALLET) && logic->IsChild && logic->AtNight), //TODO: This needs to change LOCATION(RC_GRAVEYARD_GS_WALL, logic->IsChild && logic->HookshotOrBoomerang() && logic->AtNight && logic->CanGetNightTimeGS()), - LOCATION(RC_GRAVEYARD_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && logic->CanAttack()), - LOCATION(RC_GRAVEYARD_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), - LOCATION(RC_GRAVEYARD_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), - LOCATION(RC_GRAVEYARD_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_GRAVEYARD_GS_BEAN_PATCH, logic->CanSpawnSoilSkull(RG_GRAVEYARD_BEAN_SOUL) && logic->CanAttack()), + LOCATION(RC_GRAVEYARD_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_GRAVEYARD_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_GRAVEYARD_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_GRAVEYARD_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_GRAVEYARD_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_GRAVEYARD_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_GY_GRASS_1, logic->CanCutShrubs()), LOCATION(RC_GY_GRASS_2, logic->CanCutShrubs()), LOCATION(RC_GY_GRASS_3, logic->CanCutShrubs()), @@ -32,7 +32,7 @@ void RegionTable_Init_Graveyard() { LOCATION(RC_GY_GRASS_10, logic->CanCutShrubs()), LOCATION(RC_GY_GRASS_11, logic->CanCutShrubs()), LOCATION(RC_GY_GRASS_12, logic->CanCutShrubs()), - LOCATION(RC_GRAVEYARD_CRATE, ((logic->IsAdult && CanPlantBean(RR_THE_GRAVEYARD)) || logic->CanUse(RG_LONGSHOT)) && logic->CanBreakCrates()), + LOCATION(RC_GRAVEYARD_CRATE, ((logic->IsAdult && CanPlantBean(RR_THE_GRAVEYARD, RG_GRAVEYARD_BEAN_SOUL)) || logic->CanUse(RG_LONGSHOT)) && logic->CanBreakCrates()), }, { //Exits Entrance(RR_GRAVEYARD_SHIELD_GRAVE, []{return logic->IsAdult || logic->AtNight;}), @@ -46,7 +46,7 @@ void RegionTable_Init_Graveyard() { areaTable[RR_GRAVEYARD_SHIELD_GRAVE] = Region("Graveyard Shield Grave", SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, {}, { //Locations - LOCATION(RC_GRAVEYARD_SHIELD_GRAVE_CHEST, true), + LOCATION(RC_GRAVEYARD_SHIELD_GRAVE_CHEST, logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_THE_GRAVEYARD, []{return true;}), @@ -70,7 +70,7 @@ void RegionTable_Init_Graveyard() { areaTable[RR_GRAVEYARD_HEART_PIECE_GRAVE] = Region("Graveyard Heart Piece Grave", SCENE_REDEAD_GRAVE, {}, { //Locations - LOCATION(RC_GRAVEYARD_HEART_PIECE_GRAVE_CHEST, logic->CanUse(RG_SUNS_SONG)), + LOCATION(RC_GRAVEYARD_HEART_PIECE_GRAVE_CHEST, logic->CanUse(RG_SUNS_SONG) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_THE_GRAVEYARD, []{return true;}), @@ -78,7 +78,7 @@ void RegionTable_Init_Graveyard() { areaTable[RR_GRAVEYARD_COMPOSERS_GRAVE] = Region("Graveyard Composers Grave", SCENE_ROYAL_FAMILYS_TOMB, {}, { //Locations - LOCATION(RC_GRAVEYARD_ROYAL_FAMILYS_TOMB_CHEST, logic->HasFireSource()), + LOCATION(RC_GRAVEYARD_ROYAL_FAMILYS_TOMB_CHEST, logic->HasFireSource() && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_SONG_FROM_ROYAL_FAMILYS_TOMB, logic->CanUseProjectile() || logic->CanJumpslash()), LOCATION(RC_GRAVEYARD_ROYAL_FAMILYS_TOMB_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)), }, { @@ -92,7 +92,7 @@ void RegionTable_Init_Graveyard() { EventAccess(LOGIC_DAMPES_WINDMILL_ACCESS, []{return logic->IsAdult && logic->CanUse(RG_SONG_OF_TIME);}), }, { //Locations - LOCATION(RC_GRAVEYARD_HOOKSHOT_CHEST, true), + LOCATION(RC_GRAVEYARD_HOOKSHOT_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_GRAVEYARD_DAMPE_RACE_FREESTANDING_POH, logic->IsAdult || ctx->GetTrickOption(RT_GY_CHILD_DAMPE_RACE_POH)), LOCATION(RC_GY_DAMPES_GRAVE_POT_1, logic->CanBreakPots()), LOCATION(RC_GY_DAMPES_GRAVE_POT_2, logic->CanBreakPots()), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/haunted_wasteland.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/haunted_wasteland.cpp index 20ae6155537..dc50674ce32 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/haunted_wasteland.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/haunted_wasteland.cpp @@ -22,7 +22,7 @@ void RegionTable_Init_HauntedWasteland() { EventAccess(LOGIC_CARPET_MERCHANT, []{return logic->HasItem(RG_ADULT_WALLET) && CanBuyAnother(RC_WASTELAND_BOMBCHU_SALESMAN) && (logic->CanJumpslash() || logic->CanUse(RG_HOVER_BOOTS));}), }, { //Locations - LOCATION(RC_WASTELAND_CHEST, logic->HasFireSource()), + LOCATION(RC_WASTELAND_CHEST, logic->HasFireSource() && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_WASTELAND_BOMBCHU_SALESMAN, logic->CanJumpslash() || logic->CanUse(RG_HOVER_BOOTS)), LOCATION(RC_WASTELAND_GS, logic->HookshotOrBoomerang() || (logic->IsAdult && ctx->GetTrickOption(RT_GROUND_JUMP_HARD) && logic->CanGroundJump() && logic->CanJumpslash())), // need to jumpslash immediately with two handed weapons LOCATION(RC_WASTELAND_NEAR_GS_POT_1, logic->CanBreakPots()), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp index 6c23dbcb840..d8722fa8681 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp @@ -110,6 +110,64 @@ void RegionTable_Init_HyruleField() { LOCATION(RC_HF_CHILD_SOUTHEAST_TREE_5, logic->IsChild && logic->CanBonkTrees()), LOCATION(RC_HF_CHILD_SOUTHEAST_TREE_6, logic->IsChild && logic->CanBonkTrees()), LOCATION(RC_HF_TEKTITE_GROTTO_TREE, logic->CanBonkTrees()), + LOCATION(RC_HF_BUSH_NEAR_LAKE_1, true), + LOCATION(RC_HF_BUSH_NEAR_LAKE_2, true), + LOCATION(RC_HF_BUSH_NEAR_LAKE_3, true), + LOCATION(RC_HF_BUSH_NEAR_LAKE_4, true), + LOCATION(RC_HF_BUSH_NEAR_LAKE_5, true), + LOCATION(RC_HF_BUSH_NEAR_LAKE_6, true), + LOCATION(RC_HF_BUSH_NEAR_LAKE_7, true), + LOCATION(RC_HF_BUSH_NEAR_LAKE_8, true), + LOCATION(RC_HF_BUSH_NEAR_LAKE_9, true), + LOCATION(RC_HF_BUSH_NEAR_LAKE_10, true), + LOCATION(RC_HF_BUSH_NEAR_LAKE_11, true), + LOCATION(RC_HF_NORTHERN_BUSH_1, true), + LOCATION(RC_HF_NORTHERN_BUSH_2, true), + LOCATION(RC_HF_NORTHERN_BUSH_3, true), + LOCATION(RC_HF_NORTHERN_BUSH_4, true), + LOCATION(RC_HF_NORTHERN_BUSH_5, true), + LOCATION(RC_HF_NORTHERN_BUSH_6, true), + LOCATION(RC_HF_CHILD_NORTHERN_BUSH_1, logic->IsChild), + LOCATION(RC_HF_CHILD_NORTHERN_BUSH_2, logic->IsChild), + LOCATION(RC_HF_CHILD_NORTHERN_BUSH_3, logic->IsChild), + LOCATION(RC_HF_CHILD_NORTHERN_BUSH_4, logic->IsChild), + LOCATION(RC_HF_CHILD_NORTHERN_BUSH_5, logic->IsChild), + LOCATION(RC_HF_CHILD_NORTHERN_BUSH_6, logic->IsChild), + LOCATION(RC_HF_CHILD_NORTHERN_BUSH_7, logic->IsChild), + LOCATION(RC_HF_CHILD_NORTHERN_BUSH_8, logic->IsChild), + LOCATION(RC_HF_CHILD_NORTHERN_BUSH_9, logic->IsChild), + LOCATION(RC_HF_CHILD_NORTHERN_BUSH_10, logic->IsChild), + LOCATION(RC_HF_CHILD_NORTHERN_BUSH_11, logic->IsChild), + LOCATION(RC_HF_BUSH_BY_ROCKY_PATH_1, true), + LOCATION(RC_HF_BUSH_BY_ROCKY_PATH_2, true), + LOCATION(RC_HF_BUSH_BY_ROCKY_PATH_3, true), + LOCATION(RC_HF_BUSH_BY_ROCKY_PATH_4, true), + LOCATION(RC_HF_BUSH_BY_ROCKY_PATH_5, true), + LOCATION(RC_HF_BUSH_BY_ROCKY_PATH_6, true), + LOCATION(RC_HF_SOUTHERN_BUSH_1, true), + LOCATION(RC_HF_SOUTHERN_BUSH_2, true), + LOCATION(RC_HF_SOUTHERN_BUSH_3, true), + LOCATION(RC_HF_SOUTHERN_BUSH_4, true), + LOCATION(RC_HF_SOUTHERN_BUSH_5, true), + LOCATION(RC_HF_SOUTHERN_BUSH_6, true), + LOCATION(RC_HF_SOUTHERN_BUSH_7, true), + LOCATION(RC_HF_SOUTHERN_BUSH_8, true), + LOCATION(RC_HF_SOUTHERN_BUSH_9, true), + LOCATION(RC_HF_SOUTHERN_BUSH_10, true), + LOCATION(RC_HF_SOUTHERN_BUSH_11, true), + LOCATION(RC_HF_SOUTHERN_BUSH_12, true), + LOCATION(RC_HF_CHILD_SOUTHERN_BUSH_1, logic->IsChild), + LOCATION(RC_HF_CHILD_SOUTHERN_BUSH_2, logic->IsChild), + LOCATION(RC_HF_CHILD_SOUTHERN_BUSH_3, logic->IsChild), + LOCATION(RC_HF_CHILD_SOUTHERN_BUSH_4, logic->IsChild), + LOCATION(RC_HF_CHILD_SOUTHERN_BUSH_5, logic->IsChild), + LOCATION(RC_HF_CHILD_SOUTHERN_BUSH_6, logic->IsChild), + LOCATION(RC_HF_CHILD_SOUTHERN_BUSH_7, logic->IsChild), + LOCATION(RC_HF_CHILD_SOUTHERN_BUSH_8, logic->IsChild), + LOCATION(RC_HF_CHILD_SOUTHERN_BUSH_9, logic->IsChild), + LOCATION(RC_HF_CHILD_SOUTHERN_BUSH_10, logic->IsChild), + LOCATION(RC_HF_CHILD_SOUTHERN_BUSH_11, logic->IsChild), + LOCATION(RC_HF_CHILD_SOUTHERN_BUSH_12, logic->IsChild), }, { //Exits Entrance(RR_LW_BRIDGE, []{return true;}), @@ -131,7 +189,7 @@ void RegionTable_Init_HyruleField() { areaTable[RR_HF_SOUTHEAST_GROTTO] = Region("HF Southeast Grotto", SCENE_GROTTOS, grottoEvents, { //Locations - LOCATION(RC_HF_SOUTHEAST_GROTTO_CHEST, true), + LOCATION(RC_HF_SOUTHEAST_GROTTO_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_HF_SOUTHEAST_GROTTO_FISH, logic->HasBottle()), LOCATION(RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), LOCATION(RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), @@ -149,7 +207,7 @@ void RegionTable_Init_HyruleField() { areaTable[RR_HF_OPEN_GROTTO] = Region("HF Open Grotto", SCENE_GROTTOS, grottoEvents, { //Locations - LOCATION(RC_HF_OPEN_GROTTO_CHEST, true), + LOCATION(RC_HF_OPEN_GROTTO_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_HF_OPEN_GROTTO_FISH, logic->HasBottle()), LOCATION(RC_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), LOCATION(RC_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), @@ -203,7 +261,7 @@ void RegionTable_Init_HyruleField() { areaTable[RR_HF_NEAR_MARKET_GROTTO] = Region("HF Near Market Grotto", SCENE_GROTTOS, grottoEvents, { //Locations - LOCATION(RC_HF_NEAR_MARKET_GROTTO_CHEST, true), + LOCATION(RC_HF_NEAR_MARKET_GROTTO_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_HF_NEAR_MARKET_GROTTO_FISH, logic->HasBottle()), LOCATION(RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), LOCATION(RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp index 6b39ddfc67d..53a36dfb589 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp @@ -238,7 +238,7 @@ void RegionTable_Init_Kakariko() { areaTable[RR_KAK_REDEAD_GROTTO] = Region("Kak Redead Grotto", SCENE_GROTTOS, {}, { //Locations - LOCATION(RC_KAK_REDEAD_GROTTO_CHEST, logic->CanKillEnemy(RE_REDEAD, ED_CLOSE, true, 2)), + LOCATION(RC_KAK_REDEAD_GROTTO_CHEST, logic->CanKillEnemy(RE_REDEAD, ED_CLOSE, true, 2) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_KAKARIKO_VILLAGE, []{return true;}), @@ -246,7 +246,7 @@ void RegionTable_Init_Kakariko() { areaTable[RR_KAK_OPEN_GROTTO] = Region("Kak Open Grotto", SCENE_GROTTOS, grottoEvents, { //Locations - LOCATION(RC_KAK_OPEN_GROTTO_CHEST, true), + LOCATION(RC_KAK_OPEN_GROTTO_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_KAK_OPEN_GROTTO_FISH, logic->HasBottle()), LOCATION(RC_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), LOCATION(RC_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp index 8c548745a79..7cdedbd7879 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp @@ -7,18 +7,18 @@ void RegionTable_Init_KokiriForest() { // clang-format off areaTable[RR_KOKIRI_FOREST] = Region("Kokiri Forest", SCENE_KOKIRI_FOREST, { //Events - EventAccess(LOGIC_BEAN_PLANT_FAIRY, []{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS);}), + EventAccess(LOGIC_BEAN_PLANT_FAIRY, []{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_KOKIRI_FOREST_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS);}), EventAccess(LOGIC_GOSSIP_STONE_FAIRY, []{return logic->CallGossipFairyExceptSuns();}), EventAccess(LOGIC_SHOWED_MIDO_SWORD_AND_SHIELD, []{return logic->IsChild && logic->CanUse(RG_KOKIRI_SWORD) && logic->CanUse(RG_DEKU_SHIELD);}), }, { //Locations - LOCATION(RC_KF_KOKIRI_SWORD_CHEST, logic->IsChild), + LOCATION(RC_KF_KOKIRI_SWORD_CHEST, logic->IsChild && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_KF_GS_KNOW_IT_ALL_HOUSE, logic->IsChild && logic->CanAttack() && logic->CanGetNightTimeGS()), - LOCATION(RC_KF_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && logic->CanAttack()), + LOCATION(RC_KF_GS_BEAN_PATCH, logic->CanSpawnSoilSkull(RG_KOKIRI_FOREST_BEAN_SOUL) && logic->CanAttack()), LOCATION(RC_KF_GS_HOUSE_OF_TWINS, logic->IsAdult && (logic->HookshotOrBoomerang() || (ctx->GetTrickOption(RT_KF_ADULT_GS) && logic->CanUse(RG_HOVER_BOOTS))) && logic->CanGetNightTimeGS()), - LOCATION(RC_KF_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), - LOCATION(RC_KF_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), - LOCATION(RC_KF_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_KF_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_KOKIRI_FOREST_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_KF_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_KOKIRI_FOREST_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_KF_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_KOKIRI_FOREST_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_KF_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()), LOCATION(RC_KF_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_KF_BRIDGE_RUPEE, logic->IsChild), @@ -29,13 +29,13 @@ void RegionTable_Init_KokiriForest() { 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_BEAN_RUPEE_1, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_2, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_3, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_4, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_5, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_6, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RED_RUPEE, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || 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), @@ -120,10 +120,10 @@ void RegionTable_Init_KokiriForest() { areaTable[RR_KF_MIDOS_HOUSE] = Region("KF Mido's House", SCENE_MIDOS_HOUSE, {}, { //Locations - LOCATION(RC_KF_MIDOS_TOP_LEFT_CHEST, true), - LOCATION(RC_KF_MIDOS_TOP_RIGHT_CHEST, true), - LOCATION(RC_KF_MIDOS_BOTTOM_LEFT_CHEST, true), - LOCATION(RC_KF_MIDOS_BOTTOM_RIGHT_CHEST, true), + LOCATION(RC_KF_MIDOS_TOP_LEFT_CHEST, logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_KF_MIDOS_TOP_RIGHT_CHEST, logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_KF_MIDOS_BOTTOM_LEFT_CHEST, logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_KF_MIDOS_BOTTOM_RIGHT_CHEST, logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_KOKIRI_FOREST, []{return true;}), @@ -175,7 +175,7 @@ void RegionTable_Init_KokiriForest() { areaTable[RR_KF_STORMS_GROTTO] = Region("KF Storms Grotto", SCENE_GROTTOS, grottoEvents, { //Locations - LOCATION(RC_KF_STORMS_GROTTO_CHEST, true), + LOCATION(RC_KF_STORMS_GROTTO_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_KF_STORMS_GROTTO_FISH, logic->HasBottle()), LOCATION(RC_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), LOCATION(RC_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp index f88a2cb6a1c..15a6a07cca1 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp @@ -8,7 +8,7 @@ void RegionTable_Init_LakeHylia() { areaTable[RR_LAKE_HYLIA] = Region("Lake Hylia", SCENE_LAKE_HYLIA, { //Events EventAccess(LOGIC_GOSSIP_STONE_FAIRY, []{return logic->CallGossipFairy();}), - EventAccess(LOGIC_BEAN_PLANT_FAIRY, []{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS);}), + EventAccess(LOGIC_BEAN_PLANT_FAIRY, []{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_LAKE_HYLIA_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS);}), EventAccess(LOGIC_BUTTERFLY_FAIRY, []{return logic->CanUse(RG_STICKS);}), EventAccess(LOGIC_BUG_SHRUB, []{return logic->IsChild && logic->CanCutShrubs();}), EventAccess(LOGIC_CHILD_SCARECROW, []{return logic->IsChild && logic->HasItem(RG_FAIRY_OCARINA) && logic->OcarinaButtons() >= 2;}), @@ -17,17 +17,17 @@ void RegionTable_Init_LakeHylia() { //Locations LOCATION(RC_LH_UNDERWATER_ITEM, logic->IsChild && logic->HasItem(RG_SILVER_SCALE)), LOCATION(RC_LH_SUN, logic->IsAdult && ((logic->Get(LOGIC_WATER_TEMPLE_CLEAR) && logic->HasItem(RG_BRONZE_SCALE)) || logic->CanUse(RG_DISTANT_SCARECROW)) && logic->CanUse(RG_FAIRY_BOW)), - LOCATION(RC_LH_FREESTANDING_POH, logic->IsAdult && (logic->CanUse(RG_SCARECROW) || CanPlantBean(RR_LAKE_HYLIA))), - LOCATION(RC_LH_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)), + LOCATION(RC_LH_FREESTANDING_POH, logic->IsAdult && (logic->CanUse(RG_SCARECROW) || CanPlantBean(RR_LAKE_HYLIA, RG_LAKE_HYLIA_BEAN_SOUL))), + LOCATION(RC_LH_GS_BEAN_PATCH, logic->CanSpawnSoilSkull(RG_LAKE_HYLIA_BEAN_SOUL) && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)), LOCATION(RC_LH_GS_LAB_WALL, logic->IsChild && (logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG) || (ctx->GetTrickOption(RT_LH_LAB_WALL_GS) && logic->CanJumpslashExceptHammer())) && logic->CanGetNightTimeGS()), LOCATION(RC_LH_GS_SMALL_ISLAND, logic->IsChild && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA) && logic->CanGetNightTimeGS() && logic->HasItem(RG_BRONZE_SCALE)), LOCATION(RC_LH_GS_TREE, logic->IsAdult && logic->CanUse(RG_LONGSHOT) && 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_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), - LOCATION(RC_LH_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), - LOCATION(RC_LH_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_LH_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_LAKE_HYLIA_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_LH_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_LAKE_HYLIA_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_LH_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_LAKE_HYLIA_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_LH_LAB_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), LOCATION(RC_LH_LAB_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), //You can walk along the edge of the lake to get these without swimming, the fairy is created going backwards, which is convenient here @@ -86,7 +86,7 @@ void RegionTable_Init_LakeHylia() { Entrance(RR_HYRULE_FIELD, []{return true;}), Entrance(RR_LH_FROM_SHORTCUT, []{return true;}), Entrance(RR_LH_OWL_FLIGHT, []{return logic->IsChild;}), - Entrance(RR_LH_FISHING_ISLAND, []{return ((logic->IsChild || logic->Get(LOGIC_WATER_TEMPLE_CLEAR)) && logic->HasItem(RG_BRONZE_SCALE)) || (logic->IsAdult && (logic->CanUse(RG_SCARECROW) || CanPlantBean(RR_LAKE_HYLIA)));}), + Entrance(RR_LH_FISHING_ISLAND, []{return ((logic->IsChild || logic->Get(LOGIC_WATER_TEMPLE_CLEAR)) && logic->HasItem(RG_BRONZE_SCALE)) || (logic->IsAdult && (logic->CanUse(RG_SCARECROW) || CanPlantBean(RR_LAKE_HYLIA, RG_LAKE_HYLIA_BEAN_SOUL)));}), Entrance(RR_LH_LAB, []{return logic->CanOpenOverworldDoor(RG_HYLIA_LAB_KEY);}), Entrance(RR_LH_FROM_WATER_TEMPLE, []{return true;}), Entrance(RR_LH_GROTTO, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/lost_woods.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/lost_woods.cpp index dc6d84875eb..20fc86e42bf 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/lost_woods.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/lost_woods.cpp @@ -33,7 +33,7 @@ void RegionTable_Init_LostWoods() { LOCATION(RC_LW_OCARINA_MEMORY_GAME, logic->IsChild && logic->HasItem(RG_FAIRY_OCARINA) && logic->OcarinaButtons() >= 5), 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()), + LOCATION(RC_LW_GS_BEAN_PATCH_NEAR_BRIDGE, logic->CanSpawnSoilSkull(RG_LOST_WOODS_BRIDGE_BEAN_SOUL) && 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))), @@ -43,9 +43,9 @@ void RegionTable_Init_LostWoods() { 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_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), - LOCATION(RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), - LOCATION(RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_LOST_WOODS_BRIDGE_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_LOST_WOODS_BRIDGE_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_LOST_WOODS_BRIDGE_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_LW_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()), LOCATION(RC_LW_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_LW_SHORTCUT_STORMS_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)), @@ -57,7 +57,7 @@ void RegionTable_Init_LostWoods() { //Exits Entrance(RR_LW_FOREST_EXIT, []{return true;}), Entrance(RR_GC_WOODS_WARP, []{return true;}), - Entrance(RR_LW_BRIDGE, []{return (logic->IsAdult && (CanPlantBean(RR_THE_LOST_WOODS) || ctx->GetTrickOption(RT_LW_BRIDGE))) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_LONGSHOT);}), + Entrance(RR_LW_BRIDGE, []{return (logic->IsAdult && (CanPlantBean(RR_THE_LOST_WOODS, RG_LOST_WOODS_BRIDGE_BEAN_SOUL) || ctx->GetTrickOption(RT_LW_BRIDGE))) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_LONGSHOT);}), Entrance(RR_ZR_FROM_SHORTCUT, []{return logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS) || (ctx->GetTrickOption(RT_LOST_WOOD_NAVI_DIVE) && logic->IsChild && logic->HasItem(RG_BRONZE_SCALE) && logic->CanJumpslash());}), Entrance(RR_LW_BEYOND_MIDO, []{return logic->IsChild || logic->CanUse(RG_SARIAS_SONG) || ctx->GetTrickOption(RT_LW_MIDO_BACKFLIP);}), Entrance(RR_LW_NEAR_SHORTCUTS_GROTTO, []{return Here(RR_THE_LOST_WOODS, []{return logic->BlastOrSmash();});}), @@ -65,17 +65,18 @@ void RegionTable_Init_LostWoods() { areaTable[RR_LW_BEYOND_MIDO] = Region("LW Beyond Mido", SCENE_LOST_WOODS, { //Events - EventAccess(LOGIC_BUTTERFLY_FAIRY, []{return logic->CanUse(RG_STICKS);}), + EventAccess(LOGIC_BUTTERFLY_FAIRY, []{return logic->CanUse(RG_STICKS);}), + EventAccess(LOGIC_BEAN_PLANT_FAIRY, []{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_LOST_WOODS_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS);}), }, { //Locations LOCATION(RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, logic->IsChild && logic->CanStunDeku()), LOCATION(RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, logic->IsChild && logic->CanStunDeku()), - LOCATION(RC_LW_GS_ABOVE_THEATER, logic->IsAdult && ((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_GS_ABOVE_THEATER, logic->IsAdult && ((CanPlantBean(RR_LW_BEYOND_MIDO, RG_LOST_WOODS_BEAN_SOUL) && 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(RG_LOST_WOODS_BEAN_SOUL) && (logic->CanAttack() || (ctx->GetOption(RSK_SHUFFLE_SCRUBS).Is(RO_SCRUBS_OFF) && logic->CanReflectNuts()))), LOCATION(RC_LW_BOULDER_RUPEE, logic->BlastOrSmash()), - LOCATION(RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_1, logic->IsChild && logic->HasItem(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), - LOCATION(RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_2, logic->IsChild && logic->HasItem(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), - LOCATION(RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_3, logic->IsChild && logic->HasItem(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_1, logic->IsChild && logic->HasItem(RG_MAGIC_BEAN) && logic->HasItem(RG_LOST_WOODS_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_2, logic->IsChild && logic->HasItem(RG_MAGIC_BEAN) && logic->HasItem(RG_LOST_WOODS_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_3, logic->IsChild && logic->HasItem(RG_MAGIC_BEAN) && logic->HasItem(RG_LOST_WOODS_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_LW_GRASS_4, logic->CanCutShrubs()), LOCATION(RC_LW_GRASS_5, logic->CanCutShrubs()), LOCATION(RC_LW_GRASS_6, logic->CanCutShrubs()), @@ -93,7 +94,7 @@ void RegionTable_Init_LostWoods() { areaTable[RR_LW_NEAR_SHORTCUTS_GROTTO] = Region("LW Near Shortcuts Grotto", SCENE_GROTTOS, grottoEvents, { //Locations - LOCATION(RC_LW_NEAR_SHORTCUTS_GROTTO_CHEST, true), + LOCATION(RC_LW_NEAR_SHORTCUTS_GROTTO_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_LW_NEAR_SHORTCUTS_GROTTO_FISH, logic->HasBottle()), LOCATION(RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), LOCATION(RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp index 982601b3c03..70fed912fb0 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp @@ -193,17 +193,17 @@ void RegionTable_Init_Market() { areaTable[RR_MARKET_TREASURE_CHEST_GAME] = Region("Market Treasure Chest Game", SCENE_TREASURE_BOX_SHOP, {}, { //Locations LOCATION(RC_GREG_HINT, logic->HasItem(RG_CHILD_WALLET)), - 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(SCENE_TREASURE_BOX_SHOP, 6)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 1)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_1, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 1)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 1)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_2, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 2)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 2)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_3, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 3)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_3, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 3)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_4, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 4)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_4, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 4)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_5, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 5)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), - LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 5)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_REWARD, logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_OPEN_CHEST) && ((logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 6)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 1)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_1, logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_OPEN_CHEST) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 1)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1, logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_OPEN_CHEST) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 1)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_2, logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_OPEN_CHEST) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 2)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2, logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_OPEN_CHEST) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 2)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_3, logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_OPEN_CHEST) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 3)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_3, logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_OPEN_CHEST) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 3)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_4, logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_OPEN_CHEST) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 4)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_4, logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_OPEN_CHEST) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 4)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_5, logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_OPEN_CHEST) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 5)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5, logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_OPEN_CHEST) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 5)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(SCENE_TREASURE_BOX_SHOP, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), }, { //Exits Entrance(RR_THE_MARKET, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/sacred_forest_meadow.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/sacred_forest_meadow.cpp index 34425e22987..855e5173c05 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/sacred_forest_meadow.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/sacred_forest_meadow.cpp @@ -57,7 +57,7 @@ void RegionTable_Init_SacredForestMeadow() { areaTable[RR_SFM_WOLFOS_GROTTO] = Region("SFM Wolfos Grotto", SCENE_GROTTOS, {}, { //Locations - LOCATION(RC_SFM_WOLFOS_GROTTO_CHEST, logic->CanKillEnemy(RE_WOLFOS, ED_CLOSE, true, 2)), + LOCATION(RC_SFM_WOLFOS_GROTTO_CHEST, logic->CanKillEnemy(RE_WOLFOS, ED_CLOSE, true, 2) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_SFM_ENTRYWAY, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp index 5202e7fff46..1c6d822e4b8 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp @@ -16,7 +16,7 @@ void RegionTable_Init_ZorasDomain() { }, { //Locations LOCATION(RC_ZD_DIVING_MINIGAME, logic->HasItem(RG_BRONZE_SCALE) && logic->HasItem(RG_CHILD_WALLET) && logic->IsChild), - LOCATION(RC_ZD_CHEST, logic->IsChild && logic->CanUse(RG_STICKS)), + LOCATION(RC_ZD_CHEST, logic->IsChild && logic->CanUse(RG_STICKS) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_ZD_KING_ZORA_THAWED, logic->IsAdult && logic->Get(LOGIC_KING_ZORA_THAWED)), LOCATION(RC_ZD_TRADE_PRESCRIPTION, logic->IsAdult && logic->Get(LOGIC_KING_ZORA_THAWED) && logic->CanUse(RG_PRESCRIPTION)), LOCATION(RC_ZD_GS_FROZEN_WATERFALL, logic->IsAdult && (logic->HookshotOrBoomerang() || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || (logic->CanUse(RG_MAGIC_SINGLE) && (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_BIGGORON_SWORD))) || (ctx->GetTrickOption(RT_ZD_GS) && logic->CanJumpslashExceptHammer())) && logic->CanGetNightTimeGS()), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp index 0a8a1d2bc84..20a22334245 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp @@ -8,7 +8,7 @@ void RegionTable_Init_ZorasFountain() { areaTable[RR_ZORAS_FOUNTAIN] = Region("Zoras Fountain", SCENE_ZORAS_FOUNTAIN, { //Events EventAccess(LOGIC_GOSSIP_STONE_FAIRY, []{return logic->CallGossipFairyExceptSuns();}), - EventAccess(LOGIC_BUTTERFLY_FAIRY, []{return logic->CanUse(RG_STICKS) && logic->AtDay;}), + EventAccess(LOGIC_BUTTERFLY_FAIRY, []{return logic->CanUse(RG_STICKS) && logic->AtDay;}), }, { //Locations LOCATION(RC_ZF_GS_TREE, logic->IsChild && logic->CanBonkTrees()), @@ -24,6 +24,12 @@ void RegionTable_Init_ZorasFountain() { 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_TREE, logic->IsChild && logic->CanBonkTrees()), + LOCATION(RC_ZF_BUSH_1, logic->IsChild), + LOCATION(RC_ZF_BUSH_2, logic->IsChild), + LOCATION(RC_ZF_BUSH_3, logic->IsChild), + LOCATION(RC_ZF_BUSH_4, logic->IsChild), + LOCATION(RC_ZF_BUSH_5, logic->IsChild), + LOCATION(RC_ZF_BUSH_6, logic->IsChild), }, { //Exits Entrance(RR_ZD_BEHIND_KING_ZORA, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp index 7b1ff3907c3..67f24bd422f 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp @@ -111,7 +111,7 @@ void RegionTable_Init_ZoraRiver() { areaTable[RR_ZR_OPEN_GROTTO] = Region("ZR Open Grotto", SCENE_GROTTOS, grottoEvents, { //Locations - LOCATION(RC_ZR_OPEN_GROTTO_CHEST, true), + LOCATION(RC_ZR_OPEN_GROTTO_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_ZR_OPEN_GROTTO_FISH, logic->HasBottle()), LOCATION(RC_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), LOCATION(RC_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index 6c359d529aa..3cc1130acaf 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -134,6 +134,17 @@ bool Logic::HasItem(RandomizerGet itemName) { case RG_OCARINA_C_RIGHT_BUTTON: case RG_OCARINA_C_DOWN_BUTTON: case RG_OCARINA_C_UP_BUTTON: + // Bean Souls + case RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL: + case RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL: + case RG_DESERT_COLOSSUS_BEAN_SOUL: + case RG_GERUDO_VALLEY_BEAN_SOUL: + case RG_GRAVEYARD_BEAN_SOUL: + case RG_KOKIRI_FOREST_BEAN_SOUL: + case RG_LAKE_HYLIA_BEAN_SOUL: + case RG_LOST_WOODS_BRIDGE_BEAN_SOUL: + case RG_LOST_WOODS_BEAN_SOUL: + case RG_ZORAS_RIVER_BEAN_SOUL: // Boss Souls case RG_GOHMA_SOUL: case RG_KING_DODONGO_SOUL: @@ -215,6 +226,8 @@ bool Logic::HasItem(RandomizerGet itemName) { return CurrentUpgrade(UPG_WALLET) >= 2; case RG_TYCOON_WALLET: return CurrentUpgrade(UPG_WALLET) >= 3; + case RG_OPEN_CHEST: + return CheckRandoInf(RAND_INF_CAN_OPEN_CHEST); // Scales case RG_BRONZE_SCALE: return CheckRandoInf(RAND_INF_CAN_SWIM); @@ -1175,8 +1188,8 @@ bool Logic::BlastOrSmash() { return HasExplosives() || CanUse(RG_MEGATON_HAMMER); } -bool Logic::CanSpawnSoilSkull() { - return IsChild && CanUse(RG_BOTTLE_WITH_BUGS); +bool Logic::CanSpawnSoilSkull(RandomizerGet bean) { + return IsChild && CanUse(RG_BOTTLE_WITH_BUGS) && HasItem(bean); } bool Logic::CanReflectNuts() { @@ -1404,6 +1417,16 @@ std::map Logic::RandoGetToRandInf = { { RG_ZELDAS_LETTER, RAND_INF_ZELDAS_LETTER }, { RG_WEIRD_EGG, RAND_INF_WEIRD_EGG }, { RG_RUTOS_LETTER, RAND_INF_OBTAINED_RUTOS_LETTER }, + { RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL, RAND_INF_DEATH_MOUNTAIN_CRATER_BEAN_SOUL }, + { RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL, RAND_INF_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL }, + { RG_DESERT_COLOSSUS_BEAN_SOUL, RAND_INF_DESERT_COLOSSUS_BEAN_SOUL }, + { RG_GERUDO_VALLEY_BEAN_SOUL, RAND_INF_GERUDO_VALLEY_BEAN_SOUL }, + { RG_GRAVEYARD_BEAN_SOUL, RAND_INF_GRAVEYARD_BEAN_SOUL }, + { RG_KOKIRI_FOREST_BEAN_SOUL, RAND_INF_KOKIRI_FOREST_BEAN_SOUL }, + { RG_LAKE_HYLIA_BEAN_SOUL, RAND_INF_LAKE_HYLIA_BEAN_SOUL }, + { RG_LOST_WOODS_BRIDGE_BEAN_SOUL, RAND_INF_LOST_WOODS_BRIDGE_BEAN_SOUL }, + { RG_LOST_WOODS_BEAN_SOUL, RAND_INF_LOST_WOODS_BEAN_SOUL }, + { RG_ZORAS_RIVER_BEAN_SOUL, RAND_INF_ZORAS_RIVER_BEAN_SOUL }, { RG_GOHMA_SOUL, RAND_INF_GOHMA_SOUL }, { RG_KING_DODONGO_SOUL, RAND_INF_KING_DODONGO_SOUL }, { RG_BARINADE_SOUL, RAND_INF_BARINADE_SOUL }, @@ -1574,6 +1597,9 @@ void Logic::ApplyItemEffect(Item& item, bool state) { case RG_CLAIM_CHECK: SetRandoInf(randoGet - RG_COJIRO + RAND_INF_ADULT_TRADES_HAS_COJIRO, state); break; + case RG_OPEN_CHEST: + SetRandoInf(RAND_INF_CAN_OPEN_CHEST, state); + break; case RG_PROGRESSIVE_HOOKSHOT: { uint8_t i; for (i = 0; i < 3; i++) { @@ -1770,6 +1796,16 @@ void Logic::ApplyItemEffect(Item& item, bool state) { case RG_RUTOS_LETTER: SetRandoInf(RAND_INF_OBTAINED_RUTOS_LETTER, state); break; + case RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL: + case RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL: + case RG_DESERT_COLOSSUS_BEAN_SOUL: + case RG_GERUDO_VALLEY_BEAN_SOUL: + case RG_GRAVEYARD_BEAN_SOUL: + case RG_KOKIRI_FOREST_BEAN_SOUL: + case RG_LAKE_HYLIA_BEAN_SOUL: + case RG_LOST_WOODS_BRIDGE_BEAN_SOUL: + case RG_LOST_WOODS_BEAN_SOUL: + case RG_ZORAS_RIVER_BEAN_SOUL: case RG_GOHMA_SOUL: case RG_KING_DODONGO_SOUL: case RG_BARINADE_SOUL: @@ -2311,6 +2347,11 @@ void Logic::Reset(bool resetSaveContext /*= true*/) { SetRandoInf(RAND_INF_CAN_SWIM, true); } + // If we're not shuffling open chest, we start with it + if (ctx->GetOption(RSK_SHUFFLE_OPEN_CHEST).Is(false)) { + SetRandoInf(RAND_INF_CAN_OPEN_CHEST, true); + } + // If we're not shuffling child's wallet, we start with it if (ctx->GetOption(RSK_SHUFFLE_CHILD_WALLET).Is(false)) { SetRandoInf(RAND_INF_HAS_WALLET, true); @@ -2321,6 +2362,19 @@ void Logic::Reset(bool resetSaveContext /*= true*/) { SetRandoInf(RAND_INF_FISHING_POLE_FOUND, true); } + if (ctx->GetOption(RSK_SHUFFLE_BEAN_SOULS).Is(false)) { + SetRandoInf(RAND_INF_DEATH_MOUNTAIN_CRATER_BEAN_SOUL, true); + SetRandoInf(RAND_INF_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL, true); + SetRandoInf(RAND_INF_DESERT_COLOSSUS_BEAN_SOUL, true); + SetRandoInf(RAND_INF_GERUDO_VALLEY_BEAN_SOUL, true); + SetRandoInf(RAND_INF_GRAVEYARD_BEAN_SOUL, true); + SetRandoInf(RAND_INF_KOKIRI_FOREST_BEAN_SOUL, true); + SetRandoInf(RAND_INF_LAKE_HYLIA_BEAN_SOUL, true); + SetRandoInf(RAND_INF_LOST_WOODS_BRIDGE_BEAN_SOUL, true); + SetRandoInf(RAND_INF_LOST_WOODS_BEAN_SOUL, true); + SetRandoInf(RAND_INF_ZORAS_RIVER_BEAN_SOUL, true); + } + // If not keysanity, start with 1 logical key to account for automatically unlocking the basement door in // vanilla FiT if (!IsFireLoopLocked() && ctx->GetDungeon(Rando::FIRE_TEMPLE)->IsVanilla()) { diff --git a/soh/soh/Enhancements/randomizer/logic.h b/soh/soh/Enhancements/randomizer/logic.h index a90109bdfd6..a870cc993a7 100644 --- a/soh/soh/Enhancements/randomizer/logic.h +++ b/soh/soh/Enhancements/randomizer/logic.h @@ -75,7 +75,7 @@ class Logic { bool BlueFire(); bool HasExplosives(); bool BlastOrSmash(); - bool CanSpawnSoilSkull(); + bool CanSpawnSoilSkull(RandomizerGet bean); bool CanReflectNuts(); bool CanCutShrubs(); bool CanStunDeku(); diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp index c544d3b2904..4836a476a58 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -253,6 +253,7 @@ void Settings::CreateOptionDescriptions() { "\n" "If you enter a water entrance without swim you will be respawned on land to prevent infinite death loops.\n" "If you void out in Water Temple you will immediately be kicked out to prevent a softlock."; + mOptionDescriptions[RSK_SHUFFLE_OPEN_CHEST] = "Shuffles the ability to open chests into the item pool."; mOptionDescriptions[RSK_SHUFFLE_WEIRD_EGG] = "Shuffles the Weird Egg from Malon in to the item pool. Enabling " "\"Skip Child Zelda\" disables this feature.\n" "\n" @@ -297,6 +298,8 @@ void Settings::CreateOptionDescriptions() { "Trees will have a special appearance when carrying randomized items.\n" "\nSome trees are dependant on Link's age, such as some trees in Hyrule Field.\nTwo trees at Hyrule Castle are " "only shuffle with No Logic."; + mOptionDescriptions[RSK_SHUFFLE_BUSHES] = + "Bushes in Hyrule Field & Zora's Fountain will contain randomized items when first walked through."; mOptionDescriptions[RSK_SHUFFLE_FISHING_POLE] = "Shuffles the fishing pole into the item pool.\n" "\n" "The fishing pole is required to play the fishing pond minigame."; @@ -625,6 +628,9 @@ void Settings::CreateOptionDescriptions() { "Start with the ability to summon Pierre the Scarecrow. Pulling out an Ocarina in the usual locations will " "automatically summon him.\n" "With \"Shuffle Ocarina Buttons\" enabled, you'll need at least two Ocarina buttons to summon him."; + mOptionDescriptions[RSK_SKIP_PLANTING_BEANS] = "Beans will be planted.\n" + "If beans are shuffled, you must find beans first.\n" + "If bean souls are shuffled, you must find soul first."; mOptionDescriptions[RSK_ITEM_POOL] = "Sets how many major items appear in the item pool.\n" "\n" "Plentiful - Extra major items are added to the pool.\n" @@ -770,6 +776,8 @@ void Settings::CreateOptionDescriptions() { "location is reachable. When disabled, only " "required items and locations to beat the game " "will be guaranteed reachable."; + mOptionDescriptions[RSK_SHUFFLE_BEAN_SOULS] = + "Shuffle 10 bean souls which must be found to spawn corresponding soil / plant."; mOptionDescriptions[RSK_SHUFFLE_BOSS_SOULS] = "Shuffles 8 boss souls (one for each blue warp dungeon). A boss will not appear until you collect its " "respective soul." diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index cac735121ef..1da3ef7cbef 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -3395,6 +3395,70 @@ std::map rcToRandomizerInf = { { RC_ZR_TREE, RAND_INF_ZR_TREE }, { RC_KAK_TREE, RAND_INF_KAK_TREE }, { RC_LLR_TREE, RAND_INF_LLR_TREE }, + { RC_HF_BUSH_NEAR_LAKE_1, RAND_INF_HF_BUSH_NEAR_LAKE_1 }, + { RC_HF_BUSH_NEAR_LAKE_2, RAND_INF_HF_BUSH_NEAR_LAKE_2 }, + { RC_HF_BUSH_NEAR_LAKE_3, RAND_INF_HF_BUSH_NEAR_LAKE_3 }, + { RC_HF_BUSH_NEAR_LAKE_4, RAND_INF_HF_BUSH_NEAR_LAKE_4 }, + { RC_HF_BUSH_NEAR_LAKE_5, RAND_INF_HF_BUSH_NEAR_LAKE_5 }, + { RC_HF_BUSH_NEAR_LAKE_6, RAND_INF_HF_BUSH_NEAR_LAKE_6 }, + { RC_HF_BUSH_NEAR_LAKE_7, RAND_INF_HF_BUSH_NEAR_LAKE_7 }, + { RC_HF_BUSH_NEAR_LAKE_8, RAND_INF_HF_BUSH_NEAR_LAKE_8 }, + { RC_HF_BUSH_NEAR_LAKE_9, RAND_INF_HF_BUSH_NEAR_LAKE_9 }, + { RC_HF_BUSH_NEAR_LAKE_10, RAND_INF_HF_BUSH_NEAR_LAKE_10 }, + { RC_HF_BUSH_NEAR_LAKE_11, RAND_INF_HF_BUSH_NEAR_LAKE_11 }, + { RC_HF_NORTHERN_BUSH_1, RAND_INF_HF_NORTHERN_BUSH_1 }, + { RC_HF_NORTHERN_BUSH_2, RAND_INF_HF_NORTHERN_BUSH_2 }, + { RC_HF_NORTHERN_BUSH_3, RAND_INF_HF_NORTHERN_BUSH_3 }, + { RC_HF_NORTHERN_BUSH_4, RAND_INF_HF_NORTHERN_BUSH_4 }, + { RC_HF_NORTHERN_BUSH_5, RAND_INF_HF_NORTHERN_BUSH_5 }, + { RC_HF_NORTHERN_BUSH_6, RAND_INF_HF_NORTHERN_BUSH_6 }, + { RC_HF_CHILD_NORTHERN_BUSH_1, RAND_INF_HF_CHILD_NORTHERN_BUSH_1 }, + { RC_HF_CHILD_NORTHERN_BUSH_2, RAND_INF_HF_CHILD_NORTHERN_BUSH_2 }, + { RC_HF_CHILD_NORTHERN_BUSH_3, RAND_INF_HF_CHILD_NORTHERN_BUSH_3 }, + { RC_HF_CHILD_NORTHERN_BUSH_4, RAND_INF_HF_CHILD_NORTHERN_BUSH_4 }, + { RC_HF_CHILD_NORTHERN_BUSH_5, RAND_INF_HF_CHILD_NORTHERN_BUSH_5 }, + { RC_HF_CHILD_NORTHERN_BUSH_6, RAND_INF_HF_CHILD_NORTHERN_BUSH_6 }, + { RC_HF_CHILD_NORTHERN_BUSH_7, RAND_INF_HF_CHILD_NORTHERN_BUSH_7 }, + { RC_HF_CHILD_NORTHERN_BUSH_8, RAND_INF_HF_CHILD_NORTHERN_BUSH_8 }, + { RC_HF_CHILD_NORTHERN_BUSH_9, RAND_INF_HF_CHILD_NORTHERN_BUSH_9 }, + { RC_HF_CHILD_NORTHERN_BUSH_10, RAND_INF_HF_CHILD_NORTHERN_BUSH_10 }, + { RC_HF_CHILD_NORTHERN_BUSH_11, RAND_INF_HF_CHILD_NORTHERN_BUSH_11 }, + { RC_HF_BUSH_BY_ROCKY_PATH_1, RAND_INF_HF_BUSH_BY_ROCKY_PATH_1 }, + { RC_HF_BUSH_BY_ROCKY_PATH_2, RAND_INF_HF_BUSH_BY_ROCKY_PATH_2 }, + { RC_HF_BUSH_BY_ROCKY_PATH_3, RAND_INF_HF_BUSH_BY_ROCKY_PATH_3 }, + { RC_HF_BUSH_BY_ROCKY_PATH_4, RAND_INF_HF_BUSH_BY_ROCKY_PATH_4 }, + { RC_HF_BUSH_BY_ROCKY_PATH_5, RAND_INF_HF_BUSH_BY_ROCKY_PATH_5 }, + { RC_HF_BUSH_BY_ROCKY_PATH_6, RAND_INF_HF_BUSH_BY_ROCKY_PATH_6 }, + { RC_HF_SOUTHERN_BUSH_1, RAND_INF_HF_SOUTHERN_BUSH_1 }, + { RC_HF_SOUTHERN_BUSH_2, RAND_INF_HF_SOUTHERN_BUSH_2 }, + { RC_HF_SOUTHERN_BUSH_3, RAND_INF_HF_SOUTHERN_BUSH_3 }, + { RC_HF_SOUTHERN_BUSH_4, RAND_INF_HF_SOUTHERN_BUSH_4 }, + { RC_HF_SOUTHERN_BUSH_5, RAND_INF_HF_SOUTHERN_BUSH_5 }, + { RC_HF_SOUTHERN_BUSH_6, RAND_INF_HF_SOUTHERN_BUSH_6 }, + { RC_HF_SOUTHERN_BUSH_7, RAND_INF_HF_SOUTHERN_BUSH_7 }, + { RC_HF_SOUTHERN_BUSH_8, RAND_INF_HF_SOUTHERN_BUSH_8 }, + { RC_HF_SOUTHERN_BUSH_9, RAND_INF_HF_SOUTHERN_BUSH_9 }, + { RC_HF_SOUTHERN_BUSH_10, RAND_INF_HF_SOUTHERN_BUSH_10 }, + { RC_HF_SOUTHERN_BUSH_11, RAND_INF_HF_SOUTHERN_BUSH_11 }, + { RC_HF_SOUTHERN_BUSH_12, RAND_INF_HF_SOUTHERN_BUSH_12 }, + { RC_HF_CHILD_SOUTHERN_BUSH_1, RAND_INF_HF_CHILD_SOUTHERN_BUSH_1 }, + { RC_HF_CHILD_SOUTHERN_BUSH_2, RAND_INF_HF_CHILD_SOUTHERN_BUSH_2 }, + { RC_HF_CHILD_SOUTHERN_BUSH_3, RAND_INF_HF_CHILD_SOUTHERN_BUSH_3 }, + { RC_HF_CHILD_SOUTHERN_BUSH_4, RAND_INF_HF_CHILD_SOUTHERN_BUSH_4 }, + { RC_HF_CHILD_SOUTHERN_BUSH_5, RAND_INF_HF_CHILD_SOUTHERN_BUSH_5 }, + { RC_HF_CHILD_SOUTHERN_BUSH_6, RAND_INF_HF_CHILD_SOUTHERN_BUSH_6 }, + { RC_HF_CHILD_SOUTHERN_BUSH_7, RAND_INF_HF_CHILD_SOUTHERN_BUSH_7 }, + { RC_HF_CHILD_SOUTHERN_BUSH_8, RAND_INF_HF_CHILD_SOUTHERN_BUSH_8 }, + { RC_HF_CHILD_SOUTHERN_BUSH_9, RAND_INF_HF_CHILD_SOUTHERN_BUSH_9 }, + { RC_HF_CHILD_SOUTHERN_BUSH_10, RAND_INF_HF_CHILD_SOUTHERN_BUSH_10 }, + { RC_HF_CHILD_SOUTHERN_BUSH_11, RAND_INF_HF_CHILD_SOUTHERN_BUSH_11 }, + { RC_HF_CHILD_SOUTHERN_BUSH_12, RAND_INF_HF_CHILD_SOUTHERN_BUSH_12 }, + { RC_ZF_BUSH_1, RAND_INF_ZF_BUSH_1 }, + { RC_ZF_BUSH_2, RAND_INF_ZF_BUSH_2 }, + { RC_ZF_BUSH_3, RAND_INF_ZF_BUSH_3 }, + { RC_ZF_BUSH_4, RAND_INF_ZF_BUSH_4 }, + { RC_ZF_BUSH_5, RAND_INF_ZF_BUSH_5 }, + { RC_ZF_BUSH_6, RAND_INF_ZF_BUSH_6 }, }; BeehiveIdentity Randomizer::IdentifyBeehive(s32 sceneNum, s16 xPosition, s32 respawnData) { @@ -5488,7 +5552,7 @@ CustomMessage Randomizer::GetGoronMessage(u16 index) { void Randomizer::CreateCustomMessages() { // RANDTODO: Translate into french and german and replace GIMESSAGE_UNTRANSLATED // with GIMESSAGE(getItemID, itemID, english, german, french). - const std::array getItemMessages = { { + const std::array getItemMessages = { { GIMESSAGE(RG_GREG_RUPEE, ITEM_MASK_GORON, "You found %gGreg%w!", "%gGreg%w! Du hast ihn&wirklich gefunden!", "Félicitation! Vous avez trouvé %gGreg%w!"), GIMESSAGE(RG_MASTER_SWORD, ITEM_SWORD_MASTER, "You found the %gMaster Sword%w!", @@ -5764,6 +5828,27 @@ void Randomizer::CreateCustomMessages() { "Du erhältst die %rKindergeldbörse%w!&Jetzt kannst Du bis&zu %y99 Rubine%w mit Dir führen!", "Vous obtenez la %rPetite Bourse%w!&Elle peut contenir jusqu'à %y99 rubis%w!"), + GIMESSAGE(RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL, ITEM_BEAN, "You found the&%gDeath Mountain Crater Bean Soul%w!", + TODO_TRANSLATE, TODO_TRANSLATE), + GIMESSAGE(RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL, ITEM_BEAN, "You found the&%gDeath Mountain Trail Bean Soul%w!", + TODO_TRANSLATE, TODO_TRANSLATE), + GIMESSAGE(RG_DESERT_COLOSSUS_BEAN_SOUL, ITEM_BEAN, "You found the&%gDesert Colossus Bean Soul%w!", + TODO_TRANSLATE, TODO_TRANSLATE), + GIMESSAGE(RG_GERUDO_VALLEY_BEAN_SOUL, ITEM_BEAN, "You found the&%gGerudo Valley Bean Soul%w!", TODO_TRANSLATE, + TODO_TRANSLATE), + GIMESSAGE(RG_GRAVEYARD_BEAN_SOUL, ITEM_BEAN, "You found the&%gGraveyard Bean Soul%w!", TODO_TRANSLATE, + TODO_TRANSLATE), + GIMESSAGE(RG_KOKIRI_FOREST_BEAN_SOUL, ITEM_BEAN, "You found the&%gKokiri Forest Bean Soul%w!", TODO_TRANSLATE, + TODO_TRANSLATE), + GIMESSAGE(RG_LAKE_HYLIA_BEAN_SOUL, ITEM_BEAN, "You found the&%gLake Hylia Bean Soul%w!", TODO_TRANSLATE, + TODO_TRANSLATE), + GIMESSAGE(RG_LOST_WOODS_BRIDGE_BEAN_SOUL, ITEM_BEAN, "You found the&%gLost Wood's Bridge Bean Soul%w!", + TODO_TRANSLATE, TODO_TRANSLATE), + GIMESSAGE(RG_LOST_WOODS_BEAN_SOUL, ITEM_BEAN, "You found the&%gLost Wood's Theatre Bean Soul%w!", + TODO_TRANSLATE, TODO_TRANSLATE), + GIMESSAGE(RG_ZORAS_RIVER_BEAN_SOUL, ITEM_BEAN, "You found the&%gZora's River Bean Soul%w!", TODO_TRANSLATE, + TODO_TRANSLATE), + GIMESSAGE(RG_GOHMA_SOUL, ITEM_BIG_POE, "You found the soul for %gGohma%w!", "Du hast die Seele von&%gGohma%w gefunden!", "Vous obtenez l'âme de %gGohma%w!"), GIMESSAGE(RG_KING_DODONGO_SOUL, ITEM_BIG_POE, "You found the soul for %rKing&Dodongo%w!", @@ -5812,6 +5897,8 @@ void Randomizer::CreateCustomMessages() { GIMESSAGE(RG_BRONZE_SCALE, ITEM_SCALE_SILVER, "You got the %rBronze Scale%w!&The power of buoyancy is yours!", "Du hast die %rBronzene Schuppe%w&erhalten! Die Fähigkeit zu&Schwimmen ist nun dein!", "Vous obtenez l'%rÉcaille de Bronze%w!&Le pouvoir de la flottabilité est&à vous!"), + GIMESSAGE(RG_OPEN_CHEST, ITEM_KEY_SMALL, "You got the %rAbility to Open Chests%w!", TODO_TRANSLATE, + TODO_TRANSLATE), GIMESSAGE(RG_FISHING_POLE, ITEM_FISHING_POLE, "You found a lost %rFishing Pole%w!&Time to hit the pond!", "Du hast eine verlorene %rAngelrute%w&gefunden!&Zeit, im Teich&zu angeln!", "Vous obtenez une %rCanne à pêche%w&perdue!&Il est temps d'aller à %gl'étang%w!"), @@ -5982,6 +6069,7 @@ extern "C" u8 Return_Item_Entry(GetItemEntry itemEntry, u8 returnItem); std::map randomizerGetToRandInf = { { RG_FISHING_POLE, RAND_INF_FISHING_POLE_FOUND }, { RG_BRONZE_SCALE, RAND_INF_CAN_SWIM }, + { RG_OPEN_CHEST, RAND_INF_CAN_OPEN_CHEST }, { RG_QUIVER_INF, RAND_INF_HAS_INFINITE_QUIVER }, { RG_BOMB_BAG_INF, RAND_INF_HAS_INFINITE_BOMB_BAG }, { RG_BULLET_BAG_INF, RAND_INF_HAS_INFINITE_BULLET_BAG }, @@ -5996,6 +6084,16 @@ std::map randomizerGetToRandInf = { { RG_OCARINA_C_DOWN_BUTTON, RAND_INF_HAS_OCARINA_C_DOWN }, { RG_OCARINA_C_LEFT_BUTTON, RAND_INF_HAS_OCARINA_C_LEFT }, { RG_OCARINA_C_RIGHT_BUTTON, RAND_INF_HAS_OCARINA_C_RIGHT }, + { RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL, RAND_INF_DEATH_MOUNTAIN_CRATER_BEAN_SOUL }, + { RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL, RAND_INF_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL }, + { RG_DESERT_COLOSSUS_BEAN_SOUL, RAND_INF_DESERT_COLOSSUS_BEAN_SOUL }, + { RG_GERUDO_VALLEY_BEAN_SOUL, RAND_INF_GERUDO_VALLEY_BEAN_SOUL }, + { RG_GRAVEYARD_BEAN_SOUL, RAND_INF_GRAVEYARD_BEAN_SOUL }, + { RG_KOKIRI_FOREST_BEAN_SOUL, RAND_INF_KOKIRI_FOREST_BEAN_SOUL }, + { RG_LAKE_HYLIA_BEAN_SOUL, RAND_INF_LAKE_HYLIA_BEAN_SOUL }, + { RG_LOST_WOODS_BRIDGE_BEAN_SOUL, RAND_INF_LOST_WOODS_BRIDGE_BEAN_SOUL }, + { RG_LOST_WOODS_BEAN_SOUL, RAND_INF_LOST_WOODS_BEAN_SOUL }, + { RG_ZORAS_RIVER_BEAN_SOUL, RAND_INF_ZORAS_RIVER_BEAN_SOUL }, { RG_GOHMA_SOUL, RAND_INF_GOHMA_SOUL }, { RG_KING_DODONGO_SOUL, RAND_INF_KING_DODONGO_SOUL }, { RG_BARINADE_SOUL, RAND_INF_BARINADE_SOUL }, @@ -6216,6 +6314,18 @@ extern "C" u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) { if (INV_CONTENT(ITEM_BEAN) == ITEM_NONE) { INV_CONTENT(ITEM_BEAN) = ITEM_BEAN; AMMO(ITEM_BEAN) = 10; + if (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SKIP_PLANTING_BEANS)) { + gSaveContext.sceneFlags[SCENE_DEATH_MOUNTAIN_CRATER].swch |= (1 << 3); + gSaveContext.sceneFlags[SCENE_DEATH_MOUNTAIN_TRAIL].swch |= (1 << 6); + gSaveContext.sceneFlags[SCENE_DESERT_COLOSSUS].swch |= (1 << 24); + gSaveContext.sceneFlags[SCENE_GERUDO_VALLEY].swch |= (1 << 3); + gSaveContext.sceneFlags[SCENE_GRAVEYARD].swch |= (1 << 3); + gSaveContext.sceneFlags[SCENE_KOKIRI_FOREST].swch |= (1 << 9); + gSaveContext.sceneFlags[SCENE_LAKE_HYLIA].swch |= (1 << 1); + gSaveContext.sceneFlags[SCENE_LOST_WOODS].swch |= (1 << 4) | (1 << 18); + gSaveContext.sceneFlags[SCENE_ZORAS_RIVER].swch |= (1 << 3); + AMMO(ITEM_BEAN) = 0; + } } break; case RG_DOUBLE_DEFENSE: diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 9884c60db24..15167561d3e 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -423,6 +423,7 @@ typedef enum { RCTYPE_SMALL_CRATE, // Small crates RCTYPE_TREE, // Trees RCTYPE_NLTREE, // NL Trees + RCTYPE_BUSH, // Bushes RCTYPE_DUNGEON_REWARD, // Dungeon rewards (blue warps) RCTYPE_OCARINA, // Ocarina locations RCTYPE_BEEHIVE, // Beehives @@ -2898,6 +2899,73 @@ typedef enum { RC_LLR_TREE, // End Trees + // Start Bushes + RC_HF_BUSH_NEAR_LAKE_1, + RC_HF_BUSH_NEAR_LAKE_2, + RC_HF_BUSH_NEAR_LAKE_3, + RC_HF_BUSH_NEAR_LAKE_4, + RC_HF_BUSH_NEAR_LAKE_5, + RC_HF_BUSH_NEAR_LAKE_6, + RC_HF_BUSH_NEAR_LAKE_7, + RC_HF_BUSH_NEAR_LAKE_8, + RC_HF_BUSH_NEAR_LAKE_9, + RC_HF_BUSH_NEAR_LAKE_10, + RC_HF_BUSH_NEAR_LAKE_11, + RC_HF_NORTHERN_BUSH_1, + RC_HF_NORTHERN_BUSH_2, + RC_HF_NORTHERN_BUSH_3, + RC_HF_NORTHERN_BUSH_4, + RC_HF_NORTHERN_BUSH_5, + RC_HF_NORTHERN_BUSH_6, + RC_HF_CHILD_NORTHERN_BUSH_1, + RC_HF_CHILD_NORTHERN_BUSH_2, + RC_HF_CHILD_NORTHERN_BUSH_3, + RC_HF_CHILD_NORTHERN_BUSH_4, + RC_HF_CHILD_NORTHERN_BUSH_5, + RC_HF_CHILD_NORTHERN_BUSH_6, + RC_HF_CHILD_NORTHERN_BUSH_7, + RC_HF_CHILD_NORTHERN_BUSH_8, + RC_HF_CHILD_NORTHERN_BUSH_9, + RC_HF_CHILD_NORTHERN_BUSH_10, + RC_HF_CHILD_NORTHERN_BUSH_11, + RC_HF_BUSH_BY_ROCKY_PATH_1, + RC_HF_BUSH_BY_ROCKY_PATH_2, + RC_HF_BUSH_BY_ROCKY_PATH_3, + RC_HF_BUSH_BY_ROCKY_PATH_4, + RC_HF_BUSH_BY_ROCKY_PATH_5, + RC_HF_BUSH_BY_ROCKY_PATH_6, + RC_HF_SOUTHERN_BUSH_1, + RC_HF_SOUTHERN_BUSH_2, + RC_HF_SOUTHERN_BUSH_3, + RC_HF_SOUTHERN_BUSH_4, + RC_HF_SOUTHERN_BUSH_5, + RC_HF_SOUTHERN_BUSH_6, + RC_HF_SOUTHERN_BUSH_7, + RC_HF_SOUTHERN_BUSH_8, + RC_HF_SOUTHERN_BUSH_9, + RC_HF_SOUTHERN_BUSH_10, + RC_HF_SOUTHERN_BUSH_11, + RC_HF_SOUTHERN_BUSH_12, + RC_HF_CHILD_SOUTHERN_BUSH_1, + RC_HF_CHILD_SOUTHERN_BUSH_2, + RC_HF_CHILD_SOUTHERN_BUSH_3, + RC_HF_CHILD_SOUTHERN_BUSH_4, + RC_HF_CHILD_SOUTHERN_BUSH_5, + RC_HF_CHILD_SOUTHERN_BUSH_6, + RC_HF_CHILD_SOUTHERN_BUSH_7, + RC_HF_CHILD_SOUTHERN_BUSH_8, + RC_HF_CHILD_SOUTHERN_BUSH_9, + RC_HF_CHILD_SOUTHERN_BUSH_10, + RC_HF_CHILD_SOUTHERN_BUSH_11, + RC_HF_CHILD_SOUTHERN_BUSH_12, + RC_ZF_BUSH_1, + RC_ZF_BUSH_2, + RC_ZF_BUSH_3, + RC_ZF_BUSH_4, + RC_ZF_BUSH_5, + RC_ZF_BUSH_6, + // End Bushes + RC_PIERRE, RC_DELIVER_RUTOS_LETTER, RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE, @@ -4239,6 +4307,16 @@ typedef enum { RG_BUY_RED_POTION_50, RG_TRIFORCE, RG_TRIFORCE_PIECE, + RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL, + RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL, + RG_DESERT_COLOSSUS_BEAN_SOUL, + RG_GERUDO_VALLEY_BEAN_SOUL, + RG_GRAVEYARD_BEAN_SOUL, + RG_KOKIRI_FOREST_BEAN_SOUL, + RG_LAKE_HYLIA_BEAN_SOUL, + RG_LOST_WOODS_BRIDGE_BEAN_SOUL, + RG_LOST_WOODS_BEAN_SOUL, + RG_ZORAS_RIVER_BEAN_SOUL, RG_GOHMA_SOUL, RG_KING_DODONGO_SOUL, RG_BARINADE_SOUL, @@ -4260,6 +4338,7 @@ typedef enum { RG_HINT, RG_TYCOON_WALLET, RG_BRONZE_SCALE, + RG_OPEN_CHEST, RG_CHILD_WALLET, RG_BOMBCHU_BAG, RG_QUIVER_INF, @@ -5442,6 +5521,7 @@ typedef enum { RHT_DEKU_STICK_CAPACITY_20, RHT_DEKU_STICK_CAPACITY_30, RHT_TRIFORCE_PIECE, + RHT_BEAN_SOUL, RHT_GOHMA_SOUL, RHT_KING_DODONGO_SOUL, RHT_BARINADE_SOUL, @@ -5457,6 +5537,7 @@ typedef enum { RHT_OCARINA_C_LEFT_BUTTON, RHT_OCARINA_C_RIGHT_BUTTON, RHT_BRONZE_SCALE, + RHT_OPEN_CHEST, RHT_FISHING_POLE, RHT_SKELETON_KEY, RHT_EPONA, @@ -5746,6 +5827,8 @@ typedef enum { RHT_TREE_ZORAS_RIVER, RHT_TREE_LON_LON_RANCH, RHT_TREE_KAKARIKO, + RHT_BUSH_HYRULE_FIELD, + RHT_BUSH_ZORAS_FOUNTAIN, // Ganon Line RHT_GANON_JOKE01, RHT_GANON_JOKE02, @@ -6034,6 +6117,7 @@ typedef enum { RSK_SHUFFLE_OCARINA, RSK_SHUFFLE_OCARINA_BUTTONS, RSK_SHUFFLE_SWIM, + RSK_SHUFFLE_OPEN_CHEST, RSK_STARTING_DEKU_SHIELD, RSK_STARTING_KOKIRI_SWORD, RSK_STARTING_MASTER_SWORD, @@ -6086,6 +6170,7 @@ typedef enum { RSK_SHUFFLE_POTS, RSK_SHUFFLE_CRATES, RSK_SHUFFLE_TREES, + RSK_SHUFFLE_BUSHES, RSK_SHUFFLE_FROG_SONG_RUPEES, RSK_ITEM_POOL, RSK_ICE_TRAPS, @@ -6133,6 +6218,7 @@ typedef enum { RSK_SKIP_EPONA_RACE, RSK_COMPLETE_MASK_QUEST, RSK_SKIP_SCARECROWS_SONG, + RSK_SKIP_PLANTING_BEANS, RSK_SKULLS_SUNS_SONG, RSK_SHUFFLE_ADULT_TRADE, RSK_SHUFFLE_MERCHANTS, @@ -6210,6 +6296,7 @@ typedef enum { RSK_TRIFORCE_HUNT, RSK_TRIFORCE_HUNT_PIECES_TOTAL, RSK_TRIFORCE_HUNT_PIECES_REQUIRED, + RSK_SHUFFLE_BEAN_SOULS, RSK_SHUFFLE_BOSS_SOULS, RSK_FISHSANITY, RSK_FISHSANITY_POND_COUNT, diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index 022303aa321..4e8d0fbe65a 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -83,6 +83,7 @@ bool showDungeonGrass; bool showOverworldCrates; bool showDungeonCrates; bool showTrees; +bool showBushes; bool showFrogSongRupees; bool showFountainFairies; bool showStoneFairies; @@ -1485,6 +1486,7 @@ void LoadSettings() { break; } showTrees = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_TREES); + showBushes = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_BUSHES); } else { // Vanilla showOverworldTokens = true; showDungeonTokens = true; @@ -1495,6 +1497,7 @@ void LoadSettings() { showOverworldCrates = false; showDungeonCrates = false; showTrees = false; + showBushes = false; } fortressFast = false; @@ -1611,7 +1614,7 @@ bool IsCheckShuffled(RandomizerCheck rc) { (loc->GetRCType() != RCTYPE_NLTREE || (showTrees && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LOGIC_RULES) == RO_LOGIC_NO_LOGIC)) && - (loc->GetRCType() != RCTYPE_COW || showCows) && + (loc->GetRCType() != RCTYPE_BUSH || showBushes) && (loc->GetRCType() != RCTYPE_COW || showCows) && (loc->GetRCType() != RCTYPE_FISH || OTRGlobals::Instance->gRandoContext->GetFishsanity()->GetFishLocationIncluded(loc)) && (loc->GetRCType() != RCTYPE_FREESTANDING || diff --git a/soh/soh/Enhancements/randomizer/randomizer_inf.h b/soh/soh/Enhancements/randomizer/randomizer_inf.h index 8742805a6f2..76abc6e2e14 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_inf.h +++ b/soh/soh/Enhancements/randomizer/randomizer_inf.h @@ -182,6 +182,17 @@ DEFINE_RAND_INF(RAND_INF_ADULT_LOACH) DEFINE_RAND_INF(RAND_INF_10_BIG_POES) DEFINE_RAND_INF(RAND_INF_GRANT_GANONS_BOSSKEY) +DEFINE_RAND_INF(RAND_INF_DEATH_MOUNTAIN_CRATER_BEAN_SOUL) +DEFINE_RAND_INF(RAND_INF_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL) +DEFINE_RAND_INF(RAND_INF_DESERT_COLOSSUS_BEAN_SOUL) +DEFINE_RAND_INF(RAND_INF_GERUDO_VALLEY_BEAN_SOUL) +DEFINE_RAND_INF(RAND_INF_GRAVEYARD_BEAN_SOUL) +DEFINE_RAND_INF(RAND_INF_KOKIRI_FOREST_BEAN_SOUL) +DEFINE_RAND_INF(RAND_INF_LAKE_HYLIA_BEAN_SOUL) +DEFINE_RAND_INF(RAND_INF_LOST_WOODS_BRIDGE_BEAN_SOUL) +DEFINE_RAND_INF(RAND_INF_LOST_WOODS_BEAN_SOUL) +DEFINE_RAND_INF(RAND_INF_ZORAS_RIVER_BEAN_SOUL) + DEFINE_RAND_INF(RAND_INF_GOHMA_SOUL) DEFINE_RAND_INF(RAND_INF_KING_DODONGO_SOUL) DEFINE_RAND_INF(RAND_INF_BARINADE_SOUL) @@ -1060,10 +1071,75 @@ DEFINE_RAND_INF(RAND_INF_ZF_TREE) DEFINE_RAND_INF(RAND_INF_ZR_TREE) DEFINE_RAND_INF(RAND_INF_KAK_TREE) DEFINE_RAND_INF(RAND_INF_LLR_TREE) +DEFINE_RAND_INF(RAND_INF_HF_BUSH_NEAR_LAKE_1) +DEFINE_RAND_INF(RAND_INF_HF_BUSH_NEAR_LAKE_2) +DEFINE_RAND_INF(RAND_INF_HF_BUSH_NEAR_LAKE_3) +DEFINE_RAND_INF(RAND_INF_HF_BUSH_NEAR_LAKE_4) +DEFINE_RAND_INF(RAND_INF_HF_BUSH_NEAR_LAKE_5) +DEFINE_RAND_INF(RAND_INF_HF_BUSH_NEAR_LAKE_6) +DEFINE_RAND_INF(RAND_INF_HF_BUSH_NEAR_LAKE_7) +DEFINE_RAND_INF(RAND_INF_HF_BUSH_NEAR_LAKE_8) +DEFINE_RAND_INF(RAND_INF_HF_BUSH_NEAR_LAKE_9) +DEFINE_RAND_INF(RAND_INF_HF_BUSH_NEAR_LAKE_10) +DEFINE_RAND_INF(RAND_INF_HF_BUSH_NEAR_LAKE_11) +DEFINE_RAND_INF(RAND_INF_HF_NORTHERN_BUSH_1) +DEFINE_RAND_INF(RAND_INF_HF_NORTHERN_BUSH_2) +DEFINE_RAND_INF(RAND_INF_HF_NORTHERN_BUSH_3) +DEFINE_RAND_INF(RAND_INF_HF_NORTHERN_BUSH_4) +DEFINE_RAND_INF(RAND_INF_HF_NORTHERN_BUSH_5) +DEFINE_RAND_INF(RAND_INF_HF_NORTHERN_BUSH_6) +DEFINE_RAND_INF(RAND_INF_HF_CHILD_NORTHERN_BUSH_1) +DEFINE_RAND_INF(RAND_INF_HF_CHILD_NORTHERN_BUSH_2) +DEFINE_RAND_INF(RAND_INF_HF_CHILD_NORTHERN_BUSH_3) +DEFINE_RAND_INF(RAND_INF_HF_CHILD_NORTHERN_BUSH_4) +DEFINE_RAND_INF(RAND_INF_HF_CHILD_NORTHERN_BUSH_5) +DEFINE_RAND_INF(RAND_INF_HF_CHILD_NORTHERN_BUSH_6) +DEFINE_RAND_INF(RAND_INF_HF_CHILD_NORTHERN_BUSH_7) +DEFINE_RAND_INF(RAND_INF_HF_CHILD_NORTHERN_BUSH_8) +DEFINE_RAND_INF(RAND_INF_HF_CHILD_NORTHERN_BUSH_9) +DEFINE_RAND_INF(RAND_INF_HF_CHILD_NORTHERN_BUSH_10) +DEFINE_RAND_INF(RAND_INF_HF_CHILD_NORTHERN_BUSH_11) +DEFINE_RAND_INF(RAND_INF_HF_BUSH_BY_ROCKY_PATH_1) +DEFINE_RAND_INF(RAND_INF_HF_BUSH_BY_ROCKY_PATH_2) +DEFINE_RAND_INF(RAND_INF_HF_BUSH_BY_ROCKY_PATH_3) +DEFINE_RAND_INF(RAND_INF_HF_BUSH_BY_ROCKY_PATH_4) +DEFINE_RAND_INF(RAND_INF_HF_BUSH_BY_ROCKY_PATH_5) +DEFINE_RAND_INF(RAND_INF_HF_BUSH_BY_ROCKY_PATH_6) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHERN_BUSH_1) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHERN_BUSH_2) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHERN_BUSH_3) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHERN_BUSH_4) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHERN_BUSH_5) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHERN_BUSH_6) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHERN_BUSH_7) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHERN_BUSH_8) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHERN_BUSH_9) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHERN_BUSH_10) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHERN_BUSH_11) +DEFINE_RAND_INF(RAND_INF_HF_SOUTHERN_BUSH_12) +DEFINE_RAND_INF(RAND_INF_HF_CHILD_SOUTHERN_BUSH_1) +DEFINE_RAND_INF(RAND_INF_HF_CHILD_SOUTHERN_BUSH_2) +DEFINE_RAND_INF(RAND_INF_HF_CHILD_SOUTHERN_BUSH_3) +DEFINE_RAND_INF(RAND_INF_HF_CHILD_SOUTHERN_BUSH_4) +DEFINE_RAND_INF(RAND_INF_HF_CHILD_SOUTHERN_BUSH_5) +DEFINE_RAND_INF(RAND_INF_HF_CHILD_SOUTHERN_BUSH_6) +DEFINE_RAND_INF(RAND_INF_HF_CHILD_SOUTHERN_BUSH_7) +DEFINE_RAND_INF(RAND_INF_HF_CHILD_SOUTHERN_BUSH_8) +DEFINE_RAND_INF(RAND_INF_HF_CHILD_SOUTHERN_BUSH_9) +DEFINE_RAND_INF(RAND_INF_HF_CHILD_SOUTHERN_BUSH_10) +DEFINE_RAND_INF(RAND_INF_HF_CHILD_SOUTHERN_BUSH_11) +DEFINE_RAND_INF(RAND_INF_HF_CHILD_SOUTHERN_BUSH_12) +DEFINE_RAND_INF(RAND_INF_ZF_BUSH_1) +DEFINE_RAND_INF(RAND_INF_ZF_BUSH_2) +DEFINE_RAND_INF(RAND_INF_ZF_BUSH_3) +DEFINE_RAND_INF(RAND_INF_ZF_BUSH_4) +DEFINE_RAND_INF(RAND_INF_ZF_BUSH_5) +DEFINE_RAND_INF(RAND_INF_ZF_BUSH_6) DEFINE_RAND_INF(RAND_INF_CAUGHT_LOACH) DEFINE_RAND_INF(RAND_INF_CAN_SWIM) +DEFINE_RAND_INF(RAND_INF_CAN_OPEN_CHEST) DEFINE_RAND_INF(RAND_INF_HAS_WALLET) diff --git a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp index cd32cc4b144..4023ca577a6 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp @@ -55,6 +55,7 @@ static WidgetInfo triforcePieceCount; static WidgetInfo dungeonItemTracking; static WidgetInfo gregTracking; static WidgetInfo triforcePieceTracking; +static WidgetInfo beanSoulsTracking; static WidgetInfo bossSoulsTracking; static WidgetInfo ocarinaButtonTracking; static WidgetInfo overworldKeysTracking; @@ -136,6 +137,19 @@ std::vector triforcePieces = { ITEM_TRACKER_ITEM(RG_TRIFORCE_PIECE, 0, DrawItem), }; +std::vector beanSoulItems = { + ITEM_TRACKER_ITEM_CUSTOM(RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL, ITEM_BEAN, ITEM_BEAN, 0, DrawItem), + ITEM_TRACKER_ITEM_CUSTOM(RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL, ITEM_BEAN, ITEM_BEAN, 0, DrawItem), + ITEM_TRACKER_ITEM_CUSTOM(RG_DESERT_COLOSSUS_BEAN_SOUL, ITEM_BEAN, ITEM_BEAN, 0, DrawItem), + ITEM_TRACKER_ITEM_CUSTOM(RG_GERUDO_VALLEY_BEAN_SOUL, ITEM_BEAN, ITEM_BEAN, 0, DrawItem), + ITEM_TRACKER_ITEM_CUSTOM(RG_GRAVEYARD_BEAN_SOUL, ITEM_BEAN, ITEM_BEAN, 0, DrawItem), + ITEM_TRACKER_ITEM_CUSTOM(RG_KOKIRI_FOREST_BEAN_SOUL, ITEM_BEAN, ITEM_BEAN, 0, DrawItem), + ITEM_TRACKER_ITEM_CUSTOM(RG_LAKE_HYLIA_BEAN_SOUL, ITEM_BEAN, ITEM_BEAN, 0, DrawItem), + ITEM_TRACKER_ITEM_CUSTOM(RG_LOST_WOODS_BRIDGE_BEAN_SOUL, ITEM_BEAN, ITEM_BEAN, 0, DrawItem), + ITEM_TRACKER_ITEM_CUSTOM(RG_LOST_WOODS_BEAN_SOUL, ITEM_BEAN, ITEM_BEAN, 0, DrawItem), + ITEM_TRACKER_ITEM_CUSTOM(RG_ZORAS_RIVER_BEAN_SOUL, ITEM_BEAN, ITEM_BEAN, 0, DrawItem), +}; + std::vector bossSoulItems = { ITEM_TRACKER_ITEM(RG_GOHMA_SOUL, 0, DrawItem), ITEM_TRACKER_ITEM(RG_KING_DODONGO_SOUL, 0, DrawItem), ITEM_TRACKER_ITEM(RG_BARINADE_SOUL, 0, DrawItem), ITEM_TRACKER_ITEM(RG_PHANTOM_GANON_SOUL, 0, DrawItem), @@ -246,6 +260,19 @@ std::map itemTrackerDungeonShortNames = { { SCENE_THIEVES_HIDEOUT, "HIDE" }, }; +std::map itemTrackerBeanShortNames = { + { RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL, "DMC" }, + { RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL, "DMT" }, + { RG_DESERT_COLOSSUS_BEAN_SOUL, "DC" }, + { RG_GERUDO_VALLEY_BEAN_SOUL, "GV" }, + { RG_GRAVEYARD_BEAN_SOUL, "GY" }, + { RG_KOKIRI_FOREST_BEAN_SOUL, "KF" }, + { RG_LAKE_HYLIA_BEAN_SOUL, "LA" }, + { RG_LOST_WOODS_BRIDGE_BEAN_SOUL, "LWB" }, + { RG_LOST_WOODS_BEAN_SOUL, "LWT" }, + { RG_ZORAS_RIVER_BEAN_SOUL, "ZR" }, +}; + std::map itemTrackerBossShortNames = { { RG_GOHMA_SOUL, "GOHMA" }, { RG_KING_DODONGO_SOUL, "KD" }, { RG_BARINADE_SOUL, "BARI" }, { RG_PHANTOM_GANON_SOUL, "PG" }, { RG_VOLVAGIA_SOUL, "VOLV" }, { RG_MORPHA_SOUL, "MORPH" }, @@ -809,6 +836,56 @@ void DrawItem(ItemTrackerItem item) { hasItem = IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT); itemName = "Triforce Piece"; break; + case RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_DEATH_MOUNTAIN_CRATER_BEAN_SOUL); + itemName = "Death Mountain Crater Bean Soul"; + break; + case RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL); + itemName = "Death Mountain Trail Bean Soul"; + break; + case RG_DESERT_COLOSSUS_BEAN_SOUL: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_DESERT_COLOSSUS_BEAN_SOUL); + itemName = "Desert Colossus Bean Soul"; + break; + case RG_GERUDO_VALLEY_BEAN_SOUL: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_GERUDO_VALLEY_BEAN_SOUL); + itemName = "Gerudo Valley Bean Soul"; + break; + case RG_GRAVEYARD_BEAN_SOUL: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_GRAVEYARD_BEAN_SOUL); + itemName = "Graveyard Bean Soul"; + break; + case RG_KOKIRI_FOREST_BEAN_SOUL: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_KOKIRI_FOREST_BEAN_SOUL); + itemName = "Kokiri Forest Bean Soul"; + break; + case RG_LAKE_HYLIA_BEAN_SOUL: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_LAKE_HYLIA_BEAN_SOUL); + itemName = "Lake Hylia Bean Soul"; + break; + case RG_LOST_WOODS_BRIDGE_BEAN_SOUL: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_LOST_WOODS_BRIDGE_BEAN_SOUL); + itemName = "Lost Woods Bridge Bean Soul"; + break; + case RG_LOST_WOODS_BEAN_SOUL: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_LOST_WOODS_BEAN_SOUL); + itemName = "Lost Woods Theatre Bean Soul"; + break; + case RG_ZORAS_RIVER_BEAN_SOUL: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_ZORAS_RIVER_BEAN_SOUL); + itemName = "Zora's River Bean Soul"; + break; case RG_GOHMA_SOUL: actualItemId = item.id; hasItem = Flags_GetRandomizerInf(RAND_INF_GOHMA_SOUL); @@ -1025,6 +1102,16 @@ void DrawItem(ItemTrackerItem item) { DrawItemCount(item, false); + if (item.id >= RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL && item.id <= RG_ZORAS_RIVER_BEAN_SOUL) { + ImVec2 p = ImGui::GetCursorScreenPos(); + std::string beanName = itemTrackerBeanShortNames[item.id]; + ImGui::SetCursorScreenPos( + ImVec2(p.x + (iconSize / 2) - (ImGui::CalcTextSize(beanName.c_str()).x / 2), p.y - (iconSize + 13))); + ImGui::PushStyleColor(ImGuiCol_Text, IM_COL_WHITE); + ImGui::Text("%s", beanName.c_str()); + ImGui::PopStyleColor(); + } + if (item.id >= RG_GOHMA_SOUL && item.id <= RG_GANON_SOUL) { ImVec2 p = ImGui::GetCursorScreenPos(); std::string bossName = itemTrackerBossShortNames[item.id]; @@ -1478,6 +1565,19 @@ void UpdateVectors() { mainWindowItems.insert(mainWindowItems.end(), fishingPoleItems.begin(), fishingPoleItems.end()); } + // If we're adding bean souls to the main window... + if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.BeanSouls"), SECTION_DISPLAY_HIDDEN) == + SECTION_DISPLAY_MAIN_WINDOW) { + //...add empty items on the main window to get the souls on their own row. (Too many to sit with Greg/Triforce + // pieces) + while (mainWindowItems.size() % 6) { + mainWindowItems.push_back(ITEM_TRACKER_ITEM(ITEM_NONE, 0, DrawItem)); + } + + // Add bean souls + mainWindowItems.insert(mainWindowItems.end(), beanSoulItems.begin(), beanSoulItems.end()); + } + // If we're adding boss souls to the main window... if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.BossSouls"), SECTION_DISPLAY_HIDDEN) == SECTION_DISPLAY_MAIN_WINDOW) { @@ -1674,6 +1774,13 @@ void ItemTrackerWindow::DrawElement() { EndFloatingWindows(); } + if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.BeanSouls"), SECTION_DISPLAY_HIDDEN) == + SECTION_DISPLAY_SEPARATE) { + BeginFloatingWindows("Bean Soul Tracker"); + DrawItemsInRows(beanSoulItems); + EndFloatingWindows(); + } + if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.BossSouls"), SECTION_DISPLAY_HIDDEN) == SECTION_DISPLAY_SEPARATE) { BeginFloatingWindows("Boss Soul Tracker"); @@ -1914,6 +2021,7 @@ void ItemTrackerSettingsWindow::DrawElement() { } SohGui::mSohMenu->MenuDrawItem(gregTracking, 250, THEME_COLOR); SohGui::mSohMenu->MenuDrawItem(triforcePieceTracking, 250, THEME_COLOR); + SohGui::mSohMenu->MenuDrawItem(beanSoulsTracking, 250, THEME_COLOR); SohGui::mSohMenu->MenuDrawItem(bossSoulsTracking, 250, THEME_COLOR); SohGui::mSohMenu->MenuDrawItem(ocarinaButtonTracking, 250, THEME_COLOR); SohGui::mSohMenu->MenuDrawItem(overworldKeysTracking, 250, THEME_COLOR); @@ -2028,6 +2136,18 @@ void RegisterItemTrackerWidgets() { ; SohGui::mSohMenu->AddSearchWidget({ gregTracking, "Randomizer", "Item Tracker", "General Settings", "icon" }); + beanSoulsTracking = { .name = "Bean Souls", .type = WidgetType::WIDGET_CVAR_COMBOBOX }; + beanSoulsTracking.CVar(CVAR_TRACKER_ITEM("DisplayType.BeanSouls")) + .Options(ComboboxOptions() + .DefaultIndex(SECTION_DISPLAY_HIDDEN) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR) + .ComboMap(displayTypes)) + .Callback([](WidgetInfo& info) { shouldUpdateVectors = true; }); + ; + SohGui::mSohMenu->AddSearchWidget({ beanSoulsTracking, "Randomizer", "Item Tracker", "General Settings", "icon" }); + bossSoulsTracking = { .name = "Boss Souls", .type = WidgetType::WIDGET_CVAR_COMBOBOX }; bossSoulsTracking.CVar(CVAR_TRACKER_ITEM("DisplayType.BossSouls")) .Options(ComboboxOptions() @@ -2087,6 +2207,7 @@ void RegisterItemTrackerWidgets() { .ComboMap(extendedDisplayTypes)) .Callback([](WidgetInfo& info) { shouldUpdateVectors = true; }); ; + SohGui::mSohMenu->AddSearchWidget( { fishingPoleTracking, "Randomizer", "Item Tracker", "General Settings", "icon" }); diff --git a/soh/soh/Enhancements/randomizer/savefile.cpp b/soh/soh/Enhancements/randomizer/savefile.cpp index 106cecb11a4..d968a93c237 100644 --- a/soh/soh/Enhancements/randomizer/savefile.cpp +++ b/soh/soh/Enhancements/randomizer/savefile.cpp @@ -251,6 +251,33 @@ extern "C" void Randomizer_InitSaveFile() { // Go away Ruto (Water Temple first cutscene). gSaveContext.sceneFlags[SCENE_WATER_TEMPLE].swch |= (1 << 0x10); + if (Randomizer_GetSettingValue(RSK_SKIP_PLANTING_BEANS) && + !(Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) == RO_SHUFFLE_MERCHANTS_BEANS_ONLY || + Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) == RO_SHUFFLE_MERCHANTS_ALL)) { + gSaveContext.sceneFlags[SCENE_DEATH_MOUNTAIN_CRATER].swch |= (1 << 3); + gSaveContext.sceneFlags[SCENE_DEATH_MOUNTAIN_TRAIL].swch |= (1 << 6); + gSaveContext.sceneFlags[SCENE_DESERT_COLOSSUS].swch |= (1 << 24); + gSaveContext.sceneFlags[SCENE_GERUDO_VALLEY].swch |= (1 << 3); + gSaveContext.sceneFlags[SCENE_GRAVEYARD].swch |= (1 << 3); + gSaveContext.sceneFlags[SCENE_KOKIRI_FOREST].swch |= (1 << 9); + gSaveContext.sceneFlags[SCENE_LAKE_HYLIA].swch |= (1 << 1); + gSaveContext.sceneFlags[SCENE_LOST_WOODS].swch |= (1 << 4) | (1 << 18); + gSaveContext.sceneFlags[SCENE_ZORAS_RIVER].swch |= (1 << 3); + } + + if (Randomizer_GetSettingValue(RSK_SHUFFLE_BEAN_SOULS) == RO_GENERIC_OFF) { + Flags_SetRandomizerInf(RAND_INF_DEATH_MOUNTAIN_CRATER_BEAN_SOUL); + Flags_SetRandomizerInf(RAND_INF_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL); + Flags_SetRandomizerInf(RAND_INF_DESERT_COLOSSUS_BEAN_SOUL); + Flags_SetRandomizerInf(RAND_INF_GERUDO_VALLEY_BEAN_SOUL); + Flags_SetRandomizerInf(RAND_INF_GRAVEYARD_BEAN_SOUL); + Flags_SetRandomizerInf(RAND_INF_KOKIRI_FOREST_BEAN_SOUL); + Flags_SetRandomizerInf(RAND_INF_LAKE_HYLIA_BEAN_SOUL); + Flags_SetRandomizerInf(RAND_INF_LOST_WOODS_BRIDGE_BEAN_SOUL); + Flags_SetRandomizerInf(RAND_INF_LOST_WOODS_BEAN_SOUL); + Flags_SetRandomizerInf(RAND_INF_ZORAS_RIVER_BEAN_SOUL); + } + if (Randomizer_GetSettingValue(RSK_SHUFFLE_OCARINA_BUTTONS) == RO_GENERIC_OFF) { Flags_SetRandomizerInf(RAND_INF_HAS_OCARINA_A); Flags_SetRandomizerInf(RAND_INF_HAS_OCARINA_C_LEFT); @@ -263,6 +290,10 @@ extern "C" void Randomizer_InitSaveFile() { Flags_SetRandomizerInf(RAND_INF_CAN_SWIM); } + if (Randomizer_GetSettingValue(RSK_SHUFFLE_OPEN_CHEST) == RO_GENERIC_OFF) { + Flags_SetRandomizerInf(RAND_INF_CAN_OPEN_CHEST); + } + if (Randomizer_GetSettingValue(RSK_SHUFFLE_CHILD_WALLET) == RO_GENERIC_OFF) { Flags_SetRandomizerInf(RAND_INF_HAS_WALLET); } diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index 6adccc5e5a3..92db72a3c93 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -214,12 +214,14 @@ void Settings::CreateOptions() { OPT_BOOL(RSK_SHUFFLE_OCARINA, "Shuffle Ocarinas", CVAR_RANDOMIZER_SETTING("ShuffleOcarinas"), mOptionDescriptions[RSK_SHUFFLE_OCARINA]); OPT_BOOL(RSK_SHUFFLE_OCARINA_BUTTONS, "Shuffle Ocarina Buttons", CVAR_RANDOMIZER_SETTING("ShuffleOcarinaButtons"), mOptionDescriptions[RSK_SHUFFLE_OCARINA_BUTTONS]); OPT_BOOL(RSK_SHUFFLE_SWIM, "Shuffle Swim", CVAR_RANDOMIZER_SETTING("ShuffleSwim"), mOptionDescriptions[RSK_SHUFFLE_SWIM]); + OPT_BOOL(RSK_SHUFFLE_OPEN_CHEST, "Shuffle Open Chest", CVAR_RANDOMIZER_SETTING("ShuffleOpenChest"), mOptionDescriptions[RSK_SHUFFLE_OPEN_CHEST]); OPT_BOOL(RSK_SHUFFLE_WEIRD_EGG, "Shuffle Weird Egg", CVAR_RANDOMIZER_SETTING("ShuffleWeirdEgg"), mOptionDescriptions[RSK_SHUFFLE_WEIRD_EGG]); OPT_BOOL(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD, "Shuffle Gerudo Membership Card", CVAR_RANDOMIZER_SETTING("ShuffleGerudoToken"), mOptionDescriptions[RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD]); OPT_U8(RSK_SHUFFLE_POTS, "Shuffle Pots", {"Off", "Dungeons", "Overworld", "All Pots"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShufflePots"), mOptionDescriptions[RSK_SHUFFLE_POTS], WidgetType::Combobox, RO_SHUFFLE_POTS_OFF); OPT_U8(RSK_SHUFFLE_GRASS, "Shuffle Grass", {"Off", "Dungeons", "Overworld", "All Grass/Bushes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleGrass"), mOptionDescriptions[RSK_SHUFFLE_GRASS], WidgetType::Combobox, RO_SHUFFLE_GRASS_OFF); OPT_U8(RSK_SHUFFLE_CRATES, "Shuffle Crates", {"Off", "Dungeons", "Overworld", "All Crates"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleCrates"), mOptionDescriptions[RSK_SHUFFLE_CRATES], WidgetType::Combobox, RO_SHUFFLE_CRATES_OFF); OPT_BOOL(RSK_SHUFFLE_TREES, "Shuffle Trees", CVAR_RANDOMIZER_SETTING("ShuffleTrees"), mOptionDescriptions[RSK_SHUFFLE_TREES]); + OPT_BOOL(RSK_SHUFFLE_BUSHES, "Shuffle Bushes", CVAR_RANDOMIZER_SETTING("ShuffleBushes"), mOptionDescriptions[RSK_SHUFFLE_BUSHES]); OPT_BOOL(RSK_SHUFFLE_FISHING_POLE, "Shuffle Fishing Pole", CVAR_RANDOMIZER_SETTING("ShuffleFishingPole"), mOptionDescriptions[RSK_SHUFFLE_FISHING_POLE]); OPT_U8(RSK_SHUFFLE_MERCHANTS, "Shuffle Merchants", {"Off", "Bean Merchant Only", "All But Beans", "All"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleMerchants"), mOptionDescriptions[RSK_SHUFFLE_MERCHANTS], WidgetType::Combobox, RO_SHUFFLE_MERCHANTS_OFF, IMFLAG_NONE); OPT_U8(RSK_MERCHANT_PRICES, "Merchant Prices", {"Vanilla", "Cheap Balanced", "Balanced", "Fixed", "Range", "Set By Wallet"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantPrices"), mOptionDescriptions[RSK_MERCHANT_PRICES], WidgetType::Combobox, RO_PRICE_VANILLA, false, IMFLAG_NONE); @@ -236,6 +238,7 @@ void Settings::CreateOptions() { OPT_BOOL(RSK_SHUFFLE_ADULT_TRADE, "Shuffle Adult Trade", CVAR_RANDOMIZER_SETTING("ShuffleAdultTrade"), mOptionDescriptions[RSK_SHUFFLE_ADULT_TRADE]); OPT_U8(RSK_SHUFFLE_CHEST_MINIGAME, "Shuffle Chest Minigame", {"Off", "On (Separate)", "On (Pack)"}); OPT_BOOL(RSK_SHUFFLE_100_GS_REWARD, "Shuffle 100 GS Reward", CVAR_RANDOMIZER_SETTING("Shuffle100GSReward"), mOptionDescriptions[RSK_SHUFFLE_100_GS_REWARD], IMFLAG_SEPARATOR_BOTTOM, WidgetType::Checkbox, RO_GENERIC_OFF); + OPT_BOOL(RSK_SHUFFLE_BEAN_SOULS, "Shuffle Bean Souls", CVAR_RANDOMIZER_SETTING("ShuffleBeanSouls"), mOptionDescriptions[RSK_SHUFFLE_BEAN_SOULS], IMFLAG_SEPARATOR_BOTTOM, WidgetType::Checkbox, RO_GENERIC_OFF); OPT_U8(RSK_SHUFFLE_BOSS_SOULS, "Shuffle Boss Souls", {"Off", "On", "On + Ganon"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleBossSouls"), mOptionDescriptions[RSK_SHUFFLE_BOSS_SOULS], WidgetType::Combobox); OPT_BOOL(RSK_SHUFFLE_DEKU_STICK_BAG, "Shuffle Deku Stick Bag", CVAR_RANDOMIZER_SETTING("ShuffleDekuStickBag"), mOptionDescriptions[RSK_SHUFFLE_DEKU_STICK_BAG], IMFLAG_SEPARATOR_BOTTOM, WidgetType::Checkbox, RO_GENERIC_OFF); OPT_BOOL(RSK_SHUFFLE_DEKU_NUT_BAG, "Shuffle Deku Nut Bag", CVAR_RANDOMIZER_SETTING("ShuffleDekuNutBag"), mOptionDescriptions[RSK_SHUFFLE_DEKU_NUT_BAG], IMFLAG_SEPARATOR_BOTTOM, WidgetType::Checkbox, RO_GENERIC_OFF); @@ -275,6 +278,7 @@ void Settings::CreateOptions() { OPT_BOOL(RSK_SKIP_CHILD_ZELDA, "Skip Child Zelda", {"Don't Skip", "Skip"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("SkipChildZelda"), mOptionDescriptions[RSK_SKIP_CHILD_ZELDA], WidgetType::Checkbox, RO_GENERIC_DONT_SKIP); OPT_BOOL(RSK_SKIP_EPONA_RACE, "Skip Epona Race", {"Don't Skip", "Skip"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("SkipEponaRace"), mOptionDescriptions[RSK_SKIP_EPONA_RACE], WidgetType::Checkbox, RO_GENERIC_DONT_SKIP); OPT_BOOL(RSK_SKIP_SCARECROWS_SONG, "Skip Scarecrow's Song", CVAR_RANDOMIZER_SETTING("SkipScarecrowsSong"), mOptionDescriptions[RSK_SKIP_SCARECROWS_SONG]); + OPT_BOOL(RSK_SKIP_PLANTING_BEANS, "Skip Planting Beans", CVAR_RANDOMIZER_SETTING("SkipPlantingBeans"), mOptionDescriptions[RSK_SKIP_PLANTING_BEANS]); OPT_U8(RSK_BIG_POE_COUNT, "Big Poe Target Count", {NumOpts(0, 10)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("BigPoeTargetCount"), mOptionDescriptions[RSK_BIG_POE_COUNT], WidgetType::Slider, 10); OPT_BOOL(RSK_COMPLETE_MASK_QUEST, "Complete Mask Quest", CVAR_RANDOMIZER_SETTING("CompleteMaskQuest"), mOptionDescriptions[RSK_COMPLETE_MASK_QUEST]); OPT_U8(RSK_GOSSIP_STONE_HINTS, "Gossip Stone Hints", {"No Hints", "Need Nothing", "Mask of Truth", "Stone of Agony"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GossipStoneHints"), mOptionDescriptions[RSK_GOSSIP_STONE_HINTS], WidgetType::Combobox, RO_GOSSIP_STONES_NEED_NOTHING, false, IMFLAG_NONE); @@ -1262,6 +1266,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_OCARINA], &mOptions[RSK_SHUFFLE_OCARINA_BUTTONS], &mOptions[RSK_SHUFFLE_SWIM], + &mOptions[RSK_SHUFFLE_OPEN_CHEST], &mOptions[RSK_SHUFFLE_WEIRD_EGG], &mOptions[RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD], &mOptions[RSK_SHUFFLE_FISHING_POLE], @@ -1304,6 +1309,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_POTS], &mOptions[RSK_SHUFFLE_CRATES], &mOptions[RSK_SHUFFLE_TREES], + &mOptions[RSK_SHUFFLE_BUSHES], &mOptions[RSK_SHUFFLE_MERCHANTS], &mOptions[RSK_MERCHANT_PRICES], &mOptions[RSK_MERCHANT_PRICES_FIXED_PRICE], @@ -1318,6 +1324,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_FROG_SONG_RUPEES], &mOptions[RSK_SHUFFLE_ADULT_TRADE], &mOptions[RSK_SHUFFLE_100_GS_REWARD], + &mOptions[RSK_SHUFFLE_BEAN_SOULS], &mOptions[RSK_SHUFFLE_BOSS_SOULS], &mOptions[RSK_SHUFFLE_FOUNTAIN_FAIRIES], &mOptions[RSK_SHUFFLE_STONE_FAIRIES], @@ -1364,7 +1371,7 @@ void Settings::CreateOptions() { mOptionGroups[RSG_TIMESAVERS_IMGUI] = OptionGroup::SubGroup( "Timesavers", { &mOptions[RSK_BIG_POE_COUNT], &mOptions[RSK_SKIP_CHILD_ZELDA], &mOptions[RSK_SKIP_EPONA_RACE], - &mOptions[RSK_COMPLETE_MASK_QUEST], &mOptions[RSK_SKIP_SCARECROWS_SONG] }, + &mOptions[RSK_COMPLETE_MASK_QUEST], &mOptions[RSK_SKIP_SCARECROWS_SONG], &mOptions[RSK_SKIP_PLANTING_BEANS] }, WidgetContainerType::COLUMN); mOptionGroups[RSG_ITEM_POOL_HINTS_IMGUI] = OptionGroup::SubGroup("", { @@ -1561,10 +1568,12 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_POTS], &mOptions[RSK_SHUFFLE_CRATES], &mOptions[RSK_SHUFFLE_TREES], + &mOptions[RSK_SHUFFLE_BUSHES], &mOptions[RSK_SHUFFLE_KOKIRI_SWORD], &mOptions[RSK_SHUFFLE_OCARINA], &mOptions[RSK_SHUFFLE_OCARINA_BUTTONS], &mOptions[RSK_SHUFFLE_SWIM], + &mOptions[RSK_SHUFFLE_OPEN_CHEST], &mOptions[RSK_SHUFFLE_WEIRD_EGG], &mOptions[RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD], &mOptions[RSK_SHUFFLE_MERCHANTS], @@ -1582,6 +1591,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_ADULT_TRADE], &mOptions[RSK_SHUFFLE_CHEST_MINIGAME], &mOptions[RSK_SHUFFLE_100_GS_REWARD], + &mOptions[RSK_SHUFFLE_BEAN_SOULS], &mOptions[RSK_SHUFFLE_BOSS_SOULS], &mOptions[RSK_SHUFFLE_DEKU_STICK_BAG], &mOptions[RSK_SHUFFLE_DEKU_NUT_BAG], @@ -1653,6 +1663,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SKIP_CHILD_ZELDA], &mOptions[RSK_SKIP_EPONA_RACE], &mOptions[RSK_SKIP_SCARECROWS_SONG], + &mOptions[RSK_SKIP_PLANTING_BEANS], &mOptions[RSK_BIG_POE_COUNT], &mOptions[RSK_COMPLETE_MASK_QUEST], }); diff --git a/soh/soh/SohGui/SohMenuEnhancements.cpp b/soh/soh/SohGui/SohMenuEnhancements.cpp index 149eb6577c4..46307f186bf 100644 --- a/soh/soh/SohGui/SohMenuEnhancements.cpp +++ b/soh/soh/SohGui/SohMenuEnhancements.cpp @@ -293,6 +293,10 @@ void SohMenu::AddMenuEnhancements() { .CVar(CVAR_ENHANCEMENT("BetterOwl")) .Options(CheckboxOptions().Tooltip( "The default response to Kaepora Gaebora is always that you understood what he said.")); + AddWidget(path, "Allow Dropping Throw-Only Objects", WIDGET_CVAR_CHECKBOX) + .CVar(CVAR_ENHANCEMENT("DropThrowOnlyObjects")) + .Options(CheckboxOptions().Tooltip("Allows normally throw-only objects (such as Cuccos, pots, grass, and small " + "rocks) to be dropped by pressing A while standing still.")); AddWidget(path, "Convenience", WIDGET_SEPARATOR_TEXT); AddWidget(path, "Quit Fishing at Door", WIDGET_CVAR_CHECKBOX) @@ -1629,6 +1633,17 @@ void SohMenu::AddMenuEnhancements() { .CVar(CVAR_ENHANCEMENT("ExtraTraps.Teleport")) .PreFunc( [](WidgetInfo& info) { info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) == 0; }); + AddWidget(path, "Nightmare Traps:", WIDGET_TEXT).PreFunc([](WidgetInfo& info) { + info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) == 0; + }); + AddWidget(path, "Pocket Traps", WIDGET_CVAR_CHECKBOX) + .CVar(CVAR_ENHANCEMENT("ExtraTraps.Pocket")) + .PreFunc( + [](WidgetInfo& info) { info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) == 0; }); + AddWidget(path, "Perma Death Traps", WIDGET_CVAR_CHECKBOX) + .CVar(CVAR_ENHANCEMENT("ExtraTraps.Permadeath")) + .PreFunc( + [](WidgetInfo& info) { info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) == 0; }); path.column = SECTION_COLUMN_2; AddWidget(path, "Enemy Randomizer", WIDGET_CVAR_COMBOBOX) @@ -1739,6 +1754,9 @@ void SohMenu::AddMenuEnhancements() { .Options(CheckboxOptions().Tooltip( "Keese and Guay no longer target you and simply ignore you as if you were wearing the " "Skull Mask.")); + AddWidget(path, "Like Like don't Steal Items", WIDGET_CVAR_CHECKBOX) + .CVar(CVAR_CHEAT("NoLikeLikeItemSteal")) + .Options(CheckboxOptions().Tooltip("Prevents Like Likes from being able to steal your equipments.")); AddWidget(path, "Disable Haunted Wasteland Sandstorm", WIDGET_CVAR_CHECKBOX) .CVar(CVAR_CHEAT("DisableSandstorm")) .Options(CheckboxOptions().Tooltip("Disables sandstorm effect in Haunted Wasteland.")); diff --git a/soh/src/overlays/actors/ovl_En_Rr/z_en_rr.c b/soh/src/overlays/actors/ovl_En_Rr/z_en_rr.c index 831e11b8c38..d94e6dd220b 100644 --- a/soh/src/overlays/actors/ovl_En_Rr/z_en_rr.c +++ b/soh/src/overlays/actors/ovl_En_Rr/z_en_rr.c @@ -300,32 +300,35 @@ void EnRr_SetupReleasePlayer(EnRr* this, PlayState* play) { this->wobbleSizeTarget = 2048.0f; tunic = 0; shield = 0; - if (CUR_EQUIP_VALUE(EQUIP_TYPE_SHIELD) != EQUIP_VALUE_SHIELD_MIRROR) { - shield = Inventory_DeleteEquipment(play, EQUIP_TYPE_SHIELD); - if (shield != 0) { - this->eatenShield = shield; - this->retreat = true; + if (GameInteractor_Should(VB_LIKE_LIKE_STEAL_EQUIPMENT, true, this)) { + if (CUR_EQUIP_VALUE(EQUIP_TYPE_SHIELD) != EQUIP_VALUE_SHIELD_MIRROR) { + shield = Inventory_DeleteEquipment(play, EQUIP_TYPE_SHIELD); + if (shield != 0) { + this->eatenShield = shield; + this->retreat = true; + } } - } - if (CUR_EQUIP_VALUE(EQUIP_TYPE_TUNIC) != EQUIP_VALUE_TUNIC_KOKIRI && !IS_RANDO /* Randomizer Save File */) { - tunic = Inventory_DeleteEquipment(play, EQUIP_TYPE_TUNIC); - if (tunic != 0) { - this->eatenTunic = tunic; - this->retreat = true; + if (CUR_EQUIP_VALUE(EQUIP_TYPE_TUNIC) != EQUIP_VALUE_TUNIC_KOKIRI && !IS_RANDO /* Randomizer Save File */) { + tunic = Inventory_DeleteEquipment(play, EQUIP_TYPE_TUNIC); + if (tunic != 0) { + this->eatenTunic = tunic; + this->retreat = true; + } + } + + switch (EnRr_GetMessage(shield, tunic)) { + case RR_MESSAGE_SHIELD: + Message_StartTextbox(play, 0x305F, NULL); + break; + case RR_MESSAGE_TUNIC: + Message_StartTextbox(play, 0x3060, NULL); + break; + case RR_MESSAGE_TUNIC | RR_MESSAGE_SHIELD: + Message_StartTextbox(play, 0x3061, NULL); + break; } } player->actor.parent = NULL; - switch (EnRr_GetMessage(shield, tunic)) { - case RR_MESSAGE_SHIELD: - Message_StartTextbox(play, 0x305F, NULL); - break; - case RR_MESSAGE_TUNIC: - Message_StartTextbox(play, 0x3060, NULL); - break; - case RR_MESSAGE_TUNIC | RR_MESSAGE_SHIELD: - Message_StartTextbox(play, 0x3061, NULL); - break; - } osSyncPrintf(VT_FGCOL(YELLOW) "%s[%d] : Rr_Catch_Cancel" VT_RST "\n", __FILE__, __LINE__); func_8002F6D4(play, &this->actor, 4.0f, this->actor.shape.rot.y, 12.0f, 8); if (this->actor.colorFilterTimer == 0) { @@ -666,50 +669,53 @@ void EnRr_Death(EnRr* this, PlayState* play) { (SQ(4 - i) * (f32)this->frameCount * 0.003f) + 1.0f; } } else if (this->frameCount >= 95) { - Vec3f dropPos; - - dropPos.x = this->actor.world.pos.x; - dropPos.y = this->actor.world.pos.y; - dropPos.z = this->actor.world.pos.z; - switch (this->eatenShield) { - case 1: - Item_DropCollectible(play, &dropPos, ITEM00_SHIELD_DEKU); - break; - case 2: - Item_DropCollectible(play, &dropPos, ITEM00_SHIELD_HYLIAN); - break; - } - switch (this->eatenTunic) { - case 2: - Item_DropCollectible(play, &dropPos, ITEM00_TUNIC_GORON); - break; - case 3: - Item_DropCollectible(play, &dropPos, ITEM00_TUNIC_ZORA); - break; - } - // "dropped" - osSyncPrintf(VT_FGCOL(GREEN) "「%s」が出た!!" VT_RST "\n", sDropNames[this->dropType]); - switch (this->dropType) { - case RR_DROP_MAGIC: - Item_DropCollectible(play, &dropPos, ITEM00_MAGIC_SMALL); - break; - case RR_DROP_ARROW: - Item_DropCollectible(play, &dropPos, ITEM00_ARROWS_SINGLE); - break; - case RR_DROP_FLEXIBLE: - Item_DropCollectible(play, &dropPos, ITEM00_FLEXIBLE); - break; - case RR_DROP_RUPEE_PURPLE: - Item_DropCollectible(play, &dropPos, ITEM00_RUPEE_PURPLE); - break; - case RR_DROP_RUPEE_RED: - Item_DropCollectible(play, &dropPos, ITEM00_RUPEE_RED); - break; - case RR_DROP_RANDOM_RUPEE: - default: - Item_DropCollectibleRandom(play, &this->actor, &dropPos, 12 << 4); - break; + if (GameInteractor_Should(VB_LIKE_LIKE_DROP_COLLECTIBLE, true, this)) { + Vec3f dropPos; + + dropPos.x = this->actor.world.pos.x; + dropPos.y = this->actor.world.pos.y; + dropPos.z = this->actor.world.pos.z; + switch (this->eatenShield) { + case 1: + Item_DropCollectible(play, &dropPos, ITEM00_SHIELD_DEKU); + break; + case 2: + Item_DropCollectible(play, &dropPos, ITEM00_SHIELD_HYLIAN); + break; + } + switch (this->eatenTunic) { + case 2: + Item_DropCollectible(play, &dropPos, ITEM00_TUNIC_GORON); + break; + case 3: + Item_DropCollectible(play, &dropPos, ITEM00_TUNIC_ZORA); + break; + } + // "dropped" + osSyncPrintf(VT_FGCOL(GREEN) "「%s」が出た!!" VT_RST "\n", sDropNames[this->dropType]); + switch (this->dropType) { + case RR_DROP_MAGIC: + Item_DropCollectible(play, &dropPos, ITEM00_MAGIC_SMALL); + break; + case RR_DROP_ARROW: + Item_DropCollectible(play, &dropPos, ITEM00_ARROWS_SINGLE); + break; + case RR_DROP_FLEXIBLE: + Item_DropCollectible(play, &dropPos, ITEM00_FLEXIBLE); + break; + case RR_DROP_RUPEE_PURPLE: + Item_DropCollectible(play, &dropPos, ITEM00_RUPEE_PURPLE); + break; + case RR_DROP_RUPEE_RED: + Item_DropCollectible(play, &dropPos, ITEM00_RUPEE_RED); + break; + case RR_DROP_RANDOM_RUPEE: + default: + Item_DropCollectibleRandom(play, &this->actor, &dropPos, 12 << 4); + break; + } } + Actor_Kill(&this->actor); } else if (this->frameCount == 88) { Vec3f pos; diff --git a/soh/src/overlays/actors/ovl_En_Wood02/z_en_wood02.c b/soh/src/overlays/actors/ovl_En_Wood02/z_en_wood02.c index 1fe96d38c67..b83bd3ddd04 100644 --- a/soh/src/overlays/actors/ovl_En_Wood02/z_en_wood02.c +++ b/soh/src/overlays/actors/ovl_En_Wood02/z_en_wood02.c @@ -403,12 +403,14 @@ void EnWood02_Update(Actor* thisx, PlayState* play2) { (player->linearVelocity != 0.0f)) || ((player->rideActor != NULL) && (sqrt(this->actor.xyzDistToPlayerSq) < 60.0) && (player->rideActor->speedXZ != 0.0f))) { - if ((this->unk_14C >= 0) && (this->unk_14C < 0x64)) { - Item_DropCollectibleRandom(play, &this->actor, &this->actor.world.pos, - ((this->unk_14C << 4) | 0x8000)); + if (GameInteractor_Should(VB_BUSH_DROP_ITEM, true, this)) { + if ((this->unk_14C >= 0) && (this->unk_14C < 0x64)) { + Item_DropCollectibleRandom(play, &this->actor, &this->actor.world.pos, + ((this->unk_14C << 4) | 0x8000)); + } + this->unk_14C = -0x15; + Audio_PlayActorSound2(&this->actor, NA_SE_EV_TREE_SWING); } - this->unk_14C = -0x15; - Audio_PlayActorSound2(&this->actor, NA_SE_EV_TREE_SWING); } } } else { // Leaves 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 7da8447c03a..320be5f2a59 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -7382,7 +7382,7 @@ s32 Player_ActionHandler_2(Player* this, PlayState* play) { } else if (CHECK_BTN_ALL(sControlInput->press.button, BTN_A) && !(this->stateFlags1 & PLAYER_STATE1_CARRYING_ACTOR) && !(this->stateFlags2 & PLAYER_STATE2_UNDERWATER)) { - if (this->getItemId != GI_NONE) { + if (GameInteractor_Should(VB_OPEN_CHEST, this->getItemId != GI_NONE)) { GetItemEntry giEntry; if (this->getItemEntry.objectId == OBJECT_INVALID) { giEntry = ItemTable_Retrieve(-this->getItemId); From 272f223a9ee49b0956a7cabe3170f07b8536a5af Mon Sep 17 00:00:00 2001 From: TheLynk Date: Tue, 18 Nov 2025 18:40:52 +0100 Subject: [PATCH 12/45] Add Branch "Shuffle Roll" | Version : 2.0 --- .../vanilla-behavior/GIVanillaBehavior.h | 8 ++++++++ soh/soh/Enhancements/gameplaystats.cpp | 2 +- .../3drando/hint_list/hint_list_item.cpp | 2 ++ .../randomizer/3drando/item_pool.cpp | 4 ++++ soh/soh/Enhancements/randomizer/draw.cpp | 18 ++++++++++++++++++ soh/soh/Enhancements/randomizer/draw.h | 1 + .../Enhancements/randomizer/hook_handlers.cpp | 3 +++ soh/soh/Enhancements/randomizer/item_list.cpp | 3 +++ soh/soh/Enhancements/randomizer/logic.cpp | 14 ++++++++++++-- .../randomizer/option_descriptions.cpp | 1 + soh/soh/Enhancements/randomizer/randomizer.cpp | 6 +++++- .../Enhancements/randomizer/randomizerTypes.h | 3 +++ .../Enhancements/randomizer/randomizer_inf.h | 1 + soh/soh/Enhancements/randomizer/savefile.cpp | 4 ++++ soh/soh/Enhancements/randomizer/settings.cpp | 3 +++ .../actors/ovl_player_actor/z_player.c | 12 +++++++----- 16 files changed, 76 insertions(+), 9 deletions(-) diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index 5ce333e5484..60d5d3ccaa0 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -318,6 +318,14 @@ typedef enum { // - `*ObjKibako2` VB_CRATE_SETUP_DRAW, + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - None + VB_ROLL, + // #### `result` // ```c // true diff --git a/soh/soh/Enhancements/gameplaystats.cpp b/soh/soh/Enhancements/gameplaystats.cpp index ade699a3cc1..20a6e9a5ba9 100644 --- a/soh/soh/Enhancements/gameplaystats.cpp +++ b/soh/soh/Enhancements/gameplaystats.cpp @@ -446,7 +446,7 @@ void DrawGameplayStatsHeader() { // if tag is empty (not a release build) if (gGitCommitTag[0] == 0) { GameplayStatsRow("Git Branch:", (char*)gGitBranch); - GameplayStatsRow("Version : 1.0 | Git Commit Hash:", (char*)gGitCommitHash); + GameplayStatsRow("Version : 2.0 | Git Commit Hash:", (char*)gGitCommitHash); } else { GameplayStatsRow("Build Version:", (char*)gBuildVersion); } diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp index 471362e30e7..ee114d114fe 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp @@ -2102,6 +2102,8 @@ void StaticData::HintTable_Init_Item() { { CustomMessage("a master unlocker", /*german*/ "ein Meisterentsperrer", /*french*/ "un Kit de Déverrouillage") }); // /*spanish*/un desbloqueador maestro + hintTextTable[RHT_ROLL] = HintText(CustomMessage("the ability to roll", /*german*/"die Fähigkeit zu rollen", /*french*/"la capacité de faire des roulades")); + hintTextTable[RHT_OPEN_CHEST] = HintText(CustomMessage("the ability to open chests", /*german*/"!!!", /*french*/"!!!")); //RANDOTODO if these are ever used for anything other than name, they want abscure and ambiguous hints diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index 75089f210e9..94155866894 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -578,6 +578,10 @@ void GenerateItemPool() { AddItemToMainPool(RG_PROGRESSIVE_SCALE); } + if (ctx->GetOption(RSK_SHUFFLE_ROLL)) { + AddItemToMainPool(RG_ROLL); + } + if (ctx->GetOption(RSK_SHUFFLE_OPEN_CHEST)) { AddItemToMainPool(RG_OPEN_CHEST); } diff --git a/soh/soh/Enhancements/randomizer/draw.cpp b/soh/soh/Enhancements/randomizer/draw.cpp index 25e9f060e60..adbc022c4ad 100644 --- a/soh/soh/Enhancements/randomizer/draw.cpp +++ b/soh/soh/Enhancements/randomizer/draw.cpp @@ -35,6 +35,7 @@ extern "C" { #include "overlays/ovl_Boss_Sst/ovl_Boss_Sst.h" #include "objects/object_tw/object_tw.h" #include "objects/object_ganon2/object_ganon2.h" +#include "objects/object_vase/object_vase.h" extern PlayState* gPlayState; extern SaveContext gSaveContext; @@ -1122,6 +1123,23 @@ extern "C" void Randomizer_DrawBronzeScale(PlayState* play, GetItemEntry* getIte CLOSE_DISPS(play->state.gfxCtx); } +extern "C" void Randomizer_DrawRollAbility(PlayState* play, GetItemEntry* getItemEntry) { + OPEN_DISPS(play->state.gfxCtx); + + Gfx_SetupDL_25Opa(play->state.gfxCtx); + + // Objet central qui roule - réduit de 20% avec centrage ajusté + Matrix_Translate(21.0f, 0.0f, 0.0f, MTXMODE_APPLY); + Matrix_RotateZ(1.57f, MTXMODE_APPLY); + Matrix_RotateY(play->gameplayFrames * 0.15f, MTXMODE_APPLY); + Matrix_Scale(0.018f, 0.018f, 0.018f, MTXMODE_APPLY); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), + G_MTX_MODELVIEW | G_MTX_LOAD); + gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gUnusedVaseDL); + + CLOSE_DISPS(play->state.gfxCtx); +} + extern "C" void Randomizer_DrawOpenChest(PlayState* play, GetItemEntry* getItemEntry) { OPEN_DISPS(play->state.gfxCtx); diff --git a/soh/soh/Enhancements/randomizer/draw.h b/soh/soh/Enhancements/randomizer/draw.h index 3adad3899ad..6514319400a 100644 --- a/soh/soh/Enhancements/randomizer/draw.h +++ b/soh/soh/Enhancements/randomizer/draw.h @@ -22,6 +22,7 @@ void Randomizer_DrawTriforcePiece(PlayState* play, GetItemEntry getItemEntry); void Randomizer_DrawTriforcePieceGI(PlayState* play, GetItemEntry getItemEntry); void Randomizer_DrawOcarinaButton(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawBronzeScale(PlayState* play, GetItemEntry* getItemEntry); +void Randomizer_DrawRollAbility(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawOpenChest(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawFishingPoleGI(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawSkeletonKey(PlayState* play, GetItemEntry* getItemEntry); diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 4fdc39cc3df..be1703168c7 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -795,6 +795,9 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l va_copy(args, originalArgs); switch (id) { + case VB_ROLL: + *should = !RAND_GET_OPTION(RSK_SHUFFLE_ROLL) || Flags_GetRandomizerInf(RAND_INF_CAN_ROLL); + break; case VB_ALLOW_ENTRANCE_CS_FOR_EITHER_AGE: { s32 entranceIndex = va_arg(args, s32); diff --git a/soh/soh/Enhancements/randomizer/item_list.cpp b/soh/soh/Enhancements/randomizer/item_list.cpp index e3882732faf..27d85af1e3b 100644 --- a/soh/soh/Enhancements/randomizer/item_list.cpp +++ b/soh/soh/Enhancements/randomizer/item_list.cpp @@ -372,6 +372,9 @@ void Rando::StaticData::InitItemTable() { itemTable[RG_BRONZE_SCALE] = Item(RG_BRONZE_SCALE, Text{ "Bronze Scale", "Écaille de Bronze", "Bronzene Schuppe" }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, LOGIC_NONE, RHT_BRONZE_SCALE, RG_BRONZE_SCALE, OBJECT_GI_SCALE, GID_SCALE_SILVER, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_BRONZE_SCALE].SetCustomDrawFunc(Randomizer_DrawBronzeScale); + itemTable[RG_ROLL] = Item(RG_ROLL, Text{ "Roll", "Rouler", "Rolle" }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, LOGIC_NONE, RHT_ROLL, RG_ROLL, OBJECT_GI_SCALE, GID_SCALE_SILVER, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_ROLL].SetCustomDrawFunc(Randomizer_DrawRollAbility); + itemTable[RG_OPEN_CHEST] = Item(RG_OPEN_CHEST, Text{ "Open Chests", "!!!", "!!!" }, ITEMTYPE_ITEM, GI_KEY_SMALL, true, LOGIC_NONE, RHT_OPEN_CHEST, RG_OPEN_CHEST, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_OPEN_CHEST].SetCustomDrawFunc(Randomizer_DrawOpenChest); diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index 3cc1130acaf..327bfcc8614 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -235,6 +235,8 @@ bool Logic::HasItem(RandomizerGet itemName) { return CurrentUpgrade(UPG_SCALE) >= 1; case RG_GOLDEN_SCALE: return CurrentUpgrade(UPG_SCALE) >= 2; + case RG_ROLL: + return CheckRandoInf(RAND_INF_CAN_ROLL); case RG_POCKET_EGG: return CheckRandoInf(RAND_INF_ADULT_TRADES_HAS_POCKET_EGG); case RG_COJIRO: @@ -1169,7 +1171,7 @@ bool Logic::CanBreakPots() { } bool Logic::CanBreakCrates() { - return true; + return HasItem(RG_ROLL) || CanUse(RG_MEGATON_HAMMER) || CanUse(RG_BOMB_BAG) || CanUse(RG_BOMBCHU_5); } bool Logic::CanBreakSmallCrates() { @@ -1177,7 +1179,7 @@ bool Logic::CanBreakSmallCrates() { } bool Logic::CanBonkTrees() { - return true; + return HasItem(RG_ROLL); } bool Logic::HasExplosives() { @@ -1597,6 +1599,9 @@ void Logic::ApplyItemEffect(Item& item, bool state) { case RG_CLAIM_CHECK: SetRandoInf(randoGet - RG_COJIRO + RAND_INF_ADULT_TRADES_HAS_COJIRO, state); break; + case RG_ROLL: + SetRandoInf(RAND_INF_CAN_ROLL, state); + break; case RG_OPEN_CHEST: SetRandoInf(RAND_INF_CAN_OPEN_CHEST, state); break; @@ -2352,6 +2357,11 @@ void Logic::Reset(bool resetSaveContext /*= true*/) { SetRandoInf(RAND_INF_CAN_OPEN_CHEST, true); } + // If we're not shuffling roll, we start with it + if (ctx->GetOption(RSK_SHUFFLE_ROLL).Is(false)) { + SetRandoInf(RAND_INF_CAN_ROLL, true); + } + // If we're not shuffling child's wallet, we start with it if (ctx->GetOption(RSK_SHUFFLE_CHILD_WALLET).Is(false)) { SetRandoInf(RAND_INF_HAS_WALLET, true); diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp index 4836a476a58..fadc4e630fc 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -253,6 +253,7 @@ void Settings::CreateOptionDescriptions() { "\n" "If you enter a water entrance without swim you will be respawned on land to prevent infinite death loops.\n" "If you void out in Water Temple you will immediately be kicked out to prevent a softlock."; + mOptionDescriptions[RSK_SHUFFLE_ROLL] = "Shuffles the ability do a roll into the item pool."; mOptionDescriptions[RSK_SHUFFLE_OPEN_CHEST] = "Shuffles the ability to open chests into the item pool."; mOptionDescriptions[RSK_SHUFFLE_WEIRD_EGG] = "Shuffles the Weird Egg from Malon in to the item pool. Enabling " "\"Skip Child Zelda\" disables this feature.\n" diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 1da3ef7cbef..75388a614f8 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -5552,7 +5552,7 @@ CustomMessage Randomizer::GetGoronMessage(u16 index) { void Randomizer::CreateCustomMessages() { // RANDTODO: Translate into french and german and replace GIMESSAGE_UNTRANSLATED // with GIMESSAGE(getItemID, itemID, english, german, french). - const std::array getItemMessages = { { + const std::array getItemMessages = { { GIMESSAGE(RG_GREG_RUPEE, ITEM_MASK_GORON, "You found %gGreg%w!", "%gGreg%w! Du hast ihn&wirklich gefunden!", "Félicitation! Vous avez trouvé %gGreg%w!"), GIMESSAGE(RG_MASTER_SWORD, ITEM_SWORD_MASTER, "You found the %gMaster Sword%w!", @@ -5897,6 +5897,9 @@ void Randomizer::CreateCustomMessages() { GIMESSAGE(RG_BRONZE_SCALE, ITEM_SCALE_SILVER, "You got the %rBronze Scale%w!&The power of buoyancy is yours!", "Du hast die %rBronzene Schuppe%w&erhalten! Die Fähigkeit zu&Schwimmen ist nun dein!", "Vous obtenez l'%rÉcaille de Bronze%w!&Le pouvoir de la flottabilité est&à vous!"), + GIMESSAGE(RG_ROLL, ITEM_SCALE_SILVER, "You got the %rAbility do a roll%w!", + "Du hast die Fähigkeit, %reinen Wurf&zu machen%w!", + "Vous obtenez la %rCapacité de faire&des roulades%w!"), GIMESSAGE(RG_OPEN_CHEST, ITEM_KEY_SMALL, "You got the %rAbility to Open Chests%w!", TODO_TRANSLATE, TODO_TRANSLATE), GIMESSAGE(RG_FISHING_POLE, ITEM_FISHING_POLE, "You found a lost %rFishing Pole%w!&Time to hit the pond!", @@ -6069,6 +6072,7 @@ extern "C" u8 Return_Item_Entry(GetItemEntry itemEntry, u8 returnItem); std::map randomizerGetToRandInf = { { RG_FISHING_POLE, RAND_INF_FISHING_POLE_FOUND }, { RG_BRONZE_SCALE, RAND_INF_CAN_SWIM }, + { RG_ROLL, RAND_INF_CAN_ROLL }, { RG_OPEN_CHEST, RAND_INF_CAN_OPEN_CHEST }, { RG_QUIVER_INF, RAND_INF_HAS_INFINITE_QUIVER }, { RG_BOMB_BAG_INF, RAND_INF_HAS_INFINITE_BOMB_BAG }, diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 15167561d3e..5966b6a1e81 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -4338,6 +4338,7 @@ typedef enum { RG_HINT, RG_TYCOON_WALLET, RG_BRONZE_SCALE, + RG_ROLL, RG_OPEN_CHEST, RG_CHILD_WALLET, RG_BOMBCHU_BAG, @@ -5537,6 +5538,7 @@ typedef enum { RHT_OCARINA_C_LEFT_BUTTON, RHT_OCARINA_C_RIGHT_BUTTON, RHT_BRONZE_SCALE, + RHT_ROLL, RHT_OPEN_CHEST, RHT_FISHING_POLE, RHT_SKELETON_KEY, @@ -6117,6 +6119,7 @@ typedef enum { RSK_SHUFFLE_OCARINA, RSK_SHUFFLE_OCARINA_BUTTONS, RSK_SHUFFLE_SWIM, + RSK_SHUFFLE_ROLL, RSK_SHUFFLE_OPEN_CHEST, RSK_STARTING_DEKU_SHIELD, RSK_STARTING_KOKIRI_SWORD, diff --git a/soh/soh/Enhancements/randomizer/randomizer_inf.h b/soh/soh/Enhancements/randomizer/randomizer_inf.h index 76abc6e2e14..d6e5101f173 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_inf.h +++ b/soh/soh/Enhancements/randomizer/randomizer_inf.h @@ -1139,6 +1139,7 @@ DEFINE_RAND_INF(RAND_INF_ZF_BUSH_6) DEFINE_RAND_INF(RAND_INF_CAUGHT_LOACH) DEFINE_RAND_INF(RAND_INF_CAN_SWIM) +DEFINE_RAND_INF(RAND_INF_CAN_ROLL) DEFINE_RAND_INF(RAND_INF_CAN_OPEN_CHEST) DEFINE_RAND_INF(RAND_INF_HAS_WALLET) diff --git a/soh/soh/Enhancements/randomizer/savefile.cpp b/soh/soh/Enhancements/randomizer/savefile.cpp index d968a93c237..cc796a6656c 100644 --- a/soh/soh/Enhancements/randomizer/savefile.cpp +++ b/soh/soh/Enhancements/randomizer/savefile.cpp @@ -290,6 +290,10 @@ extern "C" void Randomizer_InitSaveFile() { Flags_SetRandomizerInf(RAND_INF_CAN_SWIM); } + if (Randomizer_GetSettingValue(RSK_SHUFFLE_ROLL) == RO_GENERIC_OFF) { + Flags_SetRandomizerInf(RAND_INF_CAN_ROLL); + } + if (Randomizer_GetSettingValue(RSK_SHUFFLE_OPEN_CHEST) == RO_GENERIC_OFF) { Flags_SetRandomizerInf(RAND_INF_CAN_OPEN_CHEST); } diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index 92db72a3c93..b277dc40d38 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -214,6 +214,7 @@ void Settings::CreateOptions() { OPT_BOOL(RSK_SHUFFLE_OCARINA, "Shuffle Ocarinas", CVAR_RANDOMIZER_SETTING("ShuffleOcarinas"), mOptionDescriptions[RSK_SHUFFLE_OCARINA]); OPT_BOOL(RSK_SHUFFLE_OCARINA_BUTTONS, "Shuffle Ocarina Buttons", CVAR_RANDOMIZER_SETTING("ShuffleOcarinaButtons"), mOptionDescriptions[RSK_SHUFFLE_OCARINA_BUTTONS]); OPT_BOOL(RSK_SHUFFLE_SWIM, "Shuffle Swim", CVAR_RANDOMIZER_SETTING("ShuffleSwim"), mOptionDescriptions[RSK_SHUFFLE_SWIM]); + OPT_BOOL(RSK_SHUFFLE_ROLL, "Shuffle Roll", CVAR_RANDOMIZER_SETTING("ShuffleRoll"), mOptionDescriptions[RSK_SHUFFLE_ROLL]); OPT_BOOL(RSK_SHUFFLE_OPEN_CHEST, "Shuffle Open Chest", CVAR_RANDOMIZER_SETTING("ShuffleOpenChest"), mOptionDescriptions[RSK_SHUFFLE_OPEN_CHEST]); OPT_BOOL(RSK_SHUFFLE_WEIRD_EGG, "Shuffle Weird Egg", CVAR_RANDOMIZER_SETTING("ShuffleWeirdEgg"), mOptionDescriptions[RSK_SHUFFLE_WEIRD_EGG]); OPT_BOOL(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD, "Shuffle Gerudo Membership Card", CVAR_RANDOMIZER_SETTING("ShuffleGerudoToken"), mOptionDescriptions[RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD]); @@ -1266,6 +1267,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_OCARINA], &mOptions[RSK_SHUFFLE_OCARINA_BUTTONS], &mOptions[RSK_SHUFFLE_SWIM], + &mOptions[RSK_SHUFFLE_ROLL], &mOptions[RSK_SHUFFLE_OPEN_CHEST], &mOptions[RSK_SHUFFLE_WEIRD_EGG], &mOptions[RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD], @@ -1573,6 +1575,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_OCARINA], &mOptions[RSK_SHUFFLE_OCARINA_BUTTONS], &mOptions[RSK_SHUFFLE_SWIM], + &mOptions[RSK_SHUFFLE_ROLL], &mOptions[RSK_SHUFFLE_OPEN_CHEST], &mOptions[RSK_SHUFFLE_WEIRD_EGG], &mOptions[RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD], diff --git a/soh/src/overlays/actors/ovl_player_actor/z_player.c b/soh/src/overlays/actors/ovl_player_actor/z_player.c index 320be5f2a59..8ee0d4546cd 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -6301,11 +6301,13 @@ s32 func_8083BBA0(Player* this, PlayState* play) { } void Player_SetupRoll(Player* this, PlayState* play) { - Player_SetupAction(play, this, Player_Action_Roll, 0); - LinkAnimation_PlayOnceSetSpeed(play, &this->skelAnime, - GET_PLAYER_ANIM(PLAYER_ANIMGROUP_landing_roll, this->modelAnimType), - 1.25f * sWaterSpeedFactor); - gSaveContext.ship.stats.count[COUNT_ROLLS]++; + if (GameInteractor_Should(VB_ROLL, true)) { + Player_SetupAction(play, this, Player_Action_Roll, 0); + LinkAnimation_PlayOnceSetSpeed(play, &this->skelAnime, + GET_PLAYER_ANIM(PLAYER_ANIMGROUP_landing_roll, this->modelAnimType), + 1.25f * sWaterSpeedFactor); + gSaveContext.ship.stats.count[COUNT_ROLLS]++; + } } s32 Player_TryRoll(Player* this, PlayState* play) { From 7cb889308ffb70f24051f8bc7c44d1ee744f2487 Mon Sep 17 00:00:00 2001 From: TheLynk Date: Wed, 19 Nov 2025 16:48:24 +0100 Subject: [PATCH 13/45] Fix Text in Item tracker and Logic for ZR | V:2.1 --- soh/soh/Enhancements/gameplaystats.cpp | 2 +- .../randomizer/location_access/overworld/zoras_river.cpp | 6 +++--- soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/soh/soh/Enhancements/gameplaystats.cpp b/soh/soh/Enhancements/gameplaystats.cpp index 20a6e9a5ba9..28cb639a8e2 100644 --- a/soh/soh/Enhancements/gameplaystats.cpp +++ b/soh/soh/Enhancements/gameplaystats.cpp @@ -446,7 +446,7 @@ void DrawGameplayStatsHeader() { // if tag is empty (not a release build) if (gGitCommitTag[0] == 0) { GameplayStatsRow("Git Branch:", (char*)gGitBranch); - GameplayStatsRow("Version : 2.0 | Git Commit Hash:", (char*)gGitCommitHash); + GameplayStatsRow("Version : 2.1 | Git Commit Hash:", (char*)gGitCommitHash); } else { GameplayStatsRow("Build Version:", (char*)gBuildVersion); } diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp index 67f24bd422f..9ef08c7904c 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp @@ -47,9 +47,9 @@ void RegionTable_Init_ZoraRiver() { LOCATION(RC_ZR_GS_LADDER, logic->IsChild && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_SHORT_JUMPSLASH) && logic->CanGetNightTimeGS()), LOCATION(RC_ZR_GS_NEAR_RAISED_GROTTOS, logic->IsAdult && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_LONGSHOT) && logic->CanGetNightTimeGS()), LOCATION(RC_ZR_GS_ABOVE_BRIDGE, logic->IsAdult && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_HOOKSHOT) && logic->CanGetNightTimeGS()), - LOCATION(RC_ZR_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), - LOCATION(RC_ZR_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), - LOCATION(RC_ZR_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_ZR_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_ZORAS_RIVER_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_ZR_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_ZORAS_RIVER_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_ZR_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_ZORAS_RIVER_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), LOCATION(RC_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_ZR_BENEATH_WATERFALL_LEFT_RUPEE, logic->IsAdult && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG))), diff --git a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp index 4023ca577a6..a7274c2f163 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp @@ -267,7 +267,7 @@ std::map itemTrackerBeanShortNames = { { RG_GERUDO_VALLEY_BEAN_SOUL, "GV" }, { RG_GRAVEYARD_BEAN_SOUL, "GY" }, { RG_KOKIRI_FOREST_BEAN_SOUL, "KF" }, - { RG_LAKE_HYLIA_BEAN_SOUL, "LA" }, + { RG_LAKE_HYLIA_BEAN_SOUL, "LH" }, { RG_LOST_WOODS_BRIDGE_BEAN_SOUL, "LWB" }, { RG_LOST_WOODS_BEAN_SOUL, "LWT" }, { RG_ZORAS_RIVER_BEAN_SOUL, "ZR" }, From 1cdff1ecb44cf54b2c7aac584fe6fb0dd18644e7 Mon Sep 17 00:00:00 2001 From: TheLynk Date: Sat, 22 Nov 2025 01:02:19 +0100 Subject: [PATCH 14/45] Fix Logic in KF --- .../location_access/overworld/kokiri_forest.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp index 8c548745a79..5917d19901f 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp @@ -29,13 +29,13 @@ void RegionTable_Init_KokiriForest() { 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_BEAN_RUPEE_1, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST) || (logic->CanUse(RG_HOVER_BOOTS) && logic->HasItem(RG_ROLL)) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_2, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST) || (logic->CanUse(RG_HOVER_BOOTS) && logic->HasItem(RG_ROLL)) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_3, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST) || (logic->CanUse(RG_HOVER_BOOTS) && logic->HasItem(RG_ROLL)) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_4, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST) || (logic->CanUse(RG_HOVER_BOOTS) && logic->HasItem(RG_ROLL)) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_5, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST) || (logic->CanUse(RG_HOVER_BOOTS) && logic->HasItem(RG_ROLL)) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_6, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST) || (logic->CanUse(RG_HOVER_BOOTS) && logic->HasItem(RG_ROLL)) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RED_RUPEE, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST) || (logic->CanUse(RG_HOVER_BOOTS) && logic->HasItem(RG_ROLL)) || 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), From b5eb52e4b47f58aad99faff9098a53df655a0982 Mon Sep 17 00:00:00 2001 From: TheLynk Date: Sat, 22 Nov 2025 01:04:59 +0100 Subject: [PATCH 15/45] Fix Logic in KF | 2.2 --- soh/soh/Enhancements/gameplaystats.cpp | 2 +- .../location_access/overworld/kokiri_forest.cpp | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/soh/soh/Enhancements/gameplaystats.cpp b/soh/soh/Enhancements/gameplaystats.cpp index 28cb639a8e2..4e9a2d80a8e 100644 --- a/soh/soh/Enhancements/gameplaystats.cpp +++ b/soh/soh/Enhancements/gameplaystats.cpp @@ -446,7 +446,7 @@ void DrawGameplayStatsHeader() { // if tag is empty (not a release build) if (gGitCommitTag[0] == 0) { GameplayStatsRow("Git Branch:", (char*)gGitBranch); - GameplayStatsRow("Version : 2.1 | Git Commit Hash:", (char*)gGitCommitHash); + GameplayStatsRow("Version : 2.2 | Git Commit Hash:", (char*)gGitCommitHash); } else { GameplayStatsRow("Build Version:", (char*)gBuildVersion); } diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp index 7cdedbd7879..eea1b42e2b9 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp @@ -29,13 +29,13 @@ void RegionTable_Init_KokiriForest() { 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, RG_KOKIRI_FOREST_BEAN_SOUL) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_KF_BEAN_RUPEE_2, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_KF_BEAN_RUPEE_3, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_KF_BEAN_RUPEE_4, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_KF_BEAN_RUPEE_5, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_KF_BEAN_RUPEE_6, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_KF_BEAN_RED_RUPEE, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_1, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || (logic->CanUse(RG_HOVER_BOOTS) && logic->HasItem(RG_ROLL)) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_2, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || (logic->CanUse(RG_HOVER_BOOTS) && logic->HasItem(RG_ROLL)) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_3, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || (logic->CanUse(RG_HOVER_BOOTS) && logic->HasItem(RG_ROLL)) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_4, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || (logic->CanUse(RG_HOVER_BOOTS) && logic->HasItem(RG_ROLL)) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_5, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || (logic->CanUse(RG_HOVER_BOOTS) && logic->HasItem(RG_ROLL)) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_6, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || (logic->CanUse(RG_HOVER_BOOTS) && logic->HasItem(RG_ROLL)) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RED_RUPEE, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || (logic->CanUse(RG_HOVER_BOOTS) && logic->HasItem(RG_ROLL)) || 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), From 9b52cbacec29c763be25857f5fa22850f3205f52 Mon Sep 17 00:00:00 2001 From: TheLynk Date: Mon, 24 Nov 2025 21:39:06 +0100 Subject: [PATCH 16/45] Add Branch add the ability to Randomize Music (Seeded) | V:3.0 --- soh/soh/Enhancements/audio/AudioEditor.cpp | 88 +++++++++++++------ soh/soh/Enhancements/audio/AudioEditor.h | 1 + .../cosmetics/CosmeticsEditor.cpp | 82 +++++++++++++---- .../Enhancements/cosmetics/CosmeticsEditor.h | 1 + soh/soh/Enhancements/enhancementTypes.h | 8 ++ soh/soh/Enhancements/gameplaystats.cpp | 2 +- soh/soh/SohGui/UIWidgets.cpp | 15 ++++ soh/soh/SohGui/UIWidgets.hpp | 2 + 8 files changed, 155 insertions(+), 44 deletions(-) diff --git a/soh/soh/Enhancements/audio/AudioEditor.cpp b/soh/soh/Enhancements/audio/AudioEditor.cpp index be6acae739b..d29bb35c6f5 100644 --- a/soh/soh/Enhancements/audio/AudioEditor.cpp +++ b/soh/soh/Enhancements/audio/AudioEditor.cpp @@ -34,8 +34,7 @@ static WidgetInfo leadingMusic; static WidgetInfo displaySeqName; static WidgetInfo ovlDuration; static WidgetInfo voicePitch; -static WidgetInfo randoMusicOnSceneChange; -static WidgetInfo randomAudioOnSeedGen; +static WidgetInfo randomAudioGenModes; static WidgetInfo lowerOctaves; namespace SohGui { @@ -79,6 +78,14 @@ size_t AuthenticCountBySequenceType(SeqType type) { } } +static const std::unordered_map audioRandomizerModes = { + { RANDOMIZE_OFF, "Disabled" }, + { RANDOMIZE_ON_NEW_SCENE, "On New Scene" }, + { RANDOMIZE_ON_RANDO_GEN_ONLY, "On Rando Gen Only" }, + { RANDOMIZE_ON_FILE_LOAD, "On File Load" }, + { RANDOMIZE_ON_FILE_LOAD_SEEDED, "On File Load (Seeded)" }, +}; + // Grabs the current BGM sequence ID and replays it // which will lookup the proper override, or reset back to vanilla void ReplayCurrentBGM() { @@ -101,9 +108,19 @@ void UpdateCurrentBGM(u16 seqKey, SeqType seqType) { } } -void RandomizeGroup(SeqType type) { +void RandomizeGroup(SeqType type, bool manual = true) { std::vector values; + if (!manual) { + if (IS_RANDO && CVarGetInteger(CVAR_AUDIO("RandomizeAudioGenModes"), 0) == RANDOMIZE_ON_FILE_LOAD_SEEDED || + IS_RANDO && CVarGetInteger(CVAR_AUDIO("RandomizeAudioGenModes"), 0) == RANDOMIZE_ON_RANDO_GEN_ONLY) { + + uint32_t finalSeed = type + (IS_RANDO ? Rando::Context::GetInstance()->GetSeed() + : static_cast(gSaveContext.ship.stats.fileCreatedAt)); + Random_Init(finalSeed); + } + } + // An empty IncludedSequences set means that the AudioEditor window has never been drawn if (AudioCollection::Instance->GetIncludedSequences().empty()) { AudioCollection::Instance->InitializeShufflePool(); @@ -479,16 +496,29 @@ void DrawTypeChip(SeqType type, std::string sequenceName) { void AudioEditorRegisterOnSceneInitHook() { GameInteractor::Instance->RegisterGameHook([](int16_t sceneNum) { - if (gSaveContext.gameMode != GAMEMODE_END_CREDITS && CVarGetInteger(CVAR_AUDIO("RandomizeAllOnNewScene"), 0)) { - AudioEditor_RandomizeAll(); + if (gSaveContext.gameMode != GAMEMODE_END_CREDITS && + CVarGetInteger(CVAR_AUDIO("RandomizeAudioGenModes"), 0) == RANDOMIZE_ON_NEW_SCENE) { + + AudioEditor_AutoRandomizeAll(); } }); } void AudioEditorRegisterOnGenerationCompletionHook() { GameInteractor::Instance->RegisterGameHook([]() { - if (CVarGetInteger(CVAR_AUDIO("RandomizeAllOnRandoGen"), 0)) { - AudioEditor_RandomizeAll(); + if (CVarGetInteger(CVAR_AUDIO("RandomizeAudioGenModes"), 0) == RANDOMIZE_ON_RANDO_GEN_ONLY) { + + AudioEditor_AutoRandomizeAll(); + } + }); +} + +void AudioEditorRegisterOnLoadGameHook() { + GameInteractor::Instance->RegisterGameHook([](int32_t fileNum) { + if (CVarGetInteger(CVAR_AUDIO("RandomizeAudioGenModes"), 0) == RANDOMIZE_ON_FILE_LOAD || + CVarGetInteger(CVAR_AUDIO("RandomizeAudioGenModes"), 0) == RANDOMIZE_ON_FILE_LOAD_SEEDED) { + + AudioEditor_AutoRandomizeAll(); } }); } @@ -496,6 +526,7 @@ void AudioEditorRegisterOnGenerationCompletionHook() { void AudioEditor::InitElement() { AudioEditorRegisterOnSceneInitHook(); AudioEditorRegisterOnGenerationCompletionHook(); + AudioEditorRegisterOnLoadGameHook(); } void AudioEditor::DrawElement() { @@ -557,8 +588,7 @@ void AudioEditor::DrawElement() { UIWidgets::ButtonOptions().Size(ImVec2(80, 36)).Padding(ImVec2(5.0f, 0.0f)))) { CVarSetFloat(CVAR_AUDIO("LinkVoiceFreqMultiplier"), 1.0f); } - SohGui::mSohMenu->MenuDrawItem(randoMusicOnSceneChange, ImGui::GetContentRegionAvail().x, THEME_COLOR); - SohGui::mSohMenu->MenuDrawItem(randomAudioOnSeedGen, ImGui::GetContentRegionAvail().x, THEME_COLOR); + SohGui::mSohMenu->MenuDrawItem(randomAudioGenModes, ImGui::GetContentRegionAvail().x, THEME_COLOR); SohGui::mSohMenu->MenuDrawItem(lowerOctaves, ImGui::GetContentRegionAvail().x, THEME_COLOR); } ImGui::EndChild(); @@ -775,6 +805,15 @@ void AudioEditor_RandomizeAll() { ReplayCurrentBGM(); } +void AudioEditor_AutoRandomizeAll() { + for (auto type : allTypes) { + RandomizeGroup(type, false); + } + + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + ReplayCurrentBGM(); +} + void AudioEditor_RandomizeGroup(SeqType group) { RandomizeGroup(group); @@ -866,22 +905,21 @@ void RegisterAudioWidgets() { .Size(ImVec2(300.0f, 0.0f))); SohGui::mSohMenu->AddSearchWidget({ voicePitch, "Enhancements", "Audio Editor", "Audio Options" }); - randoMusicOnSceneChange = { .name = "Randomize All Music and Sound Effects on New Scene", - .type = WidgetType::WIDGET_CVAR_CHECKBOX }; - randoMusicOnSceneChange.CVar(CVAR_AUDIO("RandomizeAllOnNewScene")) - .Options(CheckboxOptions() - .Color(THEME_COLOR) - .Tooltip("Enables randomizing all unlocked music and sound effects when you enter a new scene.")); - SohGui::mSohMenu->AddSearchWidget({ randoMusicOnSceneChange, "Enhancements", "Audio Editor", "Audio Options" }); - - randomAudioOnSeedGen = { .name = "Randomize All Music and Sound Effects on Randomizer Generation", - .type = WidgetType::WIDGET_CVAR_CHECKBOX }; - randomAudioOnSeedGen.CVar(CVAR_AUDIO("RandomizeAllOnRandoGen")) - .Options(CheckboxOptions() - .Color(THEME_COLOR) - .Tooltip("Enables randomizing all unlocked music and sound effects when you generate a new " - "randomizer. Respects locks already in place.")); - SohGui::mSohMenu->AddSearchWidget({ randomAudioOnSeedGen, "Enhancements", "Audio Editor", "Audio Options" }); + randomAudioGenModes = { .name = "Automatically Randomize All Music and Sound Effects", + .type = WidgetType::WIDGET_CVAR_COMBOBOX }; + randomAudioGenModes.CVar(CVAR_AUDIO("RandomizeAudioGenModes")) + .Options( + ComboboxOptions() + .DefaultIndex(RANDOMIZE_OFF) + .ComboMap(audioRandomizerModes) + .Tooltip( + "Set when the music and sound effects is automaticly randomized:\n" + "- Disabled: No music or sound effects are randomized\n" + "- On New Scene : Randomizes when you enter a new scene.\n" + "- On Rando Gen Only: Randomizes only when you generate a new randomizer.\n" + "- On File Load: Randomizes on File Load.\n" + "- On File Load (Seeded): Randomizes on file load based on the current randomizer seed/file.\n")); + SohGui::mSohMenu->AddSearchWidget({ randomAudioGenModes, "Enhancements", "Audio Editor", "Audio Options" }); lowerOctaves = { .name = "Lower Octaves of Unplayable High Notes", .type = WidgetType::WIDGET_CVAR_CHECKBOX }; lowerOctaves.CVar(CVAR_AUDIO("ExperimentalOctaveDrop")) diff --git a/soh/soh/Enhancements/audio/AudioEditor.h b/soh/soh/Enhancements/audio/AudioEditor.h index ca3636d9a84..b05c7b88e2e 100644 --- a/soh/soh/Enhancements/audio/AudioEditor.h +++ b/soh/soh/Enhancements/audio/AudioEditor.h @@ -18,6 +18,7 @@ class AudioEditor final : public Ship::GuiWindow { }; void AudioEditor_RandomizeAll(); +void AudioEditor_AutoRandomizeAll(); void AudioEditor_RandomizeGroup(SeqType group); void AudioEditor_ResetAll(); void AudioEditor_ResetGroup(SeqType group); diff --git a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp index 314b92b409d..6b91dde2c18 100644 --- a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp +++ b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp @@ -14,9 +14,11 @@ #include "soh/SohGui/SohGui.hpp" #include "soh/OTRGlobals.h" #include "soh/ResourceManagerHelpers.h" +#include "soh/Enhancements/enhancementTypes.h" extern "C" { #include "z64.h" +#include "z64save.h" #include "macros.h" #include "soh/cvar_prefixes.h" #include "objects/object_link_boy/object_link_boy.h" @@ -49,6 +51,7 @@ extern "C" { #include "objects/object_gi_rabit_mask/object_gi_rabit_mask.h" #include "overlays/ovl_Magic_Wind/ovl_Magic_Wind.h" +extern SaveContext gSaveContext; extern PlayState* gPlayState; void ResourceMgr_PatchGfxByName(const char* path, const char* patchName, int index, Gfx instruction); void ResourceMgr_PatchGfxCopyCommandByName(const char* path, const char* patchName, int destinationIndex, @@ -92,6 +95,14 @@ std::map groupLabels = { { COSMETICS_GROUP_MESSAGE, "Message" }, }; +static const std::unordered_map cosmeticsRandomizerModes = { + { RANDOMIZE_OFF, "Disabled" }, + { RANDOMIZE_ON_NEW_SCENE, "On New Scene" }, + { RANDOMIZE_ON_RANDO_GEN_ONLY, "On Rando Gen Only" }, + { RANDOMIZE_ON_FILE_LOAD, "On File Load" }, + { RANDOMIZE_ON_FILE_LOAD_SEEDED, "On File Load (Seeded)" }, +}; + typedef struct { const char* cvar; const char* valuesCvar; @@ -2097,8 +2108,24 @@ void ApplySideEffects(CosmeticOption& cosmeticOption) { } } -void RandomizeColor(CosmeticOption& cosmeticOption) { - ImVec4 randomColor = GetRandomValue(); +void RandomizeColor(CosmeticOption& cosmeticOption, bool manual = true) { + ImVec4 randomColor; + + if (!manual && IS_RANDO && + CVarGetInteger(CVAR_COSMETIC("RandomizeCosmeticsGenModes"), 0) == RANDOMIZE_ON_FILE_LOAD_SEEDED || + !manual && IS_RANDO && + CVarGetInteger(CVAR_COSMETIC("RandomizeCosmeticsGenModes"), 0) == RANDOMIZE_ON_RANDO_GEN_ONLY) { + + uint32_t finalSeed = cosmeticOption.defaultColor.r + cosmeticOption.defaultColor.g + + cosmeticOption.defaultColor.b + cosmeticOption.defaultColor.a + + (IS_RANDO ? Rando::Context::GetInstance()->GetSeed() + : static_cast(gSaveContext.ship.stats.fileCreatedAt)); + + randomColor = GetRandomValue(finalSeed); + } else { + randomColor = GetRandomValue(); + } + Color_RGBA8 newColor; newColor.r = static_cast(randomColor.x * 255.0f); newColor.g = static_cast(randomColor.y * 255.0f); @@ -2376,17 +2403,17 @@ void CosmeticsEditorWindow::DrawElement() { .Step(0.01f) .Size(ImVec2(300.0f, 0.0f)) .Color(THEME_COLOR)); - ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0)); - UIWidgets::CVarCheckbox("Randomize All on New Scene", CVAR_COSMETIC("RandomizeAllOnNewScene"), - UIWidgets::CheckboxOptions() - .Color(THEME_COLOR) - .Tooltip("Enables randomizing all unlocked cosmetics when you enter a new scene.")); - ImGui::EndDisabled(); - UIWidgets::CVarCheckbox( - "Randomize All on Randomizer Generation", CVAR_COSMETIC("RandomizeAllOnRandoGen"), - UIWidgets::CheckboxOptions() + UIWidgets::CVarCombobox( + "Automatically Randomize All Cosmetics", CVAR_COSMETIC("RandomizeCosmeticsGenModes"), cosmeticsRandomizerModes, + UIWidgets::ComboboxOptions() + .DefaultIndex(RANDOMIZE_OFF) .Color(THEME_COLOR) - .Tooltip("Enables randomizing all unlocked cosmetics when you generate a new randomizer.")); + .Tooltip("Set when the cosmetics is automaticly randomized:\n" + "- Disabled: No cosmetics are randomized\n" + "- On New Scene : Randomizes when you enter a new scene.\n" + "- On Rando Gen Only: Randomizes only when you generate a new randomizer.\n" + "- On File Load: Randomizes on File Load.\n" + "- On File Load (Seeded): Randomizes on file load based on the current randomizer seed/file.\n")); UIWidgets::CVarCheckbox( "Advanced Mode", CVAR_COSMETIC("AdvancedMode"), UIWidgets::CheckboxOptions() @@ -2578,8 +2605,15 @@ void CosmeticsEditorWindow::DrawElement() { } void RegisterOnLoadGameHook() { - GameInteractor::Instance->RegisterGameHook( - [](int32_t fileNum) { ApplyOrResetCustomGfxPatches(); }); + GameInteractor::Instance->RegisterGameHook([](int32_t fileNum) { + if (CVarGetInteger(CVAR_COSMETIC("RandomizeCosmeticsGenModes"), 0) == RANDOMIZE_ON_FILE_LOAD || + CVarGetInteger(CVAR_COSMETIC("RandomizeCosmeticsGenModes"), 0) == RANDOMIZE_ON_FILE_LOAD_SEEDED) { + + CosmeticsEditor_AutoRandomizeAll(); + } else { + ApplyOrResetCustomGfxPatches(); + } + }); } void RegisterOnGameFrameUpdateHook() { @@ -2588,16 +2622,16 @@ void RegisterOnGameFrameUpdateHook() { void Cosmetics_RegisterOnSceneInitHook() { GameInteractor::Instance->RegisterGameHook([](int16_t sceneNum) { - if (CVarGetInteger(CVAR_COSMETIC("RandomizeAllOnNewScene"), 0)) { - CosmeticsEditor_RandomizeAll(); + if (CVarGetInteger(CVAR_COSMETIC("RandomizeCosmeticsGenModes"), 0) == RANDOMIZE_ON_NEW_SCENE) { + CosmeticsEditor_AutoRandomizeAll(); } }); } void CosmeticsEditorRegisterOnGenerationCompletionHook() { GameInteractor::Instance->RegisterGameHook([]() { - if (CVarGetInteger(CVAR_COSMETIC("RandomizeAllOnRandoGen"), 0)) { - CosmeticsEditor_RandomizeAll(); + if (CVarGetInteger(CVAR_COSMETIC("RandomizeCosmeticsGenModes"), 0) == RANDOMIZE_ON_RANDO_GEN_ONLY) { + CosmeticsEditor_AutoRandomizeAll(); } }); } @@ -2636,6 +2670,18 @@ void CosmeticsEditor_RandomizeAll() { ApplyOrResetCustomGfxPatches(); } +void CosmeticsEditor_AutoRandomizeAll() { + for (auto& [id, cosmeticOption] : cosmeticOptions) { + if (!CVarGetInteger(cosmeticOption.lockedCvar, 0) && + (!cosmeticOption.advancedOption || CVarGetInteger(CVAR_COSMETIC("AdvancedMode"), 0))) { + RandomizeColor(cosmeticOption, false); + } + } + + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + ApplyOrResetCustomGfxPatches(); +} + void CosmeticsEditor_RandomizeGroup(CosmeticGroup group) { for (auto& [id, cosmeticOption] : cosmeticOptions) { if (!CVarGetInteger(cosmeticOption.lockedCvar, 0) && diff --git a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.h b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.h index e10583081d7..7da88bdbc6b 100644 --- a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.h +++ b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.h @@ -55,6 +55,7 @@ static ImGuiTableColumnFlags FlagsCell = ImGuiTableColumnFlags_WidthStretch | ImGuiTableColumnFlags_IndentEnable | ImGuiTableColumnFlags_NoSort; void CosmeticsEditor_RandomizeAll(); +void CosmeticsEditor_AutoRandomizeAll(); void CosmeticsEditor_RandomizeGroup(CosmeticGroup group); void CosmeticsEditor_ResetAll(); void CosmeticsEditor_ResetGroup(CosmeticGroup group); diff --git a/soh/soh/Enhancements/enhancementTypes.h b/soh/soh/Enhancements/enhancementTypes.h index bd025115b90..be0a3990f3a 100644 --- a/soh/soh/Enhancements/enhancementTypes.h +++ b/soh/soh/Enhancements/enhancementTypes.h @@ -123,4 +123,12 @@ typedef enum { WATERFALL_NEVER, } SleepingWaterfallType; +typedef enum { + RANDOMIZE_OFF, + RANDOMIZE_ON_NEW_SCENE, + RANDOMIZE_ON_RANDO_GEN_ONLY, + RANDOMIZE_ON_FILE_LOAD, + RANDOMIZE_ON_FILE_LOAD_SEEDED, +} RandomizeOnMode; + #endif diff --git a/soh/soh/Enhancements/gameplaystats.cpp b/soh/soh/Enhancements/gameplaystats.cpp index 4e9a2d80a8e..e29728e6b11 100644 --- a/soh/soh/Enhancements/gameplaystats.cpp +++ b/soh/soh/Enhancements/gameplaystats.cpp @@ -446,7 +446,7 @@ void DrawGameplayStatsHeader() { // if tag is empty (not a release build) if (gGitCommitTag[0] == 0) { GameplayStatsRow("Git Branch:", (char*)gGitBranch); - GameplayStatsRow("Version : 2.2 | Git Commit Hash:", (char*)gGitCommitHash); + GameplayStatsRow("Version : 3.0 | Git Commit Hash:", (char*)gGitCommitHash); } else { GameplayStatsRow("Build Version:", (char*)gBuildVersion); } diff --git a/soh/soh/SohGui/UIWidgets.cpp b/soh/soh/SohGui/UIWidgets.cpp index ca5b4be9b86..9a054735289 100644 --- a/soh/soh/SohGui/UIWidgets.cpp +++ b/soh/soh/SohGui/UIWidgets.cpp @@ -1170,6 +1170,21 @@ ImVec4 GetRandomValue() { return NewColor; } +ImVec4 GetRandomValue(uint32_t seed) { +#if !defined(__SWITCH__) && !defined(__WIIU__) + std::mt19937 rng(seed); +#else + std::mt19937_64 rng(seed); +#endif + std::uniform_int_distribution dist(0, 255 - 1); + + ImVec4 NewColor; + NewColor.x = (float)(dist(rng)) / 255.0f; + NewColor.y = (float)(dist(rng)) / 255.0f; + NewColor.z = (float)(dist(rng)) / 255.0f; + return NewColor; +} + Color_RGBA8 RGBA8FromVec(ImVec4 vec) { Color_RGBA8 color = { vec.x * 255, vec.y * 255, vec.z * 255, vec.w * 255 }; return color; diff --git a/soh/soh/SohGui/UIWidgets.hpp b/soh/soh/SohGui/UIWidgets.hpp index 95590b1ce5c..9dacf95fcc2 100644 --- a/soh/soh/SohGui/UIWidgets.hpp +++ b/soh/soh/SohGui/UIWidgets.hpp @@ -1047,7 +1047,9 @@ void DrawFlagArray8Mask(const std::string& name, uint8_t& flags, Colors color = void InsertHelpHoverText(const std::string& text); void InsertHelpHoverText(const char* text); } // namespace UIWidgets + ImVec4 GetRandomValue(); +ImVec4 GetRandomValue(uint32_t seed); Color_RGBA8 RGBA8FromVec(ImVec4 vec); ImVec4 VecFromRGBA8(Color_RGBA8 color); From bd31a0ec1927a4cdd06ae3c7af087e2d3a7bf58f Mon Sep 17 00:00:00 2001 From: TheLynk Date: Tue, 25 Nov 2025 18:54:58 +0100 Subject: [PATCH 17/45] Add branch "Invisible Navi option" | V:4.0 --- .../audio/DisableNaviCallAudio.cpp | 13 +++ .../cosmetics/CosmeticsEditor.cpp | 4 + .../Enhancements/cosmetics/InvisibleNavi.cpp | 63 +++++++++++++ .../vanilla-behavior/GIVanillaBehavior.h | 65 +++++++++++++ soh/soh/Enhancements/gameplaystats.cpp | 2 +- soh/src/code/z_parameter.c | 2 +- soh/src/overlays/actors/ovl_En_Elf/z_en_elf.c | 94 +++++++++++-------- .../ovl_Object_Kankyo/z_object_kankyo.c | 31 +++--- 8 files changed, 221 insertions(+), 53 deletions(-) create mode 100644 soh/soh/Enhancements/audio/DisableNaviCallAudio.cpp create mode 100644 soh/soh/Enhancements/cosmetics/InvisibleNavi.cpp diff --git a/soh/soh/Enhancements/audio/DisableNaviCallAudio.cpp b/soh/soh/Enhancements/audio/DisableNaviCallAudio.cpp new file mode 100644 index 00000000000..2a2cfbc5780 --- /dev/null +++ b/soh/soh/Enhancements/audio/DisableNaviCallAudio.cpp @@ -0,0 +1,13 @@ +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ShipInit.hpp" + +static constexpr int32_t CVAR_DISABLENAVICALLAUDIO_DEFAULT = 0; +#define CVAR_DISABLENAVICALLAUDIO_NAME CVAR_AUDIO("DisableNaviCallAudio") +#define CVAR_DISABLENAVICALLAUDIO_VALUE \ + CVarGetInteger(CVAR_DISABLENAVICALLAUDIO_NAME, CVAR_DISABLENAVICALLAUDIO_DEFAULT) + +void RegisterDisableNaviCallAudio() { + COND_VB_SHOULD(VB_PLAY_NAVI_CALL_SOUND, CVAR_DISABLENAVICALLAUDIO_VALUE, { *should = false; }); +} + +static RegisterShipInitFunc initFunc(RegisterDisableNaviCallAudio, { CVAR_DISABLENAVICALLAUDIO_NAME }); \ No newline at end of file diff --git a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp index 6b91dde2c18..10049a09fd0 100644 --- a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp +++ b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp @@ -1885,6 +1885,10 @@ void DrawSillyTab() { UIWidgets::Separator(true, true, 2.0f, 2.0f); + UIWidgets::CVarCheckbox( + "Invisible Navi", CVAR_COSMETIC("InvisibleNavi"), + UIWidgets::CheckboxOptions().Color(THEME_COLOR).Tooltip("Makes Navi invisible and disables her sounds.")); + UIWidgets::CVarCheckbox("Let It Snow", CVAR_GENERAL("LetItSnow"), UIWidgets::CheckboxOptions() .Color(THEME_COLOR) diff --git a/soh/soh/Enhancements/cosmetics/InvisibleNavi.cpp b/soh/soh/Enhancements/cosmetics/InvisibleNavi.cpp new file mode 100644 index 00000000000..ce1006e83e3 --- /dev/null +++ b/soh/soh/Enhancements/cosmetics/InvisibleNavi.cpp @@ -0,0 +1,63 @@ +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ShipInit.hpp" + +extern "C" { +#include "src/overlays/actors/ovl_En_Elf/z_en_elf.h" +} + +static constexpr int32_t CVAR_INVISIBLENAVI_DEFAULT = 0; +#define CVAR_INVISIBLENAVI_NAME CVAR_COSMETIC("InvisibleNavi") +#define CVAR_INVISIBLENAVI_VALUE CVarGetInteger(CVAR_INVISIBLENAVI_NAME, CVAR_INVISIBLENAVI_DEFAULT) + +void RegisterInvisibleNavi() { + COND_VB_SHOULD(VB_FAIRY_DRAW, CVAR_INVISIBLENAVI_VALUE, { + EnElf* enElf = va_arg(args, EnElf*); + if (enElf->actor.params == FAIRY_NAVI) { + *should = false; + } + }); + + COND_VB_SHOULD(VB_FAIRY_SPAWN_SPARKLES, CVAR_INVISIBLENAVI_VALUE, { + EnElf* enElf = va_arg(args, EnElf*); + if (enElf->actor.params == FAIRY_NAVI) { + *should = false; + } + }); + + COND_VB_SHOULD(VB_FAIRY_PLAY_C_UP_TALK_SOUND, CVAR_INVISIBLENAVI_VALUE, { + EnElf* enElf = va_arg(args, EnElf*); + if (enElf->actor.params == FAIRY_NAVI) { + *should = false; + } + }); + + COND_VB_SHOULD(VB_FAIRY_PLAY_DASH_SOUND, CVAR_INVISIBLENAVI_VALUE, { + EnElf* enElf = va_arg(args, EnElf*); + if (enElf->actor.params == FAIRY_NAVI) { + *should = false; + } + }); + + COND_VB_SHOULD(VB_FAIRY_PLAY_VANISH_SOUND, CVAR_INVISIBLENAVI_VALUE, { + EnElf* enElf = va_arg(args, EnElf*); + if (enElf->actor.params == FAIRY_NAVI) { + *should = false; + } + }); + + COND_VB_SHOULD(VB_FAIRY_UPDATE_LIGHTS, CVAR_INVISIBLENAVI_VALUE, { + EnElf* enElf = va_arg(args, EnElf*); + if (enElf->actor.params == FAIRY_NAVI) { + // Force Navi's light radius to zero. + Lights_PointGlowSetInfo(&enElf->lightInfoGlow, enElf->actor.world.pos.x, enElf->actor.world.pos.y, + enElf->actor.world.pos.z, 255, 255, 255, 0); + *should = false; + } + }); + + COND_VB_SHOULD(VB_PLAY_NAVI_CALL_SOUND, CVAR_INVISIBLENAVI_VALUE, { *should = false; }); + + COND_VB_SHOULD(VB_PLAY_INTRO_NAVI_SOUNDS, CVAR_INVISIBLENAVI_VALUE, { *should = false; }); +} + +static RegisterShipInitFunc initFunc(RegisterInvisibleNavi, { CVAR_INVISIBLENAVI_NAME }); \ No newline at end of file diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index 60d5d3ccaa0..a83185b4a37 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -535,6 +535,14 @@ typedef enum { // - `int32_t` (startMode) VB_EXECUTE_PLAYER_STARTMODE_FUNC, + // #### `result` + // ```c + // ((this->unk_2A8 != 8) && !(this->fairyFlags & 8)) + // ``` + // #### `args` + // - `*EnElf` + VB_FAIRY_DRAW, + // #### `result` // ```c // true @@ -543,6 +551,47 @@ typedef enum { // - `*EnElf` VB_FAIRY_HEAL, + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `*EnElf` + // - `int32_t` (sparkleLife) + VB_FAIRY_SPAWN_SPARKLES, + + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `*EnElf` + VB_FAIRY_PLAY_C_UP_TALK_SOUND, + + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `*EnElf` + VB_FAIRY_PLAY_DASH_SOUND, + + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `*EnElf` + VB_FAIRY_PLAY_VANISH_SOUND, + + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `*EnElf` + VB_FAIRY_UPDATE_LIGHTS, + // #### `result` // ```c // false @@ -1604,6 +1653,14 @@ typedef enum { // - None VB_PLAY_GORON_FREE_CS, + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `*ObjectKankyo` + VB_PLAY_INTRO_NAVI_SOUNDS, + // #### `result` // ```c // true @@ -1628,6 +1685,14 @@ typedef enum { // - None VB_PLAY_NABOORU_CAPTURED_CS, + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `int32_t` (naviCallState) (promoted from `uint16_t` by va_arg) + VB_PLAY_NAVI_CALL_SOUND, + // #### `result` // ```c // true diff --git a/soh/soh/Enhancements/gameplaystats.cpp b/soh/soh/Enhancements/gameplaystats.cpp index e29728e6b11..172d6502cd4 100644 --- a/soh/soh/Enhancements/gameplaystats.cpp +++ b/soh/soh/Enhancements/gameplaystats.cpp @@ -446,7 +446,7 @@ void DrawGameplayStatsHeader() { // if tag is empty (not a release build) if (gGitCommitTag[0] == 0) { GameplayStatsRow("Git Branch:", (char*)gGitBranch); - GameplayStatsRow("Version : 3.0 | Git Commit Hash:", (char*)gGitCommitHash); + GameplayStatsRow("Version : 4.0 | Git Commit Hash:", (char*)gGitCommitHash); } else { GameplayStatsRow("Build Version:", (char*)gBuildVersion); } diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index f2713c8d604..08d77ff0f49 100644 --- a/soh/src/code/z_parameter.c +++ b/soh/src/code/z_parameter.c @@ -2807,7 +2807,7 @@ void Interface_SetNaviCall(PlayState* play, u16 naviCallState) { if (((naviCallState == 0x1D) || (naviCallState == 0x1E)) && !interfaceCtx->naviCalling && (play->csCtx.state == CS_STATE_IDLE)) { - if (!CVarGetInteger(CVAR_AUDIO("DisableNaviCallAudio"), 0)) { + if (GameInteractor_Should(VB_PLAY_NAVI_CALL_SOUND, true, naviCallState)) { // clang-format off if (naviCallState == 0x1E) { Audio_PlaySoundGeneral(NA_SE_VO_NAVY_CALL, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } diff --git a/soh/src/overlays/actors/ovl_En_Elf/z_en_elf.c b/soh/src/overlays/actors/ovl_En_Elf/z_en_elf.c index 96a9297b969..94f3d75a411 100644 --- a/soh/src/overlays/actors/ovl_En_Elf/z_en_elf.c +++ b/soh/src/overlays/actors/ovl_En_Elf/z_en_elf.c @@ -817,28 +817,30 @@ void EnElf_UpdateLights(EnElf* this, PlayState* play) { s16 glowLightRadius; Player* player; - glowLightRadius = 100; + if (GameInteractor_Should(VB_FAIRY_UPDATE_LIGHTS, true, this)) { + glowLightRadius = 100; - if (this->unk_2A8 == 8) { - glowLightRadius = 0; - } + if (this->unk_2A8 == 8) { + glowLightRadius = 0; + } - if (this->fairyFlags & 0x20) { - player = GET_PLAYER(play); - Lights_PointNoGlowSetInfo(&this->lightInfoNoGlow, player->actor.world.pos.x, - (s16)(player->actor.world.pos.y) + 60.0f, player->actor.world.pos.z, 255, 255, 255, - 200); - } else { - Lights_PointNoGlowSetInfo(&this->lightInfoNoGlow, this->actor.world.pos.x, this->actor.world.pos.y, - this->actor.world.pos.z, 255, 255, 255, -1); - } + if (this->fairyFlags & 0x20) { + player = GET_PLAYER(play); + Lights_PointNoGlowSetInfo(&this->lightInfoNoGlow, player->actor.world.pos.x, + (s16)(player->actor.world.pos.y) + 60.0f, player->actor.world.pos.z, 255, 255, + 255, 200); + } else { + Lights_PointNoGlowSetInfo(&this->lightInfoNoGlow, this->actor.world.pos.x, this->actor.world.pos.y, + this->actor.world.pos.z, 255, 255, 255, -1); + } - Lights_PointGlowSetInfo(&this->lightInfoGlow, this->actor.world.pos.x, this->actor.world.pos.y, - this->actor.world.pos.z, 255, 255, 255, glowLightRadius); + Lights_PointGlowSetInfo(&this->lightInfoGlow, this->actor.world.pos.x, this->actor.world.pos.y, + this->actor.world.pos.z, 255, 255, 255, glowLightRadius); - this->unk_2BC = Math_Atan2S(this->actor.velocity.z, this->actor.velocity.x); + this->unk_2BC = Math_Atan2S(this->actor.velocity.z, this->actor.velocity.x); - Actor_SetScale(&this->actor, this->actor.scale.x); + Actor_SetScale(&this->actor, this->actor.scale.x); + } } void func_80A03CF8(EnElf* this, PlayState* play) { @@ -872,7 +874,9 @@ void func_80A03CF8(EnElf* this, PlayState* play) { if ((play->sceneNum == SCENE_LINKS_HOUSE) && (gSaveContext.sceneSetupIndex == 4)) { // play dash sound as Navi enters Links house in the intro if (play->csCtx.frames == 55) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_FAIRY_DASH); + if (GameInteractor_Should(VB_FAIRY_PLAY_DASH_SOUND, true, this)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_FAIRY_DASH); + } } // play dash sound in intervals as Navi is waking up Link in the intro @@ -884,7 +888,9 @@ void func_80A03CF8(EnElf* this, PlayState* play) { } else { if (this->actor.world.pos.y < prevPos.y) { this->fairyFlags |= 0x40; - Audio_PlayActorSound2(&this->actor, NA_SE_EV_FAIRY_DASH); + if (GameInteractor_Should(VB_FAIRY_PLAY_DASH_SOUND, true, this)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_FAIRY_DASH); + } } } } @@ -967,7 +973,9 @@ void func_80A03CF8(EnElf* this, PlayState* play) { this->fairyFlags |= 2; if (this->unk_2C7 == 0) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_FAIRY_DASH); + if (GameInteractor_Should(VB_FAIRY_PLAY_DASH_SOUND, true, this)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_FAIRY_DASH); + } } this->unk_2C0 = 0x64; @@ -1015,7 +1023,9 @@ void func_80A04414(EnElf* this, PlayState* play) { this->unk_29C = 1.0f; if (this->unk_2C7 == 0) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_FAIRY_DASH); + if (GameInteractor_Should(VB_FAIRY_PLAY_DASH_SOUND, true, this)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_FAIRY_DASH); + } } } else { @@ -1105,7 +1115,9 @@ void func_80A0461C(EnElf* this, PlayState* play) { temp = 0; } else { if (this->unk_2C7 == 0) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_NAVY_VANISH); + if (GameInteractor_Should(VB_FAIRY_PLAY_VANISH_SOUND, true, this)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_NAVY_VANISH); + } } temp = 7; } @@ -1149,7 +1161,9 @@ void func_80A0461C(EnElf* this, PlayState* play) { if (!(player->stateFlags2 & PLAYER_STATE2_NAVI_ACTIVE)) { temp = 7; if (this->unk_2C7 == 0) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_NAVY_VANISH); + if (GameInteractor_Should(VB_FAIRY_PLAY_VANISH_SOUND, true, this)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_NAVY_VANISH); + } } } break; @@ -1159,7 +1173,9 @@ void func_80A0461C(EnElf* this, PlayState* play) { this->unk_2C0 = 42; temp = 11; if (this->unk_2C7 == 0) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_FAIRY_DASH); + if (GameInteractor_Should(VB_FAIRY_PLAY_DASH_SOUND, true, this)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_FAIRY_DASH); + } } } break; @@ -1190,20 +1206,22 @@ void EnElf_SpawnSparkles(EnElf* this, PlayState* play, s32 sparkleLife) { Color_RGBA8 primColor; Color_RGBA8 envColor; - sparklePos.x = Rand_CenteredFloat(6.0f) + this->actor.world.pos.x; - sparklePos.y = (Rand_ZeroOne() * 6.0f) + this->actor.world.pos.y; - sparklePos.z = Rand_CenteredFloat(6.0f) + this->actor.world.pos.z; + if (GameInteractor_Should(VB_FAIRY_SPAWN_SPARKLES, true, this, sparkleLife)) { + sparklePos.x = Rand_CenteredFloat(6.0f) + this->actor.world.pos.x; + sparklePos.y = (Rand_ZeroOne() * 6.0f) + this->actor.world.pos.y; + sparklePos.z = Rand_CenteredFloat(6.0f) + this->actor.world.pos.z; - primColor.r = this->innerColor.r; - primColor.g = this->innerColor.g; - primColor.b = this->innerColor.b; + primColor.r = this->innerColor.r; + primColor.g = this->innerColor.g; + primColor.b = this->innerColor.b; - envColor.r = this->outerColor.r; - envColor.g = this->outerColor.g; - envColor.b = this->outerColor.b; + envColor.r = this->outerColor.r; + envColor.g = this->outerColor.g; + envColor.b = this->outerColor.b; - EffectSsKiraKira_SpawnDispersed(play, &sparklePos, &sparkleVelocity, &sparkleAccel, &primColor, &envColor, 1000, - sparkleLife); + EffectSsKiraKira_SpawnDispersed(play, &sparklePos, &sparkleVelocity, &sparkleAccel, &primColor, &envColor, 1000, + sparkleLife); + } } void func_80A04D90(EnElf* this, PlayState* play) { @@ -1392,7 +1410,9 @@ void func_80A053F0(Actor* thisx, PlayState* play) { } if (Actor_ProcessTalkRequest(thisx, play)) { - func_800F4524(&gSfxDefaultPos, NA_SE_VO_SK_LAUGH, 0x20); + if (GameInteractor_Should(VB_FAIRY_PLAY_C_UP_TALK_SOUND, true, this)) { + func_800F4524(&gSfxDefaultPos, NA_SE_VO_SK_LAUGH, 0x20); + } thisx->focus.pos = thisx->world.pos; if (thisx->textId == ElfMessage_GetCUpText(play)) { @@ -1506,7 +1526,7 @@ void EnElf_Draw(Actor* thisx, PlayState* play) { Gfx* dListHead; Player* player = GET_PLAYER(play); - if ((this->unk_2A8 != 8) && !(this->fairyFlags & 8)) { + if (GameInteractor_Should(VB_FAIRY_DRAW, ((this->unk_2A8 != 8) && !(this->fairyFlags & 8)), this)) { if (!(player->stateFlags1 & PLAYER_STATE1_FIRST_PERSON) || (kREG(90) < this->actor.projectedPos.z)) { dListHead = Graph_Alloc(play->state.gfxCtx, sizeof(Gfx) * 4); diff --git a/soh/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c b/soh/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c index 2b8cfcb7a10..8582f2e3ea3 100644 --- a/soh/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c +++ b/soh/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c @@ -8,6 +8,7 @@ #include "objects/object_demo_kekkai/object_demo_kekkai.h" #include "objects/gameplay_keep/gameplay_keep.h" #include "objects/object_spot02_objects/object_spot02_objects.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include "soh/frame_interpolation.h" #include @@ -205,23 +206,25 @@ void ObjectKankyo_Fairies(ObjectKankyo* this, PlayState* play) { dist = 1.0f; } - func_800F436C(&sSoundPos, NA_SE_EV_NAVY_FLY - SFX_FLAG, (0.4f * dist) + 0.6f); - switch (play->csCtx.frames) { - case 473: - Sfx_PlaySfxCentered2(NA_SE_VO_NA_HELLO_3); - break; + if (GameInteractor_Should(VB_PLAY_INTRO_NAVI_SOUNDS, true, this)) { + func_800F436C(&sSoundPos, NA_SE_EV_NAVY_FLY - SFX_FLAG, (0.4f * dist) + 0.6f); + switch (play->csCtx.frames) { + case 473: + Sfx_PlaySfxCentered2(NA_SE_VO_NA_HELLO_3); + break; - case 583: - func_800F4524(&gSfxDefaultPos, NA_SE_VO_NA_HELLO_2, 32); - break; + case 583: + func_800F4524(&gSfxDefaultPos, NA_SE_VO_NA_HELLO_2, 32); + break; - case 763: - Sfx_PlaySfxCentered(NA_SE_EV_NAVY_CRASH - SFX_FLAG); - break; + case 763: + Sfx_PlaySfxCentered(NA_SE_EV_NAVY_CRASH - SFX_FLAG); + break; - case 771: - Sfx_PlaySfxCentered(NA_SE_VO_RT_THROW); - break; + case 771: + Sfx_PlaySfxCentered(NA_SE_VO_RT_THROW); + break; + } } } From 8259c4d2fec1a9ba09d84f219583847ff34ac6a8 Mon Sep 17 00:00:00 2001 From: TheLynk Date: Sun, 30 Nov 2025 21:13:17 +0100 Subject: [PATCH 18/45] Add branch "Rando: Add Triforce Hunt GBK setting" | V:5.0 --- .../Enhancements/debugger/debugSaveEditor.cpp | 3 ++- soh/soh/Enhancements/gameplaystats.cpp | 2 +- soh/soh/Enhancements/kaleido.cpp | 2 +- .../randomizer/3drando/item_pool.cpp | 19 +++++++++++---- .../randomizer/3drando/starting_inventory.cpp | 5 ++-- soh/soh/Enhancements/randomizer/hint.cpp | 2 +- .../Enhancements/randomizer/hook_handlers.cpp | 2 +- .../randomizer/option_descriptions.cpp | 6 ++--- .../Enhancements/randomizer/randomizer.cpp | 23 +++++++++++-------- .../Enhancements/randomizer/randomizerTypes.h | 7 ++++++ .../randomizer/randomizer_item_tracker.cpp | 6 +++-- soh/soh/Enhancements/randomizer/settings.cpp | 6 ++--- 12 files changed, 55 insertions(+), 28 deletions(-) diff --git a/soh/soh/Enhancements/debugger/debugSaveEditor.cpp b/soh/soh/Enhancements/debugger/debugSaveEditor.cpp index d7eceb82973..36364a4fb22 100644 --- a/soh/soh/Enhancements/debugger/debugSaveEditor.cpp +++ b/soh/soh/Enhancements/debugger/debugSaveEditor.cpp @@ -297,7 +297,8 @@ void DrawInfoTab() { Combobox("Z Target Mode", &gSaveContext.zTargetSetting, zTargetMap, comboboxOptionsBase.Tooltip("Z-Targeting behavior")); - if (IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT)) { + if (IS_RANDO && + (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT) != RO_TRIFORCE_HUNT_OFF)) { PushStyleInput(THEME_COLOR); ImGui::InputScalar("Triforce Pieces", ImGuiDataType_U8, &gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected); diff --git a/soh/soh/Enhancements/gameplaystats.cpp b/soh/soh/Enhancements/gameplaystats.cpp index 172d6502cd4..488dee18e59 100644 --- a/soh/soh/Enhancements/gameplaystats.cpp +++ b/soh/soh/Enhancements/gameplaystats.cpp @@ -446,7 +446,7 @@ void DrawGameplayStatsHeader() { // if tag is empty (not a release build) if (gGitCommitTag[0] == 0) { GameplayStatsRow("Git Branch:", (char*)gGitBranch); - GameplayStatsRow("Version : 4.0 | Git Commit Hash:", (char*)gGitCommitHash); + GameplayStatsRow("Version : 5.0 | Git Commit Hash:", (char*)gGitCommitHash); } else { GameplayStatsRow("Build Version:", (char*)gBuildVersion); } diff --git a/soh/soh/Enhancements/kaleido.cpp b/soh/soh/Enhancements/kaleido.cpp index 2b95522633a..d2a6c2e5bea 100644 --- a/soh/soh/Enhancements/kaleido.cpp +++ b/soh/soh/Enhancements/kaleido.cpp @@ -116,7 +116,7 @@ Kaleido::Kaleido() { gRupeeCounterIconTex, G_IM_FMT_IA, G_IM_SIZ_8b, 16, 16, Color_RGBA8{ 0xC8, 0xFF, 0x64, 255 }, FlagType::FLAG_RANDOMIZER_INF, static_cast(RAND_INF_GREG_FOUND), 0, yOffset, "Greg")); yOffset += 18; - if (ctx->GetOption(RSK_TRIFORCE_HUNT)) { + if (ctx->GetOption(RSK_TRIFORCE_HUNT).IsNot(RO_TRIFORCE_HUNT_OFF)) { mEntries.push_back(std::make_shared( gTriforcePieceTex, G_IM_FMT_RGBA, G_IM_SIZ_32b, 32, 32, Color_RGBA8{ 255, 255, 255, 255 }, 0, yOffset, reinterpret_cast(&gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected), diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index 94155866894..c478721c411 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -502,11 +502,21 @@ void GenerateItemPool() { ctx->possibleIceTrapModels.push_back(RG_LIGHT_MEDALLION); } - if (ctx->GetOption(RSK_TRIFORCE_HUNT)) { + if (ctx->GetOption(RSK_TRIFORCE_HUNT).IsNot(RO_TRIFORCE_HUNT_OFF)) { ctx->possibleIceTrapModels.push_back(RG_TRIFORCE_PIECE); AddItemToMainPool(RG_TRIFORCE_PIECE, (ctx->GetOption(RSK_TRIFORCE_HUNT_PIECES_TOTAL).Get() + 1)); - ctx->PlaceItemInLocation(RC_TRIFORCE_COMPLETED, RG_TRIFORCE); // Win condition - ctx->PlaceItemInLocation(RC_GANON, GetJunkItem(), false, true); + switch (ctx->GetOption(RSK_TRIFORCE_HUNT).Get()) { + case RO_TRIFORCE_HUNT_OFF: + break; + case RO_TRIFORCE_HUNT_WIN: + ctx->PlaceItemInLocation(RC_TRIFORCE_COMPLETED, RG_TRIFORCE); // Win condition + ctx->PlaceItemInLocation(RC_GANON, GetJunkItem(), false, true); + break; + case RO_TRIFORCE_HUNT_GBK: + ctx->PlaceItemInLocation(RC_TRIFORCE_COMPLETED, RG_GANONS_CASTLE_BOSS_KEY); + ctx->PlaceItemInLocation(RC_GANON, RG_TRIFORCE); // Win condition + break; + } } else { ctx->PlaceItemInLocation(RC_GANON, RG_TRIFORCE); // Win condition } @@ -1247,7 +1257,8 @@ void GenerateItemPool() { AddItemToMainPool(RG_SHADOW_TEMPLE_BOSS_KEY); } - if (!ctx->GetOption(RSK_TRIFORCE_HUNT)) { // Don't add GBK to the pool at all for Triforce Hunt. + if (!ctx->GetOption(RSK_TRIFORCE_HUNT) + .IsNot(RO_TRIFORCE_HUNT_OFF)) { // Don't add GBK to the pool at all for Triforce Hunt. if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_KAK_TOKENS)) { ctx->PlaceItemInLocation(RC_KAK_100_GOLD_SKULLTULA_REWARD, RG_GANONS_CASTLE_BOSS_KEY); } else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Get() >= RO_GANON_BOSS_KEY_LACS_VANILLA) { diff --git a/soh/soh/Enhancements/randomizer/3drando/starting_inventory.cpp b/soh/soh/Enhancements/randomizer/3drando/starting_inventory.cpp index dda37b18a15..27443f04468 100644 --- a/soh/soh/Enhancements/randomizer/3drando/starting_inventory.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/starting_inventory.cpp @@ -54,9 +54,10 @@ void GenerateStartingInventory() { AddItemToInventory(RG_SHADOW_TEMPLE_BOSS_KEY); } - // Add Ganon's Boss key with Triforce Hunt so the game thinks it's obtainable from the start. + // Add Ganon's Boss key with Triforce Hunt's Win setting so the game thinks it's obtainable from the start. // During save init, the boss key isn't actually given and it's instead given when completing the triforce. - if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_STARTWITH) || ctx->GetOption(RSK_TRIFORCE_HUNT)) { + if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_STARTWITH) || + ctx->GetOption(RSK_TRIFORCE_HUNT).Is(RO_TRIFORCE_HUNT_WIN)) { AddItemToInventory(RG_GANONS_CASTLE_BOSS_KEY); } diff --git a/soh/soh/Enhancements/randomizer/hint.cpp b/soh/soh/Enhancements/randomizer/hint.cpp index 27ca4eb2a2e..7684c39cb01 100644 --- a/soh/soh/Enhancements/randomizer/hint.cpp +++ b/soh/soh/Enhancements/randomizer/hint.cpp @@ -590,7 +590,7 @@ CustomMessage Hint::GetGanonBossKeyText() { auto ctx = Rando::Context::GetInstance(); CustomMessage ganonBossKeyMessage; - if (ctx->GetOption(RSK_TRIFORCE_HUNT)) { + if (ctx->GetOption(RSK_TRIFORCE_HUNT).IsNot(RO_TRIFORCE_HUNT_OFF)) { return StaticData::hintTextTable[RHT_GANON_BK_TRIFORCE_HINT].GetHintMessage(); } diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index be1703168c7..66e32cfdf28 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -2391,7 +2391,7 @@ void RandomizerOnPlayerUpdateHandler() { *Rando::StaticData::GetItemTable().at(RG_GANONS_CASTLE_BOSS_KEY).GetGIEntry()); } - if (!GameInteractor::IsGameplayPaused() && RAND_GET_OPTION(RSK_TRIFORCE_HUNT)) { + if (!GameInteractor::IsGameplayPaused() && RAND_GET_OPTION(RSK_TRIFORCE_HUNT) != RO_TRIFORCE_HUNT_OFF) { // Warp to credits if (GameInteractor::State::TriforceHuntCreditsWarpActive) { gPlayState->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp index fadc4e630fc..2c744cb4cde 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -125,9 +125,9 @@ void Settings::CreateOptionDescriptions() { "set."; mOptionDescriptions[RSK_TRIFORCE_HUNT] = "Pieces of the Triforce of Courage have been scattered across the world. Find them all to finish the game!\n\n" - "When the required amount of pieces have been found, the game is saved and Ganon's Boss key is given " - "to you when you load back into the game if you desire to beat Ganon afterwards.\n\n" - "Keep in mind Ganon might not be logically beatable when \"All Locations Reachable\" is turned off."; + "When the required amount of pieces have been found, Ganon's Boss key is given. If set to Win: the game is " + "saved and you can load back into the game if you desire to beat Ganon afterwards, and " + "keep in mind Ganon might not be logically beatable when \"All Locations Reachable\" is turned off."; mOptionDescriptions[RSK_TRIFORCE_HUNT_PIECES_TOTAL] = "The amount of Triforce pieces that will be placed in the world. " "Keep in mind seed generation can fail if more pieces are placed than there are junk items in the item pool."; diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 75388a614f8..126562f952d 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -6358,18 +6358,23 @@ extern "C" u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) { gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected++; GameInteractor_SetTriforceHuntPieceGiven(true); - // Teleport to credits when goal is reached. + // Give Ganon's Boss Key and teleport to credits if set to Win when goal is reached. if (gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected == (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT_PIECES_REQUIRED) + 1)) { - gSaveContext.ship.stats.itemTimestamp[TIMESTAMP_TRIFORCE_COMPLETED] = - static_cast(GAMEPLAYSTAT_TOTAL_TIME); - gSaveContext.ship.stats.gameComplete = 1; + Flags_SetRandomizerInf(RAND_INF_GRANT_GANONS_BOSSKEY); - Play_PerformSave(play); - Notification::Emit({ - .message = "Game autosaved", - }); - GameInteractor_SetTriforceHuntCreditsWarpActive(true); + + if (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT) == + RO_TRIFORCE_HUNT_WIN) { + gSaveContext.ship.stats.itemTimestamp[TIMESTAMP_TRIFORCE_COMPLETED] = + static_cast(GAMEPLAYSTAT_TOTAL_TIME); + gSaveContext.ship.stats.gameComplete = 1; + Play_PerformSave(play); + Notification::Emit({ + .message = "Game autosaved", + }); + GameInteractor_SetTriforceHuntCreditsWarpActive(true); + } } break; diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 5966b6a1e81..8b40ba387cb 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -6718,6 +6718,13 @@ typedef enum { RO_MQ_DUNGEONS_SELECTION, } RandoOptionMQDungeons; +// Triforce Hunt settings (off, win, Ganon's Boss Key) +typedef enum { + RO_TRIFORCE_HUNT_OFF, + RO_TRIFORCE_HUNT_WIN, + RO_TRIFORCE_HUNT_GBK, +} RandoOptionTriforceHunt; + typedef enum { RO_LOCATION_INCLUDE, RO_LOCATION_EXCLUDE, diff --git a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp index a7274c2f163..ee7003fa293 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp @@ -714,7 +714,8 @@ void DrawItemCount(ItemTrackerItem item, bool hideMax) { ImGui::Text("%s", maxString.c_str()); ImGui::PopStyleColor(); } else if (item.id == RG_TRIFORCE_PIECE && IS_RANDO && - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT) && IsValidSaveFile()) { + (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT) != RO_TRIFORCE_HUNT_OFF) && + IsValidSaveFile()) { std::string currentString = ""; std::string requiredString = ""; std::string maxString = ""; @@ -833,7 +834,8 @@ void DrawItem(ItemTrackerItem item) { break; case RG_TRIFORCE_PIECE: actualItemId = item.id; - hasItem = IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT); + hasItem = IS_RANDO && (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT) != + RO_TRIFORCE_HUNT_OFF); itemName = "Triforce Piece"; break; case RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL: diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index b277dc40d38..22020ae0bf6 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -160,7 +160,7 @@ void Settings::CreateOptions() { OPT_BOOL(RSK_BOMBCHU_BAG, "Bombchu Bag", CVAR_RANDOMIZER_SETTING("BombchuBag"), mOptionDescriptions[RSK_BOMBCHU_BAG]); OPT_U8(RSK_ENABLE_BOMBCHU_DROPS, "Bombchu Drops", {"No", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("EnableBombchuDrops"), mOptionDescriptions[RSK_ENABLE_BOMBCHU_DROPS], WidgetType::Combobox, RO_AMMO_DROPS_ON); // TODO: AmmoDrops and/or HeartDropRefill, combine with/separate Ammo Drops from Bombchu Drops? - OPT_BOOL(RSK_TRIFORCE_HUNT, "Triforce Hunt", CVAR_RANDOMIZER_SETTING("TriforceHunt"), mOptionDescriptions[RSK_TRIFORCE_HUNT], IMFLAG_NONE); + OPT_U8(RSK_TRIFORCE_HUNT, "Triforce Hunt", {"Off", "Win", "Ganon's Boss Key"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("TriforceHunt"), mOptionDescriptions[RSK_TRIFORCE_HUNT]); OPT_U8(RSK_TRIFORCE_HUNT_PIECES_TOTAL, "Triforce Hunt Total Pieces", {NumOpts(1, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("TriforceHuntTotalPieces"), mOptionDescriptions[RSK_TRIFORCE_HUNT_PIECES_TOTAL], WidgetType::Slider, 29, false, IMFLAG_NONE); OPT_U8(RSK_TRIFORCE_HUNT_PIECES_REQUIRED, "Triforce Hunt Required Pieces", {NumOpts(1, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("TriforceHuntRequiredPieces"), mOptionDescriptions[RSK_TRIFORCE_HUNT_PIECES_REQUIRED], WidgetType::Slider, 19); OPT_U8(RSK_MQ_DUNGEON_RANDOM, "MQ Dungeon Setting", {"None", "Set Number", "Random", "Selection Only"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeons"), mOptionDescriptions[RSK_MQ_DUNGEON_RANDOM], WidgetType::Combobox, RO_MQ_DUNGEONS_NONE, true, IMFLAG_NONE); @@ -1977,7 +1977,7 @@ void Settings::UpdateOptionProperties() { mOptions[RSK_TRIFORCE_HUNT_PIECES_TOTAL].Enable(); mOptions[RSK_TRIFORCE_HUNT_PIECES_REQUIRED].Enable(); // Remove the pieces required/total sliders and add a separator after Tirforce Hunt if Triforce Hunt is off - if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("TriforceHunt"), RO_GENERIC_OFF) == RO_GENERIC_OFF) { + if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("TriforceHunt"), RO_TRIFORCE_HUNT_OFF) == RO_TRIFORCE_HUNT_OFF) { mOptions[RSK_TRIFORCE_HUNT_PIECES_REQUIRED].Hide(); mOptions[RSK_TRIFORCE_HUNT_PIECES_TOTAL].Hide(); mOptions[RSK_TRIFORCE_HUNT].AddFlag(IMFLAG_SEPARATOR_BOTTOM); @@ -2449,7 +2449,7 @@ void Settings::UpdateOptionProperties() { } else { mOptions[RSK_KEYRINGS_GERUDO_FORTRESS].Enable(); } - if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("TriforceHunt"), RO_GENERIC_OFF)) { + if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("TriforceHunt"), RO_TRIFORCE_HUNT_OFF)) { mOptions[RSK_GANONS_BOSS_KEY].Disable( "This option is disabled because Triforce Hunt is enabled." "Ganon's Boss key\nwill instead be given to you after Triforce Hunt completion."); From 15b75a768e033d7fd9f4e0c47913adcbc6a614c4 Mon Sep 17 00:00:00 2001 From: TheLynk Date: Mon, 1 Dec 2025 03:16:25 +0100 Subject: [PATCH 19/45] Add branch "Add Edit buttons for custom presets" | V6.0 --- soh/soh/Enhancements/Presets/Presets.cpp | 57 +++++++++++++++++------- soh/soh/Enhancements/gameplaystats.cpp | 2 +- 2 files changed, 41 insertions(+), 18 deletions(-) diff --git a/soh/soh/Enhancements/Presets/Presets.cpp b/soh/soh/Enhancements/Presets/Presets.cpp index 7671ee18ef6..2ddc445857a 100644 --- a/soh/soh/Enhancements/Presets/Presets.cpp +++ b/soh/soh/Enhancements/Presets/Presets.cpp @@ -252,18 +252,25 @@ void SavePreset(std::string& presetName) { } presets[presetName].presetValues["presetName"] = presetName; presets[presetName].presetValues["fileType"] = FILE_TYPE_PRESET; - std::ofstream file( - fmt::format("{}/{}.json", Ship::Context::GetInstance()->LocateFileAcrossAppDirs("presets"), presetName)); + std::ofstream file(FormatPresetPath(presetName)); file << presets[presetName].presetValues.dump(4); file.close(); LoadPresets(); } -static std::string newPresetName; +void DeletePreset(std::string& presetName) { + std::string presetPath = FormatPresetPath(presetName); + if (fs::exists(presetPath)) { + fs::remove(presetPath); + } + presets.erase(presetName); +} + +static std::string newPresetName, oldPresetName; static bool saveSection[PRESET_SECTION_MAX]; -void DrawNewPresetPopup() { - bool nameExists = presets.contains(newPresetName); +void DrawEditPresetPopup() { + bool nameExists = presets.contains(newPresetName) && newPresetName != oldPresetName; UIWidgets::InputString("Preset Name", &newPresetName, UIWidgets::InputOptions() .Color(THEME_COLOR) @@ -272,7 +279,7 @@ void DrawNewPresetPopup() { .LabelPosition(UIWidgets::LabelPositions::Near) .ErrorText("Preset name already exists") .HasError(nameExists)); - nameExists = presets.contains(newPresetName); + nameExists = presets.contains(newPresetName) && newPresetName != oldPresetName; bool noneSelected = true; for (int i = PRESET_SECTION_SETTINGS; i < PRESET_SECTION_MAX; i++) { if (saveSection[i]) { @@ -350,10 +357,15 @@ void DrawNewPresetPopup() { presets[newPresetName].fileName = newPresetName; std::fill_n(presets[newPresetName].apply, PRESET_SECTION_MAX, true); SavePreset(newPresetName); + if (newPresetName != oldPresetName) { + DeletePreset(oldPresetName); + } newPresetName = ""; + oldPresetName = ""; ImGui::CloseCurrentPopup(); } if (UIWidgets::Button("Cancel", UIWidgets::ButtonOptions().Padding({ 6.0f, 6.0f }).Color(THEME_COLOR))) { + oldPresetName = ""; ImGui::CloseCurrentPopup(); } ImGui::EndPopup(); @@ -366,25 +378,32 @@ void PresetsCustomWidget(WidgetInfo& info) { .disabledTooltip = "Disabled because of race lockout" } }) .Size(UIWidgets::Sizes::Inline) .Color(THEME_COLOR))) { - ImGui::OpenPopup("newPreset"); + oldPresetName = ""; + newPresetName = ""; + std::fill_n(saveSection, PRESET_SECTION_MAX, true); + ImGui::OpenPopup("editPreset"); + } else if (oldPresetName != "") { + ImGui::OpenPopup("editPreset"); } - if (ImGui::BeginPopup("newPreset", ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | - ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar | - ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoTitleBar)) { - DrawNewPresetPopup(); + if (ImGui::BeginPopup("editPreset", ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | + ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar | + ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoTitleBar)) { + DrawEditPresetPopup(); } ImGui::SameLine(); UIWidgets::CVarCheckbox("Hide built-in presets", CVAR_GENERAL("HideBuiltInPresets"), UIWidgets::CheckboxOptions().Color(THEME_COLOR)); bool hideBuiltIn = CVarGetInteger(CVAR_GENERAL("HideBuiltInPresets"), 0); UIWidgets::PushStyleTabs(THEME_COLOR); - if (ImGui::BeginTable("PresetWidgetTable", PRESET_SECTION_MAX + 3)) { + if (ImGui::BeginTable("PresetWidgetTable", PRESET_SECTION_MAX + 4)) { ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthFixed, 250); for (int i = PRESET_SECTION_SETTINGS; i < PRESET_SECTION_MAX; i++) { ImGui::TableSetupColumn(blockInfo[i].names[0].c_str()); } ImGui::TableSetupColumn("Apply", ImGuiTableColumnFlags_WidthFixed, ImGui::CalcTextSize("Apply").x + ImGui::GetStyle().FramePadding.x * 2); + ImGui::TableSetupColumn("Edit", ImGuiTableColumnFlags_WidthFixed, + ImGui::CalcTextSize("Edit").x + ImGui::GetStyle().FramePadding.x * 2); ImGui::TableSetupColumn("Delete", ImGuiTableColumnFlags_WidthFixed, ImGui::CalcTextSize("Delete").x + ImGui::GetStyle().FramePadding.x * 2); BlankButton(); @@ -433,13 +452,17 @@ void PresetsCustomWidget(WidgetInfo& info) { ImGui::TableNextColumn(); UIWidgets::PushStyleButton(THEME_COLOR); if (!info.isBuiltIn) { + if (UIWidgets::Button(("Edit##" + name).c_str(), UIWidgets::ButtonOptions().Padding({ 6.0f, 6.0f }))) { + std::copy(info.apply, info.apply + PRESET_SECTION_MAX, saveSection); + newPresetName = name; + oldPresetName = name; + } + UIWidgets::PopStyleButton(); + ImGui::TableNextColumn(); + UIWidgets::PushStyleButton(THEME_COLOR); if (UIWidgets::Button(("Delete##" + name).c_str(), UIWidgets::ButtonOptions().Padding({ 6.0f, 6.0f }))) { - auto path = FormatPresetPath(info.fileName); - if (fs::exists(path)) { - fs::remove(path); - } - presets.erase(name); + DeletePreset(info.fileName); UIWidgets::PopStyleButton(); break; } diff --git a/soh/soh/Enhancements/gameplaystats.cpp b/soh/soh/Enhancements/gameplaystats.cpp index 488dee18e59..ca40c87d2a6 100644 --- a/soh/soh/Enhancements/gameplaystats.cpp +++ b/soh/soh/Enhancements/gameplaystats.cpp @@ -446,7 +446,7 @@ void DrawGameplayStatsHeader() { // if tag is empty (not a release build) if (gGitCommitTag[0] == 0) { GameplayStatsRow("Git Branch:", (char*)gGitBranch); - GameplayStatsRow("Version : 5.0 | Git Commit Hash:", (char*)gGitCommitHash); + GameplayStatsRow("Version : 6.0 | Git Commit Hash:", (char*)gGitCommitHash); } else { GameplayStatsRow("Build Version:", (char*)gBuildVersion); } From b97a2fb9ca701c1b055970ed1514cba4c0e5ebda Mon Sep 17 00:00:00 2001 From: TheLynk Date: Mon, 1 Dec 2025 03:27:42 +0100 Subject: [PATCH 20/45] Add branch "Check tracker improvements" | V:7.0 --- soh/soh/Enhancements/gameplaystats.cpp | 2 +- .../randomizer/randomizer_check_tracker.cpp | 118 +++++++++++------- 2 files changed, 75 insertions(+), 45 deletions(-) diff --git a/soh/soh/Enhancements/gameplaystats.cpp b/soh/soh/Enhancements/gameplaystats.cpp index ca40c87d2a6..a04ea999ede 100644 --- a/soh/soh/Enhancements/gameplaystats.cpp +++ b/soh/soh/Enhancements/gameplaystats.cpp @@ -446,7 +446,7 @@ void DrawGameplayStatsHeader() { // if tag is empty (not a release build) if (gGitCommitTag[0] == 0) { GameplayStatsRow("Git Branch:", (char*)gGitBranch); - GameplayStatsRow("Version : 6.0 | Git Commit Hash:", (char*)gGitCommitHash); + GameplayStatsRow("Version : 7.0 | Git Commit Hash:", (char*)gGitCommitHash); } else { GameplayStatsRow("Build Version:", (char*)gBuildVersion); } diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index 4e8d0fbe65a..913d440cddb 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -1043,16 +1043,17 @@ void CheckTrackerWindow::DrawElement() { #else float headerHeight = 20.0f; #endif - ImVec2 size = ImGui::GetContentRegionMax(); - size.y -= headerHeight; - if (!ImGui::BeginTable("Check Tracker", 1, 0, size)) { + if (!ImGui::BeginTable("Check Tracker", 1, 0)) { EndFloatWindows(); return; } - ImGui::TableNextRow(0, headerHeight); + ImGui::SetWindowFontScale(CVarGetFloat(CVAR_TRACKER_CHECK("FontSize"), 1.0f)); + + ImGui::TableNextRow(0, 0); ImGui::TableNextColumn(); - if (UIWidgets::CVarCheckbox( + if (CVarGetInteger(CVAR_TRACKER_CHECK("HiddenItemsToggleVisible"), 1) && + UIWidgets::CVarCheckbox( "Show Hidden Items", CVAR_TRACKER_CHECK("ShowHidden"), UIWidgets::CheckboxOptions( { { .tooltip = "When active, items will show hidden checks by default when updated to this state." } }) @@ -1061,7 +1062,7 @@ void CheckTrackerWindow::DrawElement() { showHidden = CVarGetInteger(CVAR_TRACKER_CHECK("ShowHidden"), 0); RecalculateAllAreaTotals(); } - if (enableAvailableChecks) { + if (enableAvailableChecks && CVarGetInteger(CVAR_TRACKER_CHECK("AvailableChecksToggleVisible"), 1)) { if (UIWidgets::CVarCheckbox( "Only Show Available Checks", CVAR_TRACKER_CHECK("OnlyShowAvailable"), UIWidgets::CheckboxOptions({ { .tooltip = "When active, unavailable checks will be hidden." } }) @@ -1070,49 +1071,61 @@ void CheckTrackerWindow::DrawElement() { RecalculateAllAreaTotals(); } } - UIWidgets::PaddedSeparator(); - if (UIWidgets::Button("Expand All", UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(UIWidgets::Sizes::Inline))) { - optCollapseAll = false; - optExpandAll = true; - doAreaScroll = true; - } - ImGui::SameLine(); - if (UIWidgets::Button("Collapse All", - UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(UIWidgets::Sizes::Inline))) { - optExpandAll = false; - optCollapseAll = true; - } - ImGui::SameLine(); - if (UIWidgets::Button("Clear", UIWidgets::ButtonOptions({ { .tooltip = "Clear the search field" } }) - .Color(THEME_COLOR) - .Size(UIWidgets::Sizes::Inline))) { - checkSearch.Clear(); - UpdateFilters(); - doAreaScroll = true; + if (CVarGetInteger(CVAR_TRACKER_CHECK("ExpandCollapseButtonsVisible"), 0)) { + if (UIWidgets::Button( + "Expand All", + UIWidgets::ButtonOptions().Color(THEME_COLOR).Size({ ImGui::GetContentRegionAvail().x / 2 - 6, 0 }))) { + optCollapseAll = false; + optExpandAll = true; + doAreaScroll = true; + } + ImGui::SameLine(); + if (UIWidgets::Button( + "Collapse All", + UIWidgets::ButtonOptions().Color(THEME_COLOR).Size({ ImGui::GetContentRegionAvail().x - 6, 0 }))) { + optExpandAll = false; + optCollapseAll = true; + } } UIWidgets::PushStyleCombobox(THEME_COLOR); - if (checkSearch.Draw()) { - UpdateFilters(); + if (CVarGetInteger(CVAR_TRACKER_CHECK("SearchInputVisible"), 1)) { + if (checkSearch.Draw("", ImGui::GetContentRegionAvail().x - 6)) { + UpdateFilters(); + } + std::string checkSearchText = ""; + checkSearchText = checkSearch.InputBuf; + checkSearchText.erase(std::remove(checkSearchText.begin(), checkSearchText.end(), ' '), checkSearchText.end()); + if (checkSearchText.length() < 1) { + ImGui::SameLine(20.0f); + ImGui::TextColored(ImVec4(1.0f, 1.0f, 1.0f, 0.4f), "Search..."); + } } UIWidgets::PopStyleCombobox(); - ImGui::Separator(); - - std::ostringstream totalChecksSS; - totalChecksSS << "Total Checks: "; - if (enableAvailableChecks) { - totalChecksSS << totalChecksAvailable << " Available / "; + if (CVarGetInteger(CVAR_TRACKER_CHECK("CheckTotalsVisible"), 1)) { + std::ostringstream totalChecksSS; + totalChecksSS << ""; + if (enableAvailableChecks) { + totalChecksSS << totalChecksAvailable << " Available / "; + } + totalChecksSS << totalChecksGotten << " Checked / " << totalChecks << " Total"; + ImGui::Text("%s", totalChecksSS.str().c_str()); } - totalChecksSS << totalChecksGotten << " Checked / " << totalChecks << " Total"; - ImGui::Text("%s", totalChecksSS.str().c_str()); - UIWidgets::PaddedSeparator(); + bool headerPresent = + CVarGetInteger(CVAR_TRACKER_CHECK("HiddenItemsToggleVisible"), 1) || + (enableAvailableChecks && CVarGetInteger(CVAR_TRACKER_CHECK("AvailableChecksToggleVisible"), 1)) || + CVarGetInteger(CVAR_TRACKER_CHECK("ExpandCollapseButtonsVisible"), 0) || + CVarGetInteger(CVAR_TRACKER_CHECK("SearchInputVisible"), 1) || + CVarGetInteger(CVAR_TRACKER_CHECK("CheckTotalsVisible"), 1); + if (headerPresent) { + ImGui::Separator(); + } // Checks Section Lead-in ImGui::TableNextRow(); ImGui::TableNextColumn(); - size = ImGui::GetContentRegionAvail(); - if (!ImGui::BeginTable("CheckTracker##Checks", 1, ImGuiTableFlags_ScrollY, size)) { + if (!ImGui::BeginTable("CheckTracker##Checks", 1, ImGuiTableFlags_ScrollY)) { ImGui::EndTable(); EndFloatWindows(); return; @@ -1182,7 +1195,7 @@ void CheckTrackerWindow::DrawElement() { } else { ImGui::SetNextItemOpen(!thisAreaFullyChecked, ImGuiCond_Once); } - doDraw = ImGui::TreeNode(stemp.c_str()); + doDraw = ImGui::TreeNodeEx(stemp.c_str(), ImGuiTreeNodeFlags_NoTreePushOnOpen); ImGui::PopStyleColor(); ImGui::SameLine(); ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(extraColor.r / 255.0f, extraColor.g / 255.0f, @@ -1231,10 +1244,6 @@ void CheckTrackerWindow::DrawElement() { DrawLocation(rc); } } - - if (doDraw) { - ImGui::TreePop(); - } } } ImGui::PopStyleVar(); @@ -2133,6 +2142,16 @@ void CheckTrackerSettingsWindow::DrawElement() { SohGui::mSohMenu->MenuDrawItem(windowTypeWidget, ImGui::GetContentRegionAvail().x, THEME_COLOR); + UIWidgets::CVarSliderFloat("Font Size", CVAR_TRACKER_CHECK("FontSize"), + UIWidgets::FloatSliderOptions() + .Tooltip("Sets the font size used in the check tracker.") + .Format("%.1f") + .Step(0.1f) + .Min(0.3f) + .Max(2.0f) + .Color(THEME_COLOR) + .DefaultValue(1.0f)); + if (CVarGetInteger(CVAR_TRACKER_CHECK("WindowType"), TRACKER_WINDOW_WINDOW) == TRACKER_WINDOW_FLOATING) { UIWidgets::CVarCheckbox("Enable Dragging", CVAR_TRACKER_CHECK("Draggable"), UIWidgets::CheckboxOptions().Color(THEME_COLOR)); @@ -2175,7 +2194,6 @@ void CheckTrackerSettingsWindow::DrawElement() { ImGui::EndDisabled(); // Filtering settings - UIWidgets::PaddedSeparator(); UIWidgets::CVarCheckbox( "Filter Empty Areas", CVAR_TRACKER_CHECK("HideFilteredAreas"), UIWidgets::CheckboxOptions() @@ -2183,6 +2201,18 @@ void CheckTrackerSettingsWindow::DrawElement() { .Color(THEME_COLOR) .DefaultValue(true)); + ImGui::SeparatorText("Tracker Header Visibility"); + UIWidgets::CVarCheckbox("Hidden Items Toggle", CVAR_TRACKER_CHECK("HiddenItemsToggleVisible"), + UIWidgets::CheckboxOptions().Color(THEME_COLOR).DefaultValue(true)); + UIWidgets::CVarCheckbox("Available Checks Toggle", CVAR_TRACKER_CHECK("AvailableChecksToggleVisible"), + UIWidgets::CheckboxOptions().Color(THEME_COLOR).DefaultValue(true)); + UIWidgets::CVarCheckbox("Expand/Collapse Buttons", CVAR_TRACKER_CHECK("ExpandCollapseButtonsVisible"), + UIWidgets::CheckboxOptions().Color(THEME_COLOR).DefaultValue(false)); + UIWidgets::CVarCheckbox("Search Input", CVAR_TRACKER_CHECK("SearchInputVisible"), + UIWidgets::CheckboxOptions().Color(THEME_COLOR).DefaultValue(true)); + UIWidgets::CVarCheckbox("Check Totals", CVAR_TRACKER_CHECK("CheckTotalsVisible"), + UIWidgets::CheckboxOptions().Color(THEME_COLOR).DefaultValue(true)); + ImGui::TableNextColumn(); CheckTracker::ImGuiDrawTwoColorPickerSection("Area Incomplete", CVAR_TRACKER_CHECK("AreaIncomplete.MainColor"), From b3970991b69525a697081be5efbf846e5e396604 Mon Sep 17 00:00:00 2001 From: TheLynk Date: Mon, 1 Dec 2025 04:56:07 +0100 Subject: [PATCH 21/45] Add branch "Improvements to Custom Kaleido Menu" | V:8.0 --- soh/soh/Enhancements/gameplaystats.cpp | 2 +- soh/soh/Enhancements/kaleido.cpp | 169 +++++++++++++----- soh/soh/Enhancements/kaleido.h | 21 +-- .../ovl_kaleido_scope/z_kaleido_scope_PAL.c | 6 +- 4 files changed, 136 insertions(+), 62 deletions(-) diff --git a/soh/soh/Enhancements/gameplaystats.cpp b/soh/soh/Enhancements/gameplaystats.cpp index a04ea999ede..cbfd10dea50 100644 --- a/soh/soh/Enhancements/gameplaystats.cpp +++ b/soh/soh/Enhancements/gameplaystats.cpp @@ -446,7 +446,7 @@ void DrawGameplayStatsHeader() { // if tag is empty (not a release build) if (gGitCommitTag[0] == 0) { GameplayStatsRow("Git Branch:", (char*)gGitBranch); - GameplayStatsRow("Version : 7.0 | Git Commit Hash:", (char*)gGitCommitHash); + GameplayStatsRow("Version : 8.0 | Git Commit Hash:", (char*)gGitCommitHash); } else { GameplayStatsRow("Build Version:", (char*)gBuildVersion); } diff --git a/soh/soh/Enhancements/kaleido.cpp b/soh/soh/Enhancements/kaleido.cpp index d2a6c2e5bea..40b314a5da3 100644 --- a/soh/soh/Enhancements/kaleido.cpp +++ b/soh/soh/Enhancements/kaleido.cpp @@ -1,5 +1,7 @@ #include "kaleido.h" +#include "objects/gameplay_keep/gameplay_keep.h" +#include "soh/Enhancements/randomizer/randomizerTypes.h" #include "soh/frame_interpolation.h" #include "soh/ShipUtils.h" @@ -45,7 +47,7 @@ void KaleidoEntryIcon::LoadIconTex(std::vector* mEntryDl) { } } -KaleidoEntry::KaleidoEntry(int16_t x, int16_t y, std::string text) : mX(x), mY(y), mText(std::move(text)) { +KaleidoEntry::KaleidoEntry(std::string text) : mText(std::move(text)) { mHeight = 0; mWidth = 0; vtx = nullptr; @@ -55,7 +57,12 @@ void KaleidoEntry::SetYOffset(int yOffset) { mY = yOffset; } +void KaleidoEntry::SetSelected(bool val) { + mSelected = val; +} + void KaleidoEntryIcon::Draw(PlayState* play, std::vector* mEntryDl) { + PauseContext* pauseCtx = &play->pauseCtx; if (vtx == nullptr) { return; } @@ -74,13 +81,24 @@ void KaleidoEntryIcon::Draw(PlayState* play, std::vector* mEntryDl) { mEntryDl->push_back(gsSPMatrix(Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), G_MTX_PUSH | G_MTX_LOAD | G_MTX_MODELVIEW)); + // cursor (if selected) + if (mSelected) { + mEntryDl->push_back(gsDPSetPrimColor(0, 0, 255, 255, 255, 255)); + mEntryDl->push_back(gsSPVertex(vtx, 4, 0)); + Gfx cursorIconTex[] = { gsDPLoadTextureBlock(gArrowCursorTex, G_IM_FMT_IA, G_IM_SIZ_8b, 16, 24, 0, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, + G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD) }; + mEntryDl->insert(mEntryDl->end(), std::begin(cursorIconTex), std::end(cursorIconTex)); + mEntryDl->push_back(gsSP1Quadrangle(0, 2, 3, 1, 0)); + } + // icon if (!mAchieved) { mEntryDl->push_back(gsDPSetGrayscaleColor(109, 109, 109, 255)); mEntryDl->push_back(gsSPGrayscale(true)); } mEntryDl->push_back(gsDPSetPrimColor(0, 0, mIconColor.r, mIconColor.g, mIconColor.b, mIconColor.a)); - mEntryDl->push_back(gsSPVertex(vtx, 4, 0)); + mEntryDl->push_back(gsSPVertex(&vtx[4], 4, 0)); LoadIconTex(mEntryDl); mEntryDl->push_back(gsSP1Quadrangle(0, 2, 3, 1, 0)); mEntryDl->push_back(gsSPGrayscale(false)); @@ -90,10 +108,10 @@ void KaleidoEntryIcon::Draw(PlayState* play, std::vector* mEntryDl) { for (size_t i = 0, vtxGroup = 0; i < numChar; i++) { // A maximum of 64 Vtx can be loaded at once by gSPVertex, or basically 16 characters // handle loading groups of 16 chars at a time until there are no more left to load. - // By this point 4 vertices have already been loaded for the preceding icon. + // By this point 8 vertices have already been loaded for the preceding icon and cursor. if (i % 16 == 0) { size_t numVtxToLoad = std::min(numChar - i, 16) * 4; - mEntryDl->push_back(gsSPVertex(&vtx[4 + (vtxGroup * 16 * 4)], numVtxToLoad, 0)); + mEntryDl->push_back(gsSPVertex(&vtx[8 + (vtxGroup * 16 * 4)], numVtxToLoad, 0)); vtxGroup++; } @@ -111,22 +129,29 @@ void KaleidoEntryIcon::Draw(PlayState* play, std::vector* mEntryDl) { Kaleido::Kaleido() { const auto ctx = Rando::Context::GetInstance(); - int yOffset = 2; + int yOffset = 0; mEntries.push_back(std::make_shared( gRupeeCounterIconTex, G_IM_FMT_IA, G_IM_SIZ_8b, 16, 16, Color_RGBA8{ 0xC8, 0xFF, 0x64, 255 }, - FlagType::FLAG_RANDOMIZER_INF, static_cast(RAND_INF_GREG_FOUND), 0, yOffset, "Greg")); - yOffset += 18; + FlagType::FLAG_RANDOMIZER_INF, static_cast(RAND_INF_GREG_FOUND), "Greg")); + if (ctx->GetOption(RSK_SHUFFLE_FISHING_POLE)) { + mEntries.push_back(std::make_shared( + gItemIconFishingPoleTex, G_IM_FMT_RGBA, G_IM_SIZ_32b, 32, 32, Color_RGBA8{ 255, 255, 255, 255 }, + FlagType::FLAG_RANDOMIZER_INF, static_cast(RAND_INF_FISHING_POLE_FOUND), "Fishing Pole")); + } if (ctx->GetOption(RSK_TRIFORCE_HUNT).IsNot(RO_TRIFORCE_HUNT_OFF)) { mEntries.push_back(std::make_shared( - gTriforcePieceTex, G_IM_FMT_RGBA, G_IM_SIZ_32b, 32, 32, Color_RGBA8{ 255, 255, 255, 255 }, 0, yOffset, + gTriforcePieceTex, G_IM_FMT_RGBA, G_IM_SIZ_32b, 32, 32, Color_RGBA8{ 255, 255, 255, 255 }, reinterpret_cast(&gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected), ctx->GetOption(RSK_TRIFORCE_HUNT_PIECES_REQUIRED).Get() + 1, ctx->GetOption(RSK_TRIFORCE_HUNT_PIECES_TOTAL).Get() + 1)); - yOffset += 18; + } + if (ctx->GetOption(RSK_SKELETON_KEY)) { + mEntries.push_back(std::make_shared( + gSmallKeyCounterIconTex, G_IM_FMT_IA, G_IM_SIZ_8b, 16, 16, Color_RGBA8{ 255, 255, 255, 255 }, + FlagType::FLAG_RANDOMIZER_INF, static_cast(RAND_INF_HAS_SKELETON_KEY), "Skeleton Key")); } if (ctx->GetOption(RSK_SHUFFLE_OCARINA_BUTTONS)) { - mEntries.push_back(std::make_shared(0, yOffset)); - yOffset += 18; + mEntries.push_back(std::make_shared()); } if (ctx->GetOption(RSK_SHUFFLE_BOSS_SOULS).IsNot(RO_BOSS_SOULS_OFF)) { static const char* bossSoulNames[] = { @@ -136,15 +161,22 @@ Kaleido::Kaleido() { for (int i = RAND_INF_GOHMA_SOUL; i < RAND_INF_GANON_SOUL; i++) { mEntries.push_back(std::make_shared( gBossSoulTex, G_IM_FMT_RGBA, G_IM_SIZ_32b, 32, 32, Color_RGBA8{ 255, 255, 255, 255 }, - FlagType::FLAG_RANDOMIZER_INF, i, 0, yOffset, bossSoulNames[i - RAND_INF_GOHMA_SOUL])); - yOffset += 18; + FlagType::FLAG_RANDOMIZER_INF, i, bossSoulNames[i - RAND_INF_GOHMA_SOUL])); } } if (ctx->GetOption(RSK_SHUFFLE_BOSS_SOULS).Is(RO_BOSS_SOULS_ON_PLUS_GANON)) { mEntries.push_back(std::make_shared( gBossSoulTex, G_IM_FMT_RGBA, G_IM_SIZ_32b, 32, 32, Color_RGBA8{ 255, 255, 255, 255 }, - FlagType::FLAG_RANDOMIZER_INF, RAND_INF_GANON_SOUL, 0, yOffset, "Ganon's Soul")); - yOffset += 18; + FlagType::FLAG_RANDOMIZER_INF, RAND_INF_GANON_SOUL, "Ganon's Soul")); + } + if (ctx->GetOption(RSK_LOCK_OVERWORLD_DOORS)) { + int rg = RG_GUARD_HOUSE_KEY; + for (int i = RAND_INF_GUARD_HOUSE_KEY_OBTAINED; i <= RAND_INF_FISHING_HOLE_KEY_OBTAINED; i += 2, rg++) { + mEntries.push_back(std::make_shared( + gSmallKeyCounterIconTex, G_IM_FMT_IA, G_IM_SIZ_8b, 16, 16, Color_RGBA8{ 255, 255, 255, 255 }, + FlagType::FLAG_RANDOMIZER_INF, i, + Rando::StaticData::RetrieveItem(static_cast(rg)).GetName().english)); + } } } @@ -162,6 +194,7 @@ void Kaleido::Draw(PlayState* play) { mEntryDl.clear(); OPEN_DISPS(play->state.gfxCtx); mEntryDl.push_back(gsDPPipeSync()); + Gfx_SetupDL_39Opa(play->state.gfxCtx); Gfx_SetupDL_42Opa(play->state.gfxCtx); mEntryDl.push_back(gsDPSetCombineMode(G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM)); @@ -179,13 +212,23 @@ void Kaleido::Draw(PlayState* play) { if (!((pauseCtx->state != 6) || ((pauseCtx->stickRelX == 0) && (pauseCtx->stickRelY == 0)))) { if (pauseCtx->cursorSpecialPos == 0) { if ((pauseCtx->stickRelY > 30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DUP))) { - if (mTopIndex > 0) { - mTopIndex--; + if (mCursorPos > 0) { + mCursorPos--; + Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); + } + if (mCursorPos < mTopIndex) { + mTopIndex = mCursorPos; shouldScroll = true; } } else if ((pauseCtx->stickRelY < -30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DDOWN))) { - if (mTopIndex + mNumVisible < mEntries.size()) { - mTopIndex++; + if (mCursorPos < mEntries.size() - 1) { + mCursorPos++; + Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); + } + if (mCursorPos >= mTopIndex + mNumVisible && mTopIndex + mNumVisible < mEntries.size()) { + mTopIndex = mCursorPos - mNumVisible + 1; shouldScroll = true; } } @@ -213,16 +256,14 @@ void Kaleido::Draw(PlayState* play) { pauseCtx->cursorSpecialPos = 0; } } - int yOffset = 2; + int yOffset = 1; for (int i = mTopIndex; i < (mTopIndex + mNumVisible) && i < mEntries.size(); i++) { auto& entry = mEntries[i]; - if (shouldScroll) { - entry->SetYOffset(yOffset); - yOffset += 18; - Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, - &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); - } + entry->SetYOffset(yOffset); + yOffset += 9; Matrix_Push(); + entry->SetSelected((i == mCursorPos) && !(pauseCtx->cursorSpecialPos == PAUSE_CURSOR_PAGE_RIGHT || + pauseCtx->cursorSpecialPos == PAUSE_CURSOR_PAGE_LEFT)); entry->Draw(play, &mEntryDl); Matrix_Pop(); } @@ -252,9 +293,9 @@ extern "C" void RandoKaleido_UpdateMiscCollectibles(int16_t inDungeonScene) { KaleidoEntryIconFlag::KaleidoEntryIconFlag(const char* iconResourceName, int iconFormat, int iconSize, int iconWidth, int iconHeight, Color_RGBA8 iconColor, FlagType flagType, int flag, - int16_t x, int16_t y, std::string name) - : mFlagType(flagType), mFlag(flag), KaleidoEntryIcon(iconResourceName, iconFormat, iconSize, iconWidth, iconHeight, - iconColor, x, y, std::move(name)) { + std::string name) + : mFlagType(flagType), mFlag(flag), + KaleidoEntryIcon(iconResourceName, iconFormat, iconSize, iconWidth, iconHeight, iconColor, std::move(name)) { BuildVertices(); } @@ -264,9 +305,9 @@ void KaleidoEntryIconFlag::Update(PlayState* play) { KaleidoEntryIconCountRequired::KaleidoEntryIconCountRequired(const char* iconResourceName, int iconFormat, int iconSize, int iconWidth, int iconHeight, Color_RGBA8 iconColor, - int16_t x, int16_t y, int* watch, int required, int total) + int* watch, int required, int total) : mWatch(watch), mRequired(required), mTotal(total), - KaleidoEntryIcon(iconResourceName, iconFormat, iconSize, iconWidth, iconHeight, iconColor, x, y) { + KaleidoEntryIcon(iconResourceName, iconFormat, iconSize, iconWidth, iconHeight, iconColor) { mCount = *mWatch; BuildText(); BuildVertices(); @@ -287,31 +328,54 @@ void KaleidoEntryIconCountRequired::BuildText() { void KaleidoEntryIcon::BuildVertices() { int offsetY = 0; int offsetX = 0; - // 4 vertices per character, plus one for the preceding icon. - Vtx* vertices = (Vtx*)calloc(sizeof(Vtx[4]), mText.length() + 1); + // 4 vertices per character, plus one for the preceding icon, plus one for the cursor. + Vtx* vertices = (Vtx*)calloc(sizeof(Vtx[4]), mText.length() + 2); + // Vertex for the cursor. + Ship_CreateQuadVertexGroup(vertices, offsetX, offsetY, 16, 24, 0); + offsetX += 18; // Vertex for the preceding icon. - Ship_CreateQuadVertexGroup(vertices, offsetX, offsetY, mIconWidth, mIconHeight, 0); + Ship_CreateQuadVertexGroup(&vertices[4], offsetX, offsetY, mIconWidth, mIconHeight, 0); offsetX += 18; for (size_t i = 0; i < mText.length(); i++) { int charWidth = static_cast(Ship_GetCharFontWidth(mText[i])); - Ship_CreateQuadVertexGroup(&(vertices)[(i + 1) * 4], offsetX, offsetY, charWidth, 16, 0); + Ship_CreateQuadVertexGroup(&(vertices)[((i + 1) * 4) + 4], offsetX, offsetY, charWidth, 16, 0); offsetX += charWidth; } offsetY += FONT_CHAR_TEX_HEIGHT; - mWidth = static_cast(offsetX); - mHeight = static_cast(offsetY); + // mWidth = static_cast(offsetX); + // mHeight = static_cast(offsetY); + + vertices[1].v.ob[0] = 15; // top-right x + vertices[2].v.ob[1] = 15; // bottom-left y + vertices[3].v.ob[0] = 15; // bottom-right x + vertices[3].v.ob[1] = 15; // bottom-right y + vertices[5].v.ob[0] = 32; // top-right x + vertices[6].v.ob[1] = 16; // bottom-left-y + vertices[7].v.ob[0] = 32; // bottom-right x + vertices[7].v.ob[1] = 16; // bottom-right y + + for (size_t i = 0; i < mText.length() + 2; i++) { + size_t j = i * 4; + vertices[j].v.ob[0] = vertices[j].v.ob[0] / 2; + vertices[j].v.ob[1] = vertices[j].v.ob[1] / 2; + vertices[j + 1].v.ob[0] = vertices[j + 1].v.ob[0] / 2; + vertices[j + 1].v.ob[1] = vertices[j + 1].v.ob[1] / 2; + vertices[j + 2].v.ob[0] = vertices[j + 2].v.ob[0] / 2; + vertices[j + 2].v.ob[1] = vertices[j + 2].v.ob[1] / 2; + vertices[j + 3].v.ob[0] = vertices[j + 3].v.ob[0] / 2; + vertices[j + 3].v.ob[1] = vertices[j + 3].v.ob[1] / 2; + } + + mWidth = static_cast(offsetX / 2); + mHeight = static_cast(8); - vertices[1].v.ob[0] = 16; - vertices[2].v.ob[1] = 16; - vertices[3].v.ob[0] = 16; - vertices[3].v.ob[1] = 16; vtx = vertices; } KaleidoEntryIcon::KaleidoEntryIcon(const char* iconResourceName, int iconFormat, int iconSize, int iconWidth, - int iconHeight, Color_RGBA8 iconColor, int16_t x, int16_t y, std::string text) + int iconHeight, Color_RGBA8 iconColor, std::string text) : mIconResourceName(iconResourceName), mIconFormat(iconFormat), mIconSize(iconSize), mIconWidth(iconWidth), - mIconHeight(iconHeight), mIconColor(iconColor), KaleidoEntry(x, y, std::move(text)) { + mIconHeight(iconHeight), mIconColor(iconColor), KaleidoEntry(std::move(text)) { } void KaleidoEntryIcon::RebuildVertices() { @@ -329,9 +393,9 @@ void KaleidoEntryIconCountRequired::Update(PlayState* play) { } } -KaleidoEntryOcarinaButtons::KaleidoEntryOcarinaButtons(int16_t x, int16_t y) +KaleidoEntryOcarinaButtons::KaleidoEntryOcarinaButtons() : KaleidoEntryIcon(gItemIconOcarinaOfTimeTex, G_IM_FMT_RGBA, G_IM_SIZ_32b, 32, 32, - Color_RGBA8{ 255, 255, 255, 255 }, x, y, "\x9F\xA5\xA6\xA7\xA8") { + Color_RGBA8{ 255, 255, 255, 255 }, "\x9F\xA5\xA6\xA7\xA8") { CalculateColors(); BuildVertices(); } @@ -405,13 +469,24 @@ void KaleidoEntryOcarinaButtons::Draw(PlayState* play, std::vector* mEntryD mEntryDl->push_back(gsSPMatrix(Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), G_MTX_PUSH | G_MTX_LOAD | G_MTX_MODELVIEW)); + // cursor (if selected) + if (mSelected) { + mEntryDl->push_back(gsDPSetPrimColor(0, 0, 255, 255, 255, 255)); + mEntryDl->push_back(gsSPVertex(vtx, 4, 0)); + Gfx cursorIconTex[] = { gsDPLoadTextureBlock(gArrowCursorTex, G_IM_FMT_IA, G_IM_SIZ_8b, 16, 24, 0, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, + G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD) }; + mEntryDl->insert(mEntryDl->end(), std::begin(cursorIconTex), std::end(cursorIconTex)); + mEntryDl->push_back(gsSP1Quadrangle(0, 2, 3, 1, 0)); + } + // icon if (!mAchieved) { mEntryDl->push_back(gsDPSetGrayscaleColor(109, 109, 109, 255)); mEntryDl->push_back(gsSPGrayscale(true)); } mEntryDl->push_back(gsDPSetPrimColor(0, 0, mIconColor.r, mIconColor.g, mIconColor.b, mIconColor.a)); - mEntryDl->push_back(gsSPVertex(vtx, 4, 0)); + mEntryDl->push_back(gsSPVertex(&vtx[4], 4, 0)); LoadIconTex(mEntryDl); mEntryDl->push_back(gsSP1Quadrangle(0, 2, 3, 1, 0)); mEntryDl->push_back(gsSPGrayscale(false)); @@ -426,7 +501,7 @@ void KaleidoEntryOcarinaButtons::Draw(PlayState* play, std::vector* mEntryD // By this point 4 vertices have already been loaded for the preceding icon. if (i % 16 == 0) { size_t numVtxToLoad = std::min(numChar - i, 16) * 4; - mEntryDl->push_back(gsSPVertex(&vtx[4 + (vtxGroup * 16 * 4)], numVtxToLoad, 0)); + mEntryDl->push_back(gsSPVertex(&vtx[8 + (vtxGroup * 16 * 4)], numVtxToLoad, 0)); vtxGroup++; } diff --git a/soh/soh/Enhancements/kaleido.h b/soh/soh/Enhancements/kaleido.h index 7776afb6631..605bae226d5 100644 --- a/soh/soh/Enhancements/kaleido.h +++ b/soh/soh/Enhancements/kaleido.h @@ -26,18 +26,20 @@ class KaleidoEntry { * @param text the initial value of the line of text. Can be omitted for an * empty string. */ - KaleidoEntry(int16_t x, int16_t y, std::string text = ""); + KaleidoEntry(std::string text = ""); virtual void Draw(PlayState* play, std::vector* mEntryDl) = 0; virtual void Update(PlayState* play) = 0; void SetYOffset(int yOffset); + void SetSelected(bool val); protected: - int16_t mX; - int16_t mY; + int16_t mX = 0; + int16_t mY = 0; int16_t mHeight; int16_t mWidth; Vtx* vtx; std::string mText; + bool mSelected = false; bool mAchieved = false; }; @@ -59,7 +61,7 @@ class KaleidoEntryIcon : public KaleidoEntry { * @param text text to draw to the right of the icon. */ KaleidoEntryIcon(const char* iconResourceName, int iconFormat, int iconSize, int iconWidth, int iconHeight, - Color_RGBA8 iconColor, int16_t x, int16_t y, std::string text = ""); + Color_RGBA8 iconColor, std::string text = ""); void Draw(PlayState* play, std::vector* mEntryDl) override; void RebuildVertices(); @@ -95,8 +97,7 @@ class KaleidoEntryIconFlag : public KaleidoEntryIcon { * @param mName name to draw to the right of the icon. Leave blank to omit. */ KaleidoEntryIconFlag(const char* iconResourceName, int iconFormat, int iconSize, int iconWidth, int iconHeight, - Color_RGBA8 iconColor, FlagType flagType, int flag, int16_t x, int16_t y, - std::string name = ""); + Color_RGBA8 iconColor, FlagType flagType, int flag, std::string name = ""); void Update(PlayState* play) override; private: @@ -128,8 +129,7 @@ class KaleidoEntryIconCountRequired : public KaleidoEntryIcon { * @param total The amount of this collectible available in the seed. Set to 0 to not render. */ KaleidoEntryIconCountRequired(const char* iconResourceName, int iconFormat, int iconSize, int iconWidth, - int iconHeight, Color_RGBA8 iconColor, int16_t x, int16_t y, int* watch, - int required = 0, int total = 0); + int iconHeight, Color_RGBA8 iconColor, int* watch, int required = 0, int total = 0); void Update(PlayState* play) override; private: @@ -143,7 +143,7 @@ class KaleidoEntryIconCountRequired : public KaleidoEntryIcon { class KaleidoEntryOcarinaButtons : public KaleidoEntryIcon { public: - KaleidoEntryOcarinaButtons(int16_t x, int16_t y); + KaleidoEntryOcarinaButtons(); void Update(PlayState* play) override; void Draw(PlayState* play, std::vector* mEntryDl) override; @@ -164,7 +164,8 @@ class Kaleido { std::vector> mEntries; std::vector mEntryDl; int mTopIndex = 0; - int mNumVisible = 7; + int mCursorPos = 0; + int mNumVisible = 14; }; } // namespace Rando diff --git a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c index 14f749d43da..576df18469f 100644 --- a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c +++ b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c @@ -1633,8 +1633,7 @@ void KaleidoScope_DrawPages(PlayState* play, GraphicsContext* gfxCtx) { gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); if (pauseCtx->randoQuestMode) { - POLY_OPA_DISP = - KaleidoScope_DrawPageSections(POLY_OPA_DISP, pauseCtx->saveVtx, sSaveTexs[gSaveContext.language]); + POLY_OPA_DISP = KaleidoScope_DrawPageSections(POLY_OPA_DISP, pauseCtx->saveVtx, sGameOverTexs); RandoKaleido_DrawMiscCollectibles(play); } else { POLY_OPA_DISP = KaleidoScope_DrawPageSections(POLY_OPA_DISP, pauseCtx->questPageVtx, @@ -1729,8 +1728,7 @@ void KaleidoScope_DrawPages(PlayState* play, GraphicsContext* gfxCtx) { gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); if (pauseCtx->randoQuestMode) { - POLY_OPA_DISP = KaleidoScope_DrawPageSections(POLY_OPA_DISP, pauseCtx->saveVtx, - sSaveTexs[gSaveContext.language]); + POLY_OPA_DISP = KaleidoScope_DrawPageSections(POLY_OPA_DISP, pauseCtx->saveVtx, sGameOverTexs); RandoKaleido_DrawMiscCollectibles(play); } else { POLY_OPA_DISP = KaleidoScope_DrawPageSections(POLY_OPA_DISP, pauseCtx->questPageVtx, From 2a5371ff18b1261d159b49f384ad3ec4b283e544 Mon Sep 17 00:00:00 2001 From: TheLynk Date: Tue, 2 Dec 2025 21:52:49 +0100 Subject: [PATCH 22/45] Fix Logic --- .../location_access/dungeons/water_temple.cpp | 32 +++++++++---------- .../overworld/gerudo_fortress.cpp | 2 +- .../location_access/overworld/lake_hylia.cpp | 4 +-- .../location_access/overworld/market.cpp | 10 +++--- 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp index aee55c972a4..8c77d50dfa9 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp @@ -646,10 +646,10 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_MQ_DRAGON_ROOM_TUNNEL] = Region("Water Temple MQ Dragon Room Tunnel", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_1, logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_2, logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_3, logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_4, logic->CanBreakCrates()), + LOCATION(RC_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_1, logic->HasItem(RG_ROLL)), + LOCATION(RC_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_2, logic->HasItem(RG_ROLL)), + LOCATION(RC_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_3, logic->HasItem(RG_ROLL)), + LOCATION(RC_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_4, logic->HasItem(RG_ROLL)), }, { //Exits @@ -739,12 +739,12 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_MQ_TRIANGLE_TORCH_ROOM] = Region("Water Temple MQ Triangle Torch Room", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_1, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_2, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_3, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_4, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_5, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_6, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), + LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_1, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), + LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_2, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), + LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_3, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), + LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_4, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), + LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_5, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), + LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_6, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), }, { //Exits @@ -769,12 +769,12 @@ void RegionTable_Init_WaterTemple() { //Locations LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_FRONT_CRATE_1, logic->CanBreakCrates()), LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_FRONT_CRATE_2, logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_1, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_2, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_3, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_4, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_5, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_6, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), + LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_1, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), + LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_2, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), + LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_3, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), + LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_4, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), + LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_5, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), + LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_6, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), }, { diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp index 15f75ab8dd4..209400b5aed 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp @@ -13,7 +13,7 @@ void RegionTable_Init_GerudoFortress() { }, { //Locations LOCATION(RC_GF_OUTSKIRTS_NE_CRATE, (logic->IsChild || logic->CanPassEnemy(RE_GERUDO_GUARD)) && logic->CanBreakCrates()), - LOCATION(RC_GF_OUTSKIRTS_NW_CRATE, logic->IsChild || logic->CanPassEnemy(RE_GERUDO_GUARD)), + LOCATION(RC_GF_OUTSKIRTS_NW_CRATE, (logic->IsChild || logic->CanPassEnemy(RE_GERUDO_GUARD)) && logic->CanBreakCrates()), }, { //Exits Entrance(RR_GV_FORTRESS_SIDE, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp index f88a2cb6a1c..931919f740c 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp @@ -119,11 +119,11 @@ void RegionTable_Init_LakeHylia() { //Locations LOCATION(RC_LH_LAB_DIVE, logic->HasItem(RG_GOLDEN_SCALE) || (ctx->GetTrickOption(RT_LH_LAB_DIVING) && logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT) && logic->HasItem(RG_BRONZE_SCALE))), LOCATION(RC_LH_TRADE_FROG, logic->IsAdult && logic->CanUse(RG_EYEBALL_FROG)), - LOCATION(RC_LH_GS_LAB_CRATE, logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT) && logic->CanBreakCrates()), + LOCATION(RC_LH_GS_LAB_CRATE, logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT) && logic->HasItem(RG_ROLL)), 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)), - LOCATION(RC_LH_LAB_CRATE, logic->CanUse(RG_IRON_BOOTS) && logic->CanBreakCrates()), + LOCATION(RC_LH_LAB_CRATE, logic->CanUse(RG_IRON_BOOTS) && logic->HasItem(RG_ROLL)), }, { //Exits Entrance(RR_LAKE_HYLIA, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp index 982601b3c03..f9f7fa27c83 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp @@ -23,10 +23,10 @@ void RegionTable_Init_Market() { LOCATION(RC_MARKET_GRASS_6, logic->IsChild && (logic->CanUseSword() || logic->HasItem(RG_GORONS_BRACELET))), LOCATION(RC_MARKET_GRASS_7, logic->IsChild && (logic->CanUseSword() || logic->HasItem(RG_GORONS_BRACELET))), LOCATION(RC_MARKET_GRASS_8, logic->IsChild && (logic->CanUseSword() || logic->HasItem(RG_GORONS_BRACELET))), - LOCATION(RC_MK_NEAR_BAZAAR_CRATE_1, logic->IsChild /*&& logic->CanRoll()*/), - LOCATION(RC_MK_NEAR_BAZAAR_CRATE_2, logic->IsChild /*&& logic->CanRoll()*/), - LOCATION(RC_MK_SHOOTING_GALLERY_CRATE_1, logic->IsChild /*&& logic->CanRoll()*/), - LOCATION(RC_MK_SHOOTING_GALLERY_CRATE_2, logic->IsChild /*&& logic->CanRoll()*/), + LOCATION(RC_MK_NEAR_BAZAAR_CRATE_1, logic->IsChild && logic->HasItem(RG_ROLL)), + LOCATION(RC_MK_NEAR_BAZAAR_CRATE_2, logic->IsChild && logic->HasItem(RG_ROLL)), + LOCATION(RC_MK_SHOOTING_GALLERY_CRATE_1, logic->IsChild && logic->HasItem(RG_ROLL)), + LOCATION(RC_MK_SHOOTING_GALLERY_CRATE_2, logic->IsChild && logic->HasItem(RG_ROLL)), LOCATION(RC_MARKET_TREE, logic->IsChild && logic->CanBonkTrees()), }, { //Exits @@ -227,7 +227,7 @@ void RegionTable_Init_Market() { areaTable[RR_MARKET_DOG_LADY_HOUSE] = Region("Market Dog Lady House", SCENE_DOG_LADY_HOUSE, {}, { //Locations LOCATION(RC_MARKET_LOST_DOG, logic->IsChild && logic->AtNight), - LOCATION(RC_MK_LOST_DOG_HOUSE_CRATE, logic->CanBreakCrates()), + LOCATION(RC_MK_LOST_DOG_HOUSE_CRATE, logic->HasItem(RG_ROLL)), }, { //Exits Entrance(RR_MARKET_BACK_ALLEY, []{return true;}), From 042b163171addf537b589070d1f138618d57f690 Mon Sep 17 00:00:00 2001 From: TheLynk Date: Tue, 2 Dec 2025 22:21:09 +0100 Subject: [PATCH 23/45] Fix Logic | V:8.1 --- soh/soh/Enhancements/gameplaystats.cpp | 2 +- .../location_access/dungeons/water_temple.cpp | 32 +++++++++---------- .../overworld/gerudo_fortress.cpp | 2 +- .../location_access/overworld/lake_hylia.cpp | 4 +-- .../location_access/overworld/market.cpp | 10 +++--- 5 files changed, 25 insertions(+), 25 deletions(-) diff --git a/soh/soh/Enhancements/gameplaystats.cpp b/soh/soh/Enhancements/gameplaystats.cpp index cbfd10dea50..d892378f2b9 100644 --- a/soh/soh/Enhancements/gameplaystats.cpp +++ b/soh/soh/Enhancements/gameplaystats.cpp @@ -446,7 +446,7 @@ void DrawGameplayStatsHeader() { // if tag is empty (not a release build) if (gGitCommitTag[0] == 0) { GameplayStatsRow("Git Branch:", (char*)gGitBranch); - GameplayStatsRow("Version : 8.0 | Git Commit Hash:", (char*)gGitCommitHash); + GameplayStatsRow("Version : 8.1 | Git Commit Hash:", (char*)gGitCommitHash); } else { GameplayStatsRow("Build Version:", (char*)gBuildVersion); } diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp index 3c8c6bf8fe8..a2b631ec305 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp @@ -646,10 +646,10 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_MQ_DRAGON_ROOM_TUNNEL] = Region("Water Temple MQ Dragon Room Tunnel", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_1, logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_2, logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_3, logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_4, logic->CanBreakCrates()), + LOCATION(RC_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_1, logic->HasItem(RG_ROLL)), + LOCATION(RC_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_2, logic->HasItem(RG_ROLL)), + LOCATION(RC_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_3, logic->HasItem(RG_ROLL)), + LOCATION(RC_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_4, logic->HasItem(RG_ROLL)), }, { //Exits @@ -739,12 +739,12 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_MQ_TRIANGLE_TORCH_ROOM] = Region("Water Temple MQ Triangle Torch Room", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_1, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_2, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_3, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_4, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_5, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_6, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), + LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_1, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), + LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_2, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), + LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_3, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), + LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_4, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), + LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_5, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), + LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_6, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), }, { //Exits @@ -769,12 +769,12 @@ void RegionTable_Init_WaterTemple() { //Locations LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_FRONT_CRATE_1, logic->CanBreakCrates()), LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_FRONT_CRATE_2, logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_1, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_2, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_3, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_4, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_5, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_6, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), + LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_1, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), + LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_2, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), + LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_3, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), + LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_4, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), + LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_5, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), + LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_6, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), }, { diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp index f21ab3cc2f1..e976c471dc9 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp @@ -13,7 +13,7 @@ void RegionTable_Init_GerudoFortress() { }, { //Locations LOCATION(RC_GF_OUTSKIRTS_NE_CRATE, (logic->IsChild || logic->CanPassEnemy(RE_GERUDO_GUARD)) && logic->CanBreakCrates()), - LOCATION(RC_GF_OUTSKIRTS_NW_CRATE, logic->IsChild || logic->CanPassEnemy(RE_GERUDO_GUARD)), + LOCATION(RC_GF_OUTSKIRTS_NW_CRATE, (logic->IsChild || logic->CanPassEnemy(RE_GERUDO_GUARD)) && logic->CanBreakCrates()), }, { //Exits Entrance(RR_GV_FORTRESS_SIDE, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp index 15a6a07cca1..85a897e49ce 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp @@ -119,11 +119,11 @@ void RegionTable_Init_LakeHylia() { //Locations LOCATION(RC_LH_LAB_DIVE, logic->HasItem(RG_GOLDEN_SCALE) || (ctx->GetTrickOption(RT_LH_LAB_DIVING) && logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT) && logic->HasItem(RG_BRONZE_SCALE))), LOCATION(RC_LH_TRADE_FROG, logic->IsAdult && logic->CanUse(RG_EYEBALL_FROG)), - LOCATION(RC_LH_GS_LAB_CRATE, logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT) && logic->CanBreakCrates()), + LOCATION(RC_LH_GS_LAB_CRATE, logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT) && logic->HasItem(RG_ROLL)), 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)), - LOCATION(RC_LH_LAB_CRATE, logic->CanUse(RG_IRON_BOOTS) && logic->CanBreakCrates()), + LOCATION(RC_LH_LAB_CRATE, logic->CanUse(RG_IRON_BOOTS) && logic->HasItem(RG_ROLL)), }, { //Exits Entrance(RR_LAKE_HYLIA, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp index 70fed912fb0..046a0dacbd3 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp @@ -23,10 +23,10 @@ void RegionTable_Init_Market() { LOCATION(RC_MARKET_GRASS_6, logic->IsChild && (logic->CanUseSword() || logic->HasItem(RG_GORONS_BRACELET))), LOCATION(RC_MARKET_GRASS_7, logic->IsChild && (logic->CanUseSword() || logic->HasItem(RG_GORONS_BRACELET))), LOCATION(RC_MARKET_GRASS_8, logic->IsChild && (logic->CanUseSword() || logic->HasItem(RG_GORONS_BRACELET))), - LOCATION(RC_MK_NEAR_BAZAAR_CRATE_1, logic->IsChild /*&& logic->CanRoll()*/), - LOCATION(RC_MK_NEAR_BAZAAR_CRATE_2, logic->IsChild /*&& logic->CanRoll()*/), - LOCATION(RC_MK_SHOOTING_GALLERY_CRATE_1, logic->IsChild /*&& logic->CanRoll()*/), - LOCATION(RC_MK_SHOOTING_GALLERY_CRATE_2, logic->IsChild /*&& logic->CanRoll()*/), + LOCATION(RC_MK_NEAR_BAZAAR_CRATE_1, logic->IsChild && logic->HasItem(RG_ROLL)), + LOCATION(RC_MK_NEAR_BAZAAR_CRATE_2, logic->IsChild && logic->HasItem(RG_ROLL)), + LOCATION(RC_MK_SHOOTING_GALLERY_CRATE_1, logic->IsChild && logic->HasItem(RG_ROLL)), + LOCATION(RC_MK_SHOOTING_GALLERY_CRATE_2, logic->IsChild && logic->HasItem(RG_ROLL)), LOCATION(RC_MARKET_TREE, logic->IsChild && logic->CanBonkTrees()), }, { //Exits @@ -227,7 +227,7 @@ void RegionTable_Init_Market() { areaTable[RR_MARKET_DOG_LADY_HOUSE] = Region("Market Dog Lady House", SCENE_DOG_LADY_HOUSE, {}, { //Locations LOCATION(RC_MARKET_LOST_DOG, logic->IsChild && logic->AtNight), - LOCATION(RC_MK_LOST_DOG_HOUSE_CRATE, logic->CanBreakCrates()), + LOCATION(RC_MK_LOST_DOG_HOUSE_CRATE, logic->HasItem(RG_ROLL)), }, { //Exits Entrance(RR_MARKET_BACK_ALLEY, []{return true;}), From 19d7c41c93ea8e5b5c8090bb5b8d31050966a619 Mon Sep 17 00:00:00 2001 From: TheLynk Date: Thu, 4 Dec 2025 02:47:42 +0100 Subject: [PATCH 24/45] Fix Logic Shuffle Bean Souls | V:8.2 --- soh/soh/Enhancements/gameplaystats.cpp | 2 +- .../randomizer/location_access.cpp | 20 ++++++++++--------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/soh/soh/Enhancements/gameplaystats.cpp b/soh/soh/Enhancements/gameplaystats.cpp index d892378f2b9..990b7ee2306 100644 --- a/soh/soh/Enhancements/gameplaystats.cpp +++ b/soh/soh/Enhancements/gameplaystats.cpp @@ -446,7 +446,7 @@ void DrawGameplayStatsHeader() { // if tag is empty (not a release build) if (gGitCommitTag[0] == 0) { GameplayStatsRow("Git Branch:", (char*)gGitBranch); - GameplayStatsRow("Version : 8.1 | Git Commit Hash:", (char*)gGitCommitHash); + GameplayStatsRow("Version : 8.2 | Git Commit Hash:", (char*)gGitCommitHash); } else { GameplayStatsRow("Build Version:", (char*)gBuildVersion); } diff --git a/soh/soh/Enhancements/randomizer/location_access.cpp b/soh/soh/Enhancements/randomizer/location_access.cpp index 8b468544ea4..648b03142c0 100644 --- a/soh/soh/Enhancements/randomizer/location_access.cpp +++ b/soh/soh/Enhancements/randomizer/location_access.cpp @@ -518,17 +518,14 @@ bool Region::CanPlantBeanCheck(RandomizerGet bean) const { if (!logic->HasItem(bean)) { // Never available without soul return false; - } else if (ctx->GetOption(RSK_SKIP_PLANTING_BEANS) && - !ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_BEANS_ONLY) && - !ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL)) { + } else if (ctx->GetOption(RSK_SKIP_PLANTING_BEANS)) { // All planted when skip enabled & bean pack not shuffled - return true; - } else if (logic->GetAmmo(ITEM_BEAN) <= 0) { - // Need bean pack - return false; + return (!ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_BEANS_ONLY) && + !ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL)) || + logic->GetAmmo(ITEM_BEAN) > 0; } else { // BothAgesCheck necessary when planting - return ctx->GetOption(RSK_SKIP_PLANTING_BEANS) || BothAgesCheck(); + return logic->GetAmmo(ITEM_BEAN) > 0 && BothAgesCheck(); } } @@ -699,6 +696,11 @@ bool MQSpiritSharedBrokenWallRoom(const RandomizerRegion region, ConditionFn con } bool BeanPlanted(const RandomizerGet bean) { + auto logic = Rando::Context::GetInstance()->GetLogic(); + // flag irrelevant if plant won't spawn + if (!logic->HasItem(bean)) { + return false; + } // swchFlag found using the Actor Viewer to get the Obj_Bean parameters & 0x3F // not tested with multiple OTRs, but can be automated similarly to GetDungeonSmallKeyDoors SceneID sceneID; @@ -756,7 +758,7 @@ bool BeanPlanted(const RandomizerGet bean) { if (gPlayState != nullptr && gPlayState->sceneNum == sceneID) { swch = gPlayState->actorCtx.flags.swch; } else if (sceneID != SCENE_ID_MAX) { - swch = Rando::Context::GetInstance()->GetLogic()->GetSaveContext()->sceneFlags[sceneID].swch; + swch = logic->GetSaveContext()->sceneFlags[sceneID].swch; } else { swch = 0; } From 17520850b5f7fd5275bededcc4eec4c60f27466b Mon Sep 17 00:00:00 2001 From: TheLynk Date: Sun, 7 Dec 2025 23:45:32 +0100 Subject: [PATCH 25/45] Update model for Shuffle Roll | V:8.3 --- soh/soh/Enhancements/gameplaystats.cpp | 2 +- soh/soh/Enhancements/randomizer/draw.cpp | 43 ++- .../randomizer/roll_animation_data.h | 348 ++++++++++++++++++ 3 files changed, 384 insertions(+), 9 deletions(-) create mode 100644 soh/soh/Enhancements/randomizer/roll_animation_data.h diff --git a/soh/soh/Enhancements/gameplaystats.cpp b/soh/soh/Enhancements/gameplaystats.cpp index 990b7ee2306..0cb7a3b0911 100644 --- a/soh/soh/Enhancements/gameplaystats.cpp +++ b/soh/soh/Enhancements/gameplaystats.cpp @@ -446,7 +446,7 @@ void DrawGameplayStatsHeader() { // if tag is empty (not a release build) if (gGitCommitTag[0] == 0) { GameplayStatsRow("Git Branch:", (char*)gGitBranch); - GameplayStatsRow("Version : 8.2 | Git Commit Hash:", (char*)gGitCommitHash); + GameplayStatsRow("Version : 8.3 | Git Commit Hash:", (char*)gGitCommitHash); } else { GameplayStatsRow("Build Version:", (char*)gBuildVersion); } diff --git a/soh/soh/Enhancements/randomizer/draw.cpp b/soh/soh/Enhancements/randomizer/draw.cpp index adbc022c4ad..ac3cbe00085 100644 --- a/soh/soh/Enhancements/randomizer/draw.cpp +++ b/soh/soh/Enhancements/randomizer/draw.cpp @@ -36,6 +36,8 @@ extern "C" { #include "objects/object_tw/object_tw.h" #include "objects/object_ganon2/object_ganon2.h" #include "objects/object_vase/object_vase.h" +#include "objects/object_link_child/object_link_child.h" +#include "roll_animation_data.h" extern PlayState* gPlayState; extern SaveContext gSaveContext; @@ -1124,18 +1126,43 @@ extern "C" void Randomizer_DrawBronzeScale(PlayState* play, GetItemEntry* getIte } extern "C" void Randomizer_DrawRollAbility(PlayState* play, GetItemEntry* getItemEntry) { + static bool initialized = false; + static SkelAnime skelAnime; + static Vec3s jointTable[ROLL_ANIMATION_LIMBS]; + static Vec3s morphTable[ROLL_ANIMATION_LIMBS]; + static u32 lastUpdate = 0; + static int currentFrame = 0; + + if (!initialized) { + initialized = true; + SkelAnime_InitFlex(play, &skelAnime, (FlexSkeletonHeader*)gLinkChildSkel, NULL, jointTable, morphTable, + ROLL_ANIMATION_LIMBS); + } + + // Animation manuelle avec les frames capturées + if (lastUpdate != play->state.frames) { + lastUpdate = play->state.frames; + + // Avance d'une frame toutes les 2 frames de jeu + if ((play->state.frames % 2) == 0) { + currentFrame = (currentFrame + 1) % ROLL_ANIMATION_FRAMES; + } + + // Copie les données de la frame actuelle + for (int i = 0; i < ROLL_ANIMATION_LIMBS; i++) { + jointTable[i] = rollAnimationData[currentFrame][i]; + } + } + OPEN_DISPS(play->state.gfxCtx); Gfx_SetupDL_25Opa(play->state.gfxCtx); - // Objet central qui roule - réduit de 20% avec centrage ajusté - Matrix_Translate(21.0f, 0.0f, 0.0f, MTXMODE_APPLY); - Matrix_RotateZ(1.57f, MTXMODE_APPLY); - Matrix_RotateY(play->gameplayFrames * 0.15f, MTXMODE_APPLY); - Matrix_Scale(0.018f, 0.018f, 0.018f, MTXMODE_APPLY); - gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), - G_MTX_MODELVIEW | G_MTX_LOAD); - gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gUnusedVaseDL); + Matrix_Translate(0.0f, -30.0f, 0.0f, MTXMODE_APPLY); + Matrix_RotateY(play->gameplayFrames * 0.05f, MTXMODE_APPLY); + Matrix_Scale(0.01f, 0.01f, 0.01f, MTXMODE_APPLY); + + SkelAnime_DrawFlexOpa(play, skelAnime.skeleton, jointTable, skelAnime.dListCount, NULL, NULL, NULL); CLOSE_DISPS(play->state.gfxCtx); } diff --git a/soh/soh/Enhancements/randomizer/roll_animation_data.h b/soh/soh/Enhancements/randomizer/roll_animation_data.h new file mode 100644 index 00000000000..5d0700721c0 --- /dev/null +++ b/soh/soh/Enhancements/randomizer/roll_animation_data.h @@ -0,0 +1,348 @@ +#ifndef ROLL_ANIMATION_DATA_H +#define ROLL_ANIMATION_DATA_H + +#include "z64.h" + +#define ROLL_ANIMATION_FRAMES 20 +#define ROLL_ANIMATION_LIMBS 22 + +static const Vec3s rollAnimationData[ROLL_ANIMATION_FRAMES][ROLL_ANIMATION_LIMBS] = { + { + // Frame 0 + { 74, 3528, -37 }, + { 0, 0, 0 }, + { -16384, -626, -16384 }, + { 0, 0, 0 }, + { 135, 5446, -5887 }, + { 0, 0, 23451 }, + { 2115, 1887, -20292 }, + { 1024, -219, -1846 }, + { 0, 0, 5914 }, + { -443, -1625, -21253 }, + { 16384, 417, 16384 }, + { 476, -93, 19351 }, + { 0, 0, 23344 }, + { 0, 0, 0 }, + { -21137, -12435, -10526 }, + { 0, 0, -6675 }, + { -36, -503, -16171 }, + { 12851, 7298, -17081 }, + { 0, 0, -19713 }, + { 4373, 5305, -15750 }, + { -16384, 27240, -730 }, + { 0, 0, 0 }, + }, + { + // Frame 1 + { 54, 3227, -89 }, + { 2313, 0, 0 }, + { -16384, -685, -16384 }, + { 0, 0, 0 }, + { -152, 5099, -11115 }, + { 0, 0, 24427 }, + { 2059, 1815, -21046 }, + { -59, -710, -6843 }, + { 0, 0, 10860 }, + { -979, -1386, -22412 }, + { 16183, -133, 16490 }, + { 503, -59, 18352 }, + { 0, 0, 25530 }, + { 0, 0, 0 }, + { -20393, -12323, -12080 }, + { 0, 0, -6726 }, + { -25, -562, -16150 }, + { 14095, 8887, -16891 }, + { 0, 0, -18784 }, + { 3073, 5837, -17586 }, + { -15392, 27325, 1213 }, + { 0, 0, 0 }, + }, + { + // Frame 2 + { -25, 2218, -133 }, + { 7607, 0, 0 }, + { -16384, -781, -16384 }, + { 0, 0, 0 }, + { -654, 1069, -20519 }, + { 0, 0, 20760 }, + { 1304, 1666, -23774 }, + { -518, -3910, -15614 }, + { 0, 0, 22754 }, + { -1707, -1918, -22925 }, + { 16384, -4331, 16384 }, + { 641, 74, 13206 }, + { 0, 0, 30948 }, + { 0, 0, 0 }, + { -15708, -11590, -21423 }, + { 0, 0, -6949 }, + { 37, -880, -16032 }, + { -12778, 15014, 15677 }, + { 0, 0, -13974 }, + { -4182, 8702, -27734 }, + { -13006, 28312, 6371 }, + { 0, 0, 0 }, + }, + { + // Frame 3 + { -57, 2670, 558 }, { 13602, 0, 0 }, + { -16384, 0, -16384 }, { 0, 0, 0 }, + { 1852, 198, -7548 }, { 0, 0, 1654 }, + { 1472, 2843, -23780 }, { -2685, -3676, -6545 }, + { 0, 0, 15549 }, { 1676, -2089, -20933 }, + { -1427, -19182, -27019 }, { 698, -257, 10968 }, + { 0, 0, 18514 }, { 0, 0, 0 }, + { 23192, -22237, 548 }, { 0, 0, -6929 }, + { 86, -1131, -15938 }, { -11355, 7097, 10885 }, + { 0, 0, -11056 }, { -10661, 10872, 29098 }, + { -15580, 27296, 800 }, { 0, 0, 0 }, + }, + { + // Frame 4 + { -60, 2207, 382 }, { 20068, 0, 0 }, + { -16384, 2162, -16384 }, { 0, 0, 0 }, + { 219, 581, -17012 }, { 0, 0, 16199 }, + { 1446, 2552, -20834 }, { -1193, -3974, -12795 }, + { 0, 0, 22901 }, { 1355, -1424, -20722 }, + { -24738, -12007, -7558 }, { 462, -469, 19859 }, + { 0, 0, 17568 }, { 0, 0, 0 }, + { -1152, -8811, 22716 }, { 0, 0, -5124 }, + { 43, -913, -16019 }, { -2615, 21391, 18299 }, + { 0, 0, -20972 }, { -7167, 7353, -29571 }, + { -16740, 27249, -1447 }, { 0, 0, 0 }, + }, + { + // Frame 5 + { -60, 1477, 314 }, { 26774, 0, 0 }, + { -16384, 4992, -16384 }, { 0, 0, 0 }, + { 1331, 909, -8175 }, { 0, 0, 8190 }, + { 538, 2622, -21124 }, { -443, -603, -1212 }, + { 0, 0, 24711 }, { 491, -584, -20713 }, + { -21267, -11295, -7882 }, { 552, 479, 16219 }, + { 0, 0, 17341 }, { 0, 0, 0 }, + { 2866, -7762, 19771 }, { 0, 0, -3812 }, + { -416, 862, -16656 }, { -2940, 16895, 20702 }, + { 0, 0, -18661 }, { -5100, 10643, -25824 }, + { -15495, 27304, 1032 }, { 0, 0, 0 }, + }, + { + // Frame 6 + { -60, 771, 241 }, { -32044, 0, 0 }, { -16384, 7684, -16384 }, { 0, 0, 0 }, + { -27, 459, -14461 }, { 0, 0, 13541 }, { 63, 2434, -21507 }, { 140, -3557, -8362 }, + { 0, 0, 25043 }, { -525, 149, -20932 }, { -18194, -11230, -7652 }, { 519, 2089, 15610 }, + { 0, 0, 17631 }, { 0, 0, 0 }, { 3504, -7332, 22086 }, { 0, 0, -4207 }, + { -1489, 5198, -18222 }, { 967, 12936, 27541 }, { 0, 0, -17131 }, { -2949, 6188, -22075 }, + { -16864, 27258, -1679 }, { 0, 0, 0 }, + }, + { + // Frame 7 + { -60, 511, -4 }, { -25546, 0, 0 }, + { -16384, 8878, -16384 }, { 0, 0, 0 }, + { -799, 63, -16740 }, { 0, 0, 14954 }, + { 943, 1296, -21262 }, { 1564, -3136, -16443 }, + { 0, 0, 25526 }, { -1303, 490, -21402 }, + { -18554, -11994, -7123 }, { 464, 3612, 15275 }, + { 0, 0, 18235 }, { 0, 0, 0 }, + { 3231, -6977, 25545 }, { 0, 0, -4847 }, + { -321, 5196, -18440 }, { 2710, 9642, 31101 }, + { 0, 0, -15600 }, { -985, 4840, -20355 }, + { -16899, 27261, -1747 }, { 0, 0, 0 }, + }, + { + // Frame 8 + { -60, 771, -444 }, { -19497, 0, 0 }, + { -16384, 6684, -16384 }, { 0, 0, 0 }, + { -2556, 1051, -17674 }, { 0, 0, 27472 }, + { 1977, 423, -21477 }, { 1754, -2055, -18579 }, + { 0, 0, 25919 }, { -1681, 96, -22354 }, + { -20790, -12983, -5802 }, { 376, 4598, 14848 }, + { 0, 0, 18950 }, { 0, 0, 0 }, + { 3130, -6330, 27866 }, { 0, 0, -5576 }, + { 2725, 2012, -17715 }, { 4493, 6440, -31020 }, + { 0, 0, -14167 }, { 1055, 3881, -18845 }, + { -16739, 27250, -1432 }, { 0, 0, 0 }, + }, + { + // Frame 9 + { -59, 940, -590 }, { -16713, 0, 0 }, + { -16384, 5073, -16384 }, { 0, 0, 0 }, + { -2448, 996, -16808 }, { 0, 0, 26712 }, + { 2021, 695, -22206 }, { 1957, -1988, -18219 }, + { 0, 0, 26656 }, { -1789, -334, -23017 }, + { -22257, -13213, -4844 }, { 333, 4517, 14584 }, + { 0, 0, 19285 }, { 0, 0, 0 }, + { 2948, -5849, 28856 }, { 0, 0, -5925 }, + { 4383, 81, -17239 }, { 5329, 5036, -29493 }, + { 0, 0, -13518 }, { 1992, 3521, -18202 }, + { -16629, 27244, -1214 }, { 0, 0, 0 }, + }, + { + // Frame 10 + { -59, 1348, -649 }, { -11768, 0, 0 }, + { -16384, 1883, -16384 }, { 0, 0, 0 }, + { -2196, 778, -10577 }, { 0, 0, 28012 }, + { 1653, 2033, -24440 }, { 2855, -2524, -11436 }, + { 0, 0, 27911 }, { -1938, -1318, -24470 }, + { -25057, -12419, -3692 }, { 177, 3296, 14007 }, + { 0, 0, 19787 }, { 0, 0, 0 }, + { 2482, -4950, 30438 }, { 0, 0, -6494 }, + { 6915, -3159, -16394 }, { 6751, 2940, -27054 }, + { 0, 0, -12420 }, { 3479, 2992, -17208 }, + { -16434, 27240, -830 }, { 0, 0, 0 }, + }, + { + // Frame 11 + { -58, 1735, -542 }, { -7750, 0, 0 }, + { -16384, 184, -16384 }, { 0, 0, 0 }, + { -1205, 108, -8043 }, { 0, 0, 25981 }, + { 1346, 2790, -26757 }, { 2029, -1692, -8455 }, + { 0, 0, 25863 }, { -1961, -2047, -25988 }, + { -28048, -11954, -2090 }, { -470, 3031, 12591 }, + { 0, 0, 19948 }, { 0, 0, 0 }, + { 2309, -4596, 31084 }, { 0, 0, -6786 }, + { 7219, -4155, -16045 }, { 7656, 2711, -26079 }, + { 0, 0, -11861 }, { 4229, 2661, -16666 }, + { -16363, 27240, -688 }, { 0, 0, 0 }, + }, + { + // Frame 12 + { 74, 3528, -37 }, + { 0, 0, 0 }, + { -16384, -626, -16384 }, + { 0, 0, 0 }, + { 135, 5446, -5887 }, + { 0, 0, 23451 }, + { 2115, 1887, -20292 }, + { 1024, -219, -1846 }, + { 0, 0, 5914 }, + { -443, -1625, -21253 }, + { 16384, 417, 16384 }, + { 476, -93, 19351 }, + { 0, 0, 23344 }, + { 0, 0, 0 }, + { -21137, -12435, -10526 }, + { 0, 0, -6675 }, + { -36, -503, -16171 }, + { 12851, 7298, -17081 }, + { 0, 0, -19713 }, + { 4373, 5305, -15750 }, + { -16384, 27240, -730 }, + { 0, 0, 0 }, + }, + { + // Frame 13 + { 54, 3227, -89 }, + { 2313, 0, 0 }, + { -16384, -685, -16384 }, + { 0, 0, 0 }, + { -152, 5099, -11115 }, + { 0, 0, 24427 }, + { 2059, 1815, -21046 }, + { -59, -710, -6843 }, + { 0, 0, 10860 }, + { -979, -1386, -22412 }, + { 16183, -133, 16490 }, + { 503, -59, 18352 }, + { 0, 0, 25530 }, + { 0, 0, 0 }, + { -20393, -12323, -12080 }, + { 0, 0, -6726 }, + { -25, -562, -16150 }, + { 14095, 8887, -16891 }, + { 0, 0, -18784 }, + { 3073, 5837, -17586 }, + { -15392, 27325, 1213 }, + { 0, 0, 0 }, + }, + { + // Frame 14 + { -25, 2218, -133 }, + { 7607, 0, 0 }, + { -16384, -781, -16384 }, + { 0, 0, 0 }, + { -654, 1069, -20519 }, + { 0, 0, 20760 }, + { 1304, 1666, -23774 }, + { -518, -3910, -15614 }, + { 0, 0, 22754 }, + { -1707, -1918, -22925 }, + { 16384, -4331, 16384 }, + { 641, 74, 13206 }, + { 0, 0, 30948 }, + { 0, 0, 0 }, + { -15708, -11590, -21423 }, + { 0, 0, -6949 }, + { 37, -880, -16032 }, + { -12778, 15014, 15677 }, + { 0, 0, -13974 }, + { -4182, 8702, -27734 }, + { -13006, 28312, 6371 }, + { 0, 0, 0 }, + }, + { + // Frame 15 + { -57, 2670, 558 }, { 13602, 0, 0 }, + { -16384, 0, -16384 }, { 0, 0, 0 }, + { 1852, 198, -7548 }, { 0, 0, 1654 }, + { 1472, 2843, -23780 }, { -2685, -3676, -6545 }, + { 0, 0, 15549 }, { 1676, -2089, -20933 }, + { -1427, -19182, -27019 }, { 698, -257, 10968 }, + { 0, 0, 18514 }, { 0, 0, 0 }, + { 23192, -22237, 548 }, { 0, 0, -6929 }, + { 86, -1131, -15938 }, { -11355, 7097, 10885 }, + { 0, 0, -11056 }, { -10661, 10872, 29098 }, + { -15580, 27296, 800 }, { 0, 0, 0 }, + }, + { + // Frame 16 + { -60, 2207, 382 }, { 20068, 0, 0 }, + { -16384, 2162, -16384 }, { 0, 0, 0 }, + { 219, 581, -17012 }, { 0, 0, 16199 }, + { 1446, 2552, -20834 }, { -1193, -3974, -12795 }, + { 0, 0, 22901 }, { 1355, -1424, -20722 }, + { -24738, -12007, -7558 }, { 462, -469, 19859 }, + { 0, 0, 17568 }, { 0, 0, 0 }, + { -1152, -8811, 22716 }, { 0, 0, -5124 }, + { 43, -913, -16019 }, { -2615, 21391, 18299 }, + { 0, 0, -20972 }, { -7167, 7353, -29571 }, + { -16740, 27249, -1447 }, { 0, 0, 0 }, + }, + { + // Frame 17 + { -60, 1477, 314 }, { 26774, 0, 0 }, + { -16384, 4992, -16384 }, { 0, 0, 0 }, + { 1331, 909, -8175 }, { 0, 0, 8190 }, + { 538, 2622, -21124 }, { -443, -603, -1212 }, + { 0, 0, 24711 }, { 491, -584, -20713 }, + { -21267, -11295, -7882 }, { 552, 479, 16219 }, + { 0, 0, 17341 }, { 0, 0, 0 }, + { 2866, -7762, 19771 }, { 0, 0, -3812 }, + { -416, 862, -16656 }, { -2940, 16895, 20702 }, + { 0, 0, -18661 }, { -5100, 10643, -25824 }, + { -15495, 27304, 1032 }, { 0, 0, 0 }, + }, + { + // Frame 18 + { -60, 771, 241 }, { -32044, 0, 0 }, { -16384, 7684, -16384 }, { 0, 0, 0 }, + { -27, 459, -14461 }, { 0, 0, 13541 }, { 63, 2434, -21507 }, { 140, -3557, -8362 }, + { 0, 0, 25043 }, { -525, 149, -20932 }, { -18194, -11230, -7652 }, { 519, 2089, 15610 }, + { 0, 0, 17631 }, { 0, 0, 0 }, { 3504, -7332, 22086 }, { 0, 0, -4207 }, + { -1489, 5198, -18222 }, { 967, 12936, 27541 }, { 0, 0, -17131 }, { -2949, 6188, -22075 }, + { -16864, 27258, -1679 }, { 0, 0, 0 }, + }, + { + // Frame 19 + { -60, 511, -4 }, { -25546, 0, 0 }, + { -16384, 8878, -16384 }, { 0, 0, 0 }, + { -799, 63, -16740 }, { 0, 0, 14954 }, + { 943, 1296, -21262 }, { 1564, -3136, -16443 }, + { 0, 0, 25526 }, { -1303, 490, -21402 }, + { -18554, -11994, -7123 }, { 464, 3612, 15275 }, + { 0, 0, 18235 }, { 0, 0, 0 }, + { 3231, -6977, 25545 }, { 0, 0, -4847 }, + { -321, 5196, -18440 }, { 2710, 9642, 31101 }, + { 0, 0, -15600 }, { -985, 4840, -20355 }, + { -16899, 27261, -1747 }, { 0, 0, 0 }, + }, +}; + +#endif // ROLL_ANIMATION_DATA_H \ No newline at end of file From d95815dd8f1d042be0be24d52ca9097fc39615f1 Mon Sep 17 00:00:00 2001 From: TheLynk Date: Mon, 8 Dec 2025 00:31:08 +0100 Subject: [PATCH 26/45] Fix Merge And New Model for Roll --- soh/soh/Enhancements/randomizer/draw.cpp | 44 ++- soh/soh/Enhancements/randomizer/item_list.cpp | 2 +- .../randomizer/roll_animation_data.h | 348 ++++++++++++++++++ 3 files changed, 385 insertions(+), 9 deletions(-) create mode 100644 soh/soh/Enhancements/randomizer/roll_animation_data.h diff --git a/soh/soh/Enhancements/randomizer/draw.cpp b/soh/soh/Enhancements/randomizer/draw.cpp index bb8f8ad05eb..40130688e7e 100644 --- a/soh/soh/Enhancements/randomizer/draw.cpp +++ b/soh/soh/Enhancements/randomizer/draw.cpp @@ -35,6 +35,9 @@ extern "C" { #include "objects/object_tw/object_tw.h" #include "objects/object_ganon2/object_ganon2.h" #include "objects/object_vase/object_vase.h" +#include "objects/object_link_child/object_link_child.h" +#include "roll_animation_data.h" + extern PlayState* gPlayState; extern SaveContext gSaveContext; } @@ -1111,18 +1114,43 @@ extern "C" void Randomizer_DrawBronzeScale(PlayState* play, GetItemEntry* getIte } extern "C" void Randomizer_DrawRollAbility(PlayState* play, GetItemEntry* getItemEntry) { + static bool initialized = false; + static SkelAnime skelAnime; + static Vec3s jointTable[ROLL_ANIMATION_LIMBS]; + static Vec3s morphTable[ROLL_ANIMATION_LIMBS]; + static u32 lastUpdate = 0; + static int currentFrame = 0; + + if (!initialized) { + initialized = true; + SkelAnime_InitFlex(play, &skelAnime, (FlexSkeletonHeader*)gLinkChildSkel, NULL, jointTable, morphTable, + ROLL_ANIMATION_LIMBS); + } + + // Animation manuelle avec les frames capturées + if (lastUpdate != play->state.frames) { + lastUpdate = play->state.frames; + + // Avance d'une frame toutes les 2 frames de jeu + if ((play->state.frames % 2) == 0) { + currentFrame = (currentFrame + 1) % ROLL_ANIMATION_FRAMES; + } + + // Copie les données de la frame actuelle + for (int i = 0; i < ROLL_ANIMATION_LIMBS; i++) { + jointTable[i] = rollAnimationData[currentFrame][i]; + } + } + OPEN_DISPS(play->state.gfxCtx); Gfx_SetupDL_25Opa(play->state.gfxCtx); - // Objet central qui roule - réduit de 20% avec centrage ajusté - Matrix_Translate(21.0f, 0.0f, 0.0f, MTXMODE_APPLY); - Matrix_RotateZ(1.57f, MTXMODE_APPLY); - Matrix_RotateY(play->gameplayFrames * 0.15f, MTXMODE_APPLY); - Matrix_Scale(0.018f, 0.018f, 0.018f, MTXMODE_APPLY); - gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), - G_MTX_MODELVIEW | G_MTX_LOAD); - gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gUnusedVaseDL); + Matrix_Translate(0.0f, -30.0f, 0.0f, MTXMODE_APPLY); + Matrix_RotateY(play->gameplayFrames * 0.05f, MTXMODE_APPLY); + Matrix_Scale(0.01f, 0.01f, 0.01f, MTXMODE_APPLY); + + SkelAnime_DrawFlexOpa(play, skelAnime.skeleton, jointTable, skelAnime.dListCount, NULL, NULL, NULL); CLOSE_DISPS(play->state.gfxCtx); } diff --git a/soh/soh/Enhancements/randomizer/item_list.cpp b/soh/soh/Enhancements/randomizer/item_list.cpp index 5f2b8e5dcfd..7ed73f10f2e 100644 --- a/soh/soh/Enhancements/randomizer/item_list.cpp +++ b/soh/soh/Enhancements/randomizer/item_list.cpp @@ -354,7 +354,7 @@ void Rando::StaticData::InitItemTable() { itemTable[RG_ROLL] = Item(RG_ROLL, Text{ "Roll", "Rouler", "Rolle" }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, LOGIC_NONE, RHT_ROLL, RG_ROLL, OBJECT_GI_SCALE, GID_SCALE_SILVER, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_ROLL].SetCustomDrawFunc(Randomizer_DrawRollAbility); - itemTable[RG_PROGRESSIVE_BOMBCHU_BAG] = Item(RG_PROGRESSIVE_BOMBCHU_BAG, Text{ "Bombchu Bag", "Sac de Missiles Teigneux", "Krabbelminentasche" }, ITEMTYPE_ITEM, RG_BOMBCHU_BAG, true, LOGIC_BOMBCHUS, RHT_BOMBCHU_BAG, RG_BOMBCHU_BAG, OBJECT_GI_BOMB_2, GID_BOMBCHU, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_PROGRESSIVE_BOMBCHU_BAG] = Item(RG_PROGRESSIVE_BOMBCHU_BAG, Text{ "Bombchu Bag", "Sac de Missiles Teigneux", "Krabbelminentasche" }, ITEMTYPE_ITEM, RG_PROGRESSIVE_BOMBCHU_BAG, true, LOGIC_BOMBCHUS, RHT_BOMBCHU_BAG, RG_PROGRESSIVE_BOMBCHU_BAG, OBJECT_GI_BOMB_2, GID_BOMBCHU, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_PROGRESSIVE_BOMBCHU_BAG].SetCustomDrawFunc(Randomizer_DrawBombchuBag); itemTable[RG_QUIVER_INF] = Item(RG_QUIVER_INF, Text{ "Infinite Quiver", "Carquois Infini", "Unendlicher Köcher" }, ITEMTYPE_ITEM, RG_QUIVER_INF, true, LOGIC_PROGRESSIVE_BOW, RHT_QUIVER_INF, RG_QUIVER_INF, OBJECT_GI_ARROWCASE, GID_QUIVER_50, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER); diff --git a/soh/soh/Enhancements/randomizer/roll_animation_data.h b/soh/soh/Enhancements/randomizer/roll_animation_data.h new file mode 100644 index 00000000000..5d0700721c0 --- /dev/null +++ b/soh/soh/Enhancements/randomizer/roll_animation_data.h @@ -0,0 +1,348 @@ +#ifndef ROLL_ANIMATION_DATA_H +#define ROLL_ANIMATION_DATA_H + +#include "z64.h" + +#define ROLL_ANIMATION_FRAMES 20 +#define ROLL_ANIMATION_LIMBS 22 + +static const Vec3s rollAnimationData[ROLL_ANIMATION_FRAMES][ROLL_ANIMATION_LIMBS] = { + { + // Frame 0 + { 74, 3528, -37 }, + { 0, 0, 0 }, + { -16384, -626, -16384 }, + { 0, 0, 0 }, + { 135, 5446, -5887 }, + { 0, 0, 23451 }, + { 2115, 1887, -20292 }, + { 1024, -219, -1846 }, + { 0, 0, 5914 }, + { -443, -1625, -21253 }, + { 16384, 417, 16384 }, + { 476, -93, 19351 }, + { 0, 0, 23344 }, + { 0, 0, 0 }, + { -21137, -12435, -10526 }, + { 0, 0, -6675 }, + { -36, -503, -16171 }, + { 12851, 7298, -17081 }, + { 0, 0, -19713 }, + { 4373, 5305, -15750 }, + { -16384, 27240, -730 }, + { 0, 0, 0 }, + }, + { + // Frame 1 + { 54, 3227, -89 }, + { 2313, 0, 0 }, + { -16384, -685, -16384 }, + { 0, 0, 0 }, + { -152, 5099, -11115 }, + { 0, 0, 24427 }, + { 2059, 1815, -21046 }, + { -59, -710, -6843 }, + { 0, 0, 10860 }, + { -979, -1386, -22412 }, + { 16183, -133, 16490 }, + { 503, -59, 18352 }, + { 0, 0, 25530 }, + { 0, 0, 0 }, + { -20393, -12323, -12080 }, + { 0, 0, -6726 }, + { -25, -562, -16150 }, + { 14095, 8887, -16891 }, + { 0, 0, -18784 }, + { 3073, 5837, -17586 }, + { -15392, 27325, 1213 }, + { 0, 0, 0 }, + }, + { + // Frame 2 + { -25, 2218, -133 }, + { 7607, 0, 0 }, + { -16384, -781, -16384 }, + { 0, 0, 0 }, + { -654, 1069, -20519 }, + { 0, 0, 20760 }, + { 1304, 1666, -23774 }, + { -518, -3910, -15614 }, + { 0, 0, 22754 }, + { -1707, -1918, -22925 }, + { 16384, -4331, 16384 }, + { 641, 74, 13206 }, + { 0, 0, 30948 }, + { 0, 0, 0 }, + { -15708, -11590, -21423 }, + { 0, 0, -6949 }, + { 37, -880, -16032 }, + { -12778, 15014, 15677 }, + { 0, 0, -13974 }, + { -4182, 8702, -27734 }, + { -13006, 28312, 6371 }, + { 0, 0, 0 }, + }, + { + // Frame 3 + { -57, 2670, 558 }, { 13602, 0, 0 }, + { -16384, 0, -16384 }, { 0, 0, 0 }, + { 1852, 198, -7548 }, { 0, 0, 1654 }, + { 1472, 2843, -23780 }, { -2685, -3676, -6545 }, + { 0, 0, 15549 }, { 1676, -2089, -20933 }, + { -1427, -19182, -27019 }, { 698, -257, 10968 }, + { 0, 0, 18514 }, { 0, 0, 0 }, + { 23192, -22237, 548 }, { 0, 0, -6929 }, + { 86, -1131, -15938 }, { -11355, 7097, 10885 }, + { 0, 0, -11056 }, { -10661, 10872, 29098 }, + { -15580, 27296, 800 }, { 0, 0, 0 }, + }, + { + // Frame 4 + { -60, 2207, 382 }, { 20068, 0, 0 }, + { -16384, 2162, -16384 }, { 0, 0, 0 }, + { 219, 581, -17012 }, { 0, 0, 16199 }, + { 1446, 2552, -20834 }, { -1193, -3974, -12795 }, + { 0, 0, 22901 }, { 1355, -1424, -20722 }, + { -24738, -12007, -7558 }, { 462, -469, 19859 }, + { 0, 0, 17568 }, { 0, 0, 0 }, + { -1152, -8811, 22716 }, { 0, 0, -5124 }, + { 43, -913, -16019 }, { -2615, 21391, 18299 }, + { 0, 0, -20972 }, { -7167, 7353, -29571 }, + { -16740, 27249, -1447 }, { 0, 0, 0 }, + }, + { + // Frame 5 + { -60, 1477, 314 }, { 26774, 0, 0 }, + { -16384, 4992, -16384 }, { 0, 0, 0 }, + { 1331, 909, -8175 }, { 0, 0, 8190 }, + { 538, 2622, -21124 }, { -443, -603, -1212 }, + { 0, 0, 24711 }, { 491, -584, -20713 }, + { -21267, -11295, -7882 }, { 552, 479, 16219 }, + { 0, 0, 17341 }, { 0, 0, 0 }, + { 2866, -7762, 19771 }, { 0, 0, -3812 }, + { -416, 862, -16656 }, { -2940, 16895, 20702 }, + { 0, 0, -18661 }, { -5100, 10643, -25824 }, + { -15495, 27304, 1032 }, { 0, 0, 0 }, + }, + { + // Frame 6 + { -60, 771, 241 }, { -32044, 0, 0 }, { -16384, 7684, -16384 }, { 0, 0, 0 }, + { -27, 459, -14461 }, { 0, 0, 13541 }, { 63, 2434, -21507 }, { 140, -3557, -8362 }, + { 0, 0, 25043 }, { -525, 149, -20932 }, { -18194, -11230, -7652 }, { 519, 2089, 15610 }, + { 0, 0, 17631 }, { 0, 0, 0 }, { 3504, -7332, 22086 }, { 0, 0, -4207 }, + { -1489, 5198, -18222 }, { 967, 12936, 27541 }, { 0, 0, -17131 }, { -2949, 6188, -22075 }, + { -16864, 27258, -1679 }, { 0, 0, 0 }, + }, + { + // Frame 7 + { -60, 511, -4 }, { -25546, 0, 0 }, + { -16384, 8878, -16384 }, { 0, 0, 0 }, + { -799, 63, -16740 }, { 0, 0, 14954 }, + { 943, 1296, -21262 }, { 1564, -3136, -16443 }, + { 0, 0, 25526 }, { -1303, 490, -21402 }, + { -18554, -11994, -7123 }, { 464, 3612, 15275 }, + { 0, 0, 18235 }, { 0, 0, 0 }, + { 3231, -6977, 25545 }, { 0, 0, -4847 }, + { -321, 5196, -18440 }, { 2710, 9642, 31101 }, + { 0, 0, -15600 }, { -985, 4840, -20355 }, + { -16899, 27261, -1747 }, { 0, 0, 0 }, + }, + { + // Frame 8 + { -60, 771, -444 }, { -19497, 0, 0 }, + { -16384, 6684, -16384 }, { 0, 0, 0 }, + { -2556, 1051, -17674 }, { 0, 0, 27472 }, + { 1977, 423, -21477 }, { 1754, -2055, -18579 }, + { 0, 0, 25919 }, { -1681, 96, -22354 }, + { -20790, -12983, -5802 }, { 376, 4598, 14848 }, + { 0, 0, 18950 }, { 0, 0, 0 }, + { 3130, -6330, 27866 }, { 0, 0, -5576 }, + { 2725, 2012, -17715 }, { 4493, 6440, -31020 }, + { 0, 0, -14167 }, { 1055, 3881, -18845 }, + { -16739, 27250, -1432 }, { 0, 0, 0 }, + }, + { + // Frame 9 + { -59, 940, -590 }, { -16713, 0, 0 }, + { -16384, 5073, -16384 }, { 0, 0, 0 }, + { -2448, 996, -16808 }, { 0, 0, 26712 }, + { 2021, 695, -22206 }, { 1957, -1988, -18219 }, + { 0, 0, 26656 }, { -1789, -334, -23017 }, + { -22257, -13213, -4844 }, { 333, 4517, 14584 }, + { 0, 0, 19285 }, { 0, 0, 0 }, + { 2948, -5849, 28856 }, { 0, 0, -5925 }, + { 4383, 81, -17239 }, { 5329, 5036, -29493 }, + { 0, 0, -13518 }, { 1992, 3521, -18202 }, + { -16629, 27244, -1214 }, { 0, 0, 0 }, + }, + { + // Frame 10 + { -59, 1348, -649 }, { -11768, 0, 0 }, + { -16384, 1883, -16384 }, { 0, 0, 0 }, + { -2196, 778, -10577 }, { 0, 0, 28012 }, + { 1653, 2033, -24440 }, { 2855, -2524, -11436 }, + { 0, 0, 27911 }, { -1938, -1318, -24470 }, + { -25057, -12419, -3692 }, { 177, 3296, 14007 }, + { 0, 0, 19787 }, { 0, 0, 0 }, + { 2482, -4950, 30438 }, { 0, 0, -6494 }, + { 6915, -3159, -16394 }, { 6751, 2940, -27054 }, + { 0, 0, -12420 }, { 3479, 2992, -17208 }, + { -16434, 27240, -830 }, { 0, 0, 0 }, + }, + { + // Frame 11 + { -58, 1735, -542 }, { -7750, 0, 0 }, + { -16384, 184, -16384 }, { 0, 0, 0 }, + { -1205, 108, -8043 }, { 0, 0, 25981 }, + { 1346, 2790, -26757 }, { 2029, -1692, -8455 }, + { 0, 0, 25863 }, { -1961, -2047, -25988 }, + { -28048, -11954, -2090 }, { -470, 3031, 12591 }, + { 0, 0, 19948 }, { 0, 0, 0 }, + { 2309, -4596, 31084 }, { 0, 0, -6786 }, + { 7219, -4155, -16045 }, { 7656, 2711, -26079 }, + { 0, 0, -11861 }, { 4229, 2661, -16666 }, + { -16363, 27240, -688 }, { 0, 0, 0 }, + }, + { + // Frame 12 + { 74, 3528, -37 }, + { 0, 0, 0 }, + { -16384, -626, -16384 }, + { 0, 0, 0 }, + { 135, 5446, -5887 }, + { 0, 0, 23451 }, + { 2115, 1887, -20292 }, + { 1024, -219, -1846 }, + { 0, 0, 5914 }, + { -443, -1625, -21253 }, + { 16384, 417, 16384 }, + { 476, -93, 19351 }, + { 0, 0, 23344 }, + { 0, 0, 0 }, + { -21137, -12435, -10526 }, + { 0, 0, -6675 }, + { -36, -503, -16171 }, + { 12851, 7298, -17081 }, + { 0, 0, -19713 }, + { 4373, 5305, -15750 }, + { -16384, 27240, -730 }, + { 0, 0, 0 }, + }, + { + // Frame 13 + { 54, 3227, -89 }, + { 2313, 0, 0 }, + { -16384, -685, -16384 }, + { 0, 0, 0 }, + { -152, 5099, -11115 }, + { 0, 0, 24427 }, + { 2059, 1815, -21046 }, + { -59, -710, -6843 }, + { 0, 0, 10860 }, + { -979, -1386, -22412 }, + { 16183, -133, 16490 }, + { 503, -59, 18352 }, + { 0, 0, 25530 }, + { 0, 0, 0 }, + { -20393, -12323, -12080 }, + { 0, 0, -6726 }, + { -25, -562, -16150 }, + { 14095, 8887, -16891 }, + { 0, 0, -18784 }, + { 3073, 5837, -17586 }, + { -15392, 27325, 1213 }, + { 0, 0, 0 }, + }, + { + // Frame 14 + { -25, 2218, -133 }, + { 7607, 0, 0 }, + { -16384, -781, -16384 }, + { 0, 0, 0 }, + { -654, 1069, -20519 }, + { 0, 0, 20760 }, + { 1304, 1666, -23774 }, + { -518, -3910, -15614 }, + { 0, 0, 22754 }, + { -1707, -1918, -22925 }, + { 16384, -4331, 16384 }, + { 641, 74, 13206 }, + { 0, 0, 30948 }, + { 0, 0, 0 }, + { -15708, -11590, -21423 }, + { 0, 0, -6949 }, + { 37, -880, -16032 }, + { -12778, 15014, 15677 }, + { 0, 0, -13974 }, + { -4182, 8702, -27734 }, + { -13006, 28312, 6371 }, + { 0, 0, 0 }, + }, + { + // Frame 15 + { -57, 2670, 558 }, { 13602, 0, 0 }, + { -16384, 0, -16384 }, { 0, 0, 0 }, + { 1852, 198, -7548 }, { 0, 0, 1654 }, + { 1472, 2843, -23780 }, { -2685, -3676, -6545 }, + { 0, 0, 15549 }, { 1676, -2089, -20933 }, + { -1427, -19182, -27019 }, { 698, -257, 10968 }, + { 0, 0, 18514 }, { 0, 0, 0 }, + { 23192, -22237, 548 }, { 0, 0, -6929 }, + { 86, -1131, -15938 }, { -11355, 7097, 10885 }, + { 0, 0, -11056 }, { -10661, 10872, 29098 }, + { -15580, 27296, 800 }, { 0, 0, 0 }, + }, + { + // Frame 16 + { -60, 2207, 382 }, { 20068, 0, 0 }, + { -16384, 2162, -16384 }, { 0, 0, 0 }, + { 219, 581, -17012 }, { 0, 0, 16199 }, + { 1446, 2552, -20834 }, { -1193, -3974, -12795 }, + { 0, 0, 22901 }, { 1355, -1424, -20722 }, + { -24738, -12007, -7558 }, { 462, -469, 19859 }, + { 0, 0, 17568 }, { 0, 0, 0 }, + { -1152, -8811, 22716 }, { 0, 0, -5124 }, + { 43, -913, -16019 }, { -2615, 21391, 18299 }, + { 0, 0, -20972 }, { -7167, 7353, -29571 }, + { -16740, 27249, -1447 }, { 0, 0, 0 }, + }, + { + // Frame 17 + { -60, 1477, 314 }, { 26774, 0, 0 }, + { -16384, 4992, -16384 }, { 0, 0, 0 }, + { 1331, 909, -8175 }, { 0, 0, 8190 }, + { 538, 2622, -21124 }, { -443, -603, -1212 }, + { 0, 0, 24711 }, { 491, -584, -20713 }, + { -21267, -11295, -7882 }, { 552, 479, 16219 }, + { 0, 0, 17341 }, { 0, 0, 0 }, + { 2866, -7762, 19771 }, { 0, 0, -3812 }, + { -416, 862, -16656 }, { -2940, 16895, 20702 }, + { 0, 0, -18661 }, { -5100, 10643, -25824 }, + { -15495, 27304, 1032 }, { 0, 0, 0 }, + }, + { + // Frame 18 + { -60, 771, 241 }, { -32044, 0, 0 }, { -16384, 7684, -16384 }, { 0, 0, 0 }, + { -27, 459, -14461 }, { 0, 0, 13541 }, { 63, 2434, -21507 }, { 140, -3557, -8362 }, + { 0, 0, 25043 }, { -525, 149, -20932 }, { -18194, -11230, -7652 }, { 519, 2089, 15610 }, + { 0, 0, 17631 }, { 0, 0, 0 }, { 3504, -7332, 22086 }, { 0, 0, -4207 }, + { -1489, 5198, -18222 }, { 967, 12936, 27541 }, { 0, 0, -17131 }, { -2949, 6188, -22075 }, + { -16864, 27258, -1679 }, { 0, 0, 0 }, + }, + { + // Frame 19 + { -60, 511, -4 }, { -25546, 0, 0 }, + { -16384, 8878, -16384 }, { 0, 0, 0 }, + { -799, 63, -16740 }, { 0, 0, 14954 }, + { 943, 1296, -21262 }, { 1564, -3136, -16443 }, + { 0, 0, 25526 }, { -1303, 490, -21402 }, + { -18554, -11994, -7123 }, { 464, 3612, 15275 }, + { 0, 0, 18235 }, { 0, 0, 0 }, + { 3231, -6977, 25545 }, { 0, 0, -4847 }, + { -321, 5196, -18440 }, { 2710, 9642, 31101 }, + { 0, 0, -15600 }, { -985, 4840, -20355 }, + { -16899, 27261, -1747 }, { 0, 0, 0 }, + }, +}; + +#endif // ROLL_ANIMATION_DATA_H \ No newline at end of file From cc4695f9fc6265ba9c22a1df5a98746099f6f2b2 Mon Sep 17 00:00:00 2001 From: TheLynk Date: Mon, 8 Dec 2025 04:36:28 +0100 Subject: [PATCH 27/45] Fix Update Auto Merge | V:9.0 --- soh/soh/Enhancements/{cosmetics => }/CustomSkeletons.cpp | 0 soh/soh/Enhancements/gameplaystats.cpp | 2 +- soh/soh/Enhancements/randomizer/ShuffleTrees.cpp | 2 +- soh/soh/Enhancements/randomizer/item_list.cpp | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) rename soh/soh/Enhancements/{cosmetics => }/CustomSkeletons.cpp (100%) diff --git a/soh/soh/Enhancements/cosmetics/CustomSkeletons.cpp b/soh/soh/Enhancements/CustomSkeletons.cpp similarity index 100% rename from soh/soh/Enhancements/cosmetics/CustomSkeletons.cpp rename to soh/soh/Enhancements/CustomSkeletons.cpp diff --git a/soh/soh/Enhancements/gameplaystats.cpp b/soh/soh/Enhancements/gameplaystats.cpp index 0cb7a3b0911..b0d6180029a 100644 --- a/soh/soh/Enhancements/gameplaystats.cpp +++ b/soh/soh/Enhancements/gameplaystats.cpp @@ -446,7 +446,7 @@ void DrawGameplayStatsHeader() { // if tag is empty (not a release build) if (gGitCommitTag[0] == 0) { GameplayStatsRow("Git Branch:", (char*)gGitBranch); - GameplayStatsRow("Version : 8.3 | Git Commit Hash:", (char*)gGitCommitHash); + GameplayStatsRow("Version : 9.0 | Git Commit Hash:", (char*)gGitCommitHash); } else { GameplayStatsRow("Build Version:", (char*)gBuildVersion); } diff --git a/soh/soh/Enhancements/randomizer/ShuffleTrees.cpp b/soh/soh/Enhancements/randomizer/ShuffleTrees.cpp index cf301c8c26c..6ef30592626 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleTrees.cpp +++ b/soh/soh/Enhancements/randomizer/ShuffleTrees.cpp @@ -65,7 +65,7 @@ extern "C" void EnWood02_RandomizerDraw(Actor* thisx, PlayState* play) { // If they have bombchus, don't consider the bombchu item major if (INV_CONTENT(ITEM_BOMBCHU) == ITEM_BOMBCHU && - ((treeItem.modIndex == MOD_RANDOMIZER && treeItem.getItemId == RG_PROGRESSIVE_BOMBCHUS) || + ((treeItem.modIndex == MOD_RANDOMIZER && treeItem.getItemId == RG_PROGRESSIVE_BOMBCHU_BAG) || (treeItem.modIndex == MOD_NONE && (treeItem.getItemId == GI_BOMBCHUS_5 || treeItem.getItemId == GI_BOMBCHUS_10 || treeItem.getItemId == GI_BOMBCHUS_20)))) { diff --git a/soh/soh/Enhancements/randomizer/item_list.cpp b/soh/soh/Enhancements/randomizer/item_list.cpp index 927947db62c..eedb022fb6c 100644 --- a/soh/soh/Enhancements/randomizer/item_list.cpp +++ b/soh/soh/Enhancements/randomizer/item_list.cpp @@ -377,7 +377,7 @@ void Rando::StaticData::InitItemTable() { itemTable[RG_OPEN_CHEST] = Item(RG_OPEN_CHEST, Text{ "Open Chests", "!!!", "!!!" }, ITEMTYPE_ITEM, GI_KEY_SMALL, true, LOGIC_NONE, RHT_OPEN_CHEST, RG_OPEN_CHEST, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_OPEN_CHEST].SetCustomDrawFunc(Randomizer_DrawOpenChest); - itemTable[RG_PROGRESSIVE_BOMBCHU_BAG] = Item(RG_PROGRESSIVE_BOMBCHU_BAG, Text{ "Bombchu Bag", "Sac de Missiles Teigneux", "Krabbelminentasche" }, ITEMTYPE_ITEM, RG_BOMBCHU_BAG, true, LOGIC_BOMBCHUS, RHT_BOMBCHU_BAG, RG_BOMBCHU_BAG, OBJECT_GI_BOMB_2, GID_BOMBCHU, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_PROGRESSIVE_BOMBCHU_BAG] = Item(RG_PROGRESSIVE_BOMBCHU_BAG, Text{ "Bombchu Bag", "Sac de Missiles Teigneux", "Krabbelminentasche" }, ITEMTYPE_ITEM, RG_PROGRESSIVE_BOMBCHU_BAG, true, LOGIC_BOMBCHUS, RHT_BOMBCHU_BAG, RG_PROGRESSIVE_BOMBCHU_BAG, OBJECT_GI_BOMB_2, GID_BOMBCHU, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_PROGRESSIVE_BOMBCHU_BAG].SetCustomDrawFunc(Randomizer_DrawBombchuBag); From a64c1c76150b009e77da666d73fb56f8c06f5e0f Mon Sep 17 00:00:00 2001 From: TheLynk Date: Mon, 8 Dec 2025 05:49:29 +0100 Subject: [PATCH 28/45] Fix crash Logic | V:9.1 --- soh/soh/Enhancements/gameplaystats.cpp | 2 +- .../dungeons/gerudo_training_ground.cpp | 55 ++++++++----------- 2 files changed, 25 insertions(+), 32 deletions(-) diff --git a/soh/soh/Enhancements/gameplaystats.cpp b/soh/soh/Enhancements/gameplaystats.cpp index b0d6180029a..2f184df3856 100644 --- a/soh/soh/Enhancements/gameplaystats.cpp +++ b/soh/soh/Enhancements/gameplaystats.cpp @@ -446,7 +446,7 @@ void DrawGameplayStatsHeader() { // if tag is empty (not a release build) if (gGitCommitTag[0] == 0) { GameplayStatsRow("Git Branch:", (char*)gGitBranch); - GameplayStatsRow("Version : 9.0 | Git Commit Hash:", (char*)gGitCommitHash); + GameplayStatsRow("Version : 9.1 | Git Commit Hash:", (char*)gGitCommitHash); } else { GameplayStatsRow("Build Version:", (char*)gBuildVersion); } diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp index f06938e2fed..0fe1308b0cc 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp @@ -20,8 +20,6 @@ void RegionTable_Init_GerudoTrainingGround() { //Locations LOCATION(RC_GERUDO_TRAINING_GROUND_LOBBY_LEFT_CHEST, logic->CanHitEyeTargets() && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_GERUDO_TRAINING_GROUND_LOBBY_RIGHT_CHEST, logic->CanHitEyeTargets() && logic->HasItem(RG_OPEN_CHEST)), - LOCATION(RC_GERUDO_TRAINING_GROUND_STALFOS_CHEST, logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2, true) && logic->HasItem(RG_OPEN_CHEST)), - LOCATION(RC_GERUDO_TRAINING_GROUND_BEAMOS_CHEST, logic->CanKillEnemy(RE_BEAMOS) && logic->CanKillEnemy(RE_DINOLFOS, ED_CLOSE, true, 2, true) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_GERUDO_TRAINING_GROUND_ENTRANCE_STORMS_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)), }, { //Exits @@ -33,7 +31,7 @@ void RegionTable_Init_GerudoTrainingGround() { areaTable[RR_GERUDO_TRAINING_GROUND_SAND_ROOM] = Region("Gerudo Training Ground Sand Room", SCENE_GERUDO_TRAINING_GROUND, {}, { //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_STALFOS_CHEST, logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2, true)), + LOCATION(RC_GERUDO_TRAINING_GROUND_STALFOS_CHEST, logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2, true) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_GERUDO_TRAINING_GROUND_LOBBY, []{return true;}), @@ -47,7 +45,7 @@ void RegionTable_Init_GerudoTrainingGround() { areaTable[RR_GERUDO_TRAINING_GROUND_CENTRAL_MAZE] = Region("Gerudo Training Ground Central Maze", SCENE_GERUDO_TRAINING_GROUND, {}, { //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_HIDDEN_CEILING_CHEST, logic->SmallKeys(SCENE_GERUDO_TRAINING_GROUND, 3) && (ctx->GetTrickOption(RT_LENS_GTG) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GERUDO_TRAINING_GROUND_HIDDEN_CEILING_CHEST, (logic->SmallKeys(SCENE_GERUDO_TRAINING_GROUND, 3) && (ctx->GetTrickOption(RT_LENS_GTG) || logic->CanUse(RG_LENS_OF_TRUTH))) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_FIRST_CHEST, logic->SmallKeys(SCENE_GERUDO_TRAINING_GROUND, 4) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_SECOND_CHEST, logic->SmallKeys(SCENE_GERUDO_TRAINING_GROUND, 6) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_THIRD_CHEST, logic->SmallKeys(SCENE_GERUDO_TRAINING_GROUND, 7) && logic->HasItem(RG_OPEN_CHEST)), @@ -75,7 +73,7 @@ void RegionTable_Init_GerudoTrainingGround() { EventAccess(LOGIC_GTG_PUSHED_HEAVY_BLOCK, []{return logic->CanUse(RG_SILVER_GAUNTLETS);}), }, { //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_BEFORE_HEAVY_BLOCK_CHEST, logic->CanKillEnemy(RE_WOLFOS, ED_CLOSE, true, 4, true)), + LOCATION(RC_GERUDO_TRAINING_GROUND_BEFORE_HEAVY_BLOCK_CHEST, logic->CanKillEnemy(RE_WOLFOS, ED_CLOSE, true, 4, true) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_ROOM_UPPER, []{return (ctx->GetTrickOption(RT_LENS_GTG) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_GTG_FAKE_WALL) && logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)) || (logic->IsAdult && logic->CanGroundJump()));}), @@ -100,10 +98,10 @@ void RegionTable_Init_GerudoTrainingGround() { areaTable[RR_GERUDO_TRAINING_GROUND_LIKE_LIKE_ROOM] = Region("Gerudo Training Ground Like Like Room", SCENE_GERUDO_TRAINING_GROUND, {}, { //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FIRST_CHEST, logic->CanKillEnemy(RE_LIKE_LIKE)), - LOCATION(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_SECOND_CHEST, logic->CanKillEnemy(RE_LIKE_LIKE)), - LOCATION(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_THIRD_CHEST, (ctx->GetTrickOption(RT_LENS_GTG) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanPassEnemy(RE_LIKE_LIKE)), - LOCATION(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FOURTH_CHEST, true), + LOCATION(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FIRST_CHEST, logic->CanKillEnemy(RE_LIKE_LIKE) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_SECOND_CHEST, logic->CanKillEnemy(RE_LIKE_LIKE) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_THIRD_CHEST, (ctx->GetTrickOption(RT_LENS_GTG) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanPassEnemy(RE_LIKE_LIKE) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FOURTH_CHEST, logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_GERUDO_TRAINING_GROUND_BEHIND_HEAVY_BLOCK, []{return true;}), @@ -118,7 +116,7 @@ void RegionTable_Init_GerudoTrainingGround() { areaTable[RR_GERUDO_TRAINING_GROUND_ABOVE_MAZE] = Region("Gerudo Training Ground Above Eye", SCENE_GERUDO_TRAINING_GROUND, {}, { //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_UNDERWATER_SILVER_RUPEE_CHEST, logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 24 && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GERUDO_TRAINING_GROUND_NEAR_SCARECROW_CHEST, logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_GERUDO_TRAINING_GROUND_EYE_STATUE_UPPER, []{return true;}), @@ -129,7 +127,7 @@ void RegionTable_Init_GerudoTrainingGround() { EventAccess(LOGIC_GTG_CLEARED_EYE_STATUE, []{return logic->CanUse(RG_FAIRY_BOW);}), }, { //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_EYE_STATUE_CHEST, logic->Get(LOGIC_GTG_CLEARED_EYE_STATUE)), + LOCATION(RC_GERUDO_TRAINING_GROUND_EYE_STATUE_CHEST, logic->Get(LOGIC_GTG_CLEARED_EYE_STATUE) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_GERUDO_TRAINING_GROUND_HAMMER_ROOM, []{return true;}), @@ -145,10 +143,9 @@ void RegionTable_Init_GerudoTrainingGround() { Entrance(RR_GERUDO_TRAINING_GROUND_LAVA_ROOM, []{return true;}), }); - areaTable[RR_GERUDO_TRAINING_GROUND_EYE_STATUE_LOWER] = Region("Gerudo Training Ground Eye Statue Lower", SCENE_GERUDO_TRAINING_GROUND, {}, { - //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_EYE_STATUE_CHEST, logic->CanUse(RG_FAIRY_BOW) && logic->HasItem(RG_OPEN_CHEST)), - }, { + areaTable[RR_GERUDO_TRAINING_GROUND_LAVA_ROOM] = Region("Gerudo Training Ground Lava Room", SCENE_GERUDO_TRAINING_GROUND, { + EventAccess(LOGIC_GTG_PLATFORM_SILVER_RUPEES, []{return logic->CanUse(RG_HOOKSHOT) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_SONG_OF_TIME));}), + }, {}, { //Exits Entrance(RR_GERUDO_TRAINING_GROUND_DINALFOS, []{return true;}), Entrance(RR_GERUDO_TRAINING_GROUND_CENTRAL_MAZE_RIGHT, []{return logic->CanUse(RG_SONG_OF_TIME) || logic->IsChild;}), @@ -166,7 +163,7 @@ void RegionTable_Init_GerudoTrainingGround() { areaTable[RR_GERUDO_TRAINING_GROUND_UNDERWATER] = Region("Gerudo Training Ground Underwater", SCENE_GERUDO_TRAINING_GROUND, {}, { //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_NEAR_SCARECROW_CHEST, logic->CanUse(RG_FAIRY_BOW) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GERUDO_TRAINING_GROUND_UNDERWATER_SILVER_RUPEE_CHEST, logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_IRON_BOOTS) && logic->HasItem(RG_BRONZE_SCALE) && logic->WaterTimer() >= 24 && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_GERUDO_TRAINING_GROUND_LAVA_ROOM, []{return true;}), @@ -174,21 +171,15 @@ void RegionTable_Init_GerudoTrainingGround() { areaTable[RR_GERUDO_TRAINING_GROUND_DINALFOS] = Region("Gerudo Training Dinalfos", SCENE_GERUDO_TRAINING_GROUND, {}, { //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_BEFORE_HEAVY_BLOCK_CHEST, logic->CanKillEnemy(RE_WOLFOS, ED_CLOSE, true, 4, true) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GERUDO_TRAINING_GROUND_BEAMOS_CHEST, logic->CanKillEnemy(RE_BEAMOS) && logic->CanKillEnemy(RE_DINOLFOS, ED_CLOSE, true, 2, true) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GERUDO_TRAINING_GROUND_BEAMOS_SOUTH_HEART, true), + LOCATION(RC_GERUDO_TRAINING_GROUND_BEAMOS_EAST_HEART, true), }, { //Exits Entrance(RR_GERUDO_TRAINING_GROUND_LOBBY, []{return true;}), Entrance(RR_GERUDO_TRAINING_GROUND_LAVA_ROOM, []{return Here(RR_GERUDO_TRAINING_GROUND_DINALFOS, []{return logic->CanKillEnemy(RE_BEAMOS) && logic->CanKillEnemy(RE_DINOLFOS, ED_CLOSE, true, 2, true);});}), }); - areaTable[RR_GERUDO_TRAINING_GROUND_LIKE_LIKE_ROOM] = Region("Gerudo Training Ground Like Like Room", SCENE_GERUDO_TRAINING_GROUND, {}, { - //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FIRST_CHEST, logic->CanJumpslashExceptHammer() && logic->HasItem(RG_OPEN_CHEST)), - LOCATION(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_SECOND_CHEST, logic->CanJumpslashExceptHammer() && logic->HasItem(RG_OPEN_CHEST)), - LOCATION(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_THIRD_CHEST, logic->CanJumpslashExceptHammer() && logic->HasItem(RG_OPEN_CHEST)), - LOCATION(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FOURTH_CHEST, logic->CanJumpslashExceptHammer() && logic->HasItem(RG_OPEN_CHEST)), - }, {}); - #pragma endregion #pragma region MQ @@ -197,8 +188,6 @@ void RegionTable_Init_GerudoTrainingGround() { //Locations LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_CHEST, logic->HasItem(RG_OPEN_CHEST)), - LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_FIRST_CHEST, logic->HasItem(RG_OPEN_CHEST)), - LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_SECOND_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_1, logic->CanBreakPots()), LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_2, logic->CanBreakPots()), LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_1, logic->CanBreakPots()), @@ -214,7 +203,9 @@ void RegionTable_Init_GerudoTrainingGround() { areaTable[RR_GERUDO_TRAINING_GROUND_MQ_MAZE_BY_LOBBY] = Region("Gerudo Training Ground MQ Maze By Lobby", SCENE_GERUDO_TRAINING_GROUND, {}, { //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_HIDDEN_CEILING_CHEST, logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_FIRST_CHEST, logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_SECOND_CHEST, logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_HIDDEN_CEILING_CHEST, (ctx->GetTrickOption(RT_LENS_GTG_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_GERUDO_TRAINING_GROUND_MQ_LOBBY, []{return true;}), @@ -282,7 +273,9 @@ void RegionTable_Init_GerudoTrainingGround() { //Locations //implies logic->CanKillEnemy(RE_SPIKE) LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_HEAVY_BLOCK_CHEST, logic->CanKillEnemy(RE_FREEZARD) && logic->HasItem(RG_OPEN_CHEST)), - }, {}); + }, { + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_ROOM_BEHIND_BLOCK, []{return true;}), + }); areaTable[RR_GERUDO_TRAINING_GROUND_MQ_STATUE_ROOM_LEDGE] = Region("Gerudo Training Ground MQ Statue Room Ledge", SCENE_GERUDO_TRAINING_GROUND, {}, {}, { //Exits @@ -377,7 +370,7 @@ void RegionTable_Init_GerudoTrainingGround() { areaTable[RR_GERUDO_TRAINING_GROUND_MQ_UNDERWATER] = Region("Gerudo Training Ground MQ Underwater", SCENE_GERUDO_TRAINING_GROUND, {}, { //Locations //it is possible to snipe the stingers with bow or sling before dropping in, or just get really lucky, and avoid needing to take damage, but that might be trick worthy - LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_UNDERWATER_SILVER_RUPEE_CHEST, (logic->HasFireSource() && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 24 && logic->HasItem(RG_BRONZE_SCALE) && logic->TakeDamage()) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_UNDERWATER_SILVER_RUPEE_CHEST, logic->HasFireSource() && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 24 && logic->HasItem(RG_BRONZE_SCALE) && logic->TakeDamage() && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_GERUDO_TRAINING_GROUND_MQ_PLATFORMS_UNLIT_TORCH, []{return true;}), @@ -418,4 +411,4 @@ void RegionTable_Init_GerudoTrainingGround() { #pragma endregion // clang-format on -} +} \ No newline at end of file From 69401602d1eaf5403c91ef4aa38535e6456a22a3 Mon Sep 17 00:00:00 2001 From: TheLynk Date: Mon, 8 Dec 2025 18:25:52 +0100 Subject: [PATCH 29/45] Add branch "rocksanity" | V:10.0 --- .../vanilla-behavior/GIVanillaBehavior.h | 17 + soh/soh/Enhancements/gameplaystats.cpp | 2 +- .../hint_list/hint_list_exclude_dungeon.cpp | 19 + .../hint_list/hint_list_exclude_overworld.cpp | 121 +++ .../randomizer/3drando/item_pool.cpp | 11 + .../Enhancements/randomizer/ShuffleRocks.cpp | 726 ++++++++++++++++++ .../Enhancements/randomizer/ShuffleRocks.h | 15 + soh/soh/Enhancements/randomizer/context.cpp | 12 +- soh/soh/Enhancements/randomizer/location.cpp | 17 + soh/soh/Enhancements/randomizer/location.h | 28 +- .../dungeons/bottom_of_the_well.cpp | 15 + .../location_access/dungeons/deku_tree.cpp | 3 + .../dungeons/dodongos_cavern.cpp | 24 +- .../dungeons/jabujabus_belly.cpp | 10 + .../dungeons/spirit_temple.cpp | 6 + .../overworld/castle_grounds.cpp | 21 +- .../overworld/death_mountain_crater.cpp | 29 +- .../overworld/death_mountain_trail.cpp | 29 + .../overworld/desert_colossus.cpp | 18 + .../overworld/gerudo_valley.cpp | 44 +- .../location_access/overworld/goron_city.cpp | 52 +- .../location_access/overworld/graveyard.cpp | 1 + .../overworld/hyrule_field.cpp | 16 + .../location_access/overworld/kakariko.cpp | 3 + .../overworld/kokiri_forest.cpp | 12 + .../location_access/overworld/lake_hylia.cpp | 5 +- .../location_access/overworld/lost_woods.cpp | 3 + .../overworld/zoras_domain.cpp | 8 + .../overworld/zoras_fountain.cpp | 3 + .../location_access/overworld/zoras_river.cpp | 54 +- .../randomizer/option_descriptions.cpp | 2 + .../Enhancements/randomizer/randomizer.cpp | 297 ++++++- soh/soh/Enhancements/randomizer/randomizer.h | 1 + .../Enhancements/randomizer/randomizerTypes.h | 341 ++++++++ .../randomizer/randomizer_check_tracker.cpp | 32 + .../Enhancements/randomizer/randomizer_inf.h | 282 +++++++ soh/soh/Enhancements/randomizer/settings.cpp | 4 + soh/soh/Enhancements/randomizer/static_data.h | 1 + .../overlays/actors/ovl_En_Ishi/z_en_ishi.c | 5 + .../actors/ovl_Obj_Bombiwa/z_obj_bombiwa.c | 3 +- .../actors/ovl_Obj_Hamishi/z_obj_hamishi.c | 3 +- 41 files changed, 2242 insertions(+), 53 deletions(-) create mode 100644 soh/soh/Enhancements/randomizer/ShuffleRocks.cpp create mode 100644 soh/soh/Enhancements/randomizer/ShuffleRocks.h diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index 90e4daa6a6d..5fe2d5d0e92 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -236,6 +236,15 @@ typedef enum { // - `*Actor` (interactRangeActor) VB_BOTTLE_ACTOR, + // #### `result` + // Actor is ACTOR_OBJ_BOMBIWA, or ACTOR_OBJ_HAMISHI + // ```c + // Flags_GetSwitch(play, this->actor.params & 0x3F) + // ``` + // #### `args` + // - `*Actor` (interactRangeActor) + VB_BOULDER_BREAK_FLAG, + // #### `result` // ```c // true @@ -1907,6 +1916,14 @@ typedef enum { // - None VB_REVERT_SPOILING_ITEMS, + // #### `result` + // ```c + // false + // ``` + // #### `args` + // - `*EnIshi` + VB_ROCK_DROP_ITEM, + // #### `result` // ```c // !Flags_GetInfTable(INFTABLE_145) diff --git a/soh/soh/Enhancements/gameplaystats.cpp b/soh/soh/Enhancements/gameplaystats.cpp index 2f184df3856..befc7357c37 100644 --- a/soh/soh/Enhancements/gameplaystats.cpp +++ b/soh/soh/Enhancements/gameplaystats.cpp @@ -446,7 +446,7 @@ void DrawGameplayStatsHeader() { // if tag is empty (not a release build) if (gGitCommitTag[0] == 0) { GameplayStatsRow("Git Branch:", (char*)gGitBranch); - GameplayStatsRow("Version : 9.1 | Git Commit Hash:", (char*)gGitCommitHash); + GameplayStatsRow("Version : 10.0 | Git Commit Hash:", (char*)gGitCommitHash); } else { GameplayStatsRow("Build Version:", (char*)gBuildVersion); } diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_dungeon.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_dungeon.cpp index aa375716f68..87880711616 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_dungeon.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_dungeon.cpp @@ -131,6 +131,10 @@ void StaticData::HintTable_Init_Exclude_Dungeon() { /*german*/ "Man erzählt sich, daß eine #Kiste im Deku-Baum# #[[1]]# enthielte.", /*french*/ "Selon moi, une #caisse dans l'Arbre Mojo# contient #[[1]]#.", {QM_RED, QM_GREEN})); + hintTextTable[RHT_DEKU_BOULDER] = HintText(CustomMessage("They say that a #boulder in the Deku Tree# contains #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + /*-------------------------- | DODONGOS CAVERN | ---------------------------*/ @@ -313,6 +317,10 @@ void StaticData::HintTable_Init_Exclude_Dungeon() { /*german*/ "Man erzählt sich, daß eine #Kiste in Dodongos Höhle# #[[1]]# enthielte.", /*french*/ "Selon moi, une #caisse dans la Caverne Dodongo# contient #[[1]]#.", {QM_RED, QM_GREEN})); + hintTextTable[RHT_DODONGOS_BOULDER] = HintText(CustomMessage("They say that a #boulder in Dodongo's Cavern# contains #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + /*-------------------------- | JABU JABUS BELLY | ---------------------------*/ @@ -480,6 +488,10 @@ void StaticData::HintTable_Init_Exclude_Dungeon() { /*german*/ "Man erzählt sich, daß eine #Kiste in Jabu-Jabus Bauch# #[[1]]# enthielte.", /*french*/ "Selon moi, une #caisse dans le Ventre de Jabu-Jabu# contient #[[1]]#.", {QM_RED, QM_GREEN})); + hintTextTable[RHT_JABU_BOULDER] = HintText(CustomMessage("They say that a #boulder in Jabu Jabu's Belly# contains #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + /*-------------------------- | FOREST TEMPLE | ---------------------------*/ @@ -1322,6 +1334,10 @@ void StaticData::HintTable_Init_Exclude_Dungeon() { /*german*/ "Man erzählt sich, daß eine #Kiste im Geistertempel# #[[1]]# enthielte.", /*french*/ "Selon moi, une #caisse dans le Temple de l'Esprit# contient #[[1]]#.", {QM_RED, QM_GREEN})); + hintTextTable[RHT_SPIRIT_TEMPLE_BOULDER] = HintText(CustomMessage("They say that a #boulder in the Spirit Temple# contains #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + /*-------------------------- | SHADOW TEMPLE | ---------------------------*/ @@ -1735,6 +1751,9 @@ void StaticData::HintTable_Init_Exclude_Dungeon() { /*german*/ "Man erzählt sich, daß etwas #Gras auf dem Grund des Brunnens# #[[1]]# verstecke.", /*french*/ "Selon moi, de l'#herbe dans le Puits# cache #[[1]]#.", {QM_RED, QM_GREEN})); + hintTextTable[RHT_BOTW_BOULDER] = HintText(CustomMessage("They say that a #boulder in Bottom of the Well# contains #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); /*-------------------------- | ICE CAVERN | diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_overworld.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_overworld.cpp index 487c761584b..a71d819aaf0 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 @@ -2127,6 +2127,127 @@ void StaticData::HintTable_Init_Exclude_Overworld() { /*german*/ "", /*french*/ "Selon moi, un #arbre au Ranch Lon Lon# cache #[[1]]#.", { QM_RED, QM_GREEN })); + + hintTextTable[RHT_KF_ROCK] = HintText(CustomMessage("They say that a #rock in Kokiri Forest# contains #[[1]]#.", + /*german*/ "", + /*french*/ "Selon moi, une #roche dans la Fôret Kokiri# contient #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_LW_BOULDER] = HintText(CustomMessage("They say that a #boulder in the Lost Woods# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_HC_ROCK] = HintText(CustomMessage("They say that a #rock at Hyrule Castle# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_HC_BOULDER] = HintText(CustomMessage("They say that a #boulder at Hyrule Castle# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_OGC_BRONZE_BOULDER] = HintText(CustomMessage("They say that a #bronze boulder outside Ganon's Castle# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_OGC_SILVER_BOULDER] = HintText(CustomMessage("They say that a #silver boulder outside Ganon's Castle# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_DMC_ROCK] = HintText(CustomMessage("They say that a #rock in Death Mountain Crater# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_DMC_BOULDER] = HintText(CustomMessage("They say that a #boulder in Death Mountain Crater# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_DMC_BRONZE_BOULDER] = HintText(CustomMessage("They say that a #bronze boulder in Death Mountain Crater# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_GV_SILVER_BOULDER] = HintText(CustomMessage("They say that a #silver boulder in Gerudo Valley# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_GV_ROCK] = HintText(CustomMessage("They say that a #rock in Gerudo Valley# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_GV_BOULDER] = HintText(CustomMessage("They say that a #boulder in Gerudo Valley# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_GV_BRONZE_BOULDER] = HintText(CustomMessage("They say that a #bronze boulder in Gerudo Valley# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_HF_SILVER_BOULDER] = HintText(CustomMessage("They say that a #silver boulder on Hyrule Field# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_HF_ROCK] = HintText(CustomMessage("They say that a #rock on Hyrule Field# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_HF_BOULDER] = HintText(CustomMessage("They say that a #boulder on Hyrule Field# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_HF_BRONZE_BOULDER] = HintText(CustomMessage("They say that a #bronze boulder on Hyrule Field# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_KAK_SILVER_BOULDER] = HintText(CustomMessage("They say that a #silver boulder at Kakariko Village# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_KAK_ROCK] = HintText(CustomMessage("They say that a #rock at Kakariko Village# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_GY_ROCK] = HintText(CustomMessage("They say that a #rock in a graveyard# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_LA_ROCK] = HintText(CustomMessage("They say that a #rock at Lake Hylia# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_ZD_ROCK] = HintText(CustomMessage("They say that a #rock in Zora's Domain# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_ZF_BOULDER] = HintText(CustomMessage("They say that a #boulder in Zora's Fountain# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_ZF_SILVER_BOULDER] = HintText(CustomMessage("They say that a #silver boulder in Zora's Fountain# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_ZR_ROCK] = HintText(CustomMessage("They say that a #rock along a river# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_ZR_BOULDER] = HintText(CustomMessage("They say that a #boulder along a river# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_DMT_ROCK] = HintText(CustomMessage("They say that a #rock on Death Mountain Trail# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_DMT_BOULDER] = HintText(CustomMessage("They say that a #boulder on Death Mountain Trail# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_DMT_BRONZE_BOULDER] = HintText(CustomMessage("They say that a #bronze boulder on Death Mountain Trail# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_GC_ROCK] = HintText(CustomMessage("They say that a #rock in Goron City# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_GC_BOULDER] = HintText(CustomMessage("They say that a #boulder in Goron City# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_GC_BRONZE_BOULDER] = HintText(CustomMessage("They say that a #bronze boulder in Goron City# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_GC_SILVER_BOULDER] = HintText(CustomMessage("They say that a #silver boulder in Goron City# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_COLOSSUS_SILVER_BOULDER] = HintText(CustomMessage("They say that a #silver boulder in a desert# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_COLOSSUS_ROCK] = HintText(CustomMessage("They say that a #rock in a desert# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_BUSH_HYRULE_FIELD] = HintText(CustomMessage("They say that a #bush in Hyrle Field# contains #[[1]]#.", /*german*/ "", diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index 152c76ace78..1cf6f80d2e7 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -631,6 +631,17 @@ void GenerateItemPool() { PlaceItemsForType(RCTYPE_NLCRATE, overworldCratesActive, dungeonCratesActive); } + // Shuffle Rocks + bool rocksActive = ctx->GetOption(RSK_SHUFFLE_ROCKS).Get(); + PlaceItemsForType(RCTYPE_ROCK, rocksActive, rocksActive); + + // Shuffle Boulders + bool overworldBouldersActive = ctx->GetOption(RSK_SHUFFLE_BOULDERS).Is(RO_SHUFFLE_BOULDERS_OVERWORLD) || + ctx->GetOption(RSK_SHUFFLE_BOULDERS).Is(RO_SHUFFLE_BOULDERS_ALL); + bool dungeonBouldersActive = ctx->GetOption(RSK_SHUFFLE_BOULDERS).Is(RO_SHUFFLE_BOULDERS_DUNGEONS) || + ctx->GetOption(RSK_SHUFFLE_BOULDERS).Is(RO_SHUFFLE_BOULDERS_ALL); + PlaceItemsForType(RCTYPE_BOULDER, overworldBouldersActive, dungeonBouldersActive); + auto fsMode = ctx->GetOption(RSK_FISHSANITY); if (fsMode.IsNot(RO_FISHSANITY_OFF)) { if (fsMode.Is(RO_FISHSANITY_POND) || fsMode.Is(RO_FISHSANITY_BOTH)) { diff --git a/soh/soh/Enhancements/randomizer/ShuffleRocks.cpp b/soh/soh/Enhancements/randomizer/ShuffleRocks.cpp new file mode 100644 index 00000000000..ba2fc032fa0 --- /dev/null +++ b/soh/soh/Enhancements/randomizer/ShuffleRocks.cpp @@ -0,0 +1,726 @@ +#include "ShuffleRocks.h" +#include "soh/Enhancements/enhancementTypes.h" +#include "soh_assets.h" +#include "static_data.h" +#include "soh/ObjectExtension/ObjectExtension.h" + +extern "C" { +#include "variables.h" +#include "overlays/actors/ovl_En_Ishi/z_en_ishi.h" +#include "overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.h" +#include "overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.h" +#include "objects/gameplay_field_keep/gameplay_field_keep.h" +#include "objects/gameplay_keep/gameplay_keep.h" +#include "objects/object_bombiwa/object_bombiwa.h" +extern PlayState* gPlayState; +} + +#define RAND_GET_OPTION(option) Rando::Context::GetInstance()->GetOption(option).Get() + +extern void EnItem00_DrawRandomizedItem(EnItem00* enItem00, PlayState* play); + +extern "C" void DrawItemCircle(PlayState* play, float scale, RockIdentity rockIdentity) { + GraphicsContext* __gfxCtx = play->state.gfxCtx; + int csmc = CVarGetInteger(CVAR_ENHANCEMENT("ChestSizeAndTextureMatchContents"), CSMC_DISABLED); + int requiresStoneAgony = CVarGetInteger(CVAR_ENHANCEMENT("ChestSizeDependsStoneOfAgony"), 0); + + u8 r1 = 200, g1 = 200, b1 = 200, r2 = 100, g2 = 100, b2 = 100; + + if ((csmc == CSMC_BOTH || csmc == CSMC_TEXTURE) && + (!requiresStoneAgony || (requiresStoneAgony && CHECK_QUEST_ITEM(QUEST_STONE_OF_AGONY)))) { + auto itemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(rockIdentity.randomizerCheck, true, GI_NONE); + GetItemCategory getItemCategory = itemEntry.getItemCategory; + + switch (getItemCategory) { + case ITEM_CATEGORY_LESSER: + switch (itemEntry.itemId) { + case ITEM_HEART_PIECE: + case ITEM_HEART_PIECE_2: + case ITEM_HEART_CONTAINER: + r1 = 160; + g1 = 80; + b1 = 20; + r2 = 40; + g2 = 160; + b2 = 160; + break; + default: + r1 = 160; + g1 = 140; + b1 = 80; + r2 = 80; + g2 = 70; + b2 = 40; + break; + } + break; + case ITEM_CATEGORY_SMALL_KEY: + r1 = 144; + g1 = 144; + b1 = 144; + r2 = 128; + g2 = 128; + b2 = 128; + break; + case ITEM_CATEGORY_BOSS_KEY: + r1 = 240; + g1 = 220; + b1 = 0; + r2 = 128; + g2 = 128; + b2 = 128; + break; + case ITEM_CATEGORY_SKULLTULA_TOKEN: + r1 = 24; + g1 = 20; + b1 = 0; + r2 = 96; + g2 = 80; + b2 = 0; + break; + case ITEM_CATEGORY_MAJOR: + r1 = 240; + g1 = 220; + b1 = 0; + r2 = 240; + g2 = 220; + b2 = 0; + break; + default: + break; + } + } + + Matrix_Scale(scale, 1.0, scale, MTXMODE_APPLY); + gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPSegment(POLY_XLU_DISP++, 0x08, + (uintptr_t)Gfx_TwoTexScroll(play->state.gfxCtx, 0, 0, 0, 16, 32, 1, 0, (play->gameplayFrames * 10) % 128, + 16, 32)); + gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, r1, g1, b1, 255); + gDPSetEnvColor(POLY_XLU_DISP++, r2, g2, b2, 255); + gSPDisplayList(POLY_XLU_DISP++, (Gfx*)gHoverBootsCircleDL); +} + +extern "C" void EnIshi_RandomizerDraw(Actor* thisx, PlayState* play) { + auto rockActor = ((EnIshi*)thisx); + const auto rockIdentity = ObjectExtension::GetInstance().Get(thisx); + + OPEN_DISPS(play->state.gfxCtx); + Gfx_SetupDL_25Opa(play->state.gfxCtx); + + if (rockActor->actor.params & 1) { + gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, 255); + gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gSilverRockDL); + } else { + Gfx_DrawDListOpa(play, (Gfx*)gFieldKakeraDL); + } + + if (rockIdentity != nullptr && rockIdentity->randomizerCheck != RC_MAX && + Flags_GetRandomizerInf(rockIdentity->randomizerInf) == 0) { + + Matrix_Translate(rockActor->actor.world.pos.x, + rockActor->actor.world.pos.y + (rockActor->actor.params & 1 ? 32 : 8), + rockActor->actor.world.pos.z, MTXMODE_NEW); + DrawItemCircle(play, (rockActor->actor.params & 1 ? 8 : 2), *rockIdentity); + } + + CLOSE_DISPS(play->state.gfxCtx); +} + +extern "C" void ObjBombiwa_RandomizerDraw(Actor* thisx, PlayState* play) { + auto rockActor = ((ObjBombiwa*)thisx); + const auto rockIdentity = ObjectExtension::GetInstance().Get(thisx); + + OPEN_DISPS(play->state.gfxCtx); + Gfx_SetupDL_25Opa(play->state.gfxCtx); + + Gfx_DrawDListOpa(play, (Gfx*)object_bombiwa_DL_0009E0); + gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_MODELVIEW | G_MTX_LOAD); + gSPDisplayList(POLY_OPA_DISP++, (Gfx*)object_bombiwa_DL_0009E0); + + if (rockIdentity != nullptr && rockIdentity->randomizerCheck != RC_MAX && + Flags_GetRandomizerInf(rockIdentity->randomizerInf) == 0) { + Matrix_Translate(rockActor->actor.world.pos.x, rockActor->actor.world.pos.y + 32, rockActor->actor.world.pos.z, + MTXMODE_NEW); + DrawItemCircle(play, 8, *rockIdentity); + } + + CLOSE_DISPS(play->state.gfxCtx); +} + +extern "C" void ObjHamishi_RandomizerDraw(Actor* thisx, PlayState* play) { + auto rockActor = ((ObjHamishi*)thisx); + const auto rockIdentity = ObjectExtension::GetInstance().Get(thisx); + + OPEN_DISPS(play->state.gfxCtx); + Gfx_SetupDL_25Opa(play->state.gfxCtx); + + gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 170, 130, 255); + gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gSilverRockDL); + + if (rockIdentity != nullptr && rockIdentity->randomizerCheck != RC_MAX && + Flags_GetRandomizerInf(rockIdentity->randomizerInf) == 0) { + Matrix_Translate(rockActor->actor.world.pos.x, rockActor->actor.world.pos.y + 32, rockActor->actor.world.pos.z, + MTXMODE_NEW); + DrawItemCircle(play, 8, *rockIdentity); + } + + CLOSE_DISPS(play->state.gfxCtx); +} + +uint8_t Rock_RandomizerHoldsItem(RockIdentity rockIdentity, PlayState* play, bool isBoulder) { + RandomizerCheck rc = rockIdentity.randomizerCheck; + if (rc == RC_MAX || rc == RC_UNKNOWN_CHECK) + return false; + + uint8_t isDungeon = Rando::StaticData::GetLocation(rc)->IsDungeon(); + uint8_t setting = + Rando::Context::GetInstance()->GetOption(isBoulder ? RSK_SHUFFLE_BOULDERS : RSK_SHUFFLE_ROCKS).Get(); + + // Don't pull randomized item if rock isn't randomized or is already checked + return IS_RANDO && + ((!isBoulder && setting) || (isBoulder && (setting == RO_SHUFFLE_BOULDERS_ALL || + (isDungeon && setting == RO_SHUFFLE_BOULDERS_DUNGEONS) || + (!isDungeon && setting == RO_SHUFFLE_BOULDERS_OVERWORLD)))) && + !Flags_GetRandomizerInf(rockIdentity.randomizerInf); +} + +void Rock_RandomizerSpawnCollectible(Actor* actor, RockIdentity rockIdentity, PlayState* play) { + LUSLOG_INFO("ROCKdrop %d\t:\t%d, %d", rockIdentity.randomizerCheck, (s16)actor->world.pos.x, + (s16)actor->world.pos.z); + EnItem00* item00 = (EnItem00*)Item_DropCollectible2(play, &actor->world.pos, ITEM00_SOH_DUMMY); + item00->randoInf = rockIdentity.randomizerInf; + item00->itemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(rockIdentity.randomizerCheck, true, GI_NONE); + item00->actor.draw = (ActorFunc)EnItem00_DrawRandomizedItem; + item00->actor.velocity.y = 9.0f; + item00->actor.speedXZ = 2.0f; + item00->actor.world.rot.y = Rand_CenteredFloat(65536.0f); +} + +void EnIshi_RandomizerInit(void* actorRef) { + Actor* actor = static_cast(actorRef); + + if (actor->id != ACTOR_EN_ISHI) + return; + + EnIshi* rockActor = static_cast(actorRef); + + auto rockIdentity = OTRGlobals::Instance->gRandomizer->IdentifyRock(gPlayState->sceneNum, (s16)actor->world.pos.x, + (s16)actor->world.pos.z); + if (rockIdentity.randomizerCheck == RC_MAX) { + LUSLOG_WARN("ROCK ishi %d\t:\t%d, %d", rockIdentity.randomizerCheck, actor->params & 1, + (s16)actor->world.pos.x, (s16)actor->world.pos.z); + } else { + LUSLOG_INFO("ROCK ishi%d %d\t:\t%d, %d", rockIdentity.randomizerCheck, actor->params & 1, + (s16)actor->world.pos.x, (s16)actor->world.pos.z); + } + + if (Rock_RandomizerHoldsItem(rockIdentity, gPlayState, actor->params & 1)) { + ObjectExtension::GetInstance().Set(actor, std::move(rockIdentity)); + rockActor->actor.draw = EnIshi_RandomizerDraw; + } +} + +void ObjBombiwa_RandomizerInit(void* actorRef) { + Actor* actor = static_cast(actorRef); + + if (actor->id != ACTOR_OBJ_BOMBIWA) + return; + + ObjBombiwa* rockActor = static_cast(actorRef); + + auto rockIdentity = OTRGlobals::Instance->gRandomizer->IdentifyRock(gPlayState->sceneNum, (s16)actor->world.pos.x, + (s16)actor->world.pos.z); + if (rockIdentity.randomizerCheck == RC_MAX) { + LUSLOG_INFO("ROCK bombiwa\t:\t%d, %d", rockIdentity.randomizerCheck, (s16)actor->world.pos.x, + (s16)actor->world.pos.z); + } else { + LUSLOG_INFO("ROCK bombiwa%d\t:\t%d, %d", rockIdentity.randomizerCheck, (s16)actor->world.pos.x, + (s16)actor->world.pos.z); + } + if (Rock_RandomizerHoldsItem(rockIdentity, gPlayState, true)) { + ObjectExtension::GetInstance().Set(actor, std::move(rockIdentity)); + rockActor->actor.draw = ObjBombiwa_RandomizerDraw; + } +} + +void ObjHamishi_RandomizerInit(void* actorRef) { + Actor* actor = static_cast(actorRef); + + if (actor->id != ACTOR_OBJ_HAMISHI) + return; + + ObjHamishi* rockActor = static_cast(actorRef); + + auto rockIdentity = OTRGlobals::Instance->gRandomizer->IdentifyRock(gPlayState->sceneNum, (s16)actor->world.pos.x, + (s16)actor->world.pos.z); + if (rockIdentity.randomizerCheck == RC_MAX) { + LUSLOG_WARN("ROCK hamishi\t:\t%d, %d", rockIdentity.randomizerCheck, (s16)actor->world.pos.x, + (s16)actor->world.pos.z); + } else { + LUSLOG_INFO("ROCK hamishi%d\t:\t%d, %d", rockIdentity.randomizerCheck, (s16)actor->world.pos.x, + (s16)actor->world.pos.z); + } + if (Rock_RandomizerHoldsItem(rockIdentity, gPlayState, true)) { + ObjectExtension::GetInstance().Set(actor, std::move(rockIdentity)); + rockActor->actor.draw = ObjHamishi_RandomizerDraw; + } +} + +void ObjBombiwa_RandomizerKill(void* actorRef) { + Actor* actor = static_cast(actorRef); + + if (actor->id != ACTOR_OBJ_BOMBIWA) + return; + + ObjBombiwa* rockActor = static_cast(actorRef); + const auto rockIdentity = ObjectExtension::GetInstance().Get(actorRef); + + if (rockIdentity != nullptr && Rock_RandomizerHoldsItem(*rockIdentity, gPlayState, true)) { + Rock_RandomizerSpawnCollectible(&rockActor->actor, *rockIdentity, gPlayState); + rockIdentity->randomizerCheck = RC_MAX; + rockIdentity->randomizerInf = RAND_INF_MAX; + } +} + +void ObjHamishi_RandomizerKill(void* actorRef) { + Actor* actor = static_cast(actorRef); + + if (actor->id != ACTOR_OBJ_HAMISHI) + return; + + ObjHamishi* rockActor = static_cast(actorRef); + const auto rockIdentity = ObjectExtension::GetInstance().Get(actorRef); + + if (rockIdentity != nullptr && Rock_RandomizerHoldsItem(*rockIdentity, gPlayState, true)) { + Rock_RandomizerSpawnCollectible(&rockActor->actor, *rockIdentity, gPlayState); + rockIdentity->randomizerCheck = RC_MAX; + rockIdentity->randomizerInf = RAND_INF_MAX; + } +} + +void RegisterShuffleRock() { + bool shouldRegister = IS_RANDO && (RAND_GET_OPTION(RSK_SHUFFLE_ROCKS) || RAND_GET_OPTION(RSK_SHUFFLE_BOULDERS)); + bool shouldRegisterBoulder = IS_RANDO && RAND_GET_OPTION(RSK_SHUFFLE_BOULDERS); + + COND_ID_HOOK(OnActorInit, ACTOR_EN_ISHI, shouldRegister, EnIshi_RandomizerInit); + COND_ID_HOOK(OnActorInit, ACTOR_OBJ_BOMBIWA, shouldRegisterBoulder, ObjBombiwa_RandomizerInit); + COND_ID_HOOK(OnActorInit, ACTOR_OBJ_HAMISHI, shouldRegisterBoulder, ObjHamishi_RandomizerInit); + COND_ID_HOOK(OnActorKill, ACTOR_OBJ_BOMBIWA, shouldRegisterBoulder, ObjBombiwa_RandomizerKill); + COND_ID_HOOK(OnActorKill, ACTOR_OBJ_HAMISHI, shouldRegisterBoulder, ObjHamishi_RandomizerKill); + + COND_VB_SHOULD(VB_ROCK_DROP_ITEM, shouldRegister, { + EnIshi* rockActor = va_arg(args, EnIshi*); + const auto rockIdentity = ObjectExtension::GetInstance().Get(rockActor); + if (rockIdentity != nullptr && + Rock_RandomizerHoldsItem(*rockIdentity, gPlayState, rockActor->actor.params & 1)) { + Rock_RandomizerSpawnCollectible(&rockActor->actor, *rockIdentity, gPlayState); + rockIdentity->randomizerCheck = RC_MAX; + rockIdentity->randomizerInf = RAND_INF_MAX; + *should = false; + } + }); + + COND_VB_SHOULD(VB_BOULDER_BREAK_FLAG, shouldRegisterBoulder, { + Actor* rockActor = va_arg(args, Actor*); + // hook called before OnActorInit sets up object extension + auto rockIdentity = OTRGlobals::Instance->gRandomizer->IdentifyRock( + gPlayState->sceneNum, (s16)rockActor->world.pos.x, (s16)rockActor->world.pos.z); + if (rockIdentity.randomizerCheck != RC_UNKNOWN_CHECK && + Rock_RandomizerHoldsItem(rockIdentity, gPlayState, true)) { + *should = false; + } + }); +} + +void Rando::StaticData::RegisterRockLocations() { +#define ROCKLOC(id, area, scene, hint, x, z) \ + (locationTable[RC_##id] = Location::Rock(RC_##id, RCQUEST_BOTH, area, scene, TWO_ACTOR_PARAMS(x, z), #id, hint, \ + RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_##id))) +#define BOLDLOC(id, area, scene, hint, x, z) \ + (locationTable[RC_##id] = Location::Boulder(RC_##id, RCQUEST_BOTH, area, scene, TWO_ACTOR_PARAMS(x, z), #id, hint, \ + SpoilerCollectionCheck::RandomizerInf(RAND_INF_##id))) + ROCKLOC(KF_CIRCLE_ROCK_1, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, RHT_KF_ROCK, -292, -350); + ROCKLOC(KF_CIRCLE_ROCK_2, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, RHT_KF_ROCK, -235, -373); + ROCKLOC(KF_CIRCLE_ROCK_3, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, RHT_KF_ROCK, -212, -430); + ROCKLOC(KF_CIRCLE_ROCK_4, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, RHT_KF_ROCK, -235, -486); + ROCKLOC(KF_CIRCLE_ROCK_5, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, RHT_KF_ROCK, -292, -510); + ROCKLOC(KF_CIRCLE_ROCK_6, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, RHT_KF_ROCK, -348, -486); + ROCKLOC(KF_CIRCLE_ROCK_7, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, RHT_KF_ROCK, -372, -430); + ROCKLOC(KF_CIRCLE_ROCK_8, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, RHT_KF_ROCK, -348, -373); + ROCKLOC(KF_ROCK_BY_SARIAS_HOUSE, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, RHT_KF_ROCK, 248, 601); + ROCKLOC(KF_ROCK_BEHIND_SARIAS_HOUSE, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, RHT_KF_ROCK, 726, 961); + ROCKLOC(KF_ROCK_BY_MIDOS_HOUSE, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, RHT_KF_ROCK, -672, -623); + ROCKLOC(KF_ROCK_BY_KNOW_IT_ALLS_HOUSE, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, RHT_KF_ROCK, -1361, 145); + BOLDLOC(LW_BOULDER_BY_GORON_CITY, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, RHT_LW_BOULDER, 915, -925); + BOLDLOC(LW_BOULDER_BY_SACRED_FOREST_MEADOW, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, RHT_LW_BOULDER, 670, -2520); + BOLDLOC(LW_RUPEE_BOULDER, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, RHT_LW_BOULDER, 1720, -2510); + + locationTable[RC_HC_ROCK_1] = Location::Rock( + RC_HC_ROCK_1, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(-216, 2977), + "HC Rock 1", RHT_HC_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_ROCK_1)); + locationTable[RC_HC_ROCK_2] = Location::Rock( + RC_HC_ROCK_2, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(-110, 3006), + "HC Rock 2", RHT_HC_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_ROCK_2)); + locationTable[RC_HC_ROCK_3] = Location::Rock( + RC_HC_ROCK_3, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(-129, 2897), + "HC Rock 3", RHT_HC_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_ROCK_3)); + BOLDLOC(HC_BOULDER, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, RHT_HC_BOULDER, 2730, 2540); + BOLDLOC(OGC_BRONZE_BOULDER_1, RCAREA_HYRULE_CASTLE, SCENE_OUTSIDE_GANONS_CASTLE, RHT_OGC_BRONZE_BOULDER, 2324, 533); + BOLDLOC(OGC_BRONZE_BOULDER_2, RCAREA_HYRULE_CASTLE, SCENE_OUTSIDE_GANONS_CASTLE, RHT_OGC_BRONZE_BOULDER, 1590, 787); + BOLDLOC(OGC_BRONZE_BOULDER_3, RCAREA_HYRULE_CASTLE, SCENE_OUTSIDE_GANONS_CASTLE, RHT_OGC_BRONZE_BOULDER, 1661, 748); + BOLDLOC(OGC_SILVER_BOULDER_1, RCAREA_HYRULE_CASTLE, SCENE_OUTSIDE_GANONS_CASTLE, RHT_OGC_SILVER_BOULDER, 1606, 685); + BOLDLOC(OGC_SILVER_BOULDER_2, RCAREA_HYRULE_CASTLE, SCENE_OUTSIDE_GANONS_CASTLE, RHT_OGC_SILVER_BOULDER, 1766, 726); + BOLDLOC(OGC_SILVER_BOULDER_3, RCAREA_HYRULE_CASTLE, SCENE_OUTSIDE_GANONS_CASTLE, RHT_OGC_SILVER_BOULDER, 1701, 661); + BOLDLOC(OGC_SILVER_BOULDER_4, RCAREA_HYRULE_CASTLE, SCENE_OUTSIDE_GANONS_CASTLE, RHT_OGC_SILVER_BOULDER, 2260, 560); + + ROCKLOC(DMC_ROCK_BY_FIRE_TEMPLE_1, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, -50, + -714); + ROCKLOC(DMC_ROCK_BY_FIRE_TEMPLE_2, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, -26, + -807); + ROCKLOC(DMC_ROCK_BY_FIRE_TEMPLE_3, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, 61, + -763); + ROCKLOC(DMC_ROCK_BY_FIRE_TEMPLE_4, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, 71, + -610); + ROCKLOC(DMC_ROCK_BY_FIRE_TEMPLE_5, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, 79, + -700); + ROCKLOC(DMC_CIRCLE_ROCK_1, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, 40, 1850); + ROCKLOC(DMC_CIRCLE_ROCK_2, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, 96, 1826); + ROCKLOC(DMC_CIRCLE_ROCK_3, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, 120, 1770); + ROCKLOC(DMC_CIRCLE_ROCK_4, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, 96, 1713); + ROCKLOC(DMC_CIRCLE_ROCK_5, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, 40, 1690); + ROCKLOC(DMC_CIRCLE_ROCK_6, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, -16, 1713); + ROCKLOC(DMC_CIRCLE_ROCK_7, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, -40, 1770); + ROCKLOC(DMC_CIRCLE_ROCK_8, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, -16, 1826); + ROCKLOC(DMC_GOSSIP_ROCK_1, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, 1261, 1533); + ROCKLOC(DMC_GOSSIP_ROCK_2, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, 1356, 1541); + BOLDLOC(DMC_BOULDER_1, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_BOULDER, -504, 1070); + BOLDLOC(DMC_BOULDER_2, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_BOULDER, 236, 1199); + BOLDLOC(DMC_BOULDER_3, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_BOULDER, 40, 1770); + BOLDLOC(DMC_BRONZE_BOULDER_1, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_BRONZE_BOULDER, + -1699, -472); + BOLDLOC(DMC_BRONZE_BOULDER_2, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_BRONZE_BOULDER, + -1332, 921); + BOLDLOC(DMC_BRONZE_BOULDER_3, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_BRONZE_BOULDER, + -1303, 975); + BOLDLOC(DMC_BRONZE_BOULDER_4, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_BRONZE_BOULDER, + -1060, 944); + + BOLDLOC(GV_SILVER_BOULDER, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_SILVER_BOULDER, 280, 1470); + ROCKLOC(GV_ROCK_1, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_ROCK, 2738, 297); + ROCKLOC(GV_ROCK_2, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_ROCK, 2715, 316); + ROCKLOC(GV_ROCK_3, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_ROCK, 2699, 275); + ROCKLOC(GV_UNDERWATER_ROCK_1, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_ROCK, 1559, -63); + ROCKLOC(GV_UNDERWATER_ROCK_2, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_ROCK, 1605, 26); + ROCKLOC(GV_UNDERWATER_ROCK_3, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_ROCK, 1686, -33); + ROCKLOC(GV_ROCK_ACROSS_BRIDGE_1, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_ROCK, -666, -899); + ROCKLOC(GV_ROCK_ACROSS_BRIDGE_2, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_ROCK, -526, -890); + ROCKLOC(GV_ROCK_ACROSS_BRIDGE_3, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_ROCK, -607, -791); + ROCKLOC(GV_ROCK_ACROSS_BRIDGE_4, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_ROCK, -458, -782); + BOLDLOC(GV_BOULDER_1, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_BOULDER, 751, 569); + BOLDLOC(GV_BOULDER_2, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_BOULDER, 545, -510); + BOLDLOC(GV_BOULDER_ACROSS_BRIDGE, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_BOULDER, -954, 577); + BOLDLOC(GV_BRONZE_BOULDER_1, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_BRONZE_BOULDER, 861, -778); + BOLDLOC(GV_BRONZE_BOULDER_2, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_BRONZE_BOULDER, 735, 375); + BOLDLOC(GV_BRONZE_BOULDER_ACROSS_BRIDGE_1, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_BRONZE_BOULDER, -1352, + 767); + BOLDLOC(GV_BRONZE_BOULDER_ACROSS_BRIDGE_2, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_BRONZE_BOULDER, -1695, + -350); + BOLDLOC(GV_BRONZE_BOULDER_ACROSS_BRIDGE_3, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_BRONZE_BOULDER, -1001, + 637); + BOLDLOC(GV_BRONZE_BOULDER_ACROSS_BRIDGE_4, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_BRONZE_BOULDER, -1291, + 787); + BOLDLOC(GV_BRONZE_BOULDER_ACROSS_BRIDGE_5, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_BRONZE_BOULDER, -1416, + 778); + BOLDLOC(GV_BRONZE_BOULDER_ACROSS_BRIDGE_6, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_BRONZE_BOULDER, -1256, + 856); + + BOLDLOC(HF_SILVER_BOULDER, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_SILVER_BOULDER, 674, 8256); + ROCKLOC(HF_ROCK_1, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_ROCK, -7875, 6995); + ROCKLOC(HF_ROCK_2, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_ROCK, -7818, 6971); + ROCKLOC(HF_ROCK_3, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_ROCK, -7795, 6915); + ROCKLOC(HF_ROCK_4, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_ROCK, -7818, 6858); + ROCKLOC(HF_ROCK_5, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_ROCK, -7875, 6835); + ROCKLOC(HF_ROCK_6, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_ROCK, -7931, 6858); + ROCKLOC(HF_ROCK_7, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_ROCK, -7955, 6915); + ROCKLOC(HF_ROCK_8, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_ROCK, -7931, 6971); + BOLDLOC(HF_BOULDER_NORTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_BOULDER, -4450, -425); + BOLDLOC(HF_BOULDER_BY_MARKET, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_BOULDER, -1425, 810); + BOLDLOC(HF_BOULDER_SOUTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_BOULDER, -270, 12350); + BOLDLOC(HF_BRONZE_BOULDER_1, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_BRONZE_BOULDER, -7870, 6920); + BOLDLOC(HF_BRONZE_BOULDER_2, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_BRONZE_BOULDER, -7804, 7983); + BOLDLOC(HF_BRONZE_BOULDER_3, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_BRONZE_BOULDER, -8397, 7947); + BOLDLOC(HF_BRONZE_BOULDER_4, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_BRONZE_BOULDER, -6461, 8220); + + BOLDLOC(KAK_SILVER_BOULDER, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, RHT_KAK_SILVER_BOULDER, 1436, 1361); + ROCKLOC(KAK_ROCK_1, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, RHT_KAK_ROCK, 220, -1236); + ROCKLOC(KAK_ROCK_2, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, RHT_KAK_ROCK, -664, 1288); + ROCKLOC(GY_ROCK, RCAREA_GRAVEYARD, SCENE_GRAVEYARD, RHT_GY_ROCK, -1193, 693); + ROCKLOC(LA_ROCK, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, RHT_LA_ROCK, 1222, 3953); + + ROCKLOC(ZD_CIRCLE_ROCK_1, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, RHT_ZD_ROCK, 462, -696); + ROCKLOC(ZD_CIRCLE_ROCK_2, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, RHT_ZD_ROCK, 518, -719); + ROCKLOC(ZD_CIRCLE_ROCK_3, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, RHT_ZD_ROCK, 542, -776); + ROCKLOC(ZD_CIRCLE_ROCK_4, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, RHT_ZD_ROCK, 518, -832); + ROCKLOC(ZD_CIRCLE_ROCK_5, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, RHT_ZD_ROCK, 462, -856); + ROCKLOC(ZD_CIRCLE_ROCK_6, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, RHT_ZD_ROCK, 405, -832); + ROCKLOC(ZD_CIRCLE_ROCK_7, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, RHT_ZD_ROCK, 382, -776); + ROCKLOC(ZD_CIRCLE_ROCK_8, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, RHT_ZD_ROCK, 405, -719); + BOLDLOC(ZF_BOULDER, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, RHT_ZF_BOULDER, 189, 2586); + BOLDLOC(ZF_SILVER_BOULDER, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, RHT_ZF_SILVER_BOULDER, 316, 2634); + BOLDLOC(ZF_UNDERGROUND_BOULDER, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, RHT_ZF_BOULDER, 317, 2631); + BOLDLOC(ZR_BOULDER_1, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_BOULDER, -1456, 434); + BOLDLOC(ZR_BOULDER_2, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_BOULDER, -1518, 435); + BOLDLOC(ZR_BOULDER_3, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_BOULDER, -1576, 430); + BOLDLOC(ZR_BOULDER_4, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_BOULDER, -1400, 482); + ROCKLOC(ZR_CIRCLE_ROCK_1, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, -1635, -53); + ROCKLOC(ZR_CIRCLE_ROCK_2, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, -1578, -76); + ROCKLOC(ZR_CIRCLE_ROCK_3, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, -1555, -133); + ROCKLOC(ZR_CIRCLE_ROCK_4, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, -1578, -189); + ROCKLOC(ZR_CIRCLE_ROCK_5, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, -1635, -213); + ROCKLOC(ZR_CIRCLE_ROCK_6, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, -1691, -189); + ROCKLOC(ZR_CIRCLE_ROCK_7, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, -1715, -133); + ROCKLOC(ZR_CIRCLE_ROCK_8, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, -1691, -76); + ROCKLOC(ZR_UPPER_CIRCLE_BOULDER, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_BOULDER, 672, -366); + ROCKLOC(ZR_UPPER_CIRCLE_ROCK_1, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 668, -290); + ROCKLOC(ZR_UPPER_CIRCLE_ROCK_2, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 724, -313); + ROCKLOC(ZR_UPPER_CIRCLE_ROCK_3, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 748, -370); + ROCKLOC(ZR_UPPER_CIRCLE_ROCK_4, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 724, -426); + ROCKLOC(ZR_UPPER_CIRCLE_ROCK_5, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 668, -450); + ROCKLOC(ZR_UPPER_CIRCLE_ROCK_6, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 611, -426); + ROCKLOC(ZR_UPPER_CIRCLE_ROCK_7, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 588, -370); + ROCKLOC(ZR_UPPER_CIRCLE_ROCK_8, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 611, -313); + ROCKLOC(ZR_ROCK, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 2044, -786); + ROCKLOC(ZR_UNDERWATER_ROCK_1, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 2425, -446); + ROCKLOC(ZR_UNDERWATER_ROCK_2, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 2425, -524); + ROCKLOC(ZR_UNDERWATER_ROCK_3, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 2503, -571); + ROCKLOC(ZR_UNDERWATER_ROCK_4, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 2550, -415); + + // 5 rocks by dc + ROCKLOC(DMT_ROCK_1, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -1816, -513); + ROCKLOC(DMT_ROCK_2, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -1831, -614); + ROCKLOC(DMT_ROCK_3, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -1857, -536); + ROCKLOC(DMT_ROCK_4, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -1878, -465); + ROCKLOC(DMT_ROCK_5, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -1787, -550); + // child only + ROCKLOC(DMT_SUMMIT_ROCK, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -327, -4286); + // ring in front of gc + ROCKLOC(DMT_CIRCLE_ROCK_1, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -383, -1126); + ROCKLOC(DMT_CIRCLE_ROCK_2, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -326, -1149); + ROCKLOC(DMT_CIRCLE_ROCK_3, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -303, -1206); + ROCKLOC(DMT_CIRCLE_ROCK_4, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -326, -1262); + ROCKLOC(DMT_CIRCLE_ROCK_5, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -383, -1286); + ROCKLOC(DMT_CIRCLE_ROCK_6, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -439, -1262); + ROCKLOC(DMT_CIRCLE_ROCK_7, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -463, -1206); + ROCKLOC(DMT_CIRCLE_ROCK_8, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -439, -1149); + BOLDLOC(DMT_BOULDER_1, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BOULDER, -625, -55); + BOLDLOC(DMT_BOULDER_2, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BOULDER, -808, -59); + BOLDLOC(DMT_BOULDER_3, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BOULDER, -1060, -51); + BOLDLOC(DMT_COW_BOULDER, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BOULDER, -688, -285); + BOLDLOC(DMT_BRONZE_BOULDER_1, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BRONZE_BOULDER, + -1175, -803); + BOLDLOC(DMT_BRONZE_BOULDER_2, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BRONZE_BOULDER, + -1948, 1706); + BOLDLOC(DMT_BRONZE_BOULDER_3, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BRONZE_BOULDER, + -2019, 1101); + BOLDLOC(DMT_BRONZE_BOULDER_4, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BRONZE_BOULDER, + -1658, -88); + BOLDLOC(DMT_BRONZE_BOULDER_5, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BRONZE_BOULDER, + -1753, 445); + BOLDLOC(DMT_BRONZE_BOULDER_6, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BRONZE_BOULDER, + -1018, 1283); + BOLDLOC(DMT_BRONZE_BOULDER_7, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BRONZE_BOULDER, + -1986, 727); + BOLDLOC(DMT_BRONZE_BOULDER_8, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BRONZE_BOULDER, -23, + -3196); + BOLDLOC(DMT_BRONZE_BOULDER_9, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BRONZE_BOULDER, -343, + -2794); + BOLDLOC(DMT_BRONZE_BOULDER_10, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BRONZE_BOULDER, + -154, -2484); + BOLDLOC(DMT_BRONZE_BOULDER_11, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BRONZE_BOULDER, + -1590, -402); + BOLDLOC(GC_LW_BOULDER_1, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, 416, 1049); + BOLDLOC(GC_LW_BOULDER_2, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, 470, 1031); + BOLDLOC(GC_LW_BOULDER_3, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, 367, 1078); + BOLDLOC(GC_ENTRANCE_BOULDER_1, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -670, 470); + BOLDLOC(GC_ENTRANCE_BOULDER_2, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -607, 419); + BOLDLOC(GC_ENTRANCE_BOULDER_3, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -756, 474); + BOLDLOC(GC_MAZE_SILVER_BOULDER_1, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1479, -794); + BOLDLOC(GC_MAZE_SILVER_BOULDER_2, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1478, -855); + BOLDLOC(GC_MAZE_SILVER_BOULDER_3, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1474, -624); + BOLDLOC(GC_MAZE_SILVER_BOULDER_4, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1471, -993); + BOLDLOC(GC_MAZE_SILVER_BOULDER_5, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1467, -1064); + BOLDLOC(GC_MAZE_SILVER_BOULDER_6, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1460, -1121); + BOLDLOC(GC_MAZE_SILVER_BOULDER_7, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1451, -567); + BOLDLOC(GC_MAZE_SILVER_BOULDER_8, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1448, -672); + BOLDLOC(GC_MAZE_SILVER_BOULDER_9, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1440, -1174); + BOLDLOC(GC_MAZE_SILVER_BOULDER_10, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1437, -1342); + BOLDLOC(GC_MAZE_SILVER_BOULDER_11, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1424, -1245); + BOLDLOC(GC_MAZE_SILVER_BOULDER_12, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1424, -609); + BOLDLOC(GC_MAZE_SILVER_BOULDER_13, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1399, -1300); + BOLDLOC(GC_MAZE_SILVER_BOULDER_14, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1394, -654); + BOLDLOC(GC_MAZE_SILVER_BOULDER_15, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1343, -698); + BOLDLOC(GC_MAZE_SILVER_BOULDER_16, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1319, -1086); + BOLDLOC(GC_MAZE_SILVER_BOULDER_17, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1312, -1039); + BOLDLOC(GC_MAZE_SILVER_BOULDER_18, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1306, -837); + BOLDLOC(GC_MAZE_SILVER_BOULDER_19, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1279, -656); + BOLDLOC(GC_MAZE_SILVER_BOULDER_20, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1255, -840); + BOLDLOC(GC_MAZE_SILVER_BOULDER_21, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1246, -1075); + BOLDLOC(GC_MAZE_SILVER_BOULDER_22, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1244, -589); + BOLDLOC(GC_MAZE_SILVER_BOULDER_23, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1210, -852); + BOLDLOC(GC_MAZE_SILVER_BOULDER_24, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1206, -627); + BOLDLOC(GC_MAZE_SILVER_BOULDER_25, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1187, -896); + BOLDLOC(GC_MAZE_SILVER_BOULDER_26, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1157, -954); + BOLDLOC(GC_MAZE_SILVER_BOULDER_27, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1130, -1137); + BOLDLOC(GC_MAZE_SILVER_BOULDER_28, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1120, -1001); + BOLDLOC(GC_MAZE_SILVER_BOULDER_29, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1179, -1098); + BOLDLOC(GC_MAZE_BOULDER_1, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -1342, -628); + BOLDLOC(GC_MAZE_BOULDER_2, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -1456, -501); + BOLDLOC(GC_MAZE_BOULDER_3, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -1233, -511); + BOLDLOC(GC_MAZE_BOULDER_4, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -1137, -657); + BOLDLOC(GC_MAZE_BOULDER_5, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -1124, -913); + BOLDLOC(GC_MAZE_BOULDER_6, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -1326, -771); + BOLDLOC(GC_MAZE_BOULDER_7, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -1469, -737); + BOLDLOC(GC_MAZE_BOULDER_8, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -1476, -921); + BOLDLOC(GC_MAZE_BOULDER_9, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -1391, -1087); + BOLDLOC(GC_MAZE_BOULDER_10, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -1222, -997); + BOLDLOC(GC_MAZE_BRONZE_BOULDER_1, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BRONZE_BOULDER, -1541, -631); + BOLDLOC(GC_MAZE_BRONZE_BOULDER_2, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BRONZE_BOULDER, -1536, -861); + BOLDLOC(GC_MAZE_BRONZE_BOULDER_3, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BRONZE_BOULDER, -1536, -1102); + BOLDLOC(GC_MAZE_BRONZE_BOULDER_4, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BRONZE_BOULDER, -1534, -752); + BOLDLOC(GC_MAZE_BRONZE_BOULDER_5, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BRONZE_BOULDER, -1536, -991); + ROCKLOC(GC_MAZE_ROCK, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_ROCK, -1197, -1329); + BOLDLOC(COLOSSUS_SILVER_BOULDER, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_SILVER_BOULDER, 61, + -1301); + ROCKLOC(COLOSSUS_ROCK, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, 1537, 667); + ROCKLOC(COLOSSUS_CIRCLE_1_ROCK_1, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -250, -1272); + ROCKLOC(COLOSSUS_CIRCLE_1_ROCK_2, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -193, -1295); + ROCKLOC(COLOSSUS_CIRCLE_1_ROCK_3, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -170, -1352); + ROCKLOC(COLOSSUS_CIRCLE_1_ROCK_4, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -193, -1408); + ROCKLOC(COLOSSUS_CIRCLE_1_ROCK_5, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -250, -1432); + ROCKLOC(COLOSSUS_CIRCLE_1_ROCK_6, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -306, -1408); + ROCKLOC(COLOSSUS_CIRCLE_1_ROCK_7, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -330, -1352); + ROCKLOC(COLOSSUS_CIRCLE_1_ROCK_8, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -306, -1295); + ROCKLOC(COLOSSUS_CIRCLE_2_ROCK_1, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -834, -766); + ROCKLOC(COLOSSUS_CIRCLE_2_ROCK_2, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -777, -789); + ROCKLOC(COLOSSUS_CIRCLE_2_ROCK_3, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -754, -846); + ROCKLOC(COLOSSUS_CIRCLE_2_ROCK_4, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -777, -902); + ROCKLOC(COLOSSUS_CIRCLE_2_ROCK_5, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -834, -926); + ROCKLOC(COLOSSUS_CIRCLE_2_ROCK_6, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -890, -902); + ROCKLOC(COLOSSUS_CIRCLE_2_ROCK_7, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -914, -846); + ROCKLOC(COLOSSUS_CIRCLE_2_ROCK_8, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -890, -789); + ROCKLOC(HC_STORMS_GROTTO_ROCK_1, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, RHT_HC_STORMS_GROTTO_ROCK, 1811, 813); + ROCKLOC(HC_STORMS_GROTTO_ROCK_2, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, RHT_HC_STORMS_GROTTO_ROCK, 1867, 789); + ROCKLOC(HC_STORMS_GROTTO_ROCK_3, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, RHT_HC_STORMS_GROTTO_ROCK, 1891, 733); + ROCKLOC(HC_STORMS_GROTTO_ROCK_4, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, RHT_HC_STORMS_GROTTO_ROCK, 1867, 676); + ROCKLOC(HC_STORMS_GROTTO_ROCK_5, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, RHT_HC_STORMS_GROTTO_ROCK, 1811, 653); + ROCKLOC(HC_STORMS_GROTTO_ROCK_6, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, RHT_HC_STORMS_GROTTO_ROCK, 1754, 676); + ROCKLOC(HC_STORMS_GROTTO_ROCK_7, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, RHT_HC_STORMS_GROTTO_ROCK, 1731, 733); + ROCKLOC(HC_STORMS_GROTTO_ROCK_8, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, RHT_HC_STORMS_GROTTO_ROCK, 1754, 789); + locationTable[RC_BOTW_BOULDER_1] = + Location::Boulder(RC_BOTW_BOULDER_1, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, + TWO_ACTOR_PARAMS(-684, -734), "BOTW Boulder 1", RHT_BOTW_BOULDER, + SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTW_BOULDER_1)); + locationTable[RC_BOTW_BOULDER_2] = + Location::Boulder(RC_BOTW_BOULDER_2, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, + TWO_ACTOR_PARAMS(-632, -805), "BOTW Boulder 2", RHT_BOTW_BOULDER, + SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTW_BOULDER_2)); + locationTable[RC_BOTW_BOULDER_3] = + Location::Boulder(RC_BOTW_BOULDER_3, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, + TWO_ACTOR_PARAMS(333, -681), "BOTW Boulder 3", RHT_BOTW_BOULDER, + SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTW_BOULDER_3)); + locationTable[RC_BOTW_BOULDER_4] = + Location::Boulder(RC_BOTW_BOULDER_4, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, + TWO_ACTOR_PARAMS(409, -637), "BOTW Boulder 4", RHT_BOTW_BOULDER, + SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTW_BOULDER_4)); + locationTable[RC_BOTW_BOULDER_5] = + Location::Boulder(RC_BOTW_BOULDER_5, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, + TWO_ACTOR_PARAMS(334, -8), "BOTW Boulder 5", RHT_BOTW_BOULDER, + SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTW_BOULDER_5)); + locationTable[RC_BOTW_BOULDER_6] = + Location::Boulder(RC_BOTW_BOULDER_6, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, + TWO_ACTOR_PARAMS(312, 64), "BOTW Boulder 6", RHT_BOTW_BOULDER, + SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTW_BOULDER_6)); +#define MQBOLD(id, area, hint, x, z) \ + (locationTable[RC_##id] = \ + Location::Boulder(RC_##id, RCQUEST_MQ, RCAREA_##area, SCENE_##area, TWO_ACTOR_PARAMS(x, z), #id, hint, \ + SpoilerCollectionCheck::RandomizerInf(RAND_INF_##id))) + MQBOLD(DEKU_TREE_MQ_BOULDER_1, DEKU_TREE, RHT_DEKU_BOULDER, -1237, 1558); + MQBOLD(DEKU_TREE_MQ_BOULDER_2, DEKU_TREE, RHT_DEKU_BOULDER, -1183, 1522); + MQBOLD(DEKU_TREE_MQ_BOULDER_3, DEKU_TREE, RHT_DEKU_BOULDER, -1129, 1469); + MQBOLD(DODONGOS_CAVERN_MQ_LOBBY_BOULDER_1, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, -435, -1720); + MQBOLD(DODONGOS_CAVERN_MQ_LOBBY_BOULDER_2, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 432, -1719); + MQBOLD(DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_1, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 807, -874); + MQBOLD(DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_2, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 802, -972); + MQBOLD(DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_3, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 783, -923); + MQBOLD(DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_1, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 2464, -402); + MQBOLD(DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_2, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 2942, -495); + MQBOLD(DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_1, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 4219, -1651); + MQBOLD(DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_2, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 4178, -1602); + MQBOLD(DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_3, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 4162, -1581); + MQBOLD(DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_4, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 4133, -1561); + MQBOLD(DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_5, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 4091, -1510); + MQBOLD(DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_6, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 4067, -1487); + MQBOLD(DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_7, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 4028, -1472); + MQBOLD(DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_8, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 3965, -1473); + MQBOLD(DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_9, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 3898, -1467); + MQBOLD(DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_10, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 3832, -1437); + MQBOLD(DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_11, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 3799, -1383); + MQBOLD(DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_12, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 3760, -1318); + MQBOLD(DODONGOS_CAVERN_MQ_TWO_FLAMES_BOULDER, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 2737, -1058); + locationTable[RC_JABU_JABUS_BELLY_MQ_ENTRANCE_BOULDER] = + Location::Boulder(RC_JABU_JABUS_BELLY_MQ_ENTRANCE_BOULDER, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, + TWO_ACTOR_PARAMS(-1, -296), "RC_JABU_JABUS_BELLY_MQ_ENTRANCE_BOULDER", RHT_JABU_BOULDER, + SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_ENTRANCE_BOULDER)); + locationTable[RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_1] = Location::Boulder( + RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_1, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, + TWO_ACTOR_PARAMS(350, -3533), "RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_1", RHT_JABU_BOULDER, + SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_1)); + locationTable[RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_2] = Location::Boulder( + RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_2, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, + TWO_ACTOR_PARAMS(-192, -3211), "RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_2", RHT_JABU_BOULDER, + SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_2)); + locationTable[RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_1] = Location::Boulder( + RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_1, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, + TWO_ACTOR_PARAMS(245, -2792), "RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_1", RHT_JABU_BOULDER, + SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_1)); + locationTable[RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_2] = Location::Boulder( + RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_2, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, + TWO_ACTOR_PARAMS(220, -2790), "RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_2", RHT_JABU_BOULDER, + SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_2)); + locationTable[RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_3] = Location::Boulder( + RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_3, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, + TWO_ACTOR_PARAMS(274, -2790), "RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_3", RHT_JABU_BOULDER, + SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_3)); + locationTable[RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_1] = Location::Boulder( + RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_1, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, + TWO_ACTOR_PARAMS(31, -5177), "RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_1", RHT_JABU_BOULDER, + SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_1)); + locationTable[RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_2] = Location::Boulder( + RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_2, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, + TWO_ACTOR_PARAMS(-37, -5173), "RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_2", RHT_JABU_BOULDER, + SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_2)); + locationTable[RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_BOULDER] = Location::Boulder( + RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_BOULDER, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, + TWO_ACTOR_PARAMS(-885, -5907), "RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_BOULDER", RHT_JABU_BOULDER, + SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_TAILPASARAN_BOULDER)); + locationTable[RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_WALL_BOULDER] = Location::Boulder( + RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_WALL_BOULDER, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, + TWO_ACTOR_PARAMS(-411, -5682), "RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_WALL_BOULDER", RHT_JABU_BOULDER, + SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_TAILPASARAN_WALL_BOULDER)); + // skip spirit temple boulder, so adult can clear without collecting check for child to pass + MQBOLD(SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_1, SPIRIT_TEMPLE, RHT_SPIRIT_TEMPLE_BOULDER, -160, 270); + MQBOLD(SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_2, SPIRIT_TEMPLE, RHT_SPIRIT_TEMPLE_BOULDER, 160, 270); + MQBOLD(SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_3, SPIRIT_TEMPLE, RHT_SPIRIT_TEMPLE_BOULDER, 350, 220); + MQBOLD(SPIRIT_TEMPLE_MQ_ENTRANCE_CEILING_BOULDER, SPIRIT_TEMPLE, RHT_SPIRIT_TEMPLE_BOULDER, 0, -60); + MQBOLD(SPIRIT_TEMPLE_MQ_EARLY_ADULT_BOULDER, SPIRIT_TEMPLE, RHT_SPIRIT_TEMPLE_BOULDER, 1070, -290); + MQBOLD(BOTW_MQ_BOULDER_1, BOTTOM_OF_THE_WELL, RHT_BOTW_BOULDER, -370, -160); + MQBOLD(BOTW_MQ_BOULDER_2, BOTTOM_OF_THE_WELL, RHT_BOTW_BOULDER, -521, -353); + MQBOLD(BOTW_MQ_BOULDER_3, BOTTOM_OF_THE_WELL, RHT_BOTW_BOULDER, -541, -404); +} + +static ObjectExtension::Register RegisterRockIdentity; +static RegisterShipInitFunc initFunc(RegisterShuffleRock, { "IS_RANDO" }); +static RegisterShipInitFunc initFunc2(Rando::StaticData::RegisterRockLocations); \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/ShuffleRocks.h b/soh/soh/Enhancements/randomizer/ShuffleRocks.h new file mode 100644 index 00000000000..ad7ea4d7a83 --- /dev/null +++ b/soh/soh/Enhancements/randomizer/ShuffleRocks.h @@ -0,0 +1,15 @@ +#ifndef SHUFFLEROCKS_H +#define SHUFFLEROCKS_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif +void EnIshi_RandomizerInit(void* actorRef); +#ifdef __cplusplus +}; +#endif + +#endif // SHUFFLEROCKS_H \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/context.cpp b/soh/soh/Enhancements/randomizer/context.cpp index 7dff59ae6b3..a1af5f9f084 100644 --- a/soh/soh/Enhancements/randomizer/context.cpp +++ b/soh/soh/Enhancements/randomizer/context.cpp @@ -50,6 +50,8 @@ Context::Context() { &mOptions[RSK_SHUFFLE_COWS], &mOptions[RSK_SHUFFLE_POTS], &mOptions[RSK_SHUFFLE_CRATES], + &mOptions[RSK_SHUFFLE_ROCKS], + &mOptions[RSK_SHUFFLE_BOULDERS], &mOptions[RSK_SHUFFLE_FREESTANDING], &mOptions[RSK_SHUFFLE_MERCHANTS], &mOptions[RSK_SHUFFLE_FROG_SONG_RUPEES], @@ -206,6 +208,8 @@ void Context::GenerateLocationPool() { (location.GetRCType() == RCTYPE_TREE && !mOptions[RSK_SHUFFLE_TREES]) || (location.GetRCType() == RCTYPE_NLTREE && (!mOptions[RSK_SHUFFLE_TREES] || mOptions[RSK_LOGIC_RULES].IsNot(RO_LOGIC_NO_LOGIC))) || + (location.GetRCType() == RCTYPE_ROCK && !mOptions[RSK_SHUFFLE_ROCKS]) || + (location.GetRCType() == RCTYPE_BOULDER && mOptions[RSK_SHUFFLE_BOULDERS].Is(RO_SHUFFLE_BOULDERS_OFF)) || (location.GetRCType() == RCTYPE_BUSH && !mOptions[RSK_SHUFFLE_BUSHES]) || (location.GetRCType() == RCTYPE_FREESTANDING && mOptions[RSK_SHUFFLE_FREESTANDING].Is(RO_SHUFFLE_FREESTANDING_OFF)) || @@ -224,7 +228,9 @@ void Context::GenerateLocationPool() { mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_DUNGEONS) && mOptions[RSK_LOGIC_RULES].Is(RO_LOGIC_NO_LOGIC)) || (location.GetRCType() == RCTYPE_SMALL_CRATE && - mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_DUNGEONS))) { + mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_DUNGEONS)) && + (location.GetRCType() == RCTYPE_BOULDER && + mOptions[RSK_SHUFFLE_BOULDERS].Is(RO_SHUFFLE_BOULDERS_DUNGEONS))) { continue; } // If we've gotten past all the conditions where an overworld location should not be @@ -245,7 +251,9 @@ void Context::GenerateLocationPool() { mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_OVERWORLD) && mOptions[RSK_LOGIC_RULES].Is(RO_LOGIC_NO_LOGIC)) || (location.GetRCType() == RCTYPE_SMALL_CRATE && - mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_OVERWORLD))) { + mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_OVERWORLD)) && + (location.GetRCType() == RCTYPE_BOULDER && + mOptions[RSK_SHUFFLE_BOULDERS].Is(RO_SHUFFLE_BOULDERS_OVERWORLD))) { continue; } // also add to that dungeon's location list. diff --git a/soh/soh/Enhancements/randomizer/location.cpp b/soh/soh/Enhancements/randomizer/location.cpp index 250af2cfb74..e6308fe0459 100644 --- a/soh/soh/Enhancements/randomizer/location.cpp +++ b/soh/soh/Enhancements/randomizer/location.cpp @@ -585,6 +585,23 @@ Rando::Location Rando::Location::NLTree(RandomizerCheck rc, RandomizerCheckQuest false, collectionCheck }; } +Rando::Location Rando::Location::Rock(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, + SceneID scene_, int32_t actorParams_, std::string&& shortName_, + RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, + SpoilerCollectionCheck collectionCheck) { + return { rc, quest_, RCTYPE_ROCK, area_, ACTOR_EN_ISHI, + scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem, + false, collectionCheck }; +} + +Rando::Location Rando::Location::Boulder(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, + SceneID scene_, int32_t actorParams_, std::string&& shortName_, + RandomizerHintTextKey hintKey, SpoilerCollectionCheck collectionCheck) { + return { rc, quest_, RCTYPE_BOULDER, area_, ACTOR_EN_ISHI, + scene_, actorParams_, std::move(shortName_), hintKey, RG_BOMBS_5, + false, collectionCheck }; +} + Rando::Location Rando::Location::Bush(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, diff --git a/soh/soh/Enhancements/randomizer/location.h b/soh/soh/Enhancements/randomizer/location.h index 9556012204a..6b352ab1bc3 100644 --- a/soh/soh/Enhancements/randomizer/location.h +++ b/soh/soh/Enhancements/randomizer/location.h @@ -67,15 +67,7 @@ class Location { actorParams(actorParams_), shortName(std::move(shortName_)), spoilerName(std::move(spoilerName_)), hintKey(hintKey_), vanillaItem(vanillaItem_), isVanillaCompletion(isVanillaCompletion_), collectionCheck(collectionCheck_), vanillaPrice(vanillaPrice_) { - if (spoilerName.length() < 23) { - excludedOption = LocationOption(rc, spoilerName); - } else { - const size_t lastSpace = spoilerName.rfind(' ', 23); - std::string settingText = spoilerName; - settingText.replace(lastSpace, 1, "\n "); - - excludedOption = LocationOption(rc, spoilerName); - } + excludedOption = LocationOption(rc, spoilerName); } Location(const RandomizerCheck rc_, const RandomizerCheckQuest quest_, const RandomizerCheckType checkType_, @@ -87,15 +79,7 @@ class Location { actorParams(actorParams_), shortName(shortName_), spoilerName(SpoilerNameFromShortName(shortName_, area_)), hintKey(hintKey_), vanillaItem(vanillaItem_), isVanillaCompletion(isVanillaCompletion_), collectionCheck(collectionCheck_), vanillaPrice(vanillaPrice_) { - if (spoilerName.length() < 23) { - excludedOption = LocationOption(rc, spoilerName); - } else { - const size_t lastSpace = spoilerName.rfind(' ', 23); - std::string settingText = spoilerName; - settingText.replace(lastSpace, 1, "\n "); - - excludedOption = LocationOption(rc, spoilerName); - } + excludedOption = LocationOption(rc, spoilerName); } static std::string SpoilerNameFromShortName(std::string shortName, RandomizerCheckArea area) { @@ -254,6 +238,14 @@ class Location { int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck); + static Location Rock(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, + int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey, + RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck); + + static Location Boulder(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, + int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey, + SpoilerCollectionCheck collectionCheck); + static Location Bush(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck); diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/bottom_of_the_well.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/bottom_of_the_well.cpp index be95e626a6d..2ae3b70bd55 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/bottom_of_the_well.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/bottom_of_the_well.cpp @@ -231,6 +231,12 @@ void RegionTable_Init_BottomOfTheWell() { LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_7, logic->CanCutShrubs()), LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_8, logic->CanCutShrubs()), LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_9, logic->CanCutShrubs()), + LOCATION(RC_BOTW_BOULDER_1, logic->BlastOrSmash()), + LOCATION(RC_BOTW_BOULDER_2, logic->BlastOrSmash()), + LOCATION(RC_BOTW_BOULDER_3, logic->BlastOrSmash() || logic->CanUse(RG_DINS_FIRE) || (logic->CanUse(RG_STICKS) && ctx->GetTrickOption(RT_BOTW_BASEMENT))), + LOCATION(RC_BOTW_BOULDER_4, logic->BlastOrSmash()), + LOCATION(RC_BOTW_BOULDER_5, logic->BlastOrSmash()), + LOCATION(RC_BOTW_BOULDER_6, logic->BlastOrSmash()), }, { //Exits Entrance(RR_BOTW_B3_OOZE, []{return Here(RR_BOTW_B3_BLOCKED_GRASS, []{return logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET);});}), @@ -239,6 +245,12 @@ void RegionTable_Init_BottomOfTheWell() { areaTable[RR_BOTW_B3_CHEST_AREA] = Region("Bottom of the Well B3 Chest Area", SCENE_BOTTOM_OF_THE_WELL, {}, { //Locations LOCATION(RC_BOTTOM_OF_THE_WELL_MAP_CHEST, logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_BOTW_BOULDER_1, logic->HasItem(RG_GORONS_BRACELET)), + LOCATION(RC_BOTW_BOULDER_2, logic->HasItem(RG_GORONS_BRACELET)), + LOCATION(RC_BOTW_BOULDER_3, logic->HasItem(RG_GORONS_BRACELET)), + LOCATION(RC_BOTW_BOULDER_4, logic->HasItem(RG_GORONS_BRACELET)), + LOCATION(RC_BOTW_BOULDER_5, logic->HasItem(RG_GORONS_BRACELET)), + LOCATION(RC_BOTW_BOULDER_6, logic->HasItem(RG_GORONS_BRACELET)), }, { //Exits Entrance(RR_BOTW_B3_OOZE, []{return Here(RR_BOTW_B3_CHEST_AREA, []{return logic->BlastOrSmash();});}), @@ -278,6 +290,9 @@ void RegionTable_Init_BottomOfTheWell() { LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_OUTER_LOBBY_POT, Here(RR_BOTW_MQ_PERIMETER, []{return logic->BlastOrSmash();}) && logic->CanHitEyeTargets()), LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_BOMB_LEFT_HEART, logic->HasExplosives()), LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_BOMB_RIGHT_HEART, logic->HasExplosives()), + LOCATION(RC_BOTW_MQ_BOULDER_1, logic->BlastOrSmash()), + LOCATION(RC_BOTW_MQ_BOULDER_2, logic->BlastOrSmash()), + LOCATION(RC_BOTW_MQ_BOULDER_3, logic->BlastOrSmash()), }, { //Exits Entrance(RR_BOTW_ENTRYWAY, []{return logic->IsChild/*CanCrawl() && CanClimb()*/;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp index 916d00a736d..a9e6c507e89 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp @@ -287,6 +287,9 @@ void RegionTable_Init_DekuTree() { //Locations LOCATION(RC_DEKU_TREE_MQ_GS_PAST_BOULDER_VINES, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)), LOCATION(RC_DEKU_TREE_MQ_COMPASS_ROOM_HEART, true), + LOCATION(RC_DEKU_TREE_MQ_BOULDER_1, true), + LOCATION(RC_DEKU_TREE_MQ_BOULDER_2, true), + LOCATION(RC_DEKU_TREE_MQ_BOULDER_3, true), }, { //Exits Entrance(RR_DEKU_TREE_MQ_COMPASS_ROOM, []{return logic->BlastOrSmash();}), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp index 7e4c285faa1..a561deca642 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp @@ -291,6 +291,8 @@ void RegionTable_Init_DodongosCavern() { LOCATION(RC_DODONGOS_CAVERN_MQ_MAP_CHEST, (logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET)) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR, logic->CanStunDeku()), LOCATION(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT, logic->CanStunDeku()), + LOCATION(RC_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_1, logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET)), + LOCATION(RC_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_2, logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET)), }, { //Exits Entrance(RR_DODONGOS_CAVERN_MQ_BEGINNING, []{return true;}), @@ -319,7 +321,12 @@ void RegionTable_Init_DodongosCavern() { //Events EventAccess(LOGIC_DC_MQ_CLEAR_UPPER_LOBBY_ROCKS, []{return logic->BlastOrSmash() || logic->CanUse(RG_DINS_FIRE);}), EventAccess(LOGIC_DC_EYES_LIT, []{return logic->HasExplosives() || (logic->Get(LOGIC_DC_MQ_CLEAR_UPPER_LOBBY_ROCKS) && logic->HasItem(RG_GORONS_BRACELET) && ((logic->IsAdult && ctx->GetTrickOption(RT_DC_MQ_ADULT_EYES)) || (logic->IsChild && ctx->GetTrickOption(RT_DC_MQ_CHILD_EYES))));}), - }, {}, { + }, { + //Locations + LOCATION(RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_1, logic->Get(LOGIC_DC_MQ_CLEAR_UPPER_LOBBY_ROCKS)), + LOCATION(RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_2, logic->Get(LOGIC_DC_MQ_CLEAR_UPPER_LOBBY_ROCKS)), + LOCATION(RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_3, logic->Get(LOGIC_DC_MQ_CLEAR_UPPER_LOBBY_ROCKS)), + }, { //Exits Entrance(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return true;}), Entrance(RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_UPPER, []{return logic->Get(LOGIC_DC_MQ_CLEAR_UPPER_LOBBY_ROCKS);}), @@ -447,6 +454,18 @@ void RegionTable_Init_DodongosCavern() { LOCATION(RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_3, logic->CanBreakPots()), LOCATION(RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_4, logic->CanBreakPots()), LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_HEART, logic->BlastOrSmash()), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_1, logic->BlastOrSmash() && logic->TakeDamage()), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_2, logic->BlastOrSmash() && logic->TakeDamage()), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_3, logic->BlastOrSmash() && logic->TakeDamage()), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_4, logic->BlastOrSmash() && logic->TakeDamage()), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_5, logic->BlastOrSmash()), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_6, logic->BlastOrSmash()), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_7, logic->BlastOrSmash() && logic->TakeDamage()), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_8, logic->BlastOrSmash() && logic->TakeDamage()), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_9, logic->BlastOrSmash() && logic->TakeDamage()), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_10, logic->BlastOrSmash() && logic->TakeDamage()), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_11, logic->BlastOrSmash() && logic->TakeDamage()), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_12, logic->BlastOrSmash() && logic->TakeDamage()), }, { //Exits //Falling down gets you stuck with nothing there, not a useful exit for logic @@ -460,6 +479,7 @@ void RegionTable_Init_DodongosCavern() { LOCATION(RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_2, logic->CanBreakPots()), LOCATION(RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_CRATE_1, logic->CanBreakCrates()), LOCATION(RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_CRATE_2, logic->CanBreakCrates()), + LOCATION(RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_BOULDER, logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET)), }, { //Exits Entrance(RR_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS, []{return true;}), @@ -488,6 +508,8 @@ void RegionTable_Init_DodongosCavern() { LOCATION(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_2, logic->CanBreakPots()), LOCATION(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_3, logic->CanBreakPots()), LOCATION(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_4, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_1, logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET) || logic->CanUse(RG_DINS_FIRE)), + LOCATION(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_2, logic->CanDetonateBombFlowers() || logic->HasItem(RG_GORONS_BRACELET) || (ctx->GetTrickOption(RT_BLUE_FIRE_MUD_WALLS) && logic->CanUse(RG_BOTTLE_WITH_BLUE_FIRE) && (logic->EffectiveHealth() != 1 || logic->CanUse(RG_NAYRUS_LOVE)))), }, { //Exits Entrance(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/jabujabus_belly.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/jabujabus_belly.cpp index 55357d5831a..ff3d4475ff1 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/jabujabus_belly.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/jabujabus_belly.cpp @@ -177,6 +177,7 @@ void RegionTable_Init_JabuJabusBelly() { LOCATION(RC_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_2, logic->CanBreakPots()), LOCATION(RC_JABU_JABUS_BELLY_MQ_FIRST_GRASS_1, logic->CanCutShrubs()), LOCATION(RC_JABU_JABUS_BELLY_MQ_FIRST_GRASS_2, logic->CanCutShrubs()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_ENTRANCE_BOULDER, logic->BlastOrSmash()), }, { //Exits Entrance(RR_JABU_JABUS_BELLY_ENTRYWAY, []{return true;}), @@ -229,6 +230,11 @@ void RegionTable_Init_JabuJabusBelly() { LOCATION(RC_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_1, logic->CanCutShrubs()), LOCATION(RC_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_2, logic->CanCutShrubs()), LOCATION(RC_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_3, logic->CanCutShrubs()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_1, logic->BlastOrSmash()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_2, logic->BlastOrSmash()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_1, logic->HasExplosives()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_2, logic->HasExplosives()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_3, logic->HasExplosives()), }, { //Exits Entrance(RR_JABU_JABUS_BELLY_MQ_LIFT_ROOM, []{return true;}), @@ -267,6 +273,8 @@ void RegionTable_Init_JabuJabusBelly() { LOCATION(RC_JABU_JABUS_BELLY_MQ_FALLING_LIKE_LIKE_GRASS, logic->CanCutShrubs()), LOCATION(RC_JABU_JABUS_BELLY_MQ_TRIPLE_HALLWAY_SMALL_CRATE_1, logic->CanBreakSmallCrates()), LOCATION(RC_JABU_JABUS_BELLY_MQ_TRIPLE_HALLWAY_SMALL_CRATE_2, logic->CanBreakSmallCrates()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_1, logic->BlastOrSmash()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_2, logic->BlastOrSmash()), }, { //Exits Entrance(RR_JABU_JABUS_BELLY_MQ_HOLES_ROOM, []{return logic->CanUse(RG_BOOMERANG);}), @@ -280,6 +288,8 @@ void RegionTable_Init_JabuJabusBelly() { }, { //Locations LOCATION(RC_JABU_JABUS_BELLY_MQ_GS_TAILPASARAN_ROOM, Here(RR_JABU_JABUS_BELLY_MQ_WEST_FORKED_ROOMS, []{return logic->HasExplosives();}) && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_BOULDER, logic->BlastOrSmash()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_WALL_BOULDER, logic->HasExplosives()), }, { //Exits Entrance(RR_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp index c49cd7a2d3e..33d8716f144 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp @@ -162,6 +162,10 @@ void RegionTable_Init_SpiritTemple() { LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_2, logic->CanBreakPots()), LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_3, logic->CanBreakPots()), LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_4, logic->CanBreakPots()), + LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_1, logic->BlastOrSmash()), + LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_2, logic->BlastOrSmash()), + LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_3, logic->BlastOrSmash()), + LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_CEILING_BOULDER, logic->CanUse(RG_BOMBCHU_5)), }, { //Exits Entrance(RR_SPIRIT_TEMPLE_ENTRYWAY, []{return true;}), @@ -179,6 +183,7 @@ void RegionTable_Init_SpiritTemple() { LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_SLUGMA_POT, logic->CanBreakPots()), LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_LEFT_HEART, logic->CanHitEyeTargets()), LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_RIGHT_HEART, logic->CanHitEyeTargets()), + LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_HAMMER_SWITCH_CHEST, logic->Get(LOGIC_SPIRIT_MQ_TIME_TRAVEL_CHEST)), }, { //Exits Entrance(RR_SPIRIT_TEMPLE_MQ_1F_GIBDO_ROOM_SOUTH, []{return Here(RR_SPIRIT_TEMPLE_MQ_1F_WEST, []{return logic->CanKillEnemy(RE_TORCH_SLUG);});}), @@ -394,6 +399,7 @@ void RegionTable_Init_SpiritTemple() { //Locations LOCATION(RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_1, logic->CanBreakPots()), LOCATION(RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_2, logic->CanBreakPots()), + LOCATION(RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_BOULDER, logic->BlastOrSmash()), }, { //Exits Entrance(RR_SPIRIT_TEMPLE_MQ_LOBBY, []{return logic->CanUse(RG_MEGATON_HAMMER);}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp index 09ae6443f06..02b24d9c316 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp @@ -29,6 +29,10 @@ void RegionTable_Init_CastleGrounds() { LOCATION(RC_HC_MALON_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_HC_ROCK_WALL_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), LOCATION(RC_HC_ROCK_WALL_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_HC_ROCK_1, true), + LOCATION(RC_HC_ROCK_2, true), + LOCATION(RC_HC_ROCK_3, true), + LOCATION(RC_HC_BOULDER, logic->BlastOrSmash()), LOCATION(RC_HC_MALON_GOSSIP_STONE, true), LOCATION(RC_HC_ROCK_WALL_GOSSIP_STONE, true), LOCATION(RC_HC_GRASS_1, logic->CanCutShrubs()), @@ -92,6 +96,14 @@ void RegionTable_Init_CastleGrounds() { LOCATION(RC_HC_STORMS_GROTTO_POT_2, logic->CanBreakPots()), LOCATION(RC_HC_STORMS_GROTTO_POT_3, logic->CanBreakPots()), LOCATION(RC_HC_STORMS_GROTTO_POT_4, logic->CanBreakPots()), + LOCATION(RC_HC_STORMS_GROTTO_ROCK_1, true), + LOCATION(RC_HC_STORMS_GROTTO_ROCK_2, true), + LOCATION(RC_HC_STORMS_GROTTO_ROCK_3, true), + LOCATION(RC_HC_STORMS_GROTTO_ROCK_4, true), + LOCATION(RC_HC_STORMS_GROTTO_ROCK_5, true), + LOCATION(RC_HC_STORMS_GROTTO_ROCK_6, true), + LOCATION(RC_HC_STORMS_GROTTO_ROCK_7, true), + LOCATION(RC_HC_STORMS_GROTTO_ROCK_8, true), }, { //Exits Entrance(RR_HC_STORMS_GROTTO, []{return true;}), @@ -102,7 +114,14 @@ void RegionTable_Init_CastleGrounds() { EventAccess(LOGIC_BUILD_RAINBOW_BRIDGE, []{return logic->CanBuildRainbowBridge();}), }, { //Locations - LOCATION(RC_OGC_GS, logic->CanJumpslashExceptHammer() || logic->CanUseProjectile() || (logic->CanShield() && logic->CanUse(RG_MEGATON_HAMMER)) || logic->CanUse(RG_DINS_FIRE)), + LOCATION(RC_OGC_GS, logic->CanJumpslashExceptHammer() || logic->CanUseProjectile() || (logic->CanShield() && logic->CanUse(RG_MEGATON_HAMMER)) || logic->CanUse(RG_DINS_FIRE)), + LOCATION(RC_OGC_BRONZE_BOULDER_1, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_OGC_BRONZE_BOULDER_2, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_OGC_BRONZE_BOULDER_3, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_OGC_SILVER_BOULDER_1, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_OGC_SILVER_BOULDER_2, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_OGC_SILVER_BOULDER_3, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_OGC_SILVER_BOULDER_4, logic->CanUse(RG_SILVER_GAUNTLETS)), }, { //Exits Entrance(RR_CASTLE_GROUNDS, []{return logic->AtNight;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_crater.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_crater.cpp index 89b12ca2689..9114e9f961d 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_crater.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_crater.cpp @@ -5,7 +5,21 @@ using namespace Rando; void RegionTable_Init_DeathMountainCrater() { // clang-format off - areaTable[RR_DMC_UPPER_NEARBY] = Region("DMC Upper Nearby", SCENE_DEATH_MOUNTAIN_CRATER, {}, {}, { + areaTable[RR_DMC_UPPER_NEARBY] = Region("DMC Upper Nearby", SCENE_DEATH_MOUNTAIN_CRATER, {}, { + LOCATION(RC_DMC_CIRCLE_ROCK_1, true), + LOCATION(RC_DMC_CIRCLE_ROCK_2, true), + LOCATION(RC_DMC_CIRCLE_ROCK_3, true), + LOCATION(RC_DMC_CIRCLE_ROCK_4, true), + LOCATION(RC_DMC_CIRCLE_ROCK_5, true), + LOCATION(RC_DMC_CIRCLE_ROCK_6, true), + LOCATION(RC_DMC_CIRCLE_ROCK_7, true), + LOCATION(RC_DMC_CIRCLE_ROCK_8, true), + LOCATION(RC_DMC_GOSSIP_ROCK_1, logic->IsChild), + LOCATION(RC_DMC_GOSSIP_ROCK_2, logic->IsChild), + LOCATION(RC_DMC_BOULDER_1, logic->BlastOrSmash()), + LOCATION(RC_DMC_BOULDER_2, logic->BlastOrSmash()), + LOCATION(RC_DMC_BOULDER_3, logic->BlastOrSmash()), + }, { //Exits Entrance(RR_DMC_UPPER_LOCAL, []{return logic->FireTimer() >= 48;}), Entrance(RR_DEATH_MOUNTAIN_SUMMIT, []{return true;}), @@ -48,6 +62,14 @@ void RegionTable_Init_DeathMountainCrater() { LOCATION(RC_DMC_NEAR_GC_POT_2, logic->CanBreakPots()), LOCATION(RC_DMC_NEAR_GC_POT_3, logic->CanBreakPots()), LOCATION(RC_DMC_NEAR_GC_POT_4, logic->CanBreakPots()), + LOCATION(RC_DMC_NEAR_GC_POT_1, logic->CanBreakPots()), + LOCATION(RC_DMC_NEAR_GC_POT_2, logic->CanBreakPots()), + LOCATION(RC_DMC_NEAR_GC_POT_3, logic->CanBreakPots()), + LOCATION(RC_DMC_NEAR_GC_POT_4, logic->CanBreakPots()), + LOCATION(RC_DMC_BRONZE_BOULDER_1, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMC_BRONZE_BOULDER_2, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMC_BRONZE_BOULDER_3, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMC_BRONZE_BOULDER_4, logic->CanUse(RG_MEGATON_HAMMER)), }, { //Exits Entrance(RR_DMC_LOWER_LOCAL, []{return logic->FireTimer() >= 48;}), @@ -90,6 +112,11 @@ void RegionTable_Init_DeathMountainCrater() { LOCATION(RC_DMC_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), LOCATION(RC_DMC_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), LOCATION(RC_DMC_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), + LOCATION(RC_DMC_ROCK_BY_FIRE_TEMPLE_1, logic->IsAdult), + LOCATION(RC_DMC_ROCK_BY_FIRE_TEMPLE_2, logic->IsAdult), + LOCATION(RC_DMC_ROCK_BY_FIRE_TEMPLE_3, logic->IsAdult), + LOCATION(RC_DMC_ROCK_BY_FIRE_TEMPLE_4, logic->IsAdult), + LOCATION(RC_DMC_ROCK_BY_FIRE_TEMPLE_5, logic->IsAdult), }, { //Exits Entrance(RR_DMC_CENTRAL_NEARBY, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_trail.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_trail.cpp index e166842d64c..693cd966686 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_trail.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_trail.cpp @@ -21,6 +21,33 @@ void RegionTable_Init_DeathMountainTrail() { LOCATION(RC_DMT_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET))), LOCATION(RC_DMT_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET))), LOCATION(RC_DMT_FLAG_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)), + LOCATION(RC_DMT_ROCK_1, true), + LOCATION(RC_DMT_ROCK_2, true), + LOCATION(RC_DMT_ROCK_3, true), + LOCATION(RC_DMT_ROCK_4, true), + LOCATION(RC_DMT_ROCK_5, true), + LOCATION(RC_DMT_CIRCLE_ROCK_1, true), + LOCATION(RC_DMT_CIRCLE_ROCK_2, true), + LOCATION(RC_DMT_CIRCLE_ROCK_3, true), + LOCATION(RC_DMT_CIRCLE_ROCK_4, true), + LOCATION(RC_DMT_CIRCLE_ROCK_5, true), + LOCATION(RC_DMT_CIRCLE_ROCK_6, true), + LOCATION(RC_DMT_CIRCLE_ROCK_7, true), + LOCATION(RC_DMT_CIRCLE_ROCK_8, true), + LOCATION(RC_DMT_BOULDER_1, logic->BlastOrSmash()), + LOCATION(RC_DMT_BOULDER_2, logic->BlastOrSmash()), + LOCATION(RC_DMT_BOULDER_3, logic->IsChild && logic->BlastOrSmash()), + LOCATION(RC_DMT_BRONZE_BOULDER_1, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMT_BRONZE_BOULDER_2, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMT_BRONZE_BOULDER_3, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMT_BRONZE_BOULDER_4, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMT_BRONZE_BOULDER_5, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMT_BRONZE_BOULDER_6, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMT_BRONZE_BOULDER_7, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMT_BRONZE_BOULDER_8, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMT_BRONZE_BOULDER_9, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMT_BRONZE_BOULDER_10, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMT_BRONZE_BOULDER_11, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), }, { //Exits Entrance(RR_KAK_BEHIND_GATE, []{return true;}), @@ -42,6 +69,8 @@ void RegionTable_Init_DeathMountainTrail() { LOCATION(RC_DMT_GS_FALLING_ROCKS_PATH, logic->IsAdult && logic->AtNight && (logic->CanUse(RG_MEGATON_HAMMER) || ctx->GetTrickOption(RT_DMT_UPPER_GS)) && logic->CanGetNightTimeGS()), LOCATION(RC_DMT_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), LOCATION(RC_DMT_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_DMT_COW_BOULDER, logic->BlastOrSmash()), + LOCATION(RC_DMT_SUMMIT_ROCK, logic->IsChild), LOCATION(RC_DMT_GOSSIP_STONE, true), }, { //Exits diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/desert_colossus.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/desert_colossus.cpp index 7af296dcb92..541f78c1d37 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/desert_colossus.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/desert_colossus.cpp @@ -20,6 +20,24 @@ void RegionTable_Init_DesertColossus() { LOCATION(RC_COLOSSUS_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DESERT_COLOSSUS_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_COLOSSUS_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), LOCATION(RC_COLOSSUS_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_COLOSSUS_SILVER_BOULDER, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_COLOSSUS_ROCK, true), + LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_1, true), + LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_2, true), + LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_3, true), + LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_4, true), + LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_5, true), + LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_6, true), + LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_7, true), + LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_8, true), + LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_1, true), + LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_2, true), + LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_3, true), + LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_4, true), + LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_5, true), + LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_6, true), + LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_7, true), + LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_8, true), LOCATION(RC_COLOSSUS_GOSSIP_STONE, true), }, { //Exits diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp index 3a054692536..60488f92dc6 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp @@ -10,7 +10,17 @@ void RegionTable_Init_GerudoValley() { EventAccess(LOGIC_BUG_ROCK, []{return logic->IsChild;}), }, { //Locations - LOCATION(RC_GV_GS_SMALL_BRIDGE, logic->IsChild && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), + LOCATION(RC_GV_GS_SMALL_BRIDGE, logic->IsChild && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), + LOCATION(RC_GV_ROCK_1, true), + LOCATION(RC_GV_ROCK_2, true), + LOCATION(RC_GV_ROCK_3, true), + LOCATION(RC_GV_UNDERWATER_ROCK_1, logic->IsAdult || logic->CanUse(RG_BOMBCHU_5)), + LOCATION(RC_GV_UNDERWATER_ROCK_2, logic->IsAdult || logic->CanUse(RG_BOMBCHU_5)), + LOCATION(RC_GV_UNDERWATER_ROCK_3, logic->IsAdult || logic->CanUse(RG_BOMBCHU_5)), + LOCATION(RC_GV_BOULDER_1, logic->IsAdult && logic->BlastOrSmash()), + LOCATION(RC_GV_BOULDER_2, logic->IsAdult && logic->BlastOrSmash()), + LOCATION(RC_GV_BRONZE_BOULDER_1, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GV_BRONZE_BOULDER_2, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), }, { //Exits Entrance(RR_HYRULE_FIELD, []{return true;}), @@ -48,7 +58,10 @@ void RegionTable_Init_GerudoValley() { Entrance(RR_LAKE_HYLIA, []{return true;}), }); - areaTable[RR_GV_GROTTO_LEDGE] = Region("GV Grotto Ledge", SCENE_GERUDO_VALLEY, {}, {}, { + areaTable[RR_GV_GROTTO_LEDGE] = Region("GV Grotto Ledge", SCENE_GERUDO_VALLEY, {}, { + //Locations + LOCATION(RC_GV_SILVER_BOULDER, logic->CanUse(RG_SILVER_GAUNTLETS)), + }, { //Exits Entrance(RR_GV_UPPER_STREAM, []{return ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives();}), Entrance(RR_GV_LOWER_STREAM, []{return logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS);}), @@ -68,14 +81,25 @@ void RegionTable_Init_GerudoValley() { areaTable[RR_GV_FORTRESS_SIDE] = Region("GV Fortress Side", SCENE_GERUDO_VALLEY, {}, { //Locations - LOCATION(RC_GV_CHEST, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER) && logic->HasItem(RG_OPEN_CHEST)), - LOCATION(RC_GV_TRADE_SAW, logic->IsAdult && logic->CanUse(RG_POACHERS_SAW)), - LOCATION(RC_GV_GS_BEHIND_TENT, logic->IsAdult && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), - LOCATION(RC_GV_GS_PILLAR, logic->IsAdult && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), - LOCATION(RC_GV_CRATE_BRIDGE_1, logic->IsChild && logic->CanBreakCrates()), - LOCATION(RC_GV_CRATE_BRIDGE_2, logic->IsChild && logic->CanBreakCrates()), - LOCATION(RC_GV_CRATE_BRIDGE_3, logic->IsChild && logic->CanBreakCrates()), - LOCATION(RC_GV_CRATE_BRIDGE_4, logic->IsChild && logic->CanBreakCrates()), + LOCATION(RC_GV_CHEST, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GV_TRADE_SAW, logic->IsAdult && logic->CanUse(RG_POACHERS_SAW)), + LOCATION(RC_GV_GS_BEHIND_TENT, logic->IsAdult && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), + LOCATION(RC_GV_GS_PILLAR, logic->IsAdult && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), + LOCATION(RC_GV_CRATE_BRIDGE_1, logic->IsChild && logic->CanBreakCrates()), + LOCATION(RC_GV_CRATE_BRIDGE_2, logic->IsChild && logic->CanBreakCrates()), + LOCATION(RC_GV_CRATE_BRIDGE_3, logic->IsChild && logic->CanBreakCrates()), + LOCATION(RC_GV_CRATE_BRIDGE_4, logic->IsChild && logic->CanBreakCrates()), + LOCATION(RC_GV_ROCK_ACROSS_BRIDGE_1, logic->IsAdult), + LOCATION(RC_GV_ROCK_ACROSS_BRIDGE_2, logic->IsAdult), + LOCATION(RC_GV_ROCK_ACROSS_BRIDGE_3, logic->IsAdult), + LOCATION(RC_GV_ROCK_ACROSS_BRIDGE_4, logic->IsAdult), + LOCATION(RC_GV_BOULDER_ACROSS_BRIDGE, logic->IsAdult && logic->BlastOrSmash()), + LOCATION(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_1, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_2, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_3, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_4, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_5, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_6, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), }, { //Exits Entrance(RR_GF_OUTSKIRTS, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/goron_city.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/goron_city.cpp index 107106239a3..c98c2724ee0 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/goron_city.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/goron_city.cpp @@ -36,7 +36,57 @@ void RegionTable_Init_GoronCity() { LOCATION(RC_GC_UPPER_STAIRCASE_POT_2, logic->CanBreakPots()), LOCATION(RC_GC_UPPER_STAIRCASE_POT_3, logic->CanBreakPots()), LOCATION(RC_GC_MAZE_CRATE, logic->BlastOrSmash() || (logic->CanUse(RG_SILVER_GAUNTLETS) && logic->CanBreakCrates())), - + LOCATION(RC_GC_ENTRANCE_BOULDER_1, logic->BlastOrSmash()), + LOCATION(RC_GC_ENTRANCE_BOULDER_2, logic->BlastOrSmash()), + LOCATION(RC_GC_ENTRANCE_BOULDER_3, logic->BlastOrSmash()), + LOCATION(RC_GC_LW_BOULDER_1, logic->Get(LOGIC_GORON_CITY_WOODS_WARP_OPEN)), + LOCATION(RC_GC_LW_BOULDER_2, logic->Get(LOGIC_GORON_CITY_WOODS_WARP_OPEN)), + LOCATION(RC_GC_LW_BOULDER_3, logic->Get(LOGIC_GORON_CITY_WOODS_WARP_OPEN)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_1, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_2, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_3, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_4, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_5, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_6, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_7, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_8, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_9, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_10, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_11, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_12, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_13, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_14, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_15, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_16, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_17, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_18, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_19, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_20, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_21, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_22, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_23, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_24, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_25, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_26, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_27, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_28, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_29, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_BOULDER_1, logic->BlastOrSmash()), + LOCATION(RC_GC_MAZE_BOULDER_2, logic->BlastOrSmash()), + LOCATION(RC_GC_MAZE_BOULDER_3, logic->BlastOrSmash()), + LOCATION(RC_GC_MAZE_BOULDER_4, logic->BlastOrSmash()), + LOCATION(RC_GC_MAZE_BOULDER_5, logic->BlastOrSmash()), + LOCATION(RC_GC_MAZE_BOULDER_6, logic->BlastOrSmash()), + LOCATION(RC_GC_MAZE_BOULDER_7, logic->BlastOrSmash()), + LOCATION(RC_GC_MAZE_BOULDER_8, logic->BlastOrSmash()), + LOCATION(RC_GC_MAZE_BOULDER_9, logic->BlastOrSmash()), + LOCATION(RC_GC_MAZE_BOULDER_10, logic->BlastOrSmash()), + LOCATION(RC_GC_MAZE_BRONZE_BOULDER_1, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GC_MAZE_BRONZE_BOULDER_2, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GC_MAZE_BRONZE_BOULDER_3, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GC_MAZE_BRONZE_BOULDER_4, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GC_MAZE_BRONZE_BOULDER_5, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GC_MAZE_ROCK, logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)), }, { //Exits Entrance(RR_DEATH_MOUNTAIN_TRAIL, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp index 95046874fd0..56b76878ca2 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp @@ -33,6 +33,7 @@ void RegionTable_Init_Graveyard() { LOCATION(RC_GY_GRASS_11, logic->CanCutShrubs()), LOCATION(RC_GY_GRASS_12, logic->CanCutShrubs()), LOCATION(RC_GRAVEYARD_CRATE, ((logic->IsAdult && CanPlantBean(RR_THE_GRAVEYARD, RG_GRAVEYARD_BEAN_SOUL)) || logic->CanUse(RG_LONGSHOT)) && logic->CanBreakCrates()), + LOCATION(RC_GY_ROCK, true), }, { //Exits Entrance(RR_GRAVEYARD_SHIELD_GRAVE, []{return logic->IsAdult || logic->AtNight;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp index d8722fa8681..e7a26b658db 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp @@ -110,6 +110,22 @@ void RegionTable_Init_HyruleField() { LOCATION(RC_HF_CHILD_SOUTHEAST_TREE_5, logic->IsChild && logic->CanBonkTrees()), LOCATION(RC_HF_CHILD_SOUTHEAST_TREE_6, logic->IsChild && logic->CanBonkTrees()), LOCATION(RC_HF_TEKTITE_GROTTO_TREE, logic->CanBonkTrees()), + LOCATION(RC_HF_SILVER_BOULDER, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_HF_ROCK_1, true), + LOCATION(RC_HF_ROCK_2, true), + LOCATION(RC_HF_ROCK_3, true), + LOCATION(RC_HF_ROCK_4, true), + LOCATION(RC_HF_ROCK_5, true), + LOCATION(RC_HF_ROCK_6, true), + LOCATION(RC_HF_ROCK_7, true), + LOCATION(RC_HF_ROCK_8, true), + LOCATION(RC_HF_BOULDER_NORTH, logic->BlastOrSmash()), + LOCATION(RC_HF_BOULDER_BY_MARKET, logic->BlastOrSmash()), + LOCATION(RC_HF_BOULDER_SOUTH, logic->BlastOrSmash()), + LOCATION(RC_HF_BRONZE_BOULDER_1, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_HF_BRONZE_BOULDER_2, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_HF_BRONZE_BOULDER_3, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_HF_BRONZE_BOULDER_4, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), LOCATION(RC_HF_BUSH_NEAR_LAKE_1, true), LOCATION(RC_HF_BUSH_NEAR_LAKE_2, true), LOCATION(RC_HF_BUSH_NEAR_LAKE_3, true), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp index 53a36dfb589..8826007136c 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp @@ -60,6 +60,9 @@ void RegionTable_Init_Kakariko() { LOCATION(RC_KAK_NEAR_BOARDING_HOUSE_CHILD_CRATE, logic->IsChild && logic->CanBreakCrates()), LOCATION(RC_KAK_NEAR_BAZAAR_CHILD_CRATE, logic->IsChild && logic->CanBreakCrates()), LOCATION(RC_KAK_TREE, logic->CanBonkTrees()), + LOCATION(RC_KAK_SILVER_BOULDER, logic->IsAdult && logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_KAK_ROCK_1, true), + LOCATION(RC_KAK_ROCK_2, true), }, { //Exits Entrance(RR_HYRULE_FIELD, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp index eea1b42e2b9..48780ed4eae 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp @@ -75,6 +75,18 @@ void RegionTable_Init_KokiriForest() { LOCATION(RC_KF_ADULT_GRASS_18, logic->IsAdult && logic->CanCutShrubs()), LOCATION(RC_KF_ADULT_GRASS_19, logic->IsAdult && logic->CanCutShrubs()), LOCATION(RC_KF_ADULT_GRASS_20, logic->IsAdult && logic->CanCutShrubs()), + LOCATION(RC_KF_CIRCLE_ROCK_1, true), + LOCATION(RC_KF_CIRCLE_ROCK_2, true), + LOCATION(RC_KF_CIRCLE_ROCK_3, true), + LOCATION(RC_KF_CIRCLE_ROCK_4, true), + LOCATION(RC_KF_CIRCLE_ROCK_5, true), + LOCATION(RC_KF_CIRCLE_ROCK_6, true), + LOCATION(RC_KF_CIRCLE_ROCK_7, true), + LOCATION(RC_KF_CIRCLE_ROCK_8, true), + LOCATION(RC_KF_ROCK_BY_SARIAS_HOUSE, logic->IsChild), + LOCATION(RC_KF_ROCK_BEHIND_SARIAS_HOUSE, logic->IsChild), + LOCATION(RC_KF_ROCK_BY_MIDOS_HOUSE, logic->IsChild), + LOCATION(RC_KF_ROCK_BY_KNOW_IT_ALLS_HOUSE, logic->IsChild), }, { //Exits Entrance(RR_KF_LINKS_HOUSE, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp index 85a897e49ce..9367ca31e1c 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp @@ -104,7 +104,10 @@ void RegionTable_Init_LakeHylia() { Entrance(RR_WATER_TEMPLE_ENTRYWAY, []{return logic->CanUse(RG_HOOKSHOT) && ((logic->CanUse(RG_IRON_BOOTS) || (ctx->GetTrickOption(RT_LH_WATER_HOOKSHOT) && logic->HasItem(RG_GOLDEN_SCALE))) || (logic->IsAdult && logic->CanUse(RG_LONGSHOT) && logic->HasItem(RG_GOLDEN_SCALE)));}), }); - areaTable[RR_LH_FISHING_ISLAND] = Region("LH Fishing Island", SCENE_LAKE_HYLIA, {}, {}, { + areaTable[RR_LH_FISHING_ISLAND] = Region("LH Fishing Island", SCENE_LAKE_HYLIA, {}, { + //Locations + LOCATION(RC_LA_ROCK, true), + }, { //Exits Entrance(RR_LAKE_HYLIA, []{return logic->HasItem(RG_BRONZE_SCALE);}), Entrance(RR_LH_FISHING_POND, []{return logic->CanOpenOverworldDoor(RG_FISHING_HOLE_KEY);}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/lost_woods.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/lost_woods.cpp index 20fc86e42bf..a573e45196b 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/lost_woods.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/lost_woods.cpp @@ -49,6 +49,7 @@ void RegionTable_Init_LostWoods() { LOCATION(RC_LW_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()), LOCATION(RC_LW_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_LW_SHORTCUT_STORMS_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_LW_BOULDER_BY_GORON_CITY, logic->BlastOrSmash()), LOCATION(RC_LW_GOSSIP_STONE, true), LOCATION(RC_LW_GRASS_1, logic->CanCutShrubs()), LOCATION(RC_LW_GRASS_2, logic->CanCutShrubs()), @@ -83,6 +84,8 @@ void RegionTable_Init_LostWoods() { LOCATION(RC_LW_GRASS_7, logic->CanCutShrubs()), LOCATION(RC_LW_GRASS_8, logic->CanCutShrubs()), LOCATION(RC_LW_GRASS_9, logic->CanCutShrubs()), + LOCATION(RC_LW_BOULDER_BY_SACRED_FOREST_MEADOW, logic->BlastOrSmash()), + LOCATION(RC_LW_RUPEE_BOULDER, logic->BlastOrSmash()), }, { //Exits Entrance(RR_LW_FOREST_EXIT, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp index 1c6d822e4b8..8f8fa96dbd0 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp @@ -35,6 +35,14 @@ void RegionTable_Init_ZorasDomain() { LOCATION(RC_ZD_NEAR_SHOP_POT_3, logic->CanBreakPots()), LOCATION(RC_ZD_NEAR_SHOP_POT_4, logic->CanBreakPots()), LOCATION(RC_ZD_NEAR_SHOP_POT_5, logic->CanBreakPots()), + LOCATION(RC_ZD_CIRCLE_ROCK_1, true), + LOCATION(RC_ZD_CIRCLE_ROCK_2, true), + LOCATION(RC_ZD_CIRCLE_ROCK_3, true), + LOCATION(RC_ZD_CIRCLE_ROCK_4, true), + LOCATION(RC_ZD_CIRCLE_ROCK_5, true), + LOCATION(RC_ZD_CIRCLE_ROCK_6, true), + LOCATION(RC_ZD_CIRCLE_ROCK_7, true), + LOCATION(RC_ZD_CIRCLE_ROCK_8, true), }, { //Exits Entrance(RR_ZR_BEHIND_WATERFALL, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp index 20a22334245..09b23f4b62e 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp @@ -24,6 +24,9 @@ void RegionTable_Init_ZorasFountain() { 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_TREE, logic->IsChild && logic->CanBonkTrees()), + LOCATION(RC_ZF_BOULDER, logic->BlastOrSmash()), + LOCATION(RC_ZF_SILVER_BOULDER, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_ZF_UNDERGROUND_BOULDER, logic->CanUse(RG_SILVER_GAUNTLETS) && logic->BlastOrSmash()), LOCATION(RC_ZF_BUSH_1, logic->IsChild), LOCATION(RC_ZF_BUSH_2, logic->IsChild), LOCATION(RC_ZF_BUSH_3, logic->IsChild), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp index 9ef08c7904c..10226314dbb 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp @@ -7,20 +7,24 @@ void RegionTable_Init_ZoraRiver() { // clang-format off areaTable[RR_ZR_FRONT] = Region("ZR Front", SCENE_ZORAS_RIVER, {}, { //Locations - LOCATION(RC_ZR_GS_TREE, logic->IsChild && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_CLOSE) && logic->CanBonkTrees()), - LOCATION(RC_ZR_GRASS_1, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_2, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_3, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_4, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_5, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_6, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_7, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_8, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_9, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_10, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_11, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_12, logic->CanCutShrubs()), - LOCATION(RC_ZR_TREE, logic->IsChild && logic->CanBonkTrees()), + LOCATION(RC_ZR_GS_TREE, logic->IsChild && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_CLOSE) && logic->CanBonkTrees()), + LOCATION(RC_ZR_GRASS_1, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_2, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_3, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_4, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_5, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_6, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_7, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_8, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_9, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_10, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_11, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_12, logic->CanCutShrubs()), + LOCATION(RC_ZR_TREE, logic->IsChild && logic->CanBonkTrees()), + LOCATION(RC_ZR_BOULDER_1, logic->IsChild && logic->BlastOrSmash()), + LOCATION(RC_ZR_BOULDER_2, logic->IsChild && logic->BlastOrSmash()), + LOCATION(RC_ZR_BOULDER_3, logic->IsChild && logic->BlastOrSmash()), + LOCATION(RC_ZR_BOULDER_4, logic->IsChild && logic->BlastOrSmash()), }, { //Exits Entrance(RR_ZORAS_RIVER, []{return logic->IsAdult || logic->BlastOrSmash();}), @@ -56,6 +60,28 @@ void RegionTable_Init_ZoraRiver() { 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_CIRCLE_ROCK_1, true), + LOCATION(RC_ZR_CIRCLE_ROCK_2, true), + LOCATION(RC_ZR_CIRCLE_ROCK_3, true), + LOCATION(RC_ZR_CIRCLE_ROCK_4, true), + LOCATION(RC_ZR_CIRCLE_ROCK_5, true), + LOCATION(RC_ZR_CIRCLE_ROCK_6, true), + LOCATION(RC_ZR_CIRCLE_ROCK_7, true), + LOCATION(RC_ZR_CIRCLE_ROCK_8, true), + LOCATION(RC_ZR_UPPER_CIRCLE_BOULDER, logic->BlastOrSmash()), + LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_1, true), + LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_2, true), + LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_3, true), + LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_4, true), + LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_5, true), + LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_6, true), + LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_7, true), + LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_8, true), + LOCATION(RC_ZR_ROCK, true), + LOCATION(RC_ZR_UNDERWATER_ROCK_1, logic->IsAdult || logic->CanUse(RG_BOMBCHU_5)), + LOCATION(RC_ZR_UNDERWATER_ROCK_2, logic->IsAdult || logic->CanUse(RG_BOMBCHU_5)), + LOCATION(RC_ZR_UNDERWATER_ROCK_3, logic->IsAdult || logic->CanUse(RG_BOMBCHU_5)), + LOCATION(RC_ZR_UNDERWATER_ROCK_4, logic->IsAdult || logic->CanUse(RG_BOMBCHU_5)), LOCATION(RC_ZR_NEAR_DOMAIN_GOSSIP_STONE, true), LOCATION(RC_ZR_NEAR_FREESTANDING_POH_GRASS, logic->CanUse(RG_BOOMERANG)), }, { diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp index e08964e3900..d2fa19e6f53 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -507,6 +507,8 @@ void Settings::CreateOptionDescriptions() { "Overworld - Only shuffle grass/bushes that are outside of dungeons.\n" "\n" "All Grass/Bushes - Shuffle all grass/bushes."; + mOptionDescriptions[RSK_SHUFFLE_ROCKS] = "Shuffle rock locations."; + mOptionDescriptions[RSK_SHUFFLE_BOULDERS] = "Shuffle boulder locations."; mOptionDescriptions[RSK_SHUFFLE_DUNGEON_REWARDS] = "Shuffles the location of Spiritual Stones and medallions.\n" "Vanilla - Spiritual Stones and medallions will be given from their respective boss.\n" diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 539c6521230..0e29c695aaf 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -3422,6 +3422,286 @@ std::map rcToRandomizerInf = { { RC_ZR_TREE, RAND_INF_ZR_TREE }, { RC_KAK_TREE, RAND_INF_KAK_TREE }, { RC_LLR_TREE, RAND_INF_LLR_TREE }, + { RC_KF_CIRCLE_ROCK_1, RAND_INF_KF_CIRCLE_ROCK_1 }, + { RC_KF_CIRCLE_ROCK_2, RAND_INF_KF_CIRCLE_ROCK_2 }, + { RC_KF_CIRCLE_ROCK_3, RAND_INF_KF_CIRCLE_ROCK_3 }, + { RC_KF_CIRCLE_ROCK_4, RAND_INF_KF_CIRCLE_ROCK_4 }, + { RC_KF_CIRCLE_ROCK_5, RAND_INF_KF_CIRCLE_ROCK_5 }, + { RC_KF_CIRCLE_ROCK_6, RAND_INF_KF_CIRCLE_ROCK_6 }, + { RC_KF_CIRCLE_ROCK_7, RAND_INF_KF_CIRCLE_ROCK_7 }, + { RC_KF_CIRCLE_ROCK_8, RAND_INF_KF_CIRCLE_ROCK_8 }, + { RC_KF_ROCK_BY_SARIAS_HOUSE, RAND_INF_KF_ROCK_BY_SARIAS_HOUSE }, + { RC_KF_ROCK_BEHIND_SARIAS_HOUSE, RAND_INF_KF_ROCK_BEHIND_SARIAS_HOUSE }, + { RC_KF_ROCK_BY_MIDOS_HOUSE, RAND_INF_KF_ROCK_BY_MIDOS_HOUSE }, + { RC_KF_ROCK_BY_KNOW_IT_ALLS_HOUSE, RAND_INF_KF_ROCK_BY_KNOW_IT_ALLS_HOUSE }, + { RC_LW_BOULDER_BY_GORON_CITY, RAND_INF_LW_BOULDER_BY_GORON_CITY }, + { RC_LW_BOULDER_BY_SACRED_FOREST_MEADOW, RAND_INF_LW_BOULDER_BY_SACRED_FOREST_MEADOW }, + { RC_LW_RUPEE_BOULDER, RAND_INF_LW_RUPEE_BOULDER }, + { RC_HC_ROCK_1, RAND_INF_HC_ROCK_1 }, + { RC_HC_ROCK_2, RAND_INF_HC_ROCK_2 }, + { RC_HC_ROCK_3, RAND_INF_HC_ROCK_3 }, + { RC_HC_BOULDER, RAND_INF_HC_BOULDER }, + { RC_OGC_BRONZE_BOULDER_1, RAND_INF_OGC_BRONZE_BOULDER_1 }, + { RC_OGC_BRONZE_BOULDER_2, RAND_INF_OGC_BRONZE_BOULDER_2 }, + { RC_OGC_BRONZE_BOULDER_3, RAND_INF_OGC_BRONZE_BOULDER_3 }, + { RC_OGC_SILVER_BOULDER_1, RAND_INF_OGC_SILVER_BOULDER_1 }, + { RC_OGC_SILVER_BOULDER_2, RAND_INF_OGC_SILVER_BOULDER_2 }, + { RC_OGC_SILVER_BOULDER_3, RAND_INF_OGC_SILVER_BOULDER_3 }, + { RC_OGC_SILVER_BOULDER_4, RAND_INF_OGC_SILVER_BOULDER_4 }, + { RC_DMC_CIRCLE_ROCK_1, RAND_INF_DMC_CIRCLE_ROCK_1 }, + { RC_DMC_CIRCLE_ROCK_2, RAND_INF_DMC_CIRCLE_ROCK_2 }, + { RC_DMC_CIRCLE_ROCK_3, RAND_INF_DMC_CIRCLE_ROCK_3 }, + { RC_DMC_CIRCLE_ROCK_4, RAND_INF_DMC_CIRCLE_ROCK_4 }, + { RC_DMC_CIRCLE_ROCK_5, RAND_INF_DMC_CIRCLE_ROCK_5 }, + { RC_DMC_CIRCLE_ROCK_6, RAND_INF_DMC_CIRCLE_ROCK_6 }, + { RC_DMC_CIRCLE_ROCK_7, RAND_INF_DMC_CIRCLE_ROCK_7 }, + { RC_DMC_CIRCLE_ROCK_8, RAND_INF_DMC_CIRCLE_ROCK_8 }, + { RC_DMC_ROCK_BY_FIRE_TEMPLE_1, RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_1 }, + { RC_DMC_ROCK_BY_FIRE_TEMPLE_2, RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_2 }, + { RC_DMC_ROCK_BY_FIRE_TEMPLE_3, RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_3 }, + { RC_DMC_ROCK_BY_FIRE_TEMPLE_4, RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_4 }, + { RC_DMC_ROCK_BY_FIRE_TEMPLE_5, RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_5 }, + { RC_DMC_GOSSIP_ROCK_1, RAND_INF_DMC_GOSSIP_ROCK_1 }, + { RC_DMC_GOSSIP_ROCK_2, RAND_INF_DMC_GOSSIP_ROCK_2 }, + { RC_DMC_BOULDER_1, RAND_INF_DMC_BOULDER_1 }, + { RC_DMC_BOULDER_2, RAND_INF_DMC_BOULDER_2 }, + { RC_DMC_BOULDER_3, RAND_INF_DMC_BOULDER_3 }, + { RC_DMC_BRONZE_BOULDER_1, RAND_INF_DMC_BRONZE_BOULDER_1 }, + { RC_DMC_BRONZE_BOULDER_2, RAND_INF_DMC_BRONZE_BOULDER_2 }, + { RC_DMC_BRONZE_BOULDER_3, RAND_INF_DMC_BRONZE_BOULDER_3 }, + { RC_DMC_BRONZE_BOULDER_4, RAND_INF_DMC_BRONZE_BOULDER_4 }, + { RC_GV_SILVER_BOULDER, RAND_INF_GV_SILVER_BOULDER }, + { RC_GV_ROCK_1, RAND_INF_GV_ROCK_1 }, + { RC_GV_ROCK_2, RAND_INF_GV_ROCK_2 }, + { RC_GV_ROCK_3, RAND_INF_GV_ROCK_3 }, + { RC_GV_UNDERWATER_ROCK_1, RAND_INF_GV_UNDERWATER_ROCK_1 }, + { RC_GV_UNDERWATER_ROCK_2, RAND_INF_GV_UNDERWATER_ROCK_2 }, + { RC_GV_UNDERWATER_ROCK_3, RAND_INF_GV_UNDERWATER_ROCK_3 }, + { RC_GV_ROCK_ACROSS_BRIDGE_1, RAND_INF_GV_ROCK_ACROSS_BRIDGE_1 }, + { RC_GV_ROCK_ACROSS_BRIDGE_2, RAND_INF_GV_ROCK_ACROSS_BRIDGE_2 }, + { RC_GV_ROCK_ACROSS_BRIDGE_3, RAND_INF_GV_ROCK_ACROSS_BRIDGE_3 }, + { RC_GV_ROCK_ACROSS_BRIDGE_4, RAND_INF_GV_ROCK_ACROSS_BRIDGE_4 }, + { RC_GV_BOULDER_1, RAND_INF_GV_BOULDER_1 }, + { RC_GV_BOULDER_2, RAND_INF_GV_BOULDER_2 }, + { RC_GV_BOULDER_ACROSS_BRIDGE, RAND_INF_GV_BOULDER_ACROSS_BRIDGE }, + { RC_GV_BRONZE_BOULDER_1, RAND_INF_GV_BRONZE_BOULDER_1 }, + { RC_GV_BRONZE_BOULDER_2, RAND_INF_GV_BRONZE_BOULDER_2 }, + { RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_1, RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_1 }, + { RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_2, RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_2 }, + { RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_3, RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_3 }, + { RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_4, RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_4 }, + { RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_5, RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_5 }, + { RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_6, RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_6 }, + { RC_HF_SILVER_BOULDER, RAND_INF_HF_SILVER_BOULDER }, + { RC_HF_ROCK_1, RAND_INF_HF_ROCK_1 }, + { RC_HF_ROCK_2, RAND_INF_HF_ROCK_2 }, + { RC_HF_ROCK_3, RAND_INF_HF_ROCK_3 }, + { RC_HF_ROCK_4, RAND_INF_HF_ROCK_4 }, + { RC_HF_ROCK_5, RAND_INF_HF_ROCK_5 }, + { RC_HF_ROCK_6, RAND_INF_HF_ROCK_6 }, + { RC_HF_ROCK_7, RAND_INF_HF_ROCK_7 }, + { RC_HF_ROCK_8, RAND_INF_HF_ROCK_8 }, + { RC_HF_BOULDER_NORTH, RAND_INF_HF_BOULDER_NORTH }, + { RC_HF_BOULDER_BY_MARKET, RAND_INF_HF_BOULDER_BY_MARKET }, + { RC_HF_BOULDER_SOUTH, RAND_INF_HF_BOULDER_SOUTH }, + { RC_HF_BRONZE_BOULDER_1, RAND_INF_HF_BRONZE_BOULDER_1 }, + { RC_HF_BRONZE_BOULDER_2, RAND_INF_HF_BRONZE_BOULDER_2 }, + { RC_HF_BRONZE_BOULDER_3, RAND_INF_HF_BRONZE_BOULDER_3 }, + { RC_HF_BRONZE_BOULDER_4, RAND_INF_HF_BRONZE_BOULDER_4 }, + { RC_KAK_SILVER_BOULDER, RAND_INF_KAK_SILVER_BOULDER }, + { RC_KAK_ROCK_1, RAND_INF_KAK_ROCK_1 }, + { RC_KAK_ROCK_2, RAND_INF_KAK_ROCK_2 }, + { RC_GY_ROCK, RAND_INF_GY_ROCK }, + { RC_LA_ROCK, RAND_INF_LA_ROCK }, + { RC_ZD_CIRCLE_ROCK_1, RAND_INF_ZD_CIRCLE_ROCK_1 }, + { RC_ZD_CIRCLE_ROCK_2, RAND_INF_ZD_CIRCLE_ROCK_2 }, + { RC_ZD_CIRCLE_ROCK_3, RAND_INF_ZD_CIRCLE_ROCK_3 }, + { RC_ZD_CIRCLE_ROCK_4, RAND_INF_ZD_CIRCLE_ROCK_4 }, + { RC_ZD_CIRCLE_ROCK_5, RAND_INF_ZD_CIRCLE_ROCK_5 }, + { RC_ZD_CIRCLE_ROCK_6, RAND_INF_ZD_CIRCLE_ROCK_6 }, + { RC_ZD_CIRCLE_ROCK_7, RAND_INF_ZD_CIRCLE_ROCK_7 }, + { RC_ZD_CIRCLE_ROCK_8, RAND_INF_ZD_CIRCLE_ROCK_8 }, + { RC_ZF_BOULDER, RAND_INF_ZF_BOULDER }, + { RC_ZF_SILVER_BOULDER, RAND_INF_ZF_SILVER_BOULDER }, + { RC_ZF_UNDERGROUND_BOULDER, RAND_INF_ZF_UNDERGROUND_BOULDER }, + { RC_ZR_BOULDER_1, RAND_INF_ZR_BOULDER_1 }, + { RC_ZR_BOULDER_2, RAND_INF_ZR_BOULDER_2 }, + { RC_ZR_BOULDER_3, RAND_INF_ZR_BOULDER_3 }, + { RC_ZR_BOULDER_4, RAND_INF_ZR_BOULDER_4 }, + { RC_ZR_CIRCLE_ROCK_1, RAND_INF_ZR_CIRCLE_ROCK_1 }, + { RC_ZR_CIRCLE_ROCK_2, RAND_INF_ZR_CIRCLE_ROCK_2 }, + { RC_ZR_CIRCLE_ROCK_3, RAND_INF_ZR_CIRCLE_ROCK_3 }, + { RC_ZR_CIRCLE_ROCK_4, RAND_INF_ZR_CIRCLE_ROCK_4 }, + { RC_ZR_CIRCLE_ROCK_5, RAND_INF_ZR_CIRCLE_ROCK_5 }, + { RC_ZR_CIRCLE_ROCK_6, RAND_INF_ZR_CIRCLE_ROCK_6 }, + { RC_ZR_CIRCLE_ROCK_7, RAND_INF_ZR_CIRCLE_ROCK_7 }, + { RC_ZR_CIRCLE_ROCK_8, RAND_INF_ZR_CIRCLE_ROCK_8 }, + { RC_ZR_UPPER_CIRCLE_BOULDER, RAND_INF_ZR_UPPER_CIRCLE_BOULDER }, + { RC_ZR_UPPER_CIRCLE_ROCK_1, RAND_INF_ZR_UPPER_CIRCLE_ROCK_1 }, + { RC_ZR_UPPER_CIRCLE_ROCK_2, RAND_INF_ZR_UPPER_CIRCLE_ROCK_2 }, + { RC_ZR_UPPER_CIRCLE_ROCK_3, RAND_INF_ZR_UPPER_CIRCLE_ROCK_3 }, + { RC_ZR_UPPER_CIRCLE_ROCK_4, RAND_INF_ZR_UPPER_CIRCLE_ROCK_4 }, + { RC_ZR_UPPER_CIRCLE_ROCK_5, RAND_INF_ZR_UPPER_CIRCLE_ROCK_5 }, + { RC_ZR_UPPER_CIRCLE_ROCK_6, RAND_INF_ZR_UPPER_CIRCLE_ROCK_6 }, + { RC_ZR_UPPER_CIRCLE_ROCK_7, RAND_INF_ZR_UPPER_CIRCLE_ROCK_7 }, + { RC_ZR_UPPER_CIRCLE_ROCK_8, RAND_INF_ZR_UPPER_CIRCLE_ROCK_8 }, + { RC_ZR_ROCK, RAND_INF_ZR_ROCK }, + { RC_ZR_UNDERWATER_ROCK_1, RAND_INF_ZR_UNDERWATER_ROCK_1 }, + { RC_ZR_UNDERWATER_ROCK_2, RAND_INF_ZR_UNDERWATER_ROCK_2 }, + { RC_ZR_UNDERWATER_ROCK_3, RAND_INF_ZR_UNDERWATER_ROCK_3 }, + { RC_ZR_UNDERWATER_ROCK_4, RAND_INF_ZR_UNDERWATER_ROCK_4 }, + { RC_DMT_ROCK_1, RAND_INF_DMT_ROCK_1 }, + { RC_DMT_ROCK_2, RAND_INF_DMT_ROCK_2 }, + { RC_DMT_ROCK_3, RAND_INF_DMT_ROCK_3 }, + { RC_DMT_ROCK_4, RAND_INF_DMT_ROCK_4 }, + { RC_DMT_ROCK_5, RAND_INF_DMT_ROCK_5 }, + { RC_DMT_SUMMIT_ROCK, RAND_INF_DMT_SUMMIT_ROCK }, + { RC_DMT_CIRCLE_ROCK_1, RAND_INF_DMT_CIRCLE_ROCK_1 }, + { RC_DMT_CIRCLE_ROCK_2, RAND_INF_DMT_CIRCLE_ROCK_2 }, + { RC_DMT_CIRCLE_ROCK_3, RAND_INF_DMT_CIRCLE_ROCK_3 }, + { RC_DMT_CIRCLE_ROCK_4, RAND_INF_DMT_CIRCLE_ROCK_4 }, + { RC_DMT_CIRCLE_ROCK_5, RAND_INF_DMT_CIRCLE_ROCK_5 }, + { RC_DMT_CIRCLE_ROCK_6, RAND_INF_DMT_CIRCLE_ROCK_6 }, + { RC_DMT_CIRCLE_ROCK_7, RAND_INF_DMT_CIRCLE_ROCK_7 }, + { RC_DMT_CIRCLE_ROCK_8, RAND_INF_DMT_CIRCLE_ROCK_8 }, + { RC_DMT_BOULDER_1, RAND_INF_DMT_BOULDER_1 }, + { RC_DMT_BOULDER_2, RAND_INF_DMT_BOULDER_2 }, + { RC_DMT_BOULDER_3, RAND_INF_DMT_BOULDER_3 }, + { RC_DMT_COW_BOULDER, RAND_INF_DMT_COW_BOULDER }, + { RC_DMT_BRONZE_BOULDER_1, RAND_INF_DMT_BRONZE_BOULDER_1 }, + { RC_DMT_BRONZE_BOULDER_2, RAND_INF_DMT_BRONZE_BOULDER_2 }, + { RC_DMT_BRONZE_BOULDER_3, RAND_INF_DMT_BRONZE_BOULDER_3 }, + { RC_DMT_BRONZE_BOULDER_4, RAND_INF_DMT_BRONZE_BOULDER_4 }, + { RC_DMT_BRONZE_BOULDER_5, RAND_INF_DMT_BRONZE_BOULDER_5 }, + { RC_DMT_BRONZE_BOULDER_6, RAND_INF_DMT_BRONZE_BOULDER_6 }, + { RC_DMT_BRONZE_BOULDER_7, RAND_INF_DMT_BRONZE_BOULDER_7 }, + { RC_DMT_BRONZE_BOULDER_8, RAND_INF_DMT_BRONZE_BOULDER_8 }, + { RC_DMT_BRONZE_BOULDER_9, RAND_INF_DMT_BRONZE_BOULDER_9 }, + { RC_DMT_BRONZE_BOULDER_10, RAND_INF_DMT_BRONZE_BOULDER_10 }, + { RC_DMT_BRONZE_BOULDER_11, RAND_INF_DMT_BRONZE_BOULDER_11 }, + { RC_GC_LW_BOULDER_1, RAND_INF_GC_LW_BOULDER_1 }, + { RC_GC_LW_BOULDER_2, RAND_INF_GC_LW_BOULDER_2 }, + { RC_GC_LW_BOULDER_3, RAND_INF_GC_LW_BOULDER_3 }, + { RC_GC_ENTRANCE_BOULDER_1, RAND_INF_GC_ENTRANCE_BOULDER_1 }, + { RC_GC_ENTRANCE_BOULDER_2, RAND_INF_GC_ENTRANCE_BOULDER_2 }, + { RC_GC_ENTRANCE_BOULDER_3, RAND_INF_GC_ENTRANCE_BOULDER_3 }, + { RC_GC_MAZE_SILVER_BOULDER_1, RAND_INF_GC_MAZE_SILVER_BOULDER_1 }, + { RC_GC_MAZE_SILVER_BOULDER_2, RAND_INF_GC_MAZE_SILVER_BOULDER_2 }, + { RC_GC_MAZE_SILVER_BOULDER_3, RAND_INF_GC_MAZE_SILVER_BOULDER_3 }, + { RC_GC_MAZE_SILVER_BOULDER_4, RAND_INF_GC_MAZE_SILVER_BOULDER_4 }, + { RC_GC_MAZE_SILVER_BOULDER_5, RAND_INF_GC_MAZE_SILVER_BOULDER_5 }, + { RC_GC_MAZE_SILVER_BOULDER_6, RAND_INF_GC_MAZE_SILVER_BOULDER_6 }, + { RC_GC_MAZE_SILVER_BOULDER_7, RAND_INF_GC_MAZE_SILVER_BOULDER_7 }, + { RC_GC_MAZE_SILVER_BOULDER_8, RAND_INF_GC_MAZE_SILVER_BOULDER_8 }, + { RC_GC_MAZE_SILVER_BOULDER_9, RAND_INF_GC_MAZE_SILVER_BOULDER_9 }, + { RC_GC_MAZE_SILVER_BOULDER_10, RAND_INF_GC_MAZE_SILVER_BOULDER_10 }, + { RC_GC_MAZE_SILVER_BOULDER_11, RAND_INF_GC_MAZE_SILVER_BOULDER_11 }, + { RC_GC_MAZE_SILVER_BOULDER_12, RAND_INF_GC_MAZE_SILVER_BOULDER_12 }, + { RC_GC_MAZE_SILVER_BOULDER_13, RAND_INF_GC_MAZE_SILVER_BOULDER_13 }, + { RC_GC_MAZE_SILVER_BOULDER_14, RAND_INF_GC_MAZE_SILVER_BOULDER_14 }, + { RC_GC_MAZE_SILVER_BOULDER_15, RAND_INF_GC_MAZE_SILVER_BOULDER_15 }, + { RC_GC_MAZE_SILVER_BOULDER_16, RAND_INF_GC_MAZE_SILVER_BOULDER_16 }, + { RC_GC_MAZE_SILVER_BOULDER_17, RAND_INF_GC_MAZE_SILVER_BOULDER_17 }, + { RC_GC_MAZE_SILVER_BOULDER_18, RAND_INF_GC_MAZE_SILVER_BOULDER_18 }, + { RC_GC_MAZE_SILVER_BOULDER_19, RAND_INF_GC_MAZE_SILVER_BOULDER_19 }, + { RC_GC_MAZE_SILVER_BOULDER_20, RAND_INF_GC_MAZE_SILVER_BOULDER_20 }, + { RC_GC_MAZE_SILVER_BOULDER_21, RAND_INF_GC_MAZE_SILVER_BOULDER_21 }, + { RC_GC_MAZE_SILVER_BOULDER_22, RAND_INF_GC_MAZE_SILVER_BOULDER_22 }, + { RC_GC_MAZE_SILVER_BOULDER_23, RAND_INF_GC_MAZE_SILVER_BOULDER_23 }, + { RC_GC_MAZE_SILVER_BOULDER_24, RAND_INF_GC_MAZE_SILVER_BOULDER_24 }, + { RC_GC_MAZE_SILVER_BOULDER_25, RAND_INF_GC_MAZE_SILVER_BOULDER_25 }, + { RC_GC_MAZE_SILVER_BOULDER_26, RAND_INF_GC_MAZE_SILVER_BOULDER_26 }, + { RC_GC_MAZE_SILVER_BOULDER_27, RAND_INF_GC_MAZE_SILVER_BOULDER_27 }, + { RC_GC_MAZE_SILVER_BOULDER_28, RAND_INF_GC_MAZE_SILVER_BOULDER_28 }, + { RC_GC_MAZE_SILVER_BOULDER_29, RAND_INF_GC_MAZE_SILVER_BOULDER_29 }, + { RC_GC_MAZE_BOULDER_1, RAND_INF_GC_MAZE_BOULDER_1 }, + { RC_GC_MAZE_BOULDER_2, RAND_INF_GC_MAZE_BOULDER_2 }, + { RC_GC_MAZE_BOULDER_3, RAND_INF_GC_MAZE_BOULDER_3 }, + { RC_GC_MAZE_BOULDER_4, RAND_INF_GC_MAZE_BOULDER_4 }, + { RC_GC_MAZE_BOULDER_5, RAND_INF_GC_MAZE_BOULDER_5 }, + { RC_GC_MAZE_BOULDER_6, RAND_INF_GC_MAZE_BOULDER_6 }, + { RC_GC_MAZE_BOULDER_7, RAND_INF_GC_MAZE_BOULDER_7 }, + { RC_GC_MAZE_BOULDER_8, RAND_INF_GC_MAZE_BOULDER_8 }, + { RC_GC_MAZE_BOULDER_9, RAND_INF_GC_MAZE_BOULDER_9 }, + { RC_GC_MAZE_BOULDER_10, RAND_INF_GC_MAZE_BOULDER_10 }, + { RC_GC_MAZE_BRONZE_BOULDER_1, RAND_INF_GC_MAZE_BRONZE_BOULDER_1 }, + { RC_GC_MAZE_BRONZE_BOULDER_2, RAND_INF_GC_MAZE_BRONZE_BOULDER_2 }, + { RC_GC_MAZE_BRONZE_BOULDER_3, RAND_INF_GC_MAZE_BRONZE_BOULDER_3 }, + { RC_GC_MAZE_BRONZE_BOULDER_4, RAND_INF_GC_MAZE_BRONZE_BOULDER_4 }, + { RC_GC_MAZE_BRONZE_BOULDER_5, RAND_INF_GC_MAZE_BRONZE_BOULDER_5 }, + { RC_GC_MAZE_ROCK, RAND_INF_GC_MAZE_ROCK }, + { RC_COLOSSUS_SILVER_BOULDER, RAND_INF_COLOSSUS_SILVER_BOULDER }, + { RC_COLOSSUS_ROCK, RAND_INF_COLOSSUS_ROCK }, + { RC_COLOSSUS_CIRCLE_1_ROCK_1, RAND_INF_COLOSSUS_CIRCLE_1_ROCK_1 }, + { RC_COLOSSUS_CIRCLE_1_ROCK_2, RAND_INF_COLOSSUS_CIRCLE_1_ROCK_2 }, + { RC_COLOSSUS_CIRCLE_1_ROCK_3, RAND_INF_COLOSSUS_CIRCLE_1_ROCK_3 }, + { RC_COLOSSUS_CIRCLE_1_ROCK_4, RAND_INF_COLOSSUS_CIRCLE_1_ROCK_4 }, + { RC_COLOSSUS_CIRCLE_1_ROCK_5, RAND_INF_COLOSSUS_CIRCLE_1_ROCK_5 }, + { RC_COLOSSUS_CIRCLE_1_ROCK_6, RAND_INF_COLOSSUS_CIRCLE_1_ROCK_6 }, + { RC_COLOSSUS_CIRCLE_1_ROCK_7, RAND_INF_COLOSSUS_CIRCLE_1_ROCK_7 }, + { RC_COLOSSUS_CIRCLE_1_ROCK_8, RAND_INF_COLOSSUS_CIRCLE_1_ROCK_8 }, + { RC_COLOSSUS_CIRCLE_2_ROCK_1, RAND_INF_COLOSSUS_CIRCLE_2_ROCK_1 }, + { RC_COLOSSUS_CIRCLE_2_ROCK_2, RAND_INF_COLOSSUS_CIRCLE_2_ROCK_2 }, + { RC_COLOSSUS_CIRCLE_2_ROCK_3, RAND_INF_COLOSSUS_CIRCLE_2_ROCK_3 }, + { RC_COLOSSUS_CIRCLE_2_ROCK_4, RAND_INF_COLOSSUS_CIRCLE_2_ROCK_4 }, + { RC_COLOSSUS_CIRCLE_2_ROCK_5, RAND_INF_COLOSSUS_CIRCLE_2_ROCK_5 }, + { RC_COLOSSUS_CIRCLE_2_ROCK_6, RAND_INF_COLOSSUS_CIRCLE_2_ROCK_6 }, + { RC_COLOSSUS_CIRCLE_2_ROCK_7, RAND_INF_COLOSSUS_CIRCLE_2_ROCK_7 }, + { RC_COLOSSUS_CIRCLE_2_ROCK_8, RAND_INF_COLOSSUS_CIRCLE_2_ROCK_8 }, + { RC_HC_STORMS_GROTTO_ROCK_1, RAND_INF_HC_STORMS_GROTTO_ROCK_1 }, + { RC_HC_STORMS_GROTTO_ROCK_2, RAND_INF_HC_STORMS_GROTTO_ROCK_2 }, + { RC_HC_STORMS_GROTTO_ROCK_3, RAND_INF_HC_STORMS_GROTTO_ROCK_3 }, + { RC_HC_STORMS_GROTTO_ROCK_4, RAND_INF_HC_STORMS_GROTTO_ROCK_4 }, + { RC_HC_STORMS_GROTTO_ROCK_5, RAND_INF_HC_STORMS_GROTTO_ROCK_5 }, + { RC_HC_STORMS_GROTTO_ROCK_6, RAND_INF_HC_STORMS_GROTTO_ROCK_6 }, + { RC_HC_STORMS_GROTTO_ROCK_7, RAND_INF_HC_STORMS_GROTTO_ROCK_7 }, + { RC_HC_STORMS_GROTTO_ROCK_8, RAND_INF_HC_STORMS_GROTTO_ROCK_8 }, + { RC_BOTW_BOULDER_1, RAND_INF_BOTW_BOULDER_1 }, + { RC_BOTW_BOULDER_2, RAND_INF_BOTW_BOULDER_2 }, + { RC_BOTW_BOULDER_3, RAND_INF_BOTW_BOULDER_3 }, + { RC_BOTW_BOULDER_4, RAND_INF_BOTW_BOULDER_4 }, + { RC_BOTW_BOULDER_5, RAND_INF_BOTW_BOULDER_5 }, + { RC_BOTW_BOULDER_6, RAND_INF_BOTW_BOULDER_6 }, + { RC_DEKU_TREE_MQ_BOULDER_1, RAND_INF_DEKU_TREE_MQ_BOULDER_1 }, + { RC_DEKU_TREE_MQ_BOULDER_2, RAND_INF_DEKU_TREE_MQ_BOULDER_2 }, + { RC_DEKU_TREE_MQ_BOULDER_3, RAND_INF_DEKU_TREE_MQ_BOULDER_3 }, + { RC_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_1, RAND_INF_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_1 }, + { RC_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_2, RAND_INF_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_2 }, + { RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_1, RAND_INF_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_1 }, + { RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_2, RAND_INF_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_2 }, + { RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_3, RAND_INF_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_3 }, + { RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_1, RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_1 }, + { RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_2, RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_2 }, + { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_1, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_1 }, + { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_2, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_2 }, + { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_3, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_3 }, + { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_4, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_4 }, + { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_5, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_5 }, + { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_6, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_6 }, + { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_7, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_7 }, + { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_8, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_8 }, + { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_9, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_9 }, + { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_10, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_10 }, + { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_11, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_11 }, + { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_12, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_12 }, + { RC_JABU_JABUS_BELLY_MQ_ENTRANCE_BOULDER, RAND_INF_JABU_JABUS_BELLY_MQ_ENTRANCE_BOULDER }, + { RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_1, RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_1 }, + { RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_2, RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_2 }, + { RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_1, RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_1 }, + { RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_2, RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_2 }, + { RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_3, RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_3 }, + { RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_1, RAND_INF_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_1 }, + { RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_2, RAND_INF_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_2 }, + { RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_BOULDER, RAND_INF_JABU_JABUS_BELLY_MQ_TAILPASARAN_BOULDER }, + { RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_WALL_BOULDER, RAND_INF_JABU_JABUS_BELLY_MQ_TAILPASARAN_WALL_BOULDER }, + { RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_1, RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_1 }, + { RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_2, RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_2 }, + { RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_3, RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_3 }, + { RC_SPIRIT_TEMPLE_MQ_ENTRANCE_CEILING_BOULDER, RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_CEILING_BOULDER }, + { RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_BOULDER, RAND_INF_SPIRIT_TEMPLE_MQ_EARLY_ADULT_BOULDER }, + { RC_BOTW_MQ_BOULDER_1, RAND_INF_BOTW_MQ_BOULDER_1 }, + { RC_BOTW_MQ_BOULDER_2, RAND_INF_BOTW_MQ_BOULDER_2 }, + { RC_BOTW_MQ_BOULDER_3, RAND_INF_BOTW_MQ_BOULDER_3 }, { RC_HF_BUSH_NEAR_LAKE_1, RAND_INF_HF_BUSH_NEAR_LAKE_1 }, { RC_HF_BUSH_NEAR_LAKE_2, RAND_INF_HF_BUSH_NEAR_LAKE_2 }, { RC_HF_BUSH_NEAR_LAKE_3, RAND_INF_HF_BUSH_NEAR_LAKE_3 }, @@ -3511,7 +3791,6 @@ BeehiveIdentity Randomizer::IdentifyBeehive(s32 sceneNum, s16 xPosition, s32 res } Rando::Location* Randomizer::GetCheckObjectFromActor(s16 actorId, s16 sceneNum, s32 actorParams = 0x00) { - auto fs = OTRGlobals::Instance->gRandoContext->GetFishsanity(); RandomizerCheck specialRc = RC_UNKNOWN_CHECK; // TODO: Migrate these special cases into table, or at least document why they are special switch (sceneNum) { @@ -3928,6 +4207,22 @@ TreeIdentity Randomizer::IdentifyTree(s32 sceneNum, s32 posX, s32 posZ) { return treeIdentity; } +RockIdentity Randomizer::IdentifyRock(s32 sceneNum, s32 posX, s32 posZ) { + struct RockIdentity rockIdentity; + + rockIdentity.randomizerInf = RAND_INF_MAX; + rockIdentity.randomizerCheck = RC_UNKNOWN_CHECK; + + Rando::Location* location = GetCheckObjectFromActor(ACTOR_EN_ISHI, sceneNum, TWO_ACTOR_PARAMS(posX, posZ)); + + if (location->GetRandomizerCheck() != RC_UNKNOWN_CHECK) { + rockIdentity.randomizerInf = rcToRandomizerInf[location->GetRandomizerCheck()]; + rockIdentity.randomizerCheck = location->GetRandomizerCheck(); + } + + return rockIdentity; +} + u8 Randomizer::GetRandoSettingValue(RandomizerSettingKey randoSettingKey) { return Rando::Context::GetInstance()->GetOption(randoSettingKey).Get(); } diff --git a/soh/soh/Enhancements/randomizer/randomizer.h b/soh/soh/Enhancements/randomizer/randomizer.h index 54c85307b6f..e6de9343e47 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.h +++ b/soh/soh/Enhancements/randomizer/randomizer.h @@ -58,6 +58,7 @@ class Randomizer { CrateIdentity IdentifyCrate(s32 sceneNum, s32 posX, s32 posZ); SmallCrateIdentity IdentifySmallCrate(s32 sceneNum, s32 posX, s32 posZ); TreeIdentity IdentifyTree(s32 sceneNum, s32 posX, s32 posZ); + RockIdentity IdentifyRock(s32 sceneNum, s32 posX, s32 posZ); GetItemEntry GetItemFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogItemId, bool checkObtainability = true); GetItemEntry GetItemFromActor(s16 actorId, s16 sceneNum, s16 actorParams, GetItemID ogItemId, diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index c5df5840775..036180456e1 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -437,6 +437,8 @@ typedef enum { RCTYPE_BEAN_FAIRY, // Fairies from Beans RCTYPE_SONG_FAIRY, // Fairies from Songs RCTYPE_GRASS, // Grass + RCTYPE_ROCK, // Rocks + RCTYPE_BOULDER, // Boulders } RandomizerCheckType; typedef enum { RCQUEST_VANILLA, RCQUEST_MQ, RCQUEST_BOTH } RandomizerCheckQuest; @@ -3844,6 +3846,288 @@ typedef enum { RC_DEKU_TREE_QUEEN_GOHMA_GRASS_8, // End Grass + RC_KF_CIRCLE_ROCK_1, + RC_KF_CIRCLE_ROCK_2, + RC_KF_CIRCLE_ROCK_3, + RC_KF_CIRCLE_ROCK_4, + RC_KF_CIRCLE_ROCK_5, + RC_KF_CIRCLE_ROCK_6, + RC_KF_CIRCLE_ROCK_7, + RC_KF_CIRCLE_ROCK_8, + RC_KF_ROCK_BY_SARIAS_HOUSE, + RC_KF_ROCK_BEHIND_SARIAS_HOUSE, + RC_KF_ROCK_BY_MIDOS_HOUSE, + RC_KF_ROCK_BY_KNOW_IT_ALLS_HOUSE, + RC_LW_BOULDER_BY_GORON_CITY, + RC_LW_BOULDER_BY_SACRED_FOREST_MEADOW, + RC_LW_RUPEE_BOULDER, + RC_HC_ROCK_1, + RC_HC_ROCK_2, + RC_HC_ROCK_3, + RC_HC_BOULDER, + RC_OGC_BRONZE_BOULDER_1, + RC_OGC_BRONZE_BOULDER_2, + RC_OGC_BRONZE_BOULDER_3, + RC_OGC_SILVER_BOULDER_1, + RC_OGC_SILVER_BOULDER_2, + RC_OGC_SILVER_BOULDER_3, + RC_OGC_SILVER_BOULDER_4, + RC_DMC_CIRCLE_ROCK_1, + RC_DMC_CIRCLE_ROCK_2, + RC_DMC_CIRCLE_ROCK_3, + RC_DMC_CIRCLE_ROCK_4, + RC_DMC_CIRCLE_ROCK_5, + RC_DMC_CIRCLE_ROCK_6, + RC_DMC_CIRCLE_ROCK_7, + RC_DMC_CIRCLE_ROCK_8, + RC_DMC_ROCK_BY_FIRE_TEMPLE_1, + RC_DMC_ROCK_BY_FIRE_TEMPLE_2, + RC_DMC_ROCK_BY_FIRE_TEMPLE_3, + RC_DMC_ROCK_BY_FIRE_TEMPLE_4, + RC_DMC_ROCK_BY_FIRE_TEMPLE_5, + RC_DMC_GOSSIP_ROCK_1, + RC_DMC_GOSSIP_ROCK_2, + RC_DMC_BOULDER_1, + RC_DMC_BOULDER_2, + RC_DMC_BOULDER_3, + RC_DMC_BRONZE_BOULDER_1, + RC_DMC_BRONZE_BOULDER_2, + RC_DMC_BRONZE_BOULDER_3, + RC_DMC_BRONZE_BOULDER_4, + RC_GV_SILVER_BOULDER, + RC_GV_ROCK_1, + RC_GV_ROCK_2, + RC_GV_ROCK_3, + RC_GV_UNDERWATER_ROCK_1, + RC_GV_UNDERWATER_ROCK_2, + RC_GV_UNDERWATER_ROCK_3, + RC_GV_ROCK_ACROSS_BRIDGE_1, + RC_GV_ROCK_ACROSS_BRIDGE_2, + RC_GV_ROCK_ACROSS_BRIDGE_3, + RC_GV_ROCK_ACROSS_BRIDGE_4, + RC_GV_BOULDER_1, + RC_GV_BOULDER_2, + RC_GV_BOULDER_ACROSS_BRIDGE, + RC_GV_BRONZE_BOULDER_1, + RC_GV_BRONZE_BOULDER_2, + RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_1, + RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_2, + RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_3, + RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_4, + RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_5, + RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_6, + RC_HF_SILVER_BOULDER, + RC_HF_ROCK_1, + RC_HF_ROCK_2, + RC_HF_ROCK_3, + RC_HF_ROCK_4, + RC_HF_ROCK_5, + RC_HF_ROCK_6, + RC_HF_ROCK_7, + RC_HF_ROCK_8, + RC_HF_BOULDER_NORTH, + RC_HF_BOULDER_BY_MARKET, + RC_HF_BOULDER_SOUTH, + RC_HF_BRONZE_BOULDER_1, + RC_HF_BRONZE_BOULDER_2, + RC_HF_BRONZE_BOULDER_3, + RC_HF_BRONZE_BOULDER_4, + RC_KAK_SILVER_BOULDER, + RC_KAK_ROCK_1, + RC_KAK_ROCK_2, + RC_GY_ROCK, + RC_LA_ROCK, + RC_ZD_CIRCLE_ROCK_1, + RC_ZD_CIRCLE_ROCK_2, + RC_ZD_CIRCLE_ROCK_3, + RC_ZD_CIRCLE_ROCK_4, + RC_ZD_CIRCLE_ROCK_5, + RC_ZD_CIRCLE_ROCK_6, + RC_ZD_CIRCLE_ROCK_7, + RC_ZD_CIRCLE_ROCK_8, + RC_ZF_BOULDER, + RC_ZF_SILVER_BOULDER, + RC_ZF_UNDERGROUND_BOULDER, + RC_ZR_BOULDER_1, + RC_ZR_BOULDER_2, + RC_ZR_BOULDER_3, + RC_ZR_BOULDER_4, + RC_ZR_CIRCLE_ROCK_1, + RC_ZR_CIRCLE_ROCK_2, + RC_ZR_CIRCLE_ROCK_3, + RC_ZR_CIRCLE_ROCK_4, + RC_ZR_CIRCLE_ROCK_5, + RC_ZR_CIRCLE_ROCK_6, + RC_ZR_CIRCLE_ROCK_7, + RC_ZR_CIRCLE_ROCK_8, + RC_ZR_UPPER_CIRCLE_BOULDER, + RC_ZR_UPPER_CIRCLE_ROCK_1, + RC_ZR_UPPER_CIRCLE_ROCK_2, + RC_ZR_UPPER_CIRCLE_ROCK_3, + RC_ZR_UPPER_CIRCLE_ROCK_4, + RC_ZR_UPPER_CIRCLE_ROCK_5, + RC_ZR_UPPER_CIRCLE_ROCK_6, + RC_ZR_UPPER_CIRCLE_ROCK_7, + RC_ZR_UPPER_CIRCLE_ROCK_8, + RC_ZR_ROCK, + RC_ZR_UNDERWATER_ROCK_1, + RC_ZR_UNDERWATER_ROCK_2, + RC_ZR_UNDERWATER_ROCK_3, + RC_ZR_UNDERWATER_ROCK_4, + RC_DMT_ROCK_1, + RC_DMT_ROCK_2, + RC_DMT_ROCK_3, + RC_DMT_ROCK_4, + RC_DMT_ROCK_5, + RC_DMT_SUMMIT_ROCK, + RC_DMT_CIRCLE_ROCK_1, + RC_DMT_CIRCLE_ROCK_2, + RC_DMT_CIRCLE_ROCK_3, + RC_DMT_CIRCLE_ROCK_4, + RC_DMT_CIRCLE_ROCK_5, + RC_DMT_CIRCLE_ROCK_6, + RC_DMT_CIRCLE_ROCK_7, + RC_DMT_CIRCLE_ROCK_8, + RC_DMT_BOULDER_1, + RC_DMT_BOULDER_2, + RC_DMT_BOULDER_3, + RC_DMT_COW_BOULDER, + RC_DMT_BRONZE_BOULDER_1, + RC_DMT_BRONZE_BOULDER_2, + RC_DMT_BRONZE_BOULDER_3, + RC_DMT_BRONZE_BOULDER_4, + RC_DMT_BRONZE_BOULDER_5, + RC_DMT_BRONZE_BOULDER_6, + RC_DMT_BRONZE_BOULDER_7, + RC_DMT_BRONZE_BOULDER_8, + RC_DMT_BRONZE_BOULDER_9, + RC_DMT_BRONZE_BOULDER_10, + RC_DMT_BRONZE_BOULDER_11, + RC_GC_LW_BOULDER_1, + RC_GC_LW_BOULDER_2, + RC_GC_LW_BOULDER_3, + RC_GC_ENTRANCE_BOULDER_1, + RC_GC_ENTRANCE_BOULDER_2, + RC_GC_ENTRANCE_BOULDER_3, + RC_GC_MAZE_SILVER_BOULDER_1, + RC_GC_MAZE_SILVER_BOULDER_2, + RC_GC_MAZE_SILVER_BOULDER_3, + RC_GC_MAZE_SILVER_BOULDER_4, + RC_GC_MAZE_SILVER_BOULDER_5, + RC_GC_MAZE_SILVER_BOULDER_6, + RC_GC_MAZE_SILVER_BOULDER_7, + RC_GC_MAZE_SILVER_BOULDER_8, + RC_GC_MAZE_SILVER_BOULDER_9, + RC_GC_MAZE_SILVER_BOULDER_10, + RC_GC_MAZE_SILVER_BOULDER_11, + RC_GC_MAZE_SILVER_BOULDER_12, + RC_GC_MAZE_SILVER_BOULDER_13, + RC_GC_MAZE_SILVER_BOULDER_14, + RC_GC_MAZE_SILVER_BOULDER_15, + RC_GC_MAZE_SILVER_BOULDER_16, + RC_GC_MAZE_SILVER_BOULDER_17, + RC_GC_MAZE_SILVER_BOULDER_18, + RC_GC_MAZE_SILVER_BOULDER_19, + RC_GC_MAZE_SILVER_BOULDER_20, + RC_GC_MAZE_SILVER_BOULDER_21, + RC_GC_MAZE_SILVER_BOULDER_22, + RC_GC_MAZE_SILVER_BOULDER_23, + RC_GC_MAZE_SILVER_BOULDER_24, + RC_GC_MAZE_SILVER_BOULDER_25, + RC_GC_MAZE_SILVER_BOULDER_26, + RC_GC_MAZE_SILVER_BOULDER_27, + RC_GC_MAZE_SILVER_BOULDER_28, + RC_GC_MAZE_SILVER_BOULDER_29, + RC_GC_MAZE_BOULDER_1, + RC_GC_MAZE_BOULDER_2, + RC_GC_MAZE_BOULDER_3, + RC_GC_MAZE_BOULDER_4, + RC_GC_MAZE_BOULDER_5, + RC_GC_MAZE_BOULDER_6, + RC_GC_MAZE_BOULDER_7, + RC_GC_MAZE_BOULDER_8, + RC_GC_MAZE_BOULDER_9, + RC_GC_MAZE_BOULDER_10, + RC_GC_MAZE_BRONZE_BOULDER_1, + RC_GC_MAZE_BRONZE_BOULDER_2, + RC_GC_MAZE_BRONZE_BOULDER_3, + RC_GC_MAZE_BRONZE_BOULDER_4, + RC_GC_MAZE_BRONZE_BOULDER_5, + RC_GC_MAZE_ROCK, + RC_COLOSSUS_SILVER_BOULDER, + RC_COLOSSUS_ROCK, + RC_COLOSSUS_CIRCLE_1_ROCK_1, + RC_COLOSSUS_CIRCLE_1_ROCK_2, + RC_COLOSSUS_CIRCLE_1_ROCK_3, + RC_COLOSSUS_CIRCLE_1_ROCK_4, + RC_COLOSSUS_CIRCLE_1_ROCK_5, + RC_COLOSSUS_CIRCLE_1_ROCK_6, + RC_COLOSSUS_CIRCLE_1_ROCK_7, + RC_COLOSSUS_CIRCLE_1_ROCK_8, + RC_COLOSSUS_CIRCLE_2_ROCK_1, + RC_COLOSSUS_CIRCLE_2_ROCK_2, + RC_COLOSSUS_CIRCLE_2_ROCK_3, + RC_COLOSSUS_CIRCLE_2_ROCK_4, + RC_COLOSSUS_CIRCLE_2_ROCK_5, + RC_COLOSSUS_CIRCLE_2_ROCK_6, + RC_COLOSSUS_CIRCLE_2_ROCK_7, + RC_COLOSSUS_CIRCLE_2_ROCK_8, + RC_HC_STORMS_GROTTO_ROCK_1, + RC_HC_STORMS_GROTTO_ROCK_2, + RC_HC_STORMS_GROTTO_ROCK_3, + RC_HC_STORMS_GROTTO_ROCK_4, + RC_HC_STORMS_GROTTO_ROCK_5, + RC_HC_STORMS_GROTTO_ROCK_6, + RC_HC_STORMS_GROTTO_ROCK_7, + RC_HC_STORMS_GROTTO_ROCK_8, + RC_BOTW_BOULDER_1, + RC_BOTW_BOULDER_2, + RC_BOTW_BOULDER_3, + RC_BOTW_BOULDER_4, + RC_BOTW_BOULDER_5, + RC_BOTW_BOULDER_6, + RC_DEKU_TREE_MQ_BOULDER_1, + RC_DEKU_TREE_MQ_BOULDER_2, + RC_DEKU_TREE_MQ_BOULDER_3, + RC_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_1, + RC_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_2, + RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_1, + RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_2, + RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_3, + RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_1, + RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_2, + RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_1, + RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_2, + RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_3, + RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_4, + RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_5, + RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_6, + RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_7, + RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_8, + RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_9, + RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_10, + RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_11, + RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_12, + RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_BOULDER, + RC_JABU_JABUS_BELLY_MQ_ENTRANCE_BOULDER, + RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_1, + RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_2, + RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_1, + RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_2, + RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_3, + RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_1, + RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_2, + RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_BOULDER, + RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_WALL_BOULDER, + RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_1, + RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_2, + RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_3, + RC_SPIRIT_TEMPLE_MQ_ENTRANCE_CEILING_BOULDER, + RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_BOULDER, + RC_BOTW_MQ_BOULDER_1, + RC_BOTW_MQ_BOULDER_2, + RC_BOTW_MQ_BOULDER_3, + RC_MAX } RandomizerCheck; @@ -6022,6 +6306,48 @@ typedef enum { RHT_DODONGOS_CAVERN_GRASS, RHT_BOTTOM_OF_THE_WELL_GRASS, RHT_JABU_JABUS_BELLY_GRASS, + + RHT_KF_ROCK, + RHT_LW_BOULDER, + RHT_HC_ROCK, + RHT_HC_BOULDER, + RHT_OGC_BRONZE_BOULDER, + RHT_OGC_SILVER_BOULDER, + RHT_DMC_ROCK, + RHT_DMC_BOULDER, + RHT_DMC_BRONZE_BOULDER, + RHT_GV_SILVER_BOULDER, + RHT_GV_ROCK, + RHT_GV_BOULDER, + RHT_GV_BRONZE_BOULDER, + RHT_HF_SILVER_BOULDER, + RHT_HF_ROCK, + RHT_HF_BOULDER, + RHT_HF_BRONZE_BOULDER, + RHT_KAK_SILVER_BOULDER, + RHT_KAK_ROCK, + RHT_GY_ROCK, + RHT_LA_ROCK, + RHT_ZD_ROCK, + RHT_ZF_BOULDER, + RHT_ZF_SILVER_BOULDER, + RHT_ZR_BOULDER, + RHT_ZR_ROCK, + RHT_DMT_ROCK, + RHT_DMT_BOULDER, + RHT_DMT_BRONZE_BOULDER, + RHT_GC_BOULDER, + RHT_GC_SILVER_BOULDER, + RHT_GC_BRONZE_BOULDER, + RHT_GC_ROCK, + RHT_COLOSSUS_SILVER_BOULDER, + RHT_COLOSSUS_ROCK, + RHT_HC_STORMS_GROTTO_ROCK, + RHT_BOTW_BOULDER, + RHT_DEKU_BOULDER, + RHT_DODONGOS_BOULDER, + RHT_JABU_BOULDER, + RHT_SPIRIT_TEMPLE_BOULDER, // MAX RHT_MAX, } RandomizerHintTextKey; @@ -6328,6 +6654,8 @@ typedef enum { RSK_SHUFFLE_SONG_FAIRIES, RSK_LOCK_OVERWORLD_DOORS, RSK_SHUFFLE_GRASS, + RSK_SHUFFLE_ROCKS, + RSK_SHUFFLE_BOULDERS, RSK_MAX } RandomizerSettingKey; @@ -6699,6 +7027,14 @@ typedef enum { RO_SHUFFLE_CRATES_ALL, } RandoOptionShuffleCrates; +// Shuffle Boulder settings (off, dungeons, overworld, all) +typedef enum { + RO_SHUFFLE_BOULDERS_OFF, + RO_SHUFFLE_BOULDERS_DUNGEONS, + RO_SHUFFLE_BOULDERS_OVERWORLD, + RO_SHUFFLE_BOULDERS_ALL, +} RandoOptionShuffleBoulders; + // Link's Pocket Settings (dungeon reward, advancement, anything, nothing) typedef enum { RO_LINKS_POCKET_DUNGEON_REWARD, @@ -6825,6 +7161,11 @@ typedef struct TreeIdentity { RandomizerCheck randomizerCheck; } TreeIdentity; +typedef struct RockIdentity { + RandomizerInf randomizerInf; + RandomizerCheck randomizerCheck; +} RockIdentity; + typedef enum { TRACKER_WINDOW_FLOATING, TRACKER_WINDOW_WINDOW, diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index 913d440cddb..cd5ccb4e93a 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -83,6 +83,9 @@ bool showDungeonGrass; bool showOverworldCrates; bool showDungeonCrates; bool showTrees; +bool showRocks; +bool showOverworldBoulders; +bool showDungeonBoulders; bool showBushes; bool showFrogSongRupees; bool showFountainFairies; @@ -1494,7 +1497,29 @@ void LoadSettings() { showDungeonCrates = false; break; } + showTrees = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_TREES); + + + showRocks = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_ROCKS); + switch (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_BOULDERS)) { + case RO_SHUFFLE_BOULDERS_ALL: + showOverworldBoulders = true; + showDungeonBoulders = true; + break; + case RO_SHUFFLE_BOULDERS_OVERWORLD: + showOverworldBoulders = true; + showDungeonBoulders = false; + break; + case RO_SHUFFLE_BOULDERS_DUNGEONS: + showOverworldBoulders = false; + showDungeonBoulders = true; + break; + default: + showOverworldBoulders = false; + showDungeonBoulders = false; + break; + } showBushes = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_BUSHES); } else { // Vanilla showOverworldTokens = true; @@ -1506,6 +1531,9 @@ void LoadSettings() { showOverworldCrates = false; showDungeonCrates = false; showTrees = false; + showRocks = false; + showOverworldBoulders = false; + showDungeonBoulders = false; showBushes = false; } @@ -1623,6 +1651,10 @@ bool IsCheckShuffled(RandomizerCheck rc) { (loc->GetRCType() != RCTYPE_NLTREE || (showTrees && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LOGIC_RULES) == RO_LOGIC_NO_LOGIC)) && + (loc->GetRCType() != RCTYPE_ROCK || showRocks) && + (loc->GetRCType() != RCTYPE_BOULDER || + (showOverworldBoulders && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) || + (showDungeonBoulders && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && (loc->GetRCType() != RCTYPE_BUSH || showBushes) && (loc->GetRCType() != RCTYPE_COW || showCows) && (loc->GetRCType() != RCTYPE_FISH || OTRGlobals::Instance->gRandoContext->GetFishsanity()->GetFishLocationIncluded(loc)) && diff --git a/soh/soh/Enhancements/randomizer/randomizer_inf.h b/soh/soh/Enhancements/randomizer/randomizer_inf.h index d6e5101f173..6d261f35683 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_inf.h +++ b/soh/soh/Enhancements/randomizer/randomizer_inf.h @@ -2093,4 +2093,286 @@ DEFINE_RAND_INF(RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_6) DEFINE_RAND_INF(RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_7) DEFINE_RAND_INF(RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_8) // End Grass +DEFINE_RAND_INF(RAND_INF_KF_CIRCLE_ROCK_1) +DEFINE_RAND_INF(RAND_INF_KF_CIRCLE_ROCK_2) +DEFINE_RAND_INF(RAND_INF_KF_CIRCLE_ROCK_3) +DEFINE_RAND_INF(RAND_INF_KF_CIRCLE_ROCK_4) +DEFINE_RAND_INF(RAND_INF_KF_CIRCLE_ROCK_5) +DEFINE_RAND_INF(RAND_INF_KF_CIRCLE_ROCK_6) +DEFINE_RAND_INF(RAND_INF_KF_CIRCLE_ROCK_7) +DEFINE_RAND_INF(RAND_INF_KF_CIRCLE_ROCK_8) +DEFINE_RAND_INF(RAND_INF_KF_ROCK_BY_SARIAS_HOUSE) +DEFINE_RAND_INF(RAND_INF_KF_ROCK_BEHIND_SARIAS_HOUSE) +DEFINE_RAND_INF(RAND_INF_KF_ROCK_BY_MIDOS_HOUSE) +DEFINE_RAND_INF(RAND_INF_KF_ROCK_BY_KNOW_IT_ALLS_HOUSE) +DEFINE_RAND_INF(RAND_INF_LW_BOULDER_BY_GORON_CITY) +DEFINE_RAND_INF(RAND_INF_LW_BOULDER_BY_SACRED_FOREST_MEADOW) +DEFINE_RAND_INF(RAND_INF_LW_RUPEE_BOULDER) +DEFINE_RAND_INF(RAND_INF_HC_ROCK_1) +DEFINE_RAND_INF(RAND_INF_HC_ROCK_2) +DEFINE_RAND_INF(RAND_INF_HC_ROCK_3) +DEFINE_RAND_INF(RAND_INF_HC_BOULDER) +DEFINE_RAND_INF(RAND_INF_OGC_BRONZE_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_OGC_BRONZE_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_OGC_BRONZE_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_OGC_SILVER_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_OGC_SILVER_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_OGC_SILVER_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_OGC_SILVER_BOULDER_4) +DEFINE_RAND_INF(RAND_INF_DMC_CIRCLE_ROCK_1) +DEFINE_RAND_INF(RAND_INF_DMC_CIRCLE_ROCK_2) +DEFINE_RAND_INF(RAND_INF_DMC_CIRCLE_ROCK_3) +DEFINE_RAND_INF(RAND_INF_DMC_CIRCLE_ROCK_4) +DEFINE_RAND_INF(RAND_INF_DMC_CIRCLE_ROCK_5) +DEFINE_RAND_INF(RAND_INF_DMC_CIRCLE_ROCK_6) +DEFINE_RAND_INF(RAND_INF_DMC_CIRCLE_ROCK_7) +DEFINE_RAND_INF(RAND_INF_DMC_CIRCLE_ROCK_8) +DEFINE_RAND_INF(RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_1) +DEFINE_RAND_INF(RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_2) +DEFINE_RAND_INF(RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_3) +DEFINE_RAND_INF(RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_4) +DEFINE_RAND_INF(RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_5) +DEFINE_RAND_INF(RAND_INF_DMC_GOSSIP_ROCK_1) +DEFINE_RAND_INF(RAND_INF_DMC_GOSSIP_ROCK_2) +DEFINE_RAND_INF(RAND_INF_DMC_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_DMC_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_DMC_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_DMC_BRONZE_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_DMC_BRONZE_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_DMC_BRONZE_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_DMC_BRONZE_BOULDER_4) +DEFINE_RAND_INF(RAND_INF_GV_SILVER_BOULDER) +DEFINE_RAND_INF(RAND_INF_GV_ROCK_1) +DEFINE_RAND_INF(RAND_INF_GV_ROCK_2) +DEFINE_RAND_INF(RAND_INF_GV_ROCK_3) +DEFINE_RAND_INF(RAND_INF_GV_UNDERWATER_ROCK_1) +DEFINE_RAND_INF(RAND_INF_GV_UNDERWATER_ROCK_2) +DEFINE_RAND_INF(RAND_INF_GV_UNDERWATER_ROCK_3) +DEFINE_RAND_INF(RAND_INF_GV_ROCK_ACROSS_BRIDGE_1) +DEFINE_RAND_INF(RAND_INF_GV_ROCK_ACROSS_BRIDGE_2) +DEFINE_RAND_INF(RAND_INF_GV_ROCK_ACROSS_BRIDGE_3) +DEFINE_RAND_INF(RAND_INF_GV_ROCK_ACROSS_BRIDGE_4) +DEFINE_RAND_INF(RAND_INF_GV_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_GV_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_GV_BOULDER_ACROSS_BRIDGE) +DEFINE_RAND_INF(RAND_INF_GV_BRONZE_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_GV_BRONZE_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_1) +DEFINE_RAND_INF(RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_2) +DEFINE_RAND_INF(RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_3) +DEFINE_RAND_INF(RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_4) +DEFINE_RAND_INF(RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_5) +DEFINE_RAND_INF(RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_6) +DEFINE_RAND_INF(RAND_INF_HF_SILVER_BOULDER) +DEFINE_RAND_INF(RAND_INF_HF_ROCK_1) +DEFINE_RAND_INF(RAND_INF_HF_ROCK_2) +DEFINE_RAND_INF(RAND_INF_HF_ROCK_3) +DEFINE_RAND_INF(RAND_INF_HF_ROCK_4) +DEFINE_RAND_INF(RAND_INF_HF_ROCK_5) +DEFINE_RAND_INF(RAND_INF_HF_ROCK_6) +DEFINE_RAND_INF(RAND_INF_HF_ROCK_7) +DEFINE_RAND_INF(RAND_INF_HF_ROCK_8) +DEFINE_RAND_INF(RAND_INF_HF_BOULDER_NORTH) +DEFINE_RAND_INF(RAND_INF_HF_BOULDER_BY_MARKET) +DEFINE_RAND_INF(RAND_INF_HF_BOULDER_SOUTH) +DEFINE_RAND_INF(RAND_INF_HF_BRONZE_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_HF_BRONZE_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_HF_BRONZE_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_HF_BRONZE_BOULDER_4) +DEFINE_RAND_INF(RAND_INF_KAK_SILVER_BOULDER) +DEFINE_RAND_INF(RAND_INF_KAK_ROCK_1) +DEFINE_RAND_INF(RAND_INF_KAK_ROCK_2) +DEFINE_RAND_INF(RAND_INF_GY_ROCK) +DEFINE_RAND_INF(RAND_INF_LA_ROCK) +DEFINE_RAND_INF(RAND_INF_ZD_CIRCLE_ROCK_1) +DEFINE_RAND_INF(RAND_INF_ZD_CIRCLE_ROCK_2) +DEFINE_RAND_INF(RAND_INF_ZD_CIRCLE_ROCK_3) +DEFINE_RAND_INF(RAND_INF_ZD_CIRCLE_ROCK_4) +DEFINE_RAND_INF(RAND_INF_ZD_CIRCLE_ROCK_5) +DEFINE_RAND_INF(RAND_INF_ZD_CIRCLE_ROCK_6) +DEFINE_RAND_INF(RAND_INF_ZD_CIRCLE_ROCK_7) +DEFINE_RAND_INF(RAND_INF_ZD_CIRCLE_ROCK_8) +DEFINE_RAND_INF(RAND_INF_ZF_BOULDER) +DEFINE_RAND_INF(RAND_INF_ZF_SILVER_BOULDER) +DEFINE_RAND_INF(RAND_INF_ZF_UNDERGROUND_BOULDER) +DEFINE_RAND_INF(RAND_INF_ZR_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_ZR_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_ZR_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_ZR_BOULDER_4) +DEFINE_RAND_INF(RAND_INF_ZR_CIRCLE_ROCK_1) +DEFINE_RAND_INF(RAND_INF_ZR_CIRCLE_ROCK_2) +DEFINE_RAND_INF(RAND_INF_ZR_CIRCLE_ROCK_3) +DEFINE_RAND_INF(RAND_INF_ZR_CIRCLE_ROCK_4) +DEFINE_RAND_INF(RAND_INF_ZR_CIRCLE_ROCK_5) +DEFINE_RAND_INF(RAND_INF_ZR_CIRCLE_ROCK_6) +DEFINE_RAND_INF(RAND_INF_ZR_CIRCLE_ROCK_7) +DEFINE_RAND_INF(RAND_INF_ZR_CIRCLE_ROCK_8) +DEFINE_RAND_INF(RAND_INF_ZR_UPPER_CIRCLE_BOULDER) +DEFINE_RAND_INF(RAND_INF_ZR_UPPER_CIRCLE_ROCK_1) +DEFINE_RAND_INF(RAND_INF_ZR_UPPER_CIRCLE_ROCK_2) +DEFINE_RAND_INF(RAND_INF_ZR_UPPER_CIRCLE_ROCK_3) +DEFINE_RAND_INF(RAND_INF_ZR_UPPER_CIRCLE_ROCK_4) +DEFINE_RAND_INF(RAND_INF_ZR_UPPER_CIRCLE_ROCK_5) +DEFINE_RAND_INF(RAND_INF_ZR_UPPER_CIRCLE_ROCK_6) +DEFINE_RAND_INF(RAND_INF_ZR_UPPER_CIRCLE_ROCK_7) +DEFINE_RAND_INF(RAND_INF_ZR_UPPER_CIRCLE_ROCK_8) +DEFINE_RAND_INF(RAND_INF_ZR_ROCK) +DEFINE_RAND_INF(RAND_INF_ZR_UNDERWATER_ROCK_1) +DEFINE_RAND_INF(RAND_INF_ZR_UNDERWATER_ROCK_2) +DEFINE_RAND_INF(RAND_INF_ZR_UNDERWATER_ROCK_3) +DEFINE_RAND_INF(RAND_INF_ZR_UNDERWATER_ROCK_4) +DEFINE_RAND_INF(RAND_INF_DMT_ROCK_1) +DEFINE_RAND_INF(RAND_INF_DMT_ROCK_2) +DEFINE_RAND_INF(RAND_INF_DMT_ROCK_3) +DEFINE_RAND_INF(RAND_INF_DMT_ROCK_4) +DEFINE_RAND_INF(RAND_INF_DMT_ROCK_5) +DEFINE_RAND_INF(RAND_INF_DMT_SUMMIT_ROCK) +DEFINE_RAND_INF(RAND_INF_DMT_CIRCLE_ROCK_1) +DEFINE_RAND_INF(RAND_INF_DMT_CIRCLE_ROCK_2) +DEFINE_RAND_INF(RAND_INF_DMT_CIRCLE_ROCK_3) +DEFINE_RAND_INF(RAND_INF_DMT_CIRCLE_ROCK_4) +DEFINE_RAND_INF(RAND_INF_DMT_CIRCLE_ROCK_5) +DEFINE_RAND_INF(RAND_INF_DMT_CIRCLE_ROCK_6) +DEFINE_RAND_INF(RAND_INF_DMT_CIRCLE_ROCK_7) +DEFINE_RAND_INF(RAND_INF_DMT_CIRCLE_ROCK_8) +DEFINE_RAND_INF(RAND_INF_DMT_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_DMT_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_DMT_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_DMT_COW_BOULDER) +DEFINE_RAND_INF(RAND_INF_DMT_BRONZE_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_DMT_BRONZE_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_DMT_BRONZE_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_DMT_BRONZE_BOULDER_4) +DEFINE_RAND_INF(RAND_INF_DMT_BRONZE_BOULDER_5) +DEFINE_RAND_INF(RAND_INF_DMT_BRONZE_BOULDER_6) +DEFINE_RAND_INF(RAND_INF_DMT_BRONZE_BOULDER_7) +DEFINE_RAND_INF(RAND_INF_DMT_BRONZE_BOULDER_8) +DEFINE_RAND_INF(RAND_INF_DMT_BRONZE_BOULDER_9) +DEFINE_RAND_INF(RAND_INF_DMT_BRONZE_BOULDER_10) +DEFINE_RAND_INF(RAND_INF_DMT_BRONZE_BOULDER_11) +DEFINE_RAND_INF(RAND_INF_GC_LW_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_GC_LW_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_GC_LW_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_GC_ENTRANCE_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_GC_ENTRANCE_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_GC_ENTRANCE_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_4) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_5) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_6) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_7) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_8) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_9) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_10) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_11) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_12) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_13) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_14) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_15) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_16) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_17) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_18) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_19) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_20) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_21) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_22) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_23) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_24) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_25) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_26) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_27) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_28) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_29) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_BOULDER_4) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_BOULDER_5) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_BOULDER_6) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_BOULDER_7) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_BOULDER_8) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_BOULDER_9) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_BOULDER_10) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_BRONZE_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_BRONZE_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_BRONZE_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_BRONZE_BOULDER_4) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_BRONZE_BOULDER_5) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_ROCK) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_SILVER_BOULDER) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_ROCK) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_1_ROCK_1) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_1_ROCK_2) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_1_ROCK_3) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_1_ROCK_4) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_1_ROCK_5) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_1_ROCK_6) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_1_ROCK_7) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_1_ROCK_8) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_2_ROCK_1) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_2_ROCK_2) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_2_ROCK_3) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_2_ROCK_4) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_2_ROCK_5) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_2_ROCK_6) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_2_ROCK_7) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_2_ROCK_8) +DEFINE_RAND_INF(RAND_INF_HC_STORMS_GROTTO_ROCK_1) +DEFINE_RAND_INF(RAND_INF_HC_STORMS_GROTTO_ROCK_2) +DEFINE_RAND_INF(RAND_INF_HC_STORMS_GROTTO_ROCK_3) +DEFINE_RAND_INF(RAND_INF_HC_STORMS_GROTTO_ROCK_4) +DEFINE_RAND_INF(RAND_INF_HC_STORMS_GROTTO_ROCK_5) +DEFINE_RAND_INF(RAND_INF_HC_STORMS_GROTTO_ROCK_6) +DEFINE_RAND_INF(RAND_INF_HC_STORMS_GROTTO_ROCK_7) +DEFINE_RAND_INF(RAND_INF_HC_STORMS_GROTTO_ROCK_8) +DEFINE_RAND_INF(RAND_INF_BOTW_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_BOTW_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_BOTW_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_BOTW_BOULDER_4) +DEFINE_RAND_INF(RAND_INF_BOTW_BOULDER_5) +DEFINE_RAND_INF(RAND_INF_BOTW_BOULDER_6) +DEFINE_RAND_INF(RAND_INF_DEKU_TREE_MQ_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_DEKU_TREE_MQ_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_DEKU_TREE_MQ_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_4) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_5) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_6) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_7) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_8) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_9) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_10) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_11) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_12) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_TWO_FLAMES_BOULDER) +DEFINE_RAND_INF(RAND_INF_JABU_JABUS_BELLY_MQ_ENTRANCE_BOULDER) +DEFINE_RAND_INF(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_JABU_JABUS_BELLY_MQ_TAILPASARAN_BOULDER) +DEFINE_RAND_INF(RAND_INF_JABU_JABUS_BELLY_MQ_TAILPASARAN_WALL_BOULDER) +DEFINE_RAND_INF(RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_CEILING_BOULDER) +DEFINE_RAND_INF(RAND_INF_SPIRIT_TEMPLE_MQ_EARLY_ADULT_BOULDER) +DEFINE_RAND_INF(RAND_INF_BOTW_MQ_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_BOTW_MQ_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_BOTW_MQ_BOULDER_3) + DEFINE_RAND_INF(RAND_INF_OBTAINED_RUTOS_LETTER) \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index 56935bcaa9e..b24e7b54e4e 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -222,6 +222,8 @@ void Settings::CreateOptions() { OPT_U8(RSK_SHUFFLE_GRASS, "Shuffle Grass", {"Off", "Dungeons", "Overworld", "All Grass/Bushes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleGrass"), mOptionDescriptions[RSK_SHUFFLE_GRASS], WidgetType::Combobox, RO_SHUFFLE_GRASS_OFF); OPT_U8(RSK_SHUFFLE_CRATES, "Shuffle Crates", {"Off", "Dungeons", "Overworld", "All Crates"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleCrates"), mOptionDescriptions[RSK_SHUFFLE_CRATES], WidgetType::Combobox, RO_SHUFFLE_CRATES_OFF); OPT_BOOL(RSK_SHUFFLE_TREES, "Shuffle Trees", CVAR_RANDOMIZER_SETTING("ShuffleTrees"), mOptionDescriptions[RSK_SHUFFLE_TREES]); + OPT_BOOL(RSK_SHUFFLE_ROCKS, "Shuffle Rocks", CVAR_RANDOMIZER_SETTING("ShuffleRocks"), mOptionDescriptions[RSK_SHUFFLE_ROCKS]); + OPT_U8(RSK_SHUFFLE_BOULDERS, "Shuffle Boulders", {"Off", "Dungeons", "Overworld", "All Boulders"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleBoulders"), mOptionDescriptions[RSK_SHUFFLE_BOULDERS], WidgetType::Combobox, RO_SHUFFLE_BOULDERS_OFF); OPT_BOOL(RSK_SHUFFLE_BUSHES, "Shuffle Bushes", CVAR_RANDOMIZER_SETTING("ShuffleBushes"), mOptionDescriptions[RSK_SHUFFLE_BUSHES]); OPT_BOOL(RSK_SHUFFLE_FISHING_POLE, "Shuffle Fishing Pole", CVAR_RANDOMIZER_SETTING("ShuffleFishingPole"), mOptionDescriptions[RSK_SHUFFLE_FISHING_POLE]); OPT_U8(RSK_SHUFFLE_MERCHANTS, "Shuffle Merchants", {"Off", "Bean Merchant Only", "All But Beans", "All"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleMerchants"), mOptionDescriptions[RSK_SHUFFLE_MERCHANTS], WidgetType::Combobox, RO_SHUFFLE_MERCHANTS_OFF, IMFLAG_NONE); @@ -1316,6 +1318,8 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_POTS], &mOptions[RSK_SHUFFLE_CRATES], &mOptions[RSK_SHUFFLE_TREES], + &mOptions[RSK_SHUFFLE_ROCKS], + &mOptions[RSK_SHUFFLE_BOULDERS], &mOptions[RSK_SHUFFLE_BUSHES], &mOptions[RSK_SHUFFLE_MERCHANTS], &mOptions[RSK_MERCHANT_PRICES], diff --git a/soh/soh/Enhancements/randomizer/static_data.h b/soh/soh/Enhancements/randomizer/static_data.h index cd24667a098..b2fe6180ded 100644 --- a/soh/soh/Enhancements/randomizer/static_data.h +++ b/soh/soh/Enhancements/randomizer/static_data.h @@ -62,6 +62,7 @@ class StaticData { static void RegisterGrassLocations(); static void RegisterCrateLocations(); static void RegisterTreeLocations(); + static void RegisterRockLocations(); static void InitHashMaps(); static std::array, 17> randomizerFishingPondFish; static std::unordered_map randomizerGrottoFishMap; diff --git a/soh/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c b/soh/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c index 37dc1fa9db7..fccc1a0d222 100644 --- a/soh/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c +++ b/soh/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c @@ -8,6 +8,7 @@ #include "overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.h" #include "objects/gameplay_field_keep/gameplay_field_keep.h" #include "soh/OTRGlobals.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include "vt.h" @@ -251,6 +252,10 @@ void EnIshi_SpawnDustLarge(EnIshi* this, PlayState* play) { void EnIshi_DropCollectible(EnIshi* this, PlayState* play) { s16 dropParams; + if (!GameInteractor_Should(VB_ROCK_DROP_ITEM, true, this)) { + return; + } + if ((this->actor.params & 1) == ROCK_SMALL) { dropParams = (this->actor.params >> 8) & 0xF; diff --git a/soh/src/overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.c b/soh/src/overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.c index 602236816e0..019a09320c1 100644 --- a/soh/src/overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.c +++ b/soh/src/overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.c @@ -7,6 +7,7 @@ #include "z_obj_bombiwa.h" #include "overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.h" #include "objects/object_bombiwa/object_bombiwa.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS 0 @@ -75,7 +76,7 @@ void ObjBombiwa_InitCollision(Actor* thisx, PlayState* play) { void ObjBombiwa_Init(Actor* thisx, PlayState* play) { Actor_ProcessInitChain(thisx, sInitChain); ObjBombiwa_InitCollision(thisx, play); - if ((Flags_GetSwitch(play, thisx->params & 0x3F) != 0)) { + if (GameInteractor_Should(VB_BOULDER_BREAK_FLAG, Flags_GetSwitch(play, thisx->params & 0x3F), thisx)) { Actor_Kill(thisx); } else { CollisionCheck_SetInfo(&thisx->colChkInfo, NULL, &sColChkInfoInit); diff --git a/soh/src/overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.c b/soh/src/overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.c index d4d952cc0bc..c609992d72b 100644 --- a/soh/src/overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.c +++ b/soh/src/overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.c @@ -6,6 +6,7 @@ #include "z_obj_hamishi.h" #include "objects/gameplay_field_keep/gameplay_field_keep.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS 0 @@ -150,7 +151,7 @@ void ObjHamishi_Init(Actor* thisx, PlayState* play) { ObjHamishi_InitCollision(&this->actor, play); CollisionCheck_SetInfo(&this->actor.colChkInfo, NULL, &sColChkInfoInit); - if (Flags_GetSwitch(play, this->actor.params & 0x3F)) { + if (GameInteractor_Should(VB_BOULDER_BREAK_FLAG, Flags_GetSwitch(play, this->actor.params & 0x3F), this)) { Actor_Kill(&this->actor); return; } From c142b673b9a0fff33cc16baf3b4f779efbe5ee76 Mon Sep 17 00:00:00 2001 From: TheLynk Date: Mon, 8 Dec 2025 18:28:27 +0100 Subject: [PATCH 30/45] clang-format --- soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index cd5ccb4e93a..cbf3d4d571d 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -1500,7 +1500,6 @@ void LoadSettings() { showTrees = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_TREES); - showRocks = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_ROCKS); switch (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_BOULDERS)) { case RO_SHUFFLE_BOULDERS_ALL: From cd7d8713ef05b115b93af185b7cab7d4c2ed04f6 Mon Sep 17 00:00:00 2001 From: TheLynk Date: Fri, 12 Dec 2025 09:55:27 +0100 Subject: [PATCH 31/45] Fix Logic | V:10.1 --- soh/soh/Enhancements/gameplaystats.cpp | 2 +- .../randomizer/location_access/overworld/gerudo_fortress.cpp | 5 ++--- .../randomizer/location_access/overworld/kakariko.cpp | 2 +- .../randomizer/location_access/overworld/market.cpp | 2 +- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/soh/soh/Enhancements/gameplaystats.cpp b/soh/soh/Enhancements/gameplaystats.cpp index befc7357c37..d31370319e6 100644 --- a/soh/soh/Enhancements/gameplaystats.cpp +++ b/soh/soh/Enhancements/gameplaystats.cpp @@ -446,7 +446,7 @@ void DrawGameplayStatsHeader() { // if tag is empty (not a release build) if (gGitCommitTag[0] == 0) { GameplayStatsRow("Git Branch:", (char*)gGitBranch); - GameplayStatsRow("Version : 10.0 | Git Commit Hash:", (char*)gGitCommitHash); + GameplayStatsRow("Version : 10.1 | Git Commit Hash:", (char*)gGitCommitHash); } else { GameplayStatsRow("Build Version:", (char*)gBuildVersion); } diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp index 220469c2dc9..7c6714ab391 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp @@ -223,9 +223,8 @@ void RegionTable_Init_GerudoFortress() { LOCATION(RC_GF_HBA_CANOPY_EAST_CRATE, logic->CanBreakCrates()), LOCATION(RC_GF_HBA_CANOPY_WEST_CRATE, logic->CanBreakCrates()), LOCATION(RC_GF_NORTH_TARGET_EAST_CRATE, logic->CanBreakCrates()), - LOCATION(RC_GF_NORTH_TARGET_WEST_CRATE, logic->IsAdult || (logic->BlastOrSmash() || logic->HookshotOrBoomerang() || logic->CanUse(RG_HOVER_BOOTS))), - //implies logic->CanBreakCrates() - LOCATION(RC_GF_NORTH_TARGET_CHILD_CRATE, logic->IsChild && logic->BlastOrSmash()), + LOCATION(RC_GF_NORTH_TARGET_WEST_CRATE, (logic->IsAdult || (logic->BlastOrSmash() || logic->HookshotOrBoomerang() || logic->CanUse(RG_HOVER_BOOTS))) && logic->CanBreakCrates()), + LOCATION(RC_GF_NORTH_TARGET_CHILD_CRATE, logic->IsChild && logic->BlastOrSmash() && logic->CanBreakCrates()), LOCATION(RC_GF_SOUTH_TARGET_EAST_CRATE, logic->CanBreakCrates()), LOCATION(RC_GF_SOUTH_TARGET_WEST_CRATE, logic->CanBreakCrates()), }, { diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp index 8826007136c..6d05be2fcf7 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp @@ -15,7 +15,7 @@ void RegionTable_Init_Kakariko() { }, { //Locations LOCATION(RC_SHEIK_IN_KAKARIKO, logic->IsAdult && logic->HasItem(RG_FOREST_MEDALLION) && logic->HasItem(RG_FIRE_MEDALLION) && logic->HasItem(RG_WATER_MEDALLION)), - LOCATION(RC_KAK_ANJU_AS_CHILD, logic->IsChild && logic->AtDay), + LOCATION(RC_KAK_ANJU_AS_CHILD, logic->IsChild && logic->AtDay && logic->CanBreakCrates()), //Need Break one crate for get cucoo LOCATION(RC_KAK_ANJU_AS_ADULT, logic->IsAdult && logic->AtDay), LOCATION(RC_KAK_TRADE_POCKET_CUCCO, logic->IsAdult && logic->AtDay && (logic->CanUse(RG_POCKET_EGG) && logic->Get(LOGIC_WAKE_UP_ADULT_TALON))), //Can kill lower kak skulls with pots diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp index 046a0dacbd3..e2dd891b69f 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp @@ -56,7 +56,7 @@ void RegionTable_Init_Market() { }, { //Locations LOCATION(RC_MARKET_10_BIG_POES, logic->IsAdult && (logic->Get(LOGIC_BIG_POE_KILL) || logic->BigPoes >= ctx->GetOption(RSK_BIG_POE_COUNT).Get())), - LOCATION(RC_MARKET_GS_GUARD_HOUSE, logic->IsChild), + LOCATION(RC_MARKET_GS_GUARD_HOUSE, logic->IsChild && logic->CanBreakCrates()), LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_1, logic->IsChild && logic->CanBreakPots()), LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_2, logic->IsChild && logic->CanBreakPots()), LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_3, logic->IsChild && logic->CanBreakPots()), From 94f560e02798fa65983fba22178959bbfe018e1b Mon Sep 17 00:00:00 2001 From: TheLynk Date: Wed, 14 Jan 2026 11:09:32 +0100 Subject: [PATCH 32/45] Major Update | V:11 --- soh/soh/Enhancements/gameplaystats.cpp | 2 +- .../randomizer/3drando/item_pool.cpp | 4 +- soh/soh/Enhancements/randomizer/draw.cpp | 11 - .../dungeons/bottom_of_the_well.cpp | 4 +- .../location_access/dungeons/deku_tree.cpp | 2 +- .../dungeons/dodongos_cavern.cpp | 4 +- .../location_access/dungeons/fire_temple.cpp | 30 +- .../dungeons/forest_temple.cpp | 16 +- .../dungeons/ganons_castle.cpp | 38 +- .../dungeons/gerudo_training_ground.cpp | 2 +- .../location_access/dungeons/ice_cavern.cpp | 6 +- .../dungeons/jabujabus_belly.cpp | 16 +- .../dungeons/shadow_temple.cpp | 4 +- .../dungeons/spirit_temple.cpp | 78 +- .../location_access/dungeons/water_temple.cpp | 68 +- .../overworld/death_mountain_trail.cpp | 2 +- soh/soh/Enhancements/randomizer/settings.cpp | 751 +----------------- 17 files changed, 139 insertions(+), 899 deletions(-) diff --git a/soh/soh/Enhancements/gameplaystats.cpp b/soh/soh/Enhancements/gameplaystats.cpp index fe20ff4dcf2..936a309c193 100644 --- a/soh/soh/Enhancements/gameplaystats.cpp +++ b/soh/soh/Enhancements/gameplaystats.cpp @@ -448,7 +448,7 @@ void DrawGameplayStatsHeader() { // if tag is empty (not a release build) if (gGitCommitTag[0] == 0) { GameplayStatsRow("Git Branch:", (char*)gGitBranch); - GameplayStatsRow("Version : 10.1 | Git Commit Hash:", (char*)gGitCommitHash); + GameplayStatsRow("Version : 11 | Git Commit Hash:", (char*)gGitCommitHash); } else { GameplayStatsRow("Build Version:", (char*)gBuildVersion); } diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index bcbaacb07e1..636a96cd42f 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -388,11 +388,11 @@ void GenerateItemPool() { AddItemToPool(RG_PROGRESSIVE_SCALE, 3 + bronzeScale, 2 + bronzeScale, 2 + bronzeScale, 2 + bronzeScale); if (ctx->GetOption(RSK_SHUFFLE_ROLL)) { - AddItemToMainPool(RG_ROLL); + AddItemToPool(RG_ROLL, 2, 1, 1, 1); } if (ctx->GetOption(RSK_SHUFFLE_OPEN_CHEST)) { - AddItemToMainPool(RG_OPEN_CHEST); + AddItemToPool(RG_OPEN_CHEST, 2, 1, 1, 1); } if (ctx->GetOption(RSK_SHUFFLE_BEEHIVES)) { diff --git a/soh/soh/Enhancements/randomizer/draw.cpp b/soh/soh/Enhancements/randomizer/draw.cpp index 839a2fffe60..91080b0477c 100644 --- a/soh/soh/Enhancements/randomizer/draw.cpp +++ b/soh/soh/Enhancements/randomizer/draw.cpp @@ -945,17 +945,6 @@ extern "C" void DrawGanon(PlayState* play) { CLOSE_DISPS(play->state.gfxCtx); } -extern "C" void Randomizer_DrawBeanSprout(PlayState* play, GetItemEntry* getItemEntry) { - OPEN_DISPS(play->state.gfxCtx); - - Gfx_SetupDL_25Opa(play->state.gfxCtx); - Matrix_Scale(0.3f, 0.3f, 0.3f, MTXMODE_APPLY); - gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_MODELVIEW | G_MTX_LOAD); - gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gMagicBeanSeedlingDL); - - CLOSE_DISPS(play->state.gfxCtx); -} - extern "C" void Randomizer_DrawBossSoul(PlayState* play, GetItemEntry* getItemEntry) { s16 slot; if (getItemEntry->getItemId != RG_ICE_TRAP) { diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/bottom_of_the_well.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/bottom_of_the_well.cpp index c2814f35be9..dac1416750e 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/bottom_of_the_well.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/bottom_of_the_well.cpp @@ -34,7 +34,7 @@ void RegionTable_Init_BottomOfTheWell() { LOCATION(RC_BOTTOM_OF_THE_WELL_FRONT_LEFT_FAKE_WALL_CHEST, (ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_BOTTOM_OF_THE_WELL_RIGHT_BOTTOM_FAKE_WALL_CHEST, (ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_BOTTOM_OF_THE_WELL_FRONT_CENTER_BOMBABLE_CHEST, logic->HasExplosives() && logic->HasItem(RG_OPEN_CHEST)), - LOCATION(RC_BOTTOM_OF_THE_WELL_BACK_LEFT_BOMBABLE_CHEST, (logic->HasExplosives() && (ctx->GetTrickOption(RT_LENS_BOTW) && logic->HasItem(RG_OPEN_CHEST)) || (logic->CanUse(RG_LENS_OF_TRUTH) && logic->HasItem(RG_OPEN_CHEST)))), + LOCATION(RC_BOTTOM_OF_THE_WELL_BACK_LEFT_BOMBABLE_CHEST, (logic->HasExplosives() && logic->HasItem(RG_OPEN_CHEST) && ((ctx->GetTrickOption(RT_LENS_BOTW)) || (logic->CanUse(RG_LENS_OF_TRUTH))))), LOCATION(RC_BOTTOM_OF_THE_WELL_UNDERWATER_FRONT_CHEST, (logic->Get(LOGIC_BOTW_LOWERED_WATER) || logic->CanOpenUnderwaterChest()) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_BOTTOM_OF_THE_WELL_UNDERWATER_LEFT_CHEST, (logic->Get(LOGIC_BOTW_LOWERED_WATER) || logic->CanOpenUnderwaterChest()) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_1, logic->CanBreakPots()), @@ -143,7 +143,7 @@ void RegionTable_Init_BottomOfTheWell() { areaTable[RR_BOTW_BEHIND_MOAT] = Region("Bottom of the Well Behind Moat", SCENE_BOTTOM_OF_THE_WELL, {}, { //Locations - LOCATION(RC_BOTTOM_OF_THE_WELL_UNDERWATER_LEFT_CHEST, logic->Get(LOGIC_BOTW_LOWERED_WATER) || logic->CanOpenUnderwaterChest()), + LOCATION(RC_BOTTOM_OF_THE_WELL_UNDERWATER_LEFT_CHEST, (logic->Get(LOGIC_BOTW_LOWERED_WATER) || logic->CanOpenUnderwaterChest()) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits //Climb always needed in case water is lowered out of logic diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp index 676b945807f..b399f81d58d 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp @@ -313,7 +313,7 @@ void RegionTable_Init_DekuTree() { EventAccess(LOGIC_NUT_ACCESS, []{return logic->CanGetDekuBabaNuts();}), }, { //Locations - LOCATION(RC_DEKU_TREE_MQ_BASEMENT_CHEST, logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW)), + LOCATION(RC_DEKU_TREE_MQ_BASEMENT_CHEST, (logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW)) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_DEKU_TREE_MQ_BASEMENT_LOWER_GRASS_1, logic->CanCutShrubs()), LOCATION(RC_DEKU_TREE_MQ_BASEMENT_LOWER_GRASS_2, logic->CanCutShrubs()), LOCATION(RC_DEKU_TREE_MQ_BASEMENT_LOWER_GRASS_3, logic->CanCutShrubs()), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp index 3abe08624aa..ddeda636cb1 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp @@ -319,7 +319,7 @@ void RegionTable_Init_DodongosCavern() { areaTable[RR_DODONGOS_CAVERN_MQ_OUTSIDE_POES_ROOM] = Region("Dodongos Cavern MQ Outside Poes Room", SCENE_DODONGOS_CAVERN, {}, { //Locations - LOCATION(RC_DODONGOS_CAVERN_MQ_BOMB_BAG_CHEST, true), + LOCATION(RC_DODONGOS_CAVERN_MQ_BOMB_BAG_CHEST, logic->HasItem(RG_OPEN_CHEST)), }, { //Events Entrance(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return true;}), @@ -604,7 +604,7 @@ void RegionTable_Init_DodongosCavern() { }); areaTable[RR_DODONGOS_CAVERN_MQ_BACK_POE_ROOM] = Region("Dodongos Cavern MQ Back Poe Room", SCENE_DODONGOS_CAVERN, {}, { - LOCATION(RC_DODONGOS_CAVERN_MQ_UNDER_GRAVE_CHEST, true), //pulling the grave isn't required, as you can open the chest through it + LOCATION(RC_DODONGOS_CAVERN_MQ_UNDER_GRAVE_CHEST, logic->HasItem(RG_OPEN_CHEST)), //pulling the grave isn't required, as you can open the chest through it LOCATION(RC_DODONGOS_CAVERN_MQ_BACKROOM_POT_1, logic->CanBreakPots()), LOCATION(RC_DODONGOS_CAVERN_MQ_BACKROOM_POT_2, logic->CanBreakPots()), LOCATION(RC_DODONGOS_CAVERN_MQ_BACK_POE_GRASS, logic->CanCutShrubs()), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp index 4703cd70608..2b3a43569ff 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp @@ -27,7 +27,7 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_NEAR_BOSS_ROOM] = Region("Fire Temple Near Boss Room", SCENE_FIRE_TEMPLE, {}, { //Locations - LOCATION(RC_FIRE_TEMPLE_NEAR_BOSS_CHEST, logic->FireTimer() >= 16), + LOCATION(RC_FIRE_TEMPLE_NEAR_BOSS_CHEST, logic->FireTimer() >= 16 && logic->HasItem(RG_OPEN_CHEST)), //It's plausible to get the pots with rang from the larger square platform, but it's a blind shot that likely needs a setup //and I've only been able to get the nearest 2, regardless it's a trick and probably a specific one like GY crate freestanding with rang }, { @@ -68,7 +68,7 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_LOOP_FLARE_DANCER] = Region("Fire Temple Loop Flare Dancer", SCENE_FIRE_TEMPLE, {}, { //Locations - LOCATION(RC_FIRE_TEMPLE_FLARE_DANCER_CHEST, AnyAgeTime([]{return logic->CanKillEnemy(RE_FLARE_DANCER);}) && (logic->IsAdult || logic->CanGroundJump() || logic->CanUse(RG_HOOKSHOT))), + LOCATION(RC_FIRE_TEMPLE_FLARE_DANCER_CHEST, AnyAgeTime([]{return logic->CanKillEnemy(RE_FLARE_DANCER);}) && (logic->IsAdult || logic->CanGroundJump() || logic->CanUse(RG_HOOKSHOT)) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_FIRE_TEMPLE_LOOP_5_TILE_ROOM, []{return AnyAgeTime([]{return logic->CanKillEnemy(RE_FLARE_DANCER);});}), @@ -193,7 +193,7 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_BOULDER_MAZE_LOWER] = Region("Fire Temple Boulder Maze Lower", SCENE_FIRE_TEMPLE, {}, { //Locations - LOCATION(RC_FIRE_TEMPLE_BOULDER_MAZE_LOWER_CHEST, true), + LOCATION(RC_FIRE_TEMPLE_BOULDER_MAZE_LOWER_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_FIRE_TEMPLE_GS_BOULDER_MAZE, logic->HasExplosives() && (logic->IsAdult || logic->HookshotOrBoomerang() || logic->CanGroundJumpJumpSlash())), }, { //Exits @@ -240,7 +240,7 @@ void RegionTable_Init_FireTemple() { //firetimer for entering this area from RR_FIRE_TEMPLE_FIRE_WALL_CHASE is handled there areaTable[RR_FIRE_TEMPLE_FIRE_WALL_CAGE] = Region("Fire Temple Fire Wall Cage", SCENE_FIRE_TEMPLE, {}, { //Locations - LOCATION(RC_FIRE_TEMPLE_MAP_CHEST, logic->FireTimer() >= 8), + LOCATION(RC_FIRE_TEMPLE_MAP_CHEST, logic->FireTimer() >= 8 && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_FIRE_TEMPLE_NARROW_PATH_ROOM, []{return true;}), @@ -276,7 +276,7 @@ void RegionTable_Init_FireTemple() { //RANDOTODO find a better name areaTable[RR_FIRE_TEMPLE_5F_RUINS] = Region("Fire Temple 5F Ruins", SCENE_FIRE_TEMPLE, {}, { //Locations - LOCATION(RC_FIRE_TEMPLE_SCARECROW_CHEST, true), + LOCATION(RC_FIRE_TEMPLE_SCARECROW_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_FIRE_TEMPLE_GS_SCARECROW_TOP, logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_BOMB_THROW)), }, { //Exits @@ -302,7 +302,7 @@ void RegionTable_Init_FireTemple() { Entrance(RR_FIRE_TEMPLE_NEAR_BOSS_ROOM, []{return logic->Get(LOGIC_FIRE_HIT_PLATFORM) && (logic->IsAdult || logic->CanUse(RG_HOVER_BOOTS) || logic->TakeDamage());}), Entrance(RR_FIRE_TEMPLE_CORRIDOR, []{return true;}), Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_PLATFORMS, []{return logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && (logic->Get(LOGIC_FIRE_HIT_ABOVE_MAZE_PLATFORM) || logic->CanGroundJump()));}), - Entrance(RR_FIRE_TEMPLE_CAGELESS_CHEST_ROOM, []{return true;}), + Entrance(RR_FIRE_TEMPLE_CAGELESS_CHEST_ROOM, []{return logic->HasItem(RG_OPEN_CHEST);}), Entrance(RR_FIRE_TEMPLE_SOT_CAGE_LOWER, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 8);}), Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_SWITCH, []{return (bool)ctx->GetTrickOption(RT_FIRE_SKIP_FLAME_WALLS);}), }); @@ -502,7 +502,7 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_MQ_LOOP_FLARE_DANCER] = Region("Fire Temple MQ Loop Flare Dancer", SCENE_FIRE_TEMPLE, {}, { //Locations - LOCATION(RC_FIRE_TEMPLE_MQ_MEGATON_HAMMER_CHEST, (logic->IsAdult || logic->CanUse(RG_HOOKSHOT) || logic->CanGroundJump()) && AnyAgeTime([]{return logic->CanKillEnemy(RE_FLARE_DANCER);})), + LOCATION(RC_FIRE_TEMPLE_MQ_MEGATON_HAMMER_CHEST, (logic->IsAdult || logic->CanUse(RG_HOOKSHOT) || logic->CanGroundJump()) && AnyAgeTime([]{return logic->CanKillEnemy(RE_FLARE_DANCER) && logic->HasItem(RG_OPEN_CHEST);})), }, { //Exits Entrance(RR_FIRE_TEMPLE_MQ_LOOP_5_TILE_ROOM, []{return true;}), @@ -530,7 +530,7 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_MQ_NEAR_BOSS_ROOM] = Region("Fire Temple MQ Near Boss Room", SCENE_FIRE_TEMPLE, {}, { //Locations //If we're using the south torch as the initial torch, or using FAs, we either have to cross to the north to remove the crate, or use a trick to ignore it - LOCATION(RC_FIRE_TEMPLE_MQ_NEAR_BOSS_CHEST, logic->FireTimer() >= 24 && ctx->GetTrickOption(RT_FIRE_MQ_NEAR_BOSS) && (logic->CanUse(RG_FIRE_ARROWS) || (logic->IsAdult && logic->CanUse(RG_DINS_FIRE) && logic->CanUse(RG_FAIRY_BOW)))), + LOCATION(RC_FIRE_TEMPLE_MQ_NEAR_BOSS_CHEST, (logic->FireTimer() >= 24 && ctx->GetTrickOption(RT_FIRE_MQ_NEAR_BOSS) && (logic->CanUse(RG_FIRE_ARROWS) || (logic->IsAdult && logic->CanUse(RG_DINS_FIRE) && logic->CanUse(RG_FAIRY_BOW))) && logic->HasItem(RG_OPEN_CHEST))), LOCATION(RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_1, logic->FireTimer() >= 24 && logic->CanBreakCrates()), LOCATION(RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_2, logic->FireTimer() >= 24 && logic->CanBreakCrates()), @@ -551,7 +551,7 @@ void RegionTable_Init_FireTemple() { //Fairies cannot be used for this as it is time sensetive, and NL is only useful with sticks as it disables other magic while in use, so it's tunic or raw damage taking ability. //testing tells me you take 3 ticks of lava damage, which is 12 internal damage or 3/4 of a heart at x1 damage multiplier, performing this run //logic->EffectiveHealth() works in half hearts for whatever reason, meaning this needs a deeper refactor to be perfect, but it should be good enough for now - LOCATION(RC_FIRE_TEMPLE_MQ_NEAR_BOSS_CHEST, logic->CanUse(RG_DINS_FIRE) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_LONGSHOT) || (logic->IsAdult && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_GORON_TUNIC) || logic->EffectiveHealth() >= 2 || (logic->CanUse(RG_NAYRUS_LOVE) && logic->CanUse(RG_STICKS)))))), + LOCATION(RC_FIRE_TEMPLE_MQ_NEAR_BOSS_CHEST, logic->CanUse(RG_DINS_FIRE) && logic->HasItem(RG_OPEN_CHEST) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_LONGSHOT) || (logic->IsAdult && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_GORON_TUNIC) || logic->EffectiveHealth() >= 2 || (logic->CanUse(RG_NAYRUS_LOVE) && logic->CanUse(RG_STICKS)))))), LOCATION(RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_1, logic->CanBreakPots()), LOCATION(RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_2, logic->CanBreakPots()), LOCATION(RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_5, logic->CanBreakCrates()), @@ -567,7 +567,7 @@ void RegionTable_Init_FireTemple() { //Locations //If we have FAs, we can just remove the crate and use those to light the torches. //otherwise, with Dins, we first light them with dins and then use a bow shot - LOCATION(RC_FIRE_TEMPLE_MQ_NEAR_BOSS_CHEST, logic->CanUse(RG_FIRE_ARROWS) || (logic->CanUse(RG_DINS_FIRE) && logic->CanUse(RG_FAIRY_BOW))), + LOCATION(RC_FIRE_TEMPLE_MQ_NEAR_BOSS_CHEST, (logic->CanUse(RG_FIRE_ARROWS) || (logic->CanUse(RG_DINS_FIRE) && logic->CanUse(RG_FAIRY_BOW))) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_3, logic->CanBreakCrates()), LOCATION(RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_4, logic->CanBreakCrates()), }, { @@ -612,7 +612,7 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_MQ_TORCH_LOCKED_CAGE] = Region("Fire Temple MQ Torch Locked Cage", SCENE_FIRE_TEMPLE, {}, { //Locations - LOCATION(RC_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST, logic->HasFireSource()), + LOCATION(RC_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST, logic->HasFireSource() && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM, []{return true;}), @@ -718,7 +718,7 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_MQ_3F_CURVED_CAGE] = Region("Fire Temple MQ 3F Curved Cage", SCENE_FIRE_TEMPLE, {}, { //Locations - LOCATION(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_SIDE_ROOM_CHEST, true), + LOCATION(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_SIDE_ROOM_CHEST, logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_FIRE_TEMPLE_MQ_MAZE_SWITCH_DOOR, []{return true;}), @@ -726,7 +726,7 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_MQ_MAZE_CRATE_CAGE] = Region("Fire Temple MQ Maze Crate Cage", SCENE_FIRE_TEMPLE, {}, { //Locations - LOCATION(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CHEST, true), + LOCATION(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CRATE_1, logic->CanBreakCrates()), LOCATION(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CRATE_2, logic->CanBreakCrates()), LOCATION(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CRATE_3, logic->CanBreakCrates()), @@ -789,7 +789,7 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_MQ_SHORTCUT_CAGE] = Region("Fire Temple MQ Shortcut Cage", SCENE_FIRE_TEMPLE, {}, { //Locations - LOCATION(RC_FIRE_TEMPLE_MQ_COMPASS_CHEST, true), + LOCATION(RC_FIRE_TEMPLE_MQ_COMPASS_CHEST, logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_FIRE_TEMPLE_MQ_SHORTCUT_CLIMB, []{return logic->Get(LOGIC_FIRE_OPENED_UPPER_SHORTCUT);}), @@ -1006,7 +1006,7 @@ void RegionTable_Init_FireTemple() { //Locations //This requires nothing in N64 logic, but is tight enough to need rollspam with the one-point on which is stricter than I would normally consider in logic //Child basically needs the scarecrow or a bunny hood though due to a worse ledge grab. - LOCATION(RC_FIRE_TEMPLE_MQ_CHEST_ON_FIRE, logic->IsAdult || logic->ReachScarecrow()), + LOCATION(RC_FIRE_TEMPLE_MQ_CHEST_ON_FIRE, (logic->IsAdult || logic->ReachScarecrow()) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits //The dropdown here is unusual in that it hits 1 of 3 locations: RR_FIRE_TEMPLE_MQ_2_FIRE_WALLS_LOWER, RR_FIRE_TEMPLE_MQ_2_FIRE_WALLS_UPPER_DOOR, and RR_FIRE_TEMPLE_MQ_2_FIRE_WALLS_SWITCH diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp index 1a359c914f5..279ca9cd212 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp @@ -76,7 +76,7 @@ void RegionTable_Init_ForestTemple() { EventAccess(LOGIC_FOREST_CLEAR_BETWEEN_JOELLE_AND_BETH, []{return logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2);}), }, { //Locations - LOCATION(RC_FOREST_TEMPLE_FIRST_STALFOS_CHEST, logic->Get(LOGIC_FOREST_CLEAR_BETWEEN_JOELLE_AND_BETH)), + LOCATION(RC_FOREST_TEMPLE_FIRST_STALFOS_CHEST, logic->Get(LOGIC_FOREST_CLEAR_BETWEEN_JOELLE_AND_BETH) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_FOREST_TEMPLE_LOWER_STALFOS_POT_1, logic->CanBreakPots()), LOCATION(RC_FOREST_TEMPLE_LOWER_STALFOS_POT_2, logic->CanBreakPots()), }, { @@ -153,7 +153,7 @@ void RegionTable_Init_ForestTemple() { EventAccess(LOGIC_FOREST_SUMMON_NE_SCARECROW, []{return logic->ScarecrowsSong();}), }, { //Locations - LOCATION(RC_FOREST_TEMPLE_RAISED_ISLAND_COURTYARD_CHEST, true), + LOCATION(RC_FOREST_TEMPLE_RAISED_ISLAND_COURTYARD_CHEST, logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_FOREST_TEMPLE_NE_COURTYARD_LOWER, []{return true;}), @@ -234,7 +234,7 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_MIDDLE_BLOCK_PUSH_ROOM] = Region("Forest Temple Middle Block Push Room", SCENE_FOREST_TEMPLE, {}, { //Locations - LOCATION(RC_FOREST_TEMPLE_EYE_SWITCH_CHEST, logic->CanHitEyeTargets()), + LOCATION(RC_FOREST_TEMPLE_EYE_SWITCH_CHEST, logic->CanHitEyeTargets() && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_FOREST_TEMPLE_LOWER_BLOCK_PUSH_ROOM, []{return true;}), @@ -288,7 +288,7 @@ void RegionTable_Init_ForestTemple() { EventAccess(LOGIC_FOREST_CLEAR_BETWEEN_JOELLE_AND_BETH, []{return logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2);}), }, { //Locations - LOCATION(RC_FOREST_TEMPLE_BOW_CHEST, logic->Get(LOGIC_FOREST_CLEAR_BETWEEN_JOELLE_AND_BETH) && logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 3)), + LOCATION(RC_FOREST_TEMPLE_BOW_CHEST, logic->Get(LOGIC_FOREST_CLEAR_BETWEEN_JOELLE_AND_BETH) && logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 3) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_FOREST_TEMPLE_UPPER_STALFOS_POT_1, logic->CanBreakPots()), LOCATION(RC_FOREST_TEMPLE_UPPER_STALFOS_POT_2, logic->CanBreakPots()), LOCATION(RC_FOREST_TEMPLE_UPPER_STALFOS_POT_3, logic->CanBreakPots()), @@ -338,7 +338,7 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_FALLING_ROOM] = Region("Forest Temple Falling Room", SCENE_FOREST_TEMPLE, {}, { //Locations - LOCATION(RC_FOREST_TEMPLE_FALLING_CEILING_ROOM_CHEST, true), + LOCATION(RC_FOREST_TEMPLE_FALLING_CEILING_ROOM_CHEST, logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_FOREST_TEMPLE_NE_COURTYARD_SCARECROW_LEDGE, []{return true;}), @@ -389,7 +389,7 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_MQ_TREES] = Region("Forest Temple MQ Trees", SCENE_FOREST_TEMPLE, {}, { //Locations - LOCATION(RC_FOREST_TEMPLE_MQ_FIRST_ROOM_CHEST, logic->CanPassEnemy(RE_BIG_SKULLTULA, ED_SHORT_JUMPSLASH, false) || logic->CanUse(RG_HOVER_BOOTS)), + LOCATION(RC_FOREST_TEMPLE_MQ_FIRST_ROOM_CHEST, (logic->CanPassEnemy(RE_BIG_SKULLTULA, ED_SHORT_JUMPSLASH, false) || logic->CanUse(RG_HOVER_BOOTS)) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_FOREST_TEMPLE_ENTRYWAY, []{return true;}), @@ -536,7 +536,7 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_MQ_REDEAD_ROOM] = Region("Forest Temple MQ Redead Room", SCENE_FOREST_TEMPLE, {}, { //Locations - LOCATION(RC_FOREST_TEMPLE_MQ_REDEAD_CHEST, logic->CanKillEnemy(RE_REDEAD)), + LOCATION(RC_FOREST_TEMPLE_MQ_REDEAD_CHEST, logic->CanKillEnemy(RE_REDEAD) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_FOREST_TEMPLE_MQ_NW_COURTYARD_LEDGE, []{return AnyAgeTime([]{return logic->CanKillEnemy(RE_REDEAD);});}), @@ -588,7 +588,7 @@ void RegionTable_Init_ForestTemple() { EventAccess(LOGIC_FOREST_DRAINED_WELL, []{return logic->CanHitEyeTargets();}), }, { //Locations - LOCATION(RC_FOREST_TEMPLE_MQ_WELL_CHEST, logic->Get(LOGIC_FOREST_DRAINED_WELL) || (logic->CanOpenUnderwaterChest() && logic->WaterTimer() >= 8)), + LOCATION(RC_FOREST_TEMPLE_MQ_WELL_CHEST, (logic->Get(LOGIC_FOREST_DRAINED_WELL) || (logic->CanOpenUnderwaterChest() && logic->WaterTimer() >= 8)) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_FOREST_TEMPLE_MQ_GS_RAISED_ISLAND_COURTYARD, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)), //implies logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA) LOCATION(RC_FOREST_TEMPLE_MQ_GS_WELL, logic->Get(LOGIC_FOREST_DRAINED_WELL) || (logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT))), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp index ca668cffa34..fe8cd0b3d2d 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/ganons_castle.cpp @@ -63,7 +63,7 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_FOREST_TRIAL_WOLFOS_ROOM] = Region("Ganon's Castle Forest Trial Wolfos Room", SCENE_INSIDE_GANONS_CASTLE, {}, { //Locations - LOCATION(RC_GANONS_CASTLE_FOREST_TRIAL_CHEST, logic->CanKillEnemy(RE_WOLFOS)), + LOCATION(RC_GANONS_CASTLE_FOREST_TRIAL_CHEST, logic->CanKillEnemy(RE_WOLFOS) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_GANONS_CASTLE_MAIN, []{return true;}), @@ -137,8 +137,8 @@ void RegionTable_Init_GanonsCastle() { EventAccess(LOGIC_BLUE_FIRE_ACCESS, []{return logic->CanClearStalagmite() || ctx->GetTrickOption(RT_ICE_STALAGMITE_CLIP);}), }, { //Locations - LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_LEFT_CHEST, true), - LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_RIGHT_CHEST, true), + LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_LEFT_CHEST, logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_RIGHT_CHEST, logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_GANONS_CASTLE_MAIN, []{return true;}), @@ -177,8 +177,8 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_SHADOW_TRIAL_START] = Region("Ganon's Castle Shadow Trial Main Room", SCENE_INSIDE_GANONS_CASTLE, {}, { //Locations - LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_FRONT_CHEST, logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_SONG_OF_TIME) || logic->IsChild), - LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_GOLDEN_GAUNTLETS_CHEST, logic->CanUse(RG_FIRE_ARROWS) || (logic->CanUse(RG_LONGSHOT) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_DINS_FIRE)))), + LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_FRONT_CHEST, (logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_SONG_OF_TIME) || logic->IsChild) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_GOLDEN_GAUNTLETS_CHEST, (logic->CanUse(RG_FIRE_ARROWS) || (logic->CanUse(RG_LONGSHOT) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_DINS_FIRE)))) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_POT_1, logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_LONGSHOT)), LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_POT_2, logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_LONGSHOT)), 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))), @@ -214,7 +214,7 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_SPIRIT_TRIAL_BEFORE_SWITCH] = Region("Ganon's Castle Spirit Trial Before Switch", SCENE_INSIDE_GANONS_CASTLE, {}, { //Locations - LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_CRYSTAL_SWITCH_CHEST, logic->CanJumpslash() || logic->HasExplosives() || logic->CanUse(RG_GIANTS_KNIFE)), + LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_CRYSTAL_SWITCH_CHEST, (logic->CanJumpslash() || logic->HasExplosives() || logic->CanUse(RG_GIANTS_KNIFE)) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_GANONS_CASTLE_SPIRIT_TRIAL_BEAMOS_ROOM, []{return true;}), @@ -223,8 +223,8 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_SPIRIT_TRIAL_AFTER_SWITCH] = Region("Ganon's Castle Spirit Trial After Switch", SCENE_INSIDE_GANONS_CASTLE, {}, { //Locations - LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_CRYSTAL_SWITCH_CHEST, logic->CanHitSwitch()), - LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_INVISIBLE_CHEST, ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH)), + LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_CRYSTAL_SWITCH_CHEST, (logic->CanHitSwitch()) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_INVISIBLE_CHEST, (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_GANONS_CASTLE_SPIRIT_TRIAL_BEFORE_SWITCH, []{return true;}), @@ -246,13 +246,13 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_LIGHT_TRIAL_CHESTS_ROOM] = Region("Ganon's Castle Light Trial Chests Room", SCENE_INSIDE_GANONS_CASTLE, {}, { //Locations - LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_FIRST_LEFT_CHEST, true), - LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_SECOND_LEFT_CHEST, true), - LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_THIRD_LEFT_CHEST, true), - LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_FIRST_RIGHT_CHEST, true), - LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_SECOND_RIGHT_CHEST, true), - LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_THIRD_RIGHT_CHEST, true), - LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_INVISIBLE_ENEMIES_CHEST, (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanKillEnemy(RE_BIG_SKULLTULA) && logic->CanKillEnemy(RE_KEESE, ED_CLOSE, true, 3))), + LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_FIRST_LEFT_CHEST, logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_SECOND_LEFT_CHEST, logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_THIRD_LEFT_CHEST, logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_FIRST_RIGHT_CHEST, logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_SECOND_RIGHT_CHEST, logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_THIRD_RIGHT_CHEST, logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_INVISIBLE_ENEMIES_CHEST, (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanKillEnemy(RE_BIG_SKULLTULA) && logic->CanKillEnemy(RE_KEESE, ED_CLOSE, true, 3)) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_GANONS_CASTLE_MAIN, []{return true;}), @@ -261,7 +261,7 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_LIGHT_TRIAL_TRIFORCE_ROOM] = Region("Ganon's Castle Light Trial Triforce Room", SCENE_INSIDE_GANONS_CASTLE, {}, { //Locations - LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_LULLABY_CHEST, logic->CanUse(RG_ZELDAS_LULLABY)), + LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_LULLABY_CHEST, logic->CanUse(RG_ZELDAS_LULLABY) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_GANONS_CASTLE_LIGHT_TRIAL_CHESTS_ROOM, []{return true;}), @@ -358,7 +358,7 @@ void RegionTable_Init_GanonsCastle() { EventAccess(LOGIC_FOREST_TRIAL_MQ_SPAWN_BEAMOS_CHEST, []{return logic->CanHitEyeTargets();}) }, { //Locations - LOCATION(RC_GANONS_CASTLE_MQ_FOREST_TRIAL_EYE_SWITCH_CHEST, logic->Get(LOGIC_FOREST_TRIAL_MQ_SPAWN_BEAMOS_CHEST)), + LOCATION(RC_GANONS_CASTLE_MQ_FOREST_TRIAL_EYE_SWITCH_CHEST, logic->Get(LOGIC_FOREST_TRIAL_MQ_SPAWN_BEAMOS_CHEST) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_GANONS_CASTLE_MQ_FOREST_TRIAL_STALFOS_ROOM, []{return true;}), @@ -370,7 +370,7 @@ void RegionTable_Init_GanonsCastle() { EventAccess(LOGIC_FOREST_TRIAL_MQ_SPAWN_BEAMOS_CHEST, []{return logic->CanHitEyeTargets();}) }, { //Locations - LOCATION(RC_GANONS_CASTLE_MQ_FOREST_TRIAL_FROZEN_EYE_SWITCH_CHEST, logic->HasFireSource()), + LOCATION(RC_GANONS_CASTLE_MQ_FOREST_TRIAL_FROZEN_EYE_SWITCH_CHEST, logic->HasFireSource() && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_GANONS_CASTLE_MQ_FOREST_TRIAL_BEAMOS_ROOM, []{return logic->Get(LOGIC_FOREST_TRIAL_MQ_SPAWN_BEAMOS_CHEST) && (logic->CanAvoidEnemy(RE_BEAMOS) || logic->CanKillEnemy(RE_ARMOS)) && logic->CanUse(RG_LONGSHOT);}), @@ -500,7 +500,7 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_MQ_SHADOW_TRIAL_FAR_SIDE] = Region("Ganon's Castle MQ Shadow Trial Far Side", SCENE_INSIDE_GANONS_CASTLE, {}, { //Locations - LOCATION(RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_EYE_SWITCH_CHEST, logic->CanHitEyeTargets()), + LOCATION(RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_EYE_SWITCH_CHEST, logic->CanHitEyeTargets() && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_GANONS_CASTLE_MQ_SHADOW_TRIAL_BEAMOS_TORCH, []{return logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_HOVER_BOOTS);}), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp index e6407c185ab..ec245988d47 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp @@ -101,7 +101,7 @@ void RegionTable_Init_GerudoTrainingGround() { LOCATION(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FIRST_CHEST, logic->CanKillEnemy(RE_LIKE_LIKE) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_SECOND_CHEST, logic->CanKillEnemy(RE_LIKE_LIKE) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_THIRD_CHEST, (ctx->GetTrickOption(RT_LENS_GTG) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanPassEnemy(RE_LIKE_LIKE) && logic->HasItem(RG_OPEN_CHEST)), - LOCATION(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FOURTH_CHEST, logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FOURTH_CHEST, logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_GERUDO_TRAINING_GROUND_BEHIND_HEAVY_BLOCK, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp index 4324e997f87..cb266125a61 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp @@ -66,7 +66,7 @@ void RegionTable_Init_IceCavern() { EventAccess(LOGIC_BLUE_FIRE_ACCESS, []{return true;}), }, { //Locations - LOCATION(RC_ICE_CAVERN_COMPASS_CHEST, (logic->IsChild || logic->CanClearStalagmite() || ctx->GetTrickOption(RT_ICE_STALAGMITE_CLIP)) && logic->BlueFire()), + LOCATION(RC_ICE_CAVERN_COMPASS_CHEST, (logic->IsChild || logic->CanClearStalagmite() || ctx->GetTrickOption(RT_ICE_STALAGMITE_CLIP)) && logic->BlueFire() && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_ICE_CAVERN_FREESTANDING_POH, (logic->CanClearStalagmite() || ctx->GetTrickOption(RT_ICE_STALAGMITE_CLIP)) && logic->BlueFire()), // can skip blue fire with rang trick LOCATION(RC_ICE_CAVERN_GS_HEART_PIECE_ROOM, logic->HookshotOrBoomerang()), }, { @@ -104,7 +104,7 @@ void RegionTable_Init_IceCavern() { areaTable[RR_ICE_CAVERN_FINAL_ROOM] = Region("Ice Cavern Final Room", SCENE_ICE_CAVERN, {}, { //Locations - LOCATION(RC_ICE_CAVERN_IRON_BOOTS_CHEST, AnyAgeTime([]{return logic->CanKillEnemy(RE_WOLFOS);})), + LOCATION(RC_ICE_CAVERN_IRON_BOOTS_CHEST, AnyAgeTime([]{return logic->CanKillEnemy(RE_WOLFOS) && logic->HasItem(RG_OPEN_CHEST);})), LOCATION(RC_SHEIK_IN_ICE_CAVERN, AnyAgeTime([]{return logic->CanKillEnemy(RE_WOLFOS);})), // rando enables this for child }, { //Exits @@ -165,7 +165,7 @@ void RegionTable_Init_IceCavern() { EventAccess(LOGIC_BLUE_FIRE_ACCESS, []{return logic->IsChild || logic->CanClearStalagmite() || ctx->GetTrickOption(RT_ICE_STALAGMITE_CLIP);}), }, { //Locations - LOCATION(RC_ICE_CAVERN_MQ_MAP_CHEST, logic->BlueFire() && AnyAgeTime([]{return logic->CanHitSwitch();})), + LOCATION(RC_ICE_CAVERN_MQ_MAP_CHEST, logic->BlueFire() && AnyAgeTime([]{return logic->CanHitSwitch() && logic->HasItem(RG_OPEN_CHEST);})), }, {}); areaTable[RR_ICE_CAVERN_MQ_SCARECROW_ROOM] = Region("Ice Cavern MQ Scarecrow Room", SCENE_ICE_CAVERN, { diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/jabujabus_belly.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/jabujabus_belly.cpp index c2ddef2a359..7eb44d24456 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/jabujabus_belly.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/jabujabus_belly.cpp @@ -130,7 +130,7 @@ void RegionTable_Init_JabuJabusBelly() { EventAccess(LOGIC_JABU_WEST_TENTACLE, []{return logic->CanKillEnemy(RE_TENTACLE, ED_BOOMERANG);}), }, { //Locations - LOCATION(RC_JABU_JABUS_BELLY_MAP_CHEST, logic->Get(LOGIC_JABU_WEST_TENTACLE)), + LOCATION(RC_JABU_JABUS_BELLY_MAP_CHEST, logic->Get(LOGIC_JABU_WEST_TENTACLE) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_JABU_JABUS_BELLY_FORKED_CORRIDOR, []{return true;}), @@ -146,7 +146,7 @@ void RegionTable_Init_JabuJabusBelly() { areaTable[RR_JABU_JABUS_BELLY_FORK_NORTH_WEST] = Region("Jabu Jabus Belly Fork North West", SCENE_JABU_JABU, {}, { //Locations //ruto could theoretically clear this room, but it's hard because of the timer and she doesn't appear with you when you respawn after failing, which would force a savewarp - LOCATION(RC_JABU_JABUS_BELLY_COMPASS_CHEST, logic->CanKillEnemy(RE_SHABOM, ED_CLOSE, false, 9)), + LOCATION(RC_JABU_JABUS_BELLY_COMPASS_CHEST, logic->CanKillEnemy(RE_SHABOM, ED_CLOSE, false, 9) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_JABU_JABUS_BELLY_TO_FORK_NORTH_WEST, []{return AnyAgeTime([]{return logic->CanKillEnemy(RE_SHABOM, ED_CLOSE, false, 9);});}), @@ -186,7 +186,7 @@ void RegionTable_Init_JabuJabusBelly() { areaTable[RR_JABU_JABUS_BELLY_FORK_EAST] = Region("Jabu Jabus Belly Fork East", SCENE_JABU_JABU, {}, { //Locations //We can kill the Stingers with ruto - LOCATION(RC_JABU_JABUS_BELLY_BOOMERANG_CHEST, logic->Get(LOGIC_JABU_RUTO_IN_1F) || logic->CanKillEnemy(RE_STINGER, ED_CLOSE, true, 4)), + LOCATION(RC_JABU_JABUS_BELLY_BOOMERANG_CHEST, logic->Get(LOGIC_JABU_RUTO_IN_1F) || logic->CanKillEnemy(RE_STINGER, ED_CLOSE, true, 4) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_JABU_JABUS_BELLY_FORKED_CORRIDOR, []{return true;}), @@ -330,8 +330,8 @@ void RegionTable_Init_JabuJabusBelly() { areaTable[RR_JABU_JABUS_BELLY_MQ_HOLES_BASEMENT] = Region("Jabu Jabus Belly MQ Holes Basement", SCENE_JABU_JABU, {}, { //Locations - LOCATION(RC_JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_VINES_CHEST, logic->CanUse(RG_FAIRY_SLINGSHOT)), - LOCATION(RC_JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_SWITCHES_CHEST, logic->CanUse(RG_FAIRY_SLINGSHOT)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_VINES_CHEST, logic->CanUse(RG_FAIRY_SLINGSHOT) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_SWITCHES_CHEST, logic->CanUse(RG_FAIRY_SLINGSHOT) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_1, logic->CanCutShrubs()), LOCATION(RC_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_2, logic->CanCutShrubs()), LOCATION(RC_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_3, logic->CanCutShrubs()), @@ -353,9 +353,9 @@ void RegionTable_Init_JabuJabusBelly() { EventAccess(LOGIC_JABU_MQ_WATER_SWITCH_LIFT_ACCESS, []{return logic->CanKillEnemy(RE_LIZALFOS);}), }, { //Locations - LOCATION(RC_JABU_JABUS_BELLY_MQ_BOOMERANG_ROOM_SMALL_CHEST, true), - LOCATION(RC_JABU_JABUS_BELLY_MQ_BOOMERANG_CHEST, logic->CanKillEnemy(RE_LIZALFOS)), - LOCATION(RC_JABU_JABUS_BELLY_MQ_GS_BOOMERANG_CHEST_ROOM, (logic->CanUse(RG_SONG_OF_TIME) && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)) || (ctx->GetTrickOption(RT_JABU_MQ_SOT_GS) && logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_JABU_JABUS_BELLY_MQ_BOOMERANG_ROOM_SMALL_CHEST, logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_BOOMERANG_CHEST, logic->CanKillEnemy(RE_LIZALFOS) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_GS_BOOMERANG_CHEST_ROOM, ((logic->CanUse(RG_SONG_OF_TIME) && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)) || (ctx->GetTrickOption(RT_JABU_MQ_SOT_GS) && logic->CanUse(RG_BOOMERANG))) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_1, logic->CanBreakPots()), LOCATION(RC_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_2, logic->CanBreakPots()), LOCATION(RC_JABU_JABUS_BELLY_MQ_BASEMENT_BOOMERANG_GRASS, logic->CanCutShrubs()), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp index 825112e2986..e964fe36b71 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp @@ -180,8 +180,8 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_INVISIBLE_SPINNING_BLADES] = Region("Shadow Temple Invisible Spinning Blades", SCENE_SHADOW_TEMPLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_VISIBLE_CHEST, logic->CanKillEnemy(RE_LIKE_LIKE) && logic->CanKillEnemy(RE_KEESE)), - LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_INVISIBLE_CHEST, logic->CanKillEnemy(RE_LIKE_LIKE) && logic->CanKillEnemy(RE_KEESE) && (ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_VISIBLE_CHEST, logic->CanKillEnemy(RE_LIKE_LIKE) && logic->CanKillEnemy(RE_KEESE) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_INVISIBLE_CHEST, (logic->CanKillEnemy(RE_LIKE_LIKE) && logic->CanKillEnemy(RE_KEESE) && (ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH))) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_SHADOW_TEMPLE_GS_LIKE_LIKE_ROOM, AnyAgeTime([]{return logic->CanKillEnemy(RE_LIKE_LIKE) && logic->CanKillEnemy(RE_KEESE);}) && ((logic->IsAdult && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_SHORT_JUMPSLASH)) || logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG))), //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)), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp index 470496deeb6..9d606e20dd8 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp @@ -60,7 +60,7 @@ void RegionTable_Init_SpiritTemple() { EventAccess(LOGIC_SPIRIT_CHILD_SWITCH_BRIDGE, []{return logic->CanHitSwitch();}), }, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_CHILD_BRIDGE_CHEST, true), + LOCATION(RC_SPIRIT_TEMPLE_CHILD_BRIDGE_CHEST, logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_SPIRIT_TEMPLE_SWITCH_BRIDGE_SOUTH, []{return logic->CanUse(RG_HOVER_BOOTS) || (logic->Get(LOGIC_SPIRIT_CHILD_SWITCH_BRIDGE) && logic->CanPassEnemy(RE_GREEN_BUBBLE, ED_CLOSE, false));}), @@ -85,7 +85,7 @@ void RegionTable_Init_SpiritTemple() { }, { //Locations // these assume SpiritRupeeBridge, silver rupee shuffle & shuffle climb will want to adjust - LOCATION(RC_SPIRIT_TEMPLE_CHILD_EARLY_TORCHES_CHEST, logic->HasFireSourceWithTorch()), + LOCATION(RC_SPIRIT_TEMPLE_CHILD_EARLY_TORCHES_CHEST, logic->HasFireSourceWithTorch() && logic->HasItem(RG_OPEN_CHEST)), // possible to collect without lowering fence, should be a trick LOCATION(RC_SPIRIT_TEMPLE_GS_METAL_FENCE, logic->Get(LOGIC_SPIRIT_SILVER_RUPEE_BRIDGE) && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_BOMB_THROW)), }, { @@ -126,8 +126,8 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_SUN_ON_FLOOR_2F] = Region("Spirit Temple Sun On Floor 2F", SCENE_SPIRIT_TEMPLE, {}, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_CHILD_CLIMB_NORTH_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_SUN_ON_FLOOR_2F, []{return logic->CanHitSwitch(ED_BOMB_THROW);})), - LOCATION(RC_SPIRIT_TEMPLE_CHILD_CLIMB_EAST_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_SUN_ON_FLOOR_2F, []{return logic->CanHitSwitch(ED_BOMB_THROW);})), + LOCATION(RC_SPIRIT_TEMPLE_CHILD_CLIMB_NORTH_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_SUN_ON_FLOOR_2F, []{return logic->CanHitSwitch(ED_BOMB_THROW) && logic->HasItem(RG_OPEN_CHEST);})), + LOCATION(RC_SPIRIT_TEMPLE_CHILD_CLIMB_EAST_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_SUN_ON_FLOOR_2F, []{return logic->CanHitSwitch(ED_BOMB_THROW) && logic->HasItem(RG_OPEN_CHEST);})), LOCATION(RC_SPIRIT_TEMPLE_GS_SUN_ON_FLOOR_ROOM, SpiritShared(RR_SPIRIT_TEMPLE_SUN_ON_FLOOR_2F, []{return logic->CanKillEnemy(RE_GOLD_SKULLTULA, logic->TakeDamage() ? ED_SHORT_JUMPSLASH : ED_BOMB_THROW);}, false, RR_SPIRIT_TEMPLE_SUN_ON_FLOOR_1F, []{return logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG);})), }, { @@ -147,7 +147,7 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_SAND_PIT] = Region("Spirit Temple Sand Pit", SCENE_SPIRIT_TEMPLE, {}, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_COMPASS_CHEST, logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_ZELDAS_LULLABY)), + LOCATION(RC_SPIRIT_TEMPLE_COMPASS_CHEST, logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_ZELDAS_LULLABY) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_SPIRIT_TEMPLE_ADULT_SIDE_HUB, []{return true;}), @@ -176,7 +176,7 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_PAST_BOULDERS] = Region("Spirit Temple Past Boulders", SCENE_SPIRIT_TEMPLE, {}, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_EARLY_ADULT_RIGHT_CHEST, true), + LOCATION(RC_SPIRIT_TEMPLE_EARLY_ADULT_RIGHT_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)), }, { //Exits @@ -191,8 +191,8 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_2F_MIRROR_ROOM] = Region("Spirit Temple 2F Mirror Room", SCENE_SPIRIT_TEMPLE, {}, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_FIRST_MIRROR_LEFT_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_2F_MIRROR_ROOM, []{return true/*str0 || SunlightArrows()*/;})), - LOCATION(RC_SPIRIT_TEMPLE_FIRST_MIRROR_RIGHT_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_2F_MIRROR_ROOM, []{return true/*str0 || SunlightArrows()*/;})), + LOCATION(RC_SPIRIT_TEMPLE_FIRST_MIRROR_LEFT_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_2F_MIRROR_ROOM, []{return logic->HasItem(RG_OPEN_CHEST)/*str0 || SunlightArrows()*/;})), + LOCATION(RC_SPIRIT_TEMPLE_FIRST_MIRROR_RIGHT_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_2F_MIRROR_ROOM, []{return logic->HasItem(RG_OPEN_CHEST)/*str0 || SunlightArrows()*/;})), }, { //Exits Entrance(RR_SPIRIT_TEMPLE_1F_MIRROR_ROOM, []{return true;}), @@ -202,7 +202,7 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_STATUE_ROOM_CHILD] = Region("Spirit Temple Statue Rooom Child", SCENE_SPIRIT_TEMPLE, {}, { //Locations //Assumes RR_SPIRIT_TEMPLE_STATUE_ROOM access - LOCATION(RC_SPIRIT_TEMPLE_MAP_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_STATUE_ROOM_CHILD, []{return logic->HasFireSourceWithTorch() || (ctx->GetTrickOption(RT_SPIRIT_MAP_CHEST) && logic->CanUse(RG_FAIRY_BOW));}, false, + LOCATION(RC_SPIRIT_TEMPLE_MAP_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_STATUE_ROOM_CHILD, []{return (logic->HasFireSourceWithTorch() || (ctx->GetTrickOption(RT_SPIRIT_MAP_CHEST) && logic->CanUse(RG_FAIRY_BOW)) && logic->HasItem(RG_OPEN_CHEST));}, false, RR_SPIRIT_TEMPLE_STATUE_ROOM, []{return logic->HasFireSource();})), LOCATION(RC_SPIRIT_TEMPLE_GS_LOBBY, SpiritShared(RR_SPIRIT_TEMPLE_STATUE_ROOM_CHILD, []{return logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_LONGSHOT);}, false, RR_SPIRIT_TEMPLE_INNER_WEST_HAND, []{return logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ctx->GetTrickOption(RT_SPIRIT_WEST_LEDGE) ? ED_BOOMERANG : ED_HOOKSHOT);}, @@ -249,7 +249,7 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_STATUE_ROOM] = Region("Spirit Temple Statue Room", SCENE_SPIRIT_TEMPLE, {}, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_MAP_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_STATUE_ROOM, []{return logic->HasFireSource();}, false, + LOCATION(RC_SPIRIT_TEMPLE_MAP_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_STATUE_ROOM, []{return logic->HasFireSource() && logic->HasItem(RG_OPEN_CHEST);}, false, RR_SPIRIT_TEMPLE_STATUE_ROOM_CHILD, []{return logic->HasFireSourceWithTorch() || (ctx->GetTrickOption(RT_SPIRIT_MAP_CHEST) && logic->CanUse(RG_FAIRY_BOW));})), LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_1, SpiritShared(RR_SPIRIT_TEMPLE_STATUE_ROOM, []{return logic->CanBreakPots();})), LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_2, SpiritShared(RR_SPIRIT_TEMPLE_STATUE_ROOM, []{return logic->CanBreakPots();})), @@ -301,9 +301,9 @@ void RegionTable_Init_SpiritTemple() { //Locations //Spawning the chest to get here is accounted for in movement logic, so we only need to confirm it can be spawned here LOCATION(RC_SPIRIT_TEMPLE_SUN_BLOCK_ROOM_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_SUN_BLOCK_CHEST_LEDGE, - []{return logic->HasFireSource() || + []{return (logic->HasFireSource() || (logic->Get(LOGIC_SPIRIT_SUN_BLOCK_TORCH) && //Possible without str0 by timing a shot during a backflip from the ledge, but it's probably a separate trick - (logic->CanUse(RG_STICKS) || (ctx->GetTrickOption(RT_SPIRIT_SUN_CHEST) && logic->CanUse(RG_FAIRY_BOW)/* && str0*/)));})), + (logic->CanUse(RG_STICKS) || (ctx->GetTrickOption(RT_SPIRIT_SUN_CHEST) && logic->CanUse(RG_FAIRY_BOW)) && logic->HasItem(RG_OPEN_CHEST)/* && str0*/)));})), }, { //Exits Entrance(RR_SPIRIT_TEMPLE_SUN_BLOCK_ROOM, []{return true;}), @@ -334,7 +334,7 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_OUTER_RIGHT_HAND] = Region("Spirit Temple Outer Right Hand", SCENE_SPIRIT_TEMPLE, {}, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_OUTER_RIGHT_HAND, []{return true;})), + LOCATION(RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_OUTER_RIGHT_HAND, []{return logic->HasItem(RG_OPEN_CHEST);})), }, { //Exits Entrance(RR_SPIRIT_TEMPLE_RIGHT_HAND_EXIT, []{return true;}), @@ -357,7 +357,7 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_INNER_LEFT_HAND] = Region("Spirit Temple Inner Left Hand", SCENE_SPIRIT_TEMPLE, {}, { //Locations //Assumes RR_SPIRIT_TEMPLE_INNER_WEST_HAND access via RR_SPIRIT_TEMPLE_STATUE_ROOM_CHILD and RR_SPIRIT_TEMPLE_STATUE_ROOM. - LOCATION(RC_SPIRIT_TEMPLE_STATUE_ROOM_HAND_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_INNER_LEFT_HAND, []{return logic->CanUse(RG_ZELDAS_LULLABY)/* && CanClimb()*/;})), + LOCATION(RC_SPIRIT_TEMPLE_STATUE_ROOM_HAND_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_INNER_LEFT_HAND, []{return logic->CanUse(RG_ZELDAS_LULLABY) && logic->HasItem(RG_OPEN_CHEST)/* && CanClimb()*/;})), }, { //Exits Entrance(RR_SPIRIT_TEMPLE_STATUE_ROOM, []{return true;}), @@ -373,7 +373,7 @@ void RegionTable_Init_SpiritTemple() { }, { //Locations //Assumes RR_SPIRIT_TEMPLE_INNER_LEFT_HAND access - LOCATION(RC_SPIRIT_TEMPLE_STATUE_ROOM_NORTHEAST_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_SHORTCUT_SWITCH, []{return logic->CanUse(RG_ZELDAS_LULLABY);})), + LOCATION(RC_SPIRIT_TEMPLE_STATUE_ROOM_NORTHEAST_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_SHORTCUT_SWITCH, []{return logic->CanUse(RG_ZELDAS_LULLABY) && logic->HasItem(RG_OPEN_CHEST);})), }, { //Exits Entrance(RR_SPIRIT_TEMPLE_STATUE_ROOM_ADULT, []{return true;}), @@ -403,7 +403,7 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_4_ARMOS] = Region("Spirit Temple 4 Armos", SCENE_SPIRIT_TEMPLE, {}, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_NEAR_FOUR_ARMOS_CHEST, (logic->CanUse(RG_MIRROR_SHIELD) || logic->SunlightArrows()) && logic->HasExplosives()), + LOCATION(RC_SPIRIT_TEMPLE_NEAR_FOUR_ARMOS_CHEST, ((logic->CanUse(RG_MIRROR_SHIELD) || logic->SunlightArrows()) && logic->HasExplosives()) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY, logic->HasExplosives() && logic->CanUse(RG_SUNS_SONG)), }, { Entrance(RR_SPIRIT_TEMPLE_BEAMOS_PITS, []{return true;}), @@ -413,7 +413,7 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_4_ARMOS_SIDE_ROOM] = Region("Spirit Temple 4 Armos Side Room", SCENE_SPIRIT_TEMPLE, {}, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_NEAR_FOUR_ARMOS_CHEST, true), + LOCATION(RC_SPIRIT_TEMPLE_NEAR_FOUR_ARMOS_CHEST, logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_SPIRIT_TEMPLE_4_ARMOS, []{return true;}), @@ -421,8 +421,8 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_CHEST_STAIRS] = Region("Spirit Temple Chest Stairs", SCENE_SPIRIT_TEMPLE, {}, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_HALLWAY_LEFT_INVISIBLE_CHEST, ctx->GetTrickOption(RT_LENS_SPIRIT) || logic->CanUse(RG_LENS_OF_TRUTH)), - LOCATION(RC_SPIRIT_TEMPLE_HALLWAY_RIGHT_INVISIBLE_CHEST, ctx->GetTrickOption(RT_LENS_SPIRIT) || logic->CanUse(RG_LENS_OF_TRUTH)), + LOCATION(RC_SPIRIT_TEMPLE_HALLWAY_LEFT_INVISIBLE_CHEST, (ctx->GetTrickOption(RT_LENS_SPIRIT) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_SPIRIT_TEMPLE_HALLWAY_RIGHT_INVISIBLE_CHEST, (ctx->GetTrickOption(RT_LENS_SPIRIT) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_SPIRIT_TEMPLE_4_ARMOS, []{return true;}), @@ -443,7 +443,7 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_OUTER_LEFT_HAND] = Region("Spirit Temple Outer Left Hand", SCENE_SPIRIT_TEMPLE, {}, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST, true), + LOCATION(RC_SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST, logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_SPIRIT_TEMPLE_LEFT_HAND_EXIT, []{return true;}), @@ -479,9 +479,9 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_FAKE_DOORS_ROOM] = Region("Spirit Temple Fake Doors Room", SCENE_SPIRIT_TEMPLE, {}, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_BOSS_KEY_CHEST, (logic->TakeDamage() && ctx->GetTrickOption(RT_FLAMING_CHESTS)) || + LOCATION(RC_SPIRIT_TEMPLE_BOSS_KEY_CHEST, ((logic->TakeDamage() && ctx->GetTrickOption(RT_FLAMING_CHESTS)) || (AnyAgeTime([]{return logic->CanHitEyeTargets() && logic->CanAvoidEnemy(RE_TORCH_SLUG, true, 4);}) - && logic->CanUse(RG_HOOKSHOT))), + && logic->CanUse(RG_HOOKSHOT))) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_SPIRIT_TEMPLE_4F_CENTRAL, []{return true;}), @@ -508,7 +508,7 @@ void RegionTable_Init_SpiritTemple() { EventAccess(LOGIC_SPIRIT_PUSHED_4F_MIRRORS, []{return logic->HasExplosives()/*&& str0*/;}), }, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_TOPMOST_CHEST, (logic->IsAdult && logic->CanUse(RG_MIRROR_SHIELD)) || logic->SunlightArrows()), + LOCATION(RC_SPIRIT_TEMPLE_TOPMOST_CHEST, ((logic->IsAdult && logic->CanUse(RG_MIRROR_SHIELD)) || logic->SunlightArrows()) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_SPIRIT_TEMPLE_BIG_MIRROR_ROOM, []{return true;}), @@ -552,10 +552,10 @@ void RegionTable_Init_SpiritTemple() { EventAccess(LOGIC_FORWARDS_SPIRIT_ADULT, []{return logic->IsAdult;}), }, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_LEFT_CHEST, true), - LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_LEFT_CHEST, AnyAgeTime([]{return logic->BlastOrSmash();}) && logic->CanHitEyeTargets()), - LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_RIGHT_CHEST, logic->CanHitSwitch(ED_BOOMERANG)), - LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_RIGHT_CHEST, logic->Get(LOGIC_SPIRIT_1F_SILVER_RUPEES)), + LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_LEFT_CHEST, logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_LEFT_CHEST, AnyAgeTime([]{return logic->BlastOrSmash();}) && logic->CanHitEyeTargets() && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_RIGHT_CHEST, logic->CanHitSwitch(ED_BOOMERANG) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_RIGHT_CHEST, logic->Get(LOGIC_SPIRIT_1F_SILVER_RUPEES) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_1, logic->CanBreakPots()), LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_2, logic->CanBreakPots()), LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_3, logic->CanBreakPots()), @@ -582,14 +582,14 @@ void RegionTable_Init_SpiritTemple() { LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_SLUGMA_POT, logic->CanBreakPots()), LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_LEFT_HEART, logic->CanHitEyeTargets()), LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_RIGHT_HEART, logic->CanHitEyeTargets()), - LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_HAMMER_SWITCH_CHEST, logic->Get(LOGIC_SPIRIT_MQ_TIME_TRAVEL_CHEST)), + LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_HAMMER_SWITCH_CHEST, logic->Get(LOGIC_SPIRIT_MQ_TIME_TRAVEL_CHEST) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits //Nabooru's legs are technically visible one way collision here, but I'm not sure if this counts Entrance(RR_SPIRIT_TEMPLE_MQ_FOYER, []{return logic->IsChild/*logic->CanUse(RG_CRAWL)*/;}), Entrance(RR_SPIRIT_TEMPLE_MQ_GIBDO_GRAVES, []{return AnyAgeTime([]{return logic->CanKillEnemy(RE_TORCH_SLUG);});}), - Entrance(RR_SPIRIT_TEMPLE_MQ_ANUBIS_BRIDGE_CHEST, []{return AnyAgeTime([]{return logic->CanKillEnemy(RE_TORCH_SLUG);});}), - Entrance(RR_SPIRIT_TEMPLE_MQ_1F_CHEST_SWITCH, []{return logic->IsChild/*logic->CanUse(RG_CRAWL)*/ && logic->Get(LOGIC_SPIRIT_MQ_CRAWL_BOULDER);}), + Entrance(RR_SPIRIT_TEMPLE_MQ_ANUBIS_BRIDGE_CHEST, []{return AnyAgeTime([]{return logic->CanKillEnemy(RE_TORCH_SLUG) && logic->HasItem(RG_OPEN_CHEST);});}), + Entrance(RR_SPIRIT_TEMPLE_MQ_1F_CHEST_SWITCH, []{return logic->IsChild/*logic->CanUse(RG_CRAWL)*/ && logic->Get(LOGIC_SPIRIT_MQ_CRAWL_BOULDER) && logic->HasItem(RG_OPEN_CHEST);}), }); areaTable[RR_SPIRIT_TEMPLE_MQ_GIBDO_GRAVES] = Region("Spirit Temple MQ Gibdo Graves", SCENE_SPIRIT_TEMPLE, { @@ -689,9 +689,9 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_MQ_SUN_ON_FLOOR] = Region("Spirit Temple MQ Sun on Floor Room", SCENE_SPIRIT_TEMPLE, {}, { //Locations //Implies CanKillEnemy(RE_LIKE_LIKE) - LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_NORTH_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_MQ_SUN_ON_FLOOR, []{return logic->CanKillEnemy(RE_BEAMOS);})), + LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_NORTH_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_MQ_SUN_ON_FLOOR, []{return logic->CanKillEnemy(RE_BEAMOS) && logic->HasItem(RG_OPEN_CHEST);})), //Sunlights only temp spawn this chest, which is unintuitive/a bug. - LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_SOUTH_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_MQ_SUN_ON_FLOOR, []{return (logic->HasExplosives() || logic->SunlightArrows()) && logic->CanUse(RG_HOOKSHOT);})), + LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_SOUTH_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_MQ_SUN_ON_FLOOR, []{return ((logic->HasExplosives() || logic->SunlightArrows()) && logic->CanUse(RG_HOOKSHOT)) && logic->HasItem(RG_OPEN_CHEST);})), }, { //Exits Entrance(RR_SPIRIT_TEMPLE_MQ_UNDER_LIKE_LIKE, []{return logic->CanHitSwitch();}), @@ -764,7 +764,7 @@ void RegionTable_Init_SpiritTemple() { EventAccess(LOGIC_SPIRIT_MQ_STATUE_ROOM_TORCHES, []{return logic->CanUse(RG_FIRE_ARROWS) || (ctx->GetTrickOption(RT_SPIRIT_MQ_LOWER_ADULT) && logic->CanUse(RG_DINS_FIRE));}), }, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_MQ_COMPASS_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return logic->CanHitEyeTargets();})), + LOCATION(RC_SPIRIT_TEMPLE_MQ_COMPASS_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return logic->CanHitEyeTargets() && logic->HasItem(RG_OPEN_CHEST);})), LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_2F_CENTER_EAST_POT, SpiritShared(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return logic->CanBreakPots();})), LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_2F_WEST_POT, SpiritShared(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return logic->CanBreakPots();})), LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_2F_EASTMOST_POT, SpiritShared(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return logic->CanBreakPots();})), @@ -791,7 +791,7 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM] = Region("Spirit Temple MQ Sun Block Room", SCENE_SPIRIT_TEMPLE, {}, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM, []{return true/*str0*/;})), + LOCATION(RC_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM, []{return logic->HasItem(RG_OPEN_CHEST)/*str0*/;})), //RT_SPIRIT_MQ_SUN_BLOCK_GS should probably be expanded to cover all ground based methods when str0 is added, as it can be hit with longshot because the skull hitbox is larger than the model LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_SUN_BLOCK_ROOM, SpiritShared(RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM, []{return (logic->CanUse(RG_HOOKSHOT)/* && (str0 || SunlightArrows())*/) || (ctx->GetTrickOption(RT_SPIRIT_MQ_SUN_BLOCK_GS) && logic->CanUse(RG_BOOMERANG));})), @@ -823,7 +823,7 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_MQ_OUTER_RIGHT_HAND] = Region("Spirit Temple MQ Outer Right Hand", SCENE_SPIRIT_TEMPLE, {}, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_MQ_OUTER_RIGHT_HAND, []{return true;})), + LOCATION(RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_MQ_OUTER_RIGHT_HAND, []{return logic->HasItem(RG_OPEN_CHEST);})), }, { //Exits //If it is ever relevent for 1 age to spawn the mirror shield chest for the other can longshot across, it needs an eventAccess @@ -843,7 +843,7 @@ void RegionTable_Init_SpiritTemple() { //Locations //Hard child locked because pushing the block is a permanent flag that blocks the eye target and cannot be undone //but it resets as Child as a rando QoL feature - LOCATION(RC_SPIRIT_TEMPLE_MQ_SILVER_BLOCK_HALLWAY_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_MQ_BIG_BLOCKS_DOOR, []{return logic->IsChild && logic->CanHitEyeTargets();})), + LOCATION(RC_SPIRIT_TEMPLE_MQ_SILVER_BLOCK_HALLWAY_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_MQ_BIG_BLOCKS_DOOR, []{return logic->IsChild && logic->CanHitEyeTargets() && logic->HasItem(RG_OPEN_CHEST);})), }, { //Exits //if going to RR_SPIRIT_TEMPLE_MQ_BIG_BLOCKS_HOLE from here is ever relevant, there needs to be an event to handle the block @@ -877,7 +877,7 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_MQ_INNER_LEFT_HAND] = Region("Spirit Temple MQ Inner East Hand", SCENE_SPIRIT_TEMPLE, {}, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_ROOM_LULLABY_CHEST, logic->CanUse(RG_ZELDAS_LULLABY) && logic->CanBreakCrates()), + LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_ROOM_LULLABY_CHEST, logic->CanUse(RG_ZELDAS_LULLABY) && logic->CanBreakCrates() && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return true;}), @@ -888,7 +888,7 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_MQ_CHEST_LEDGE] = Region("Spirit Temple MQ Chest Ledge", SCENE_SPIRIT_TEMPLE, {}, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_ROOM_INVISIBLE_CHEST, ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)), + LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_ROOM_INVISIBLE_CHEST, (ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return true;}), @@ -980,7 +980,7 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_MQ_BEAMOS_PITS] = Region("Spirit Temple MQ Beamos Pits", SCENE_SPIRIT_TEMPLE, {}, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_MQ_BEAMOS_ROOM_CHEST, logic->CanKillEnemy(RE_BEAMOS)), + LOCATION(RC_SPIRIT_TEMPLE_MQ_BEAMOS_ROOM_CHEST, logic->CanKillEnemy(RE_BEAMOS) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_SPIRIT_TEMPLE_MQ_BEAMOS_SMALL_CRATE, logic->CanAvoidEnemy(RE_BEAMOS, true, 4) && logic->CanUse(RG_SONG_OF_TIME) && logic->CanBreakSmallCrates()), }, { //Exits diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp index 0aed4b9d558..686de6f3f11 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp @@ -175,7 +175,7 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_4_SPIKES_ROOM] = Region("Water Temple 4 Spikes Room", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_MAP_CHEST, AnyAgeTime([]{return logic->CanKillEnemy(RE_SPIKE, ED_CLOSE, true, 4);})), + LOCATION(RC_WATER_TEMPLE_MAP_CHEST, AnyAgeTime([]{return logic->CanKillEnemy(RE_SPIKE, ED_CLOSE, true, 4) && logic->HasItem(RG_OPEN_CHEST);})), }, { //Exits Entrance(RR_WATER_TEMPLE_SIDE_TOWER_1F, []{return AnyAgeTime([]{return logic->CanKillEnemy(RE_SPIKE, ED_CLOSE, true, 4);});}), @@ -183,7 +183,7 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_CRACKED_WALL] = Region("Water Temple Cracked Wall", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_CRACKED_WALL_CHEST, logic->WaterLevel(WL_LOW_OR_MID) || logic->CanOpenUnderwaterChest()), + LOCATION(RC_WATER_TEMPLE_CRACKED_WALL_CHEST, (logic->WaterLevel(WL_LOW_OR_MID) || logic->CanOpenUnderwaterChest()) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_WATER_TEMPLE_SIDE_TOWER_2F, []{return true;}), @@ -191,8 +191,8 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_TORCH_ROOM] = Region("Water Temple Torch Room", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_TORCHES_CHEST, AnyAgeTime([]{return (logic->WaterLevel(WL_LOW) && logic->CanKillEnemy(RE_SHELL_BLADE, ED_CLOSE, true, 3)) || - logic->CanOpenUnderwaterChest();})), + LOCATION(RC_WATER_TEMPLE_TORCHES_CHEST, AnyAgeTime([]{return ((logic->WaterLevel(WL_LOW) && logic->CanKillEnemy(RE_SHELL_BLADE, ED_CLOSE, true, 3)) || + logic->CanOpenUnderwaterChest()) && logic->HasItem(RG_OPEN_CHEST);})), }, { //Exits Entrance(RR_WATER_TEMPLE_SIDE_TOWER_1F, []{return ((logic->WaterLevel(WL_LOW) || logic->CanUse(RG_IRON_BOOTS)) && @@ -215,7 +215,7 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_BOULDERS_SOUTH] = Region("Water Temple Boulders South", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST, logic->CanUse(RG_LONGSHOT)), + LOCATION(RC_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST, logic->CanUse(RG_LONGSHOT) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_WATER_TEMPLE_BEHIND_SPIKE_MOAT, []{return logic->SmallKeys(SCENE_WATER_TEMPLE, 4);}), @@ -285,11 +285,11 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_CANAL_ALCOVE] = Region("Water Temple Canal Alcove", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG) || + LOCATION(RC_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST, (logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG) || //child can also do a hovers backwalk backflip to reach the token after killing the skull ((logic->IsAdult || (ctx->GetTrickOption(RT_GROUND_JUMP_HARD) && logic->CanGroundJump())) && //killing with bombchu from here is hard due to the terrain, but adult can do it much easier from the river so it's only relevant for child - logic->CanUse(RG_HOVER_BOOTS) && logic->CanKillEnemy(RE_GOLD_SKULLTULA, logic->HasItem(RG_BRONZE_SCALE) && logic->IsAdult ? ED_SHORT_JUMPSLASH : ED_BOOMERANG))), + logic->CanUse(RG_HOVER_BOOTS) && logic->CanKillEnemy(RE_GOLD_SKULLTULA, logic->HasItem(RG_BRONZE_SCALE) && logic->IsAdult ? ED_SHORT_JUMPSLASH : ED_BOOMERANG))) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_WATER_TEMPLE_3_JETS_SWITCH, []{return true;}), @@ -299,7 +299,7 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_BOULDER_CANAL] = Region("Water Temple Boulder Canal", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST, (logic->IsAdult && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)) || (logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT))), + LOCATION(RC_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST, ((logic->IsAdult && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)) || (logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT))) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits //making the jump as adult without jumpslash is possible, but hard enough to be a trick @@ -311,7 +311,7 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_BEHIND_CANAL] = Region("Water Temple Behind Canal", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST, logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT) && logic->WaterTimer() >= 8), + LOCATION(RC_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST, logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT) && logic->WaterTimer() >= 8 && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_WATER_TEMPLE_BOULDER_CANAL, []{return logic->HasItem(RG_BRONZE_SCALE);}), @@ -373,10 +373,10 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_DRAGON_ROOM] = Region("Water Temple Dragon Room", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_DRAGON_CHEST, logic->HasItem(RG_BRONZE_SCALE) && + LOCATION(RC_WATER_TEMPLE_DRAGON_CHEST, (logic->HasItem(RG_BRONZE_SCALE) && ((logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_IRON_BOOTS)) || (((logic->IsAdult && ctx->GetTrickOption(RT_WATER_ADULT_DRAGON)) || (logic->IsChild && ctx->GetTrickOption(RT_WATER_CHILD_DRAGON))) && - logic->CanHitSwitch(ED_BOOMERANG, true) && (logic->HasItem(RG_SILVER_SCALE) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8))))), + logic->CanHitSwitch(ED_BOOMERANG, true) && (logic->HasItem(RG_SILVER_SCALE) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8))))) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_WATER_TEMPLE_1_JET_PIT, []{return true;}), @@ -418,7 +418,7 @@ void RegionTable_Init_WaterTemple() { //Assuming tunic and irons was checked on entry areaTable[RR_WATER_TEMPLE_PILLAR_B1] = Region("Water Temple Pillar B1", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_CENTRAL_PILLAR_CHEST, logic->CanUse(RG_HOOKSHOT) && logic->HasItem(RG_BRONZE_SCALE)), + LOCATION(RC_WATER_TEMPLE_CENTRAL_PILLAR_CHEST, logic->CanUse(RG_HOOKSHOT) && logic->HasItem(RG_BRONZE_SCALE) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits //Can't know water level, so we'll just assume any possibility and skip to MAIN @@ -427,7 +427,7 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_JET_CHEST_ROOM] = Region("Water Temple Jet Chest Room", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_COMPASS_CHEST, logic->CanUseProjectile()), + LOCATION(RC_WATER_TEMPLE_COMPASS_CHEST, logic->CanUseProjectile() && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_WATER_TEMPLE_NEAR_COMPASS_POT_1, logic->CanBreakPots()), LOCATION(RC_WATER_TEMPLE_NEAR_COMPASS_POT_2, logic->CanBreakPots()), LOCATION(RC_WATER_TEMPLE_NEAR_COMPASS_POT_3, logic->CanBreakPots()), @@ -477,7 +477,7 @@ void RegionTable_Init_WaterTemple() { //Currently assumes WL_LOW_OR_MID as there's no way to reach it on WL_HIGH in logic, this will need splitting if one is added areaTable[RR_WATER_TEMPLE_BLOCK_LOOP_BACK] = Region("Water Temple Block Loop Back", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_CENTRAL_BOW_TARGET_CHEST, true), + LOCATION(RC_WATER_TEMPLE_CENTRAL_BOW_TARGET_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_WATER_TEMPLE_CENTRAL_BOW_POT_1, logic->CanBreakPots()), LOCATION(RC_WATER_TEMPLE_CENTRAL_BOW_POT_2, logic->CanBreakPots()), }, {}); @@ -601,10 +601,10 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_ABOVE_DRAGON] = Region("Water Temple Above Dragon", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_RIVER_CHEST, true), - LOCATION(RC_WATER_TEMPLE_DRAGON_CHEST, logic->IsAdult && logic->CanHitSwitch(ED_LONGSHOT) && logic->HasItem(RG_BRONZE_SCALE) && + LOCATION(RC_WATER_TEMPLE_RIVER_CHEST, logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_WATER_TEMPLE_DRAGON_CHEST, (logic->IsAdult && logic->CanHitSwitch(ED_LONGSHOT) && logic->HasItem(RG_BRONZE_SCALE) && ((ctx->GetTrickOption(RT_WATER_ADULT_DRAGON) && (logic->HasItem(RG_SILVER_SCALE) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8))) || - ctx->GetTrickOption(RT_WATER_DRAGON_JUMP_DIVE))), + ctx->GetTrickOption(RT_WATER_DRAGON_JUMP_DIVE))) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_WATER_TEMPLE_DRAGON_ROOM, []{return logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_LONGSHOT) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS) && logic->CanJumpslash());}), @@ -791,7 +791,7 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_MQ_SIDE_TOWER_2F] = Region("Water Temple MQ Side Tower 2F", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_MQ_LONGSHOT_CHEST, logic->CanUse(RG_HOOKSHOT) && (logic->WaterLevel(WL_MID) || logic->CanOpenUnderwaterChest())), + LOCATION(RC_WATER_TEMPLE_MQ_LONGSHOT_CHEST, (logic->CanUse(RG_HOOKSHOT) && (logic->WaterLevel(WL_MID) || logic->CanOpenUnderwaterChest())) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_WATER_TEMPLE_MQ_SIDE_TOWER_1F, []{return logic->WaterLevel(WL_LOW) || logic->CanUse(RG_IRON_BOOTS);}), @@ -812,7 +812,7 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_MQ_3_STALFOS_ROOM] = Region("Water Temple MQ 3 Stalfos Room", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_MQ_MAP_CHEST, logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_WATER_TEMPLE_MQ_MAP_CHEST, logic->CanUse(RG_HOOKSHOT) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_WATER_TEMPLE_MQ_LOW_EMBLEM, []{return logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 4);}), @@ -823,7 +823,7 @@ void RegionTable_Init_WaterTemple() { EventAccess(LOGIC_WATER_MQ_SIDE_TOWER_TARGETS, []{return logic->CanKillEnemy(RE_LIZALFOS) && logic->CanKillEnemy(RE_SPIKE);}), }, { //Locations - LOCATION(RC_WATER_TEMPLE_MQ_COMPASS_CHEST, logic->Get(LOGIC_WATER_MQ_SIDE_TOWER_TARGETS)), + LOCATION(RC_WATER_TEMPLE_MQ_COMPASS_CHEST, logic->Get(LOGIC_WATER_MQ_SIDE_TOWER_TARGETS) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_WATER_TEMPLE_MQ_SIDE_TOWER_1F, []{return true;}), @@ -903,7 +903,7 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_MQ_PILLAR_B1_FINAL] = Region("Water Temple MQ Central Pillar B1 Final", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_CHEST, logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_CHEST, logic->CanUse(RG_HOOKSHOT) && logic->HasItem(RG_OPEN_CHEST)), }, {}); areaTable[RR_WATER_TEMPLE_MQ_STORAGE_ROOM] = Region("Water Temple MQ Storage Room", SCENE_WATER_TEMPLE, {}, { @@ -1181,7 +1181,7 @@ void RegionTable_Init_WaterTemple() { //Exits Entrance(RR_WATER_TEMPLE_MQ_DRAGON_ROOM_DOOR, []{return true;}), Entrance(RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_PIT, []{return true;}), - Entrance(RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_CHEST, []{return logic->CanHitSwitch() && AnyAgeTime([]{return logic->CanUse(RG_DINS_FIRE);});}), + Entrance(RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_CHEST, []{return logic->CanHitSwitch() && AnyAgeTime([]{return logic->CanUse(RG_DINS_FIRE) && logic->HasItem(RG_OPEN_CHEST);});}), }); //this exists for the crates in preparation for clips through the grate @@ -1221,14 +1221,14 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_MQ_TRIANGLE_TORCH_ROOM] = Region("Water Temple MQ Triangle Torch Room", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_1, (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()) || + LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_1, (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)) || (logic->CanUse(RG_BOMBCHU_5) && logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_2, (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()) || + LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_2, (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)) || (logic->CanUse(RG_BOMBCHU_5) && logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_3, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_4, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_5, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_6, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), + LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_3, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), + LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_4, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), + LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_5, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), + LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_6, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), }, { //Exits Entrance(RR_WATER_TEMPLE_MQ_MAIN, []{return logic->Get(LOGIC_WATER_MQ_B1_SWITCH) && ((logic->WaterLevel(WL_LOW) && logic->HasItem(RG_GOLDEN_SCALE)) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 40 && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_LONGSHOT))));}), @@ -1280,12 +1280,12 @@ void RegionTable_Init_WaterTemple() { //Locations LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_FRONT_CRATE_1, logic->CanBreakCrates()), LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_FRONT_CRATE_2, logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_1, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_2, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_3, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_4, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_5, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_6, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), + LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_1, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), + LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_2, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), + LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_3, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), + LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_4, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), + LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_5, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), + LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_6, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), }, { //Exits Entrance(RR_WATER_TEMPLE_MQ_BEHIND_SPIKE_MOAT, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_trail.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_trail.cpp index 049daec35f5..fd3b564a4b3 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_trail.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_trail.cpp @@ -10,7 +10,7 @@ void RegionTable_Init_DeathMountainTrail() { EventAccess(LOGIC_FAIRY_ACCESS, []{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET));}), }, { //Locations - LOCATION(RC_DMT_CHEST, logic->BlastOrSmash() || (ctx->GetTrickOption(RT_DMT_BOMBABLE) && logic->IsChild && logic->HasItem(RG_GORONS_BRACELET))), + LOCATION(RC_DMT_CHEST, (logic->BlastOrSmash() || (ctx->GetTrickOption(RT_DMT_BOMBABLE) && logic->IsChild && logic->HasItem(RG_GORONS_BRACELET))) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_DMT_FREESTANDING_POH, logic->TakeDamage() || logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && CanPlantBean(RR_DEATH_MOUNTAIN_TRAIL, RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET)))), LOCATION(RC_DMT_GS_BEAN_PATCH, logic->CanSpawnSoilSkull(RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL) && (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()), diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index ded90c62cee..86305585c81 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -789,7 +789,7 @@ void Settings::CreateOptions() { OPT_U8(RSK_SHUFFLE_CRATES, "Shuffle Crates", {"Off", "Dungeons", "Overworld", "All Crates"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleCrates"), mOptionDescriptions[RSK_SHUFFLE_CRATES], WIDGET_CVAR_COMBOBOX, RO_SHUFFLE_CRATES_OFF); OPT_BOOL(RSK_SHUFFLE_TREES, "Shuffle Trees", CVAR_RANDOMIZER_SETTING("ShuffleTrees"), mOptionDescriptions[RSK_SHUFFLE_TREES]); OPT_BOOL(RSK_SHUFFLE_ROCKS, "Shuffle Rocks", CVAR_RANDOMIZER_SETTING("ShuffleRocks"), mOptionDescriptions[RSK_SHUFFLE_ROCKS]); - OPT_U8(RSK_SHUFFLE_BOULDERS, "Shuffle Boulders", {"Off", "Dungeons", "Overworld", "All Boulders"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleBoulders"), mOptionDescriptions[RSK_SHUFFLE_BOULDERS], WidgetType::Combobox, RO_SHUFFLE_BOULDERS_OFF); + OPT_U8(RSK_SHUFFLE_BOULDERS, "Shuffle Boulders", {"Off", "Dungeons", "Overworld", "All Boulders"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleBoulders"), mOptionDescriptions[RSK_SHUFFLE_BOULDERS], WIDGET_CVAR_COMBOBOX, RO_SHUFFLE_BOULDERS_OFF); OPT_BOOL(RSK_SHUFFLE_BUSHES, "Shuffle Bushes", CVAR_RANDOMIZER_SETTING("ShuffleBushes"), mOptionDescriptions[RSK_SHUFFLE_BUSHES]); OPT_BOOL(RSK_SHUFFLE_FISHING_POLE, "Shuffle Fishing Pole", CVAR_RANDOMIZER_SETTING("ShuffleFishingPole"), mOptionDescriptions[RSK_SHUFFLE_FISHING_POLE]); OPT_CALLBACK(RSK_SHUFFLE_FISHING_POLE, { @@ -2443,57 +2443,6 @@ void Settings::CreateOptions() { std::initializer_list{ &mOptionGroups[RSG_MENU_SECTION_HINTS], &mOptionGroups[RSG_MENU_SECTION_TRAPS] }, WidgetContainerType::COLUMN); -<<<<<<< - mOptionGroups[RSG_ITEMS_IMGUI_TABLE] = OptionGroup::SubGroup("Items", - { - &mOptionGroups[RSG_SHUFFLE_ITEMS_IMGUI], - &mOptionGroups[RSG_SHUFFLE_NPCS_IMGUI], - &mOptionGroups[RSG_SHUFFLE_DUNGEON_ITEMS_IMGUI], - }, - WidgetContainerType::TABLE); - mOptionGroups[RSG_TIMESAVERS_IMGUI] = OptionGroup::SubGroup( - "Timesavers", - { &mOptions[RSK_BIG_POE_COUNT], &mOptions[RSK_SKIP_CHILD_ZELDA], &mOptions[RSK_SKIP_EPONA_RACE], - &mOptions[RSK_COMPLETE_MASK_QUEST], &mOptions[RSK_SKIP_SCARECROWS_SONG], &mOptions[RSK_SKIP_PLANTING_BEANS] }, - WidgetContainerType::COLUMN); - mOptionGroups[RSG_ITEM_POOL_HINTS_IMGUI] = OptionGroup::SubGroup("", - { - &mOptions[RSK_ITEM_POOL], - &mOptions[RSK_ICE_TRAPS], - &mOptions[RSK_GOSSIP_STONE_HINTS], - &mOptions[RSK_HINT_CLARITY], - &mOptions[RSK_HINT_DISTRIBUTION], - }, - WidgetContainerType::SECTION); - mOptionGroups[RSG_EXTRA_HINTS_IMGUI] = OptionGroup::SubGroup( - "Extra Hints", - { &mOptions[RSK_TOT_ALTAR_HINT], - &mOptions[RSK_GANONDORF_HINT], - &mOptions[RSK_SHEIK_LA_HINT], - &mOptions[RSK_DAMPES_DIARY_HINT], - &mOptions[RSK_GREG_HINT], - &mOptions[RSK_LOACH_HINT], - &mOptions[RSK_SARIA_HINT], - &mOptions[RSK_MIDO_HINT], - &mOptions[RSK_FROGS_HINT], - &mOptions[RSK_OOT_HINT], - &mOptions[RSK_BIGGORON_HINT], - &mOptions[RSK_BIG_POES_HINT], - &mOptions[RSK_CHICKENS_HINT], - &mOptions[RSK_MALON_HINT], - &mOptions[RSK_HBA_HINT], - &mOptions[RSK_FISHING_POLE_HINT], - &mOptions[RSK_WARP_SONG_HINTS], - &mOptions[RSK_SCRUB_TEXT_HINT], - &mOptions[RSK_MERCHANT_TEXT_HINT], - &mOptions[RSK_KAK_10_SKULLS_HINT], - &mOptions[RSK_KAK_20_SKULLS_HINT], - &mOptions[RSK_KAK_30_SKULLS_HINT], - &mOptions[RSK_KAK_40_SKULLS_HINT], - &mOptions[RSK_KAK_50_SKULLS_HINT], - &mOptions[RSK_KAK_100_SKULLS_HINT], - &mOptions[RSK_MASK_SHOP_HINT] }, -======= mOptionGroups[RSG_MENU_SECTION_STATIC_HINTS] = OptionGroup::SubGroup( "Static Hints", { &mOptions[RSK_TOT_ALTAR_HINT], &mOptions[RSK_GANONDORF_HINT], &mOptions[RSK_SHEIK_LA_HINT], &mOptions[RSK_BOSS_KEY_HINT], @@ -2509,7 +2458,6 @@ void Settings::CreateOptions() { &mOptions[RSK_KAK_30_SKULLS_HINT], &mOptions[RSK_KAK_40_SKULLS_HINT], &mOptions[RSK_KAK_50_SKULLS_HINT], &mOptions[RSK_KAK_100_SKULLS_HINT], &mOptions[RSK_MASK_SHOP_HINT] }, ->>>>>>> WidgetContainerType::SECTION, "This setting adds some hints at locations other than Gossip Stones."); mOptionGroups[RSG_MENU_COLUMN_STATIC_HINTS] = OptionGroup::SubGroup("", { &mOptionGroups[RSG_MENU_SECTION_STATIC_HINTS] }, WidgetContainerType::COLUMN); @@ -2973,703 +2921,6 @@ void Settings::UpdateAllOptions() { for (auto& option : mOptions) { option.RunCallback(); } -<<<<<<< - mOptions[RSK_GERUDO_FORTRESS].Enable(); - mOptions[RSK_RAINBOW_BRIDGE].Enable(); - mOptions[RSK_BRIDGE_OPTIONS].Enable(); - mOptions[RSK_RAINBOW_BRIDGE_STONE_COUNT].Enable(); - mOptions[RSK_RAINBOW_BRIDGE_MEDALLION_COUNT].Enable(); - mOptions[RSK_RAINBOW_BRIDGE_REWARD_COUNT].Enable(); - mOptions[RSK_RAINBOW_BRIDGE_DUNGEON_COUNT].Enable(); - mOptions[RSK_RAINBOW_BRIDGE_TOKEN_COUNT].Enable(); - const uint8_t bridgeOpt = CVarGetInteger(CVAR_RANDOMIZER_SETTING("BridgeRewardOptions"), RO_BRIDGE_STANDARD_REWARD); - switch (CVarGetInteger(CVAR_RANDOMIZER_SETTING("RainbowBridge"), RO_BRIDGE_VANILLA)) { - case RO_BRIDGE_STONES: - // Show Bridge Options and Stone Count slider - mOptions[RSK_RAINBOW_BRIDGE].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); - mOptions[RSK_BRIDGE_OPTIONS].Unhide(); - mOptions[RSK_RAINBOW_BRIDGE_STONE_COUNT].Unhide(); - if (bridgeOpt == RO_BRIDGE_GREG_REWARD) { - if (mOptions[RSK_RAINBOW_BRIDGE_STONE_COUNT].GetOptionCount() == 4) { - mOptions[RSK_RAINBOW_BRIDGE_STONE_COUNT].ChangeOptions(NumOpts(0, 4)); - } - } else { - if (mOptions[RSK_RAINBOW_BRIDGE_STONE_COUNT].GetOptionCount() == 5) { - mOptions[RSK_RAINBOW_BRIDGE_STONE_COUNT].ChangeOptions(NumOpts(0, 3)); - } - } - break; - case RO_BRIDGE_MEDALLIONS: - // Show Bridge Options and Medallion Count Slider - mOptions[RSK_RAINBOW_BRIDGE].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); - mOptions[RSK_BRIDGE_OPTIONS].Unhide(); - mOptions[RSK_RAINBOW_BRIDGE_MEDALLION_COUNT].Unhide(); - if (bridgeOpt == RO_BRIDGE_GREG_REWARD) { - if (mOptions[RSK_RAINBOW_BRIDGE_MEDALLION_COUNT].GetOptionCount() == 7) { - mOptions[RSK_RAINBOW_BRIDGE_MEDALLION_COUNT].ChangeOptions(NumOpts(0, 7)); - } - } else { - if (mOptions[RSK_RAINBOW_BRIDGE_MEDALLION_COUNT].GetOptionCount() == 8) { - mOptions[RSK_RAINBOW_BRIDGE_MEDALLION_COUNT].ChangeOptions(NumOpts(0, 6)); - } - } - break; - case RO_BRIDGE_DUNGEON_REWARDS: - // Show Bridge Options and Dungeon Reward Count Slider - mOptions[RSK_RAINBOW_BRIDGE].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); - mOptions[RSK_BRIDGE_OPTIONS].Unhide(); - mOptions[RSK_RAINBOW_BRIDGE_REWARD_COUNT].Unhide(); - if (bridgeOpt == RO_BRIDGE_GREG_REWARD) { - if (mOptions[RSK_RAINBOW_BRIDGE_REWARD_COUNT].GetOptionCount() == 10) { - mOptions[RSK_RAINBOW_BRIDGE_REWARD_COUNT].ChangeOptions(NumOpts(0, 10)); - } - } else { - if (mOptions[RSK_RAINBOW_BRIDGE_REWARD_COUNT].GetOptionCount() == 11) { - mOptions[RSK_RAINBOW_BRIDGE_REWARD_COUNT].ChangeOptions(NumOpts(0, 9)); - } - } - break; - case RO_BRIDGE_DUNGEONS: - // Show Bridge Options and Dungeon Count Slider - mOptions[RSK_RAINBOW_BRIDGE].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); - mOptions[RSK_BRIDGE_OPTIONS].Unhide(); - mOptions[RSK_RAINBOW_BRIDGE_DUNGEON_COUNT].Unhide(); - if (bridgeOpt == RO_BRIDGE_GREG_REWARD) { - if (mOptions[RSK_RAINBOW_BRIDGE_DUNGEON_COUNT].GetOptionCount() == 9) { - mOptions[RSK_RAINBOW_BRIDGE_DUNGEON_COUNT].ChangeOptions(NumOpts(0, 9)); - } - } else { - if (mOptions[RSK_RAINBOW_BRIDGE_DUNGEON_COUNT].GetOptionCount() == 10) { - mOptions[RSK_RAINBOW_BRIDGE_DUNGEON_COUNT].ChangeOptions(NumOpts(0, 8)); - } - } - break; - case RO_BRIDGE_TOKENS: - // Show token count slider (not bridge options) - mOptions[RSK_RAINBOW_BRIDGE].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); - mOptions[RSK_BRIDGE_OPTIONS].Hide(); - mOptions[RSK_RAINBOW_BRIDGE_TOKEN_COUNT].Unhide(); - break; - default: - break; - } - mOptions[RSK_GANONS_TRIALS].Enable(); - mOptions[RSK_TRIAL_COUNT].Enable(); - // Only show the trial count slider if Trials is set to Set Number - if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("GanonTrial"), RO_GANONS_TRIALS_SET_NUMBER) == - RO_GANONS_TRIALS_SET_NUMBER) { - mOptions[RSK_GANONS_TRIALS].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); - mOptions[RSK_TRIAL_COUNT].Unhide(); - } else { - mOptions[RSK_GANONS_TRIALS].AddFlag(IMFLAG_SEPARATOR_BOTTOM); - mOptions[RSK_TRIAL_COUNT].Hide(); - } - mOptions[RSK_TRIFORCE_HUNT].Enable(); - mOptions[RSK_TRIFORCE_HUNT_PIECES_TOTAL].Enable(); - mOptions[RSK_TRIFORCE_HUNT_PIECES_REQUIRED].Enable(); - // Remove the pieces required/total sliders and add a separator after Tirforce Hunt if Triforce Hunt is off - if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("TriforceHunt"), RO_TRIFORCE_HUNT_OFF) == RO_TRIFORCE_HUNT_OFF) { - mOptions[RSK_TRIFORCE_HUNT_PIECES_REQUIRED].Hide(); - mOptions[RSK_TRIFORCE_HUNT_PIECES_TOTAL].Hide(); - mOptions[RSK_TRIFORCE_HUNT].AddFlag(IMFLAG_SEPARATOR_BOTTOM); - } else { - mOptions[RSK_TRIFORCE_HUNT_PIECES_REQUIRED].Unhide(); - mOptions[RSK_TRIFORCE_HUNT_PIECES_TOTAL].Unhide(); - mOptions[RSK_TRIFORCE_HUNT].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); - } - // Update triforce pieces required to be capped at the current value for pieces total. - const uint8_t triforceTotal = CVarGetInteger(CVAR_RANDOMIZER_SETTING("TriforceHuntTotalPieces"), 30); - if (mOptions[RSK_TRIFORCE_HUNT_PIECES_REQUIRED].GetOptionCount() != triforceTotal + 1) { - mOptions[RSK_TRIFORCE_HUNT_PIECES_REQUIRED].ChangeOptions(NumOpts(1, triforceTotal + 1)); - } - mOptionGroups[RSG_ITEMS_IMGUI_TABLE].Enable(); - mOptionGroups[RSG_GAMEPLAY_IMGUI_TABLE].Enable(); - // Link's Pocket - Disabled when Dungeon Rewards are shuffled to End of Dungeon - if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleDungeonReward"), RO_DUNGEON_REWARDS_END_OF_DUNGEON) == - RO_DUNGEON_REWARDS_END_OF_DUNGEON) { - mOptions[RSK_LINKS_POCKET].Disable( - "This option is disabled because \"Dungeon Rewards\" are shuffled to \"End of Dungeons\"."); - } else { - mOptions[RSK_LINKS_POCKET].Enable(); - } - mOptions[RSK_STARTING_OCARINA].Enable(); - - // Don't show any MQ options if both quests aren't available - if (!(OTRGlobals::Instance->HasMasterQuest() && OTRGlobals::Instance->HasOriginal())) { - mOptions[RSK_MQ_DUNGEON_RANDOM].Hide(); - mOptions[RSK_MQ_DUNGEON_COUNT].Hide(); - mOptions[RSK_MQ_DUNGEON_SET].Hide(); - mOptions[RSK_MQ_DEKU_TREE].Hide(); - mOptions[RSK_MQ_DODONGOS_CAVERN].Hide(); - mOptions[RSK_MQ_JABU_JABU].Hide(); - mOptions[RSK_MQ_FOREST_TEMPLE].Hide(); - mOptions[RSK_MQ_FIRE_TEMPLE].Hide(); - mOptions[RSK_MQ_WATER_TEMPLE].Hide(); - mOptions[RSK_MQ_SPIRIT_TEMPLE].Hide(); - mOptions[RSK_MQ_SHADOW_TEMPLE].Hide(); - mOptions[RSK_MQ_BOTTOM_OF_THE_WELL].Hide(); - mOptions[RSK_MQ_ICE_CAVERN].Hide(); - mOptions[RSK_MQ_GTG].Hide(); - mOptions[RSK_MQ_GANONS_CASTLE].Hide(); - } else { - // If any MQ Options are available, show the MQ Dungeon Randomization Combobox - mOptions[RSK_MQ_DUNGEON_RANDOM].Unhide(); - switch (CVarGetInteger(CVAR_RANDOMIZER_SETTING("MQDungeons"), RO_MQ_DUNGEONS_NONE)) { - // If No MQ Dungeons, add a separator after the combobx and hide - // the count slider and the toggle for individual dungeon selections. - case RO_MQ_DUNGEONS_NONE: - mOptions[RSK_MQ_DUNGEON_RANDOM].AddFlag(IMFLAG_SEPARATOR_BOTTOM); - mOptions[RSK_MQ_DUNGEON_COUNT].Hide(); - mOptions[RSK_MQ_DUNGEON_SET].Hide(); - break; - // If Set Number, remove the separator and show both the count slider and the - // individual dungeon selection toggle. - case RO_MQ_DUNGEONS_SET_NUMBER: - mOptions[RSK_MQ_DUNGEON_RANDOM].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); - mOptions[RSK_MQ_DUNGEON_COUNT].Unhide(); - mOptions[RSK_MQ_DUNGEON_SET].Unhide(); - break; - // else if random number or selection only, remove the separator and only show - // the individual dungeon selection toggle. - case RO_MQ_DUNGEONS_RANDOM_NUMBER: - mOptions[RSK_MQ_DUNGEON_RANDOM].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); - mOptions[RSK_MQ_DUNGEON_COUNT].Hide(); - mOptions[RSK_MQ_DUNGEON_SET].Unhide(); - break; - case RO_MQ_DUNGEONS_SELECTION: - mOptions[RSK_MQ_DUNGEON_RANDOM].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); - mOptions[RSK_MQ_DUNGEON_COUNT].Hide(); - mOptions[RSK_MQ_DUNGEON_SET].Hide(); - break; - default: - break; - } - // Controls whether or not to show the selectors for individual dungeons. - if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("MQDungeons"), RO_MQ_DUNGEONS_NONE) != RO_MQ_DUNGEONS_NONE && - (CVarGetInteger(CVAR_RANDOMIZER_SETTING("MQDungeonsSelection"), RO_GENERIC_OFF) == RO_GENERIC_ON || - CVarGetInteger(CVAR_RANDOMIZER_SETTING("MQDungeons"), RO_MQ_DUNGEONS_NONE) == RO_MQ_DUNGEONS_SELECTION)) { - // if showing the dungeon selectors, remove the separator after the Set Dungeons checkbox. - mOptions[RSK_MQ_DUNGEON_SET].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); - mOptions[RSK_MQ_DEKU_TREE].Unhide(); - mOptions[RSK_MQ_DODONGOS_CAVERN].Unhide(); - mOptions[RSK_MQ_JABU_JABU].Unhide(); - mOptions[RSK_MQ_FOREST_TEMPLE].Unhide(); - mOptions[RSK_MQ_FIRE_TEMPLE].Unhide(); - mOptions[RSK_MQ_WATER_TEMPLE].Unhide(); - mOptions[RSK_MQ_SPIRIT_TEMPLE].Unhide(); - mOptions[RSK_MQ_SHADOW_TEMPLE].Unhide(); - mOptions[RSK_MQ_BOTTOM_OF_THE_WELL].Unhide(); - mOptions[RSK_MQ_ICE_CAVERN].Unhide(); - mOptions[RSK_MQ_GTG].Unhide(); - mOptions[RSK_MQ_GANONS_CASTLE].Unhide(); - } else { - // If those are not shown, add a separator after the Set Dungeons checkbox. - mOptions[RSK_MQ_DUNGEON_SET].AddFlag(IMFLAG_SEPARATOR_BOTTOM); - mOptions[RSK_MQ_DEKU_TREE].Hide(); - mOptions[RSK_MQ_DODONGOS_CAVERN].Hide(); - mOptions[RSK_MQ_JABU_JABU].Hide(); - mOptions[RSK_MQ_FOREST_TEMPLE].Hide(); - mOptions[RSK_MQ_FIRE_TEMPLE].Hide(); - mOptions[RSK_MQ_WATER_TEMPLE].Hide(); - mOptions[RSK_MQ_SPIRIT_TEMPLE].Hide(); - mOptions[RSK_MQ_SHADOW_TEMPLE].Hide(); - mOptions[RSK_MQ_BOTTOM_OF_THE_WELL].Hide(); - mOptions[RSK_MQ_ICE_CAVERN].Hide(); - mOptions[RSK_MQ_GTG].Hide(); - mOptions[RSK_MQ_GANONS_CASTLE].Hide(); - } - } - - bool dungeonShuffle = - CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleDungeonsEntrances"), RO_DUNGEON_ENTRANCE_SHUFFLE_OFF); - bool bossShuffle = - CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleBossEntrances"), RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF); - bool overworldShuffle = CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleOverworldEntrances"), RO_GENERIC_OFF); - bool interiorShuffle = CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleInteriorsEntrances"), RO_GENERIC_OFF); - bool grottoShuffle = CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleGrottosEntrances"), RO_GENERIC_OFF); - - // Hide Mixed Entrances option if 1 or no applicable entrance shuffles are visible - if (dungeonShuffle + bossShuffle + overworldShuffle + interiorShuffle + grottoShuffle <= 1) { - mOptions[RSK_MIXED_ENTRANCE_POOLS].Hide(); - } else { - mOptions[RSK_MIXED_ENTRANCE_POOLS].Unhide(); - } - // Show mixed entrance pool options if mixed entrance pools are enabled, but only the ones that aren't off - if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("MixedEntrances"), RO_GENERIC_OFF) == RO_GENERIC_OFF || - mOptions[RSK_MIXED_ENTRANCE_POOLS].IsHidden()) { - mOptions[RSK_MIXED_ENTRANCE_POOLS].AddFlag(IMFLAG_SEPARATOR_BOTTOM); - mOptions[RSK_MIX_DUNGEON_ENTRANCES].Hide(); - mOptions[RSK_MIX_BOSS_ENTRANCES].Hide(); - mOptions[RSK_MIX_OVERWORLD_ENTRANCES].Hide(); - mOptions[RSK_MIX_INTERIOR_ENTRANCES].Hide(); - mOptions[RSK_MIX_THIEVES_HIDEOUT_ENTRANCES].Hide(); - mOptions[RSK_MIX_GROTTO_ENTRANCES].Hide(); - } else { - mOptions[RSK_MIXED_ENTRANCE_POOLS].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); - mOptions[RSK_MIX_DUNGEON_ENTRANCES].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); - mOptions[RSK_MIX_BOSS_ENTRANCES].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); - mOptions[RSK_MIX_OVERWORLD_ENTRANCES].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); - mOptions[RSK_MIX_INTERIOR_ENTRANCES].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); - mOptions[RSK_MIX_THIEVES_HIDEOUT_ENTRANCES].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); - mOptions[RSK_MIX_GROTTO_ENTRANCES].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); - RandomizerSettingKey lastKey = RSK_MIXED_ENTRANCE_POOLS; - if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleDungeonsEntrances"), RO_DUNGEON_ENTRANCE_SHUFFLE_OFF) == - RO_DUNGEON_ENTRANCE_SHUFFLE_OFF) { - mOptions[RSK_MIX_DUNGEON_ENTRANCES].Hide(); - } else { - mOptions[RSK_MIX_DUNGEON_ENTRANCES].Unhide(); - lastKey = RSK_MIX_DUNGEON_ENTRANCES; - } - if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleBossEntrances"), RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF) == - RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF) { - mOptions[RSK_MIX_BOSS_ENTRANCES].Hide(); - } else { - mOptions[RSK_MIX_BOSS_ENTRANCES].Unhide(); - lastKey = RSK_MIX_BOSS_ENTRANCES; - } - if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleOverworldEntrances"), RO_GENERIC_OFF) == RO_GENERIC_OFF) { - mOptions[RSK_MIX_OVERWORLD_ENTRANCES].Hide(); - } else { - mOptions[RSK_MIX_OVERWORLD_ENTRANCES].Unhide(); - lastKey = RSK_MIX_OVERWORLD_ENTRANCES; - } - if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleInteriorsEntrances"), RO_GENERIC_OFF) == RO_GENERIC_OFF) { - mOptions[RSK_MIX_INTERIOR_ENTRANCES].Hide(); - } else { - mOptions[RSK_MIX_INTERIOR_ENTRANCES].Unhide(); - lastKey = RSK_MIX_INTERIOR_ENTRANCES; - } - if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleThievesHideoutEntrances"), RO_GENERIC_OFF) == - RO_GENERIC_OFF) { - mOptions[RSK_MIX_THIEVES_HIDEOUT_ENTRANCES].Hide(); - } else { - mOptions[RSK_MIX_THIEVES_HIDEOUT_ENTRANCES].Unhide(); - lastKey = RSK_MIX_THIEVES_HIDEOUT_ENTRANCES; - } - if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleGrottosEntrances"), RO_GENERIC_OFF) == RO_GENERIC_OFF) { - mOptions[RSK_MIX_GROTTO_ENTRANCES].Hide(); - } else { - mOptions[RSK_MIX_GROTTO_ENTRANCES].Unhide(); - lastKey = RSK_MIX_GROTTO_ENTRANCES; - } - mOptions[lastKey].AddFlag(IMFLAG_SEPARATOR_BOTTOM); - } - - if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleDekuStickBag"), 0)) { - mOptions[RSK_STARTING_STICKS].Disable("Disabled because Shuffle Deku Stick Bag is on."); - } else { - mOptions[RSK_STARTING_STICKS].Enable(); - } - if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleDekuNutBag"), 0)) { - mOptions[RSK_STARTING_NUTS].Disable("Disabled because Shuffle Deku Nut Bag is on."); - } else { - mOptions[RSK_STARTING_NUTS].Enable(); - } - - // Shuffle Weird Egg - Disabled when Skip Child Zelda is active - if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("SkipChildZelda"), RO_GENERIC_DONT_SKIP)) { - mOptions[RSK_SHUFFLE_WEIRD_EGG].Disable("This option is disabled because \"Skip Child Zelda\" is enabled."); - } else { - mOptions[RSK_SHUFFLE_WEIRD_EGG].Enable(); - } - bool isTycoon = CVarGetInteger(CVAR_RANDOMIZER_SETTING("IncludeTycoonWallet"), RO_GENERIC_OFF); - // Hide shopsanity prices if shopsanity is off or zero - switch (CVarGetInteger(CVAR_RANDOMIZER_SETTING("Shopsanity"), RO_SHOPSANITY_OFF)) { - case RO_SHOPSANITY_OFF: - mOptions[RSK_SHOPSANITY].AddFlag(IMFLAG_SEPARATOR_BOTTOM); - mOptions[RSK_SHOPSANITY_COUNT].Hide(); - mOptions[RSK_SHOPSANITY_COUNT].Hide(); - mOptions[RSK_SHOPSANITY_PRICES].Hide(); - mOptions[RSK_SHOPSANITY_PRICES_AFFORDABLE].Hide(); - mOptions[RSK_SHOPSANITY_PRICES_FIXED_PRICE].Hide(); - mOptions[RSK_SHOPSANITY_PRICES_RANGE_1].Hide(); - mOptions[RSK_SHOPSANITY_PRICES_RANGE_2].Hide(); - mOptions[RSK_SHOPSANITY_PRICES_NO_WALLET_WEIGHT].Hide(); - mOptions[RSK_SHOPSANITY_PRICES_CHILD_WALLET_WEIGHT].Hide(); - mOptions[RSK_SHOPSANITY_PRICES_ADULT_WALLET_WEIGHT].Hide(); - mOptions[RSK_SHOPSANITY_PRICES_GIANT_WALLET_WEIGHT].Hide(); - mOptions[RSK_SHOPSANITY_PRICES_TYCOON_WALLET_WEIGHT].Hide(); - break; - case RO_SHOPSANITY_SPECIFIC_COUNT: - mOptions[RSK_SHOPSANITY_COUNT].Unhide(); - HandleShopsanityPriceUI(); - break; - case RO_SHOPSANITY_RANDOM: - mOptions[RSK_SHOPSANITY_COUNT].Hide(); - HandleShopsanityPriceUI(); - break; - } - switch (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleScrubs"), RO_SCRUBS_OFF)) { - case RO_SCRUBS_OFF: - mOptions[RSK_SHUFFLE_SCRUBS].AddFlag(IMFLAG_SEPARATOR_BOTTOM); - mOptions[RSK_SCRUBS_PRICES].Hide(); - mOptions[RSK_SCRUBS_PRICES_AFFORDABLE].Hide(); - mOptions[RSK_SCRUBS_PRICES_FIXED_PRICE].Hide(); - mOptions[RSK_SCRUBS_PRICES_RANGE_1].Hide(); - mOptions[RSK_SCRUBS_PRICES_RANGE_2].Hide(); - mOptions[RSK_SCRUBS_PRICES_NO_WALLET_WEIGHT].Hide(); - mOptions[RSK_SCRUBS_PRICES_CHILD_WALLET_WEIGHT].Hide(); - mOptions[RSK_SCRUBS_PRICES_ADULT_WALLET_WEIGHT].Hide(); - mOptions[RSK_SCRUBS_PRICES_GIANT_WALLET_WEIGHT].Hide(); - mOptions[RSK_SCRUBS_PRICES_TYCOON_WALLET_WEIGHT].Hide(); - break; - default: - mOptions[RSK_SHUFFLE_SCRUBS].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); - mOptions[RSK_SCRUBS_PRICES].Unhide(); - switch (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ScrubsPrices"), RO_PRICE_VANILLA)) { - case RO_PRICE_FIXED: - mOptions[RSK_SCRUBS_PRICES_FIXED_PRICE].Unhide(); - mOptions[RSK_SCRUBS_PRICES_RANGE_1].Hide(); - mOptions[RSK_SCRUBS_PRICES_RANGE_2].Hide(); - mOptions[RSK_SCRUBS_PRICES_NO_WALLET_WEIGHT].Hide(); - mOptions[RSK_SCRUBS_PRICES_CHILD_WALLET_WEIGHT].Hide(); - mOptions[RSK_SCRUBS_PRICES_ADULT_WALLET_WEIGHT].Hide(); - mOptions[RSK_SCRUBS_PRICES_GIANT_WALLET_WEIGHT].Hide(); - mOptions[RSK_SCRUBS_PRICES_TYCOON_WALLET_WEIGHT].Hide(); - if (isTycoon ? mOptions[RSK_SCRUBS_PRICES_FIXED_PRICE].GetOptionCount() == 501 - : mOptions[RSK_SCRUBS_PRICES_FIXED_PRICE].GetOptionCount() == 1000) { - mOptions[RSK_SCRUBS_PRICES_FIXED_PRICE].ChangeOptions(isTycoon ? NumOpts(0, 999) - : NumOpts(0, 500)); - } - mOptions[RSK_SCRUBS_PRICES_AFFORDABLE].Hide(); - break; - case RO_PRICE_RANGE: - mOptions[RSK_SCRUBS_PRICES_FIXED_PRICE].Hide(); - mOptions[RSK_SCRUBS_PRICES_RANGE_1].Unhide(); - mOptions[RSK_SCRUBS_PRICES_RANGE_2].Unhide(); - mOptions[RSK_SCRUBS_PRICES_NO_WALLET_WEIGHT].Hide(); - mOptions[RSK_SCRUBS_PRICES_CHILD_WALLET_WEIGHT].Hide(); - mOptions[RSK_SCRUBS_PRICES_ADULT_WALLET_WEIGHT].Hide(); - mOptions[RSK_SCRUBS_PRICES_GIANT_WALLET_WEIGHT].Hide(); - mOptions[RSK_SCRUBS_PRICES_TYCOON_WALLET_WEIGHT].Hide(); - if (isTycoon ? mOptions[RSK_SCRUBS_PRICES_RANGE_1].GetOptionCount() == 101 - : mOptions[RSK_SCRUBS_PRICES_RANGE_1].GetOptionCount() == 200) { - mOptions[RSK_SCRUBS_PRICES_RANGE_1].ChangeOptions(isTycoon ? NumOpts(0, 995, 5) - : NumOpts(0, 500, 5)); - mOptions[RSK_SCRUBS_PRICES_RANGE_2].ChangeOptions(isTycoon ? NumOpts(0, 995, 5) - : NumOpts(0, 500, 5)); - } - mOptions[RSK_SCRUBS_PRICES_AFFORDABLE].Unhide(); - break; - case RO_PRICE_SET_BY_WALLET: - mOptions[RSK_SCRUBS_PRICES_FIXED_PRICE].Hide(); - mOptions[RSK_SCRUBS_PRICES_RANGE_1].Hide(); - mOptions[RSK_SCRUBS_PRICES_RANGE_2].Hide(); - mOptions[RSK_SCRUBS_PRICES_NO_WALLET_WEIGHT].Unhide(); - mOptions[RSK_SCRUBS_PRICES_CHILD_WALLET_WEIGHT].Unhide(); - mOptions[RSK_SCRUBS_PRICES_ADULT_WALLET_WEIGHT].Unhide(); - mOptions[RSK_SCRUBS_PRICES_GIANT_WALLET_WEIGHT].Unhide(); - if (isTycoon) { - mOptions[RSK_SCRUBS_PRICES_TYCOON_WALLET_WEIGHT].Unhide(); - } else { - mOptions[RSK_SCRUBS_PRICES_TYCOON_WALLET_WEIGHT].Hide(); - } - mOptions[RSK_SCRUBS_PRICES_AFFORDABLE].Unhide(); - break; - default: - mOptions[RSK_SCRUBS_PRICES_FIXED_PRICE].Hide(); - mOptions[RSK_SCRUBS_PRICES_RANGE_1].Hide(); - mOptions[RSK_SCRUBS_PRICES_RANGE_2].Hide(); - mOptions[RSK_SCRUBS_PRICES_NO_WALLET_WEIGHT].Hide(); - mOptions[RSK_SCRUBS_PRICES_CHILD_WALLET_WEIGHT].Hide(); - mOptions[RSK_SCRUBS_PRICES_ADULT_WALLET_WEIGHT].Hide(); - mOptions[RSK_SCRUBS_PRICES_GIANT_WALLET_WEIGHT].Hide(); - mOptions[RSK_SCRUBS_PRICES_TYCOON_WALLET_WEIGHT].Hide(); - mOptions[RSK_SCRUBS_PRICES_AFFORDABLE].Unhide(); - break; - } - break; - } - switch (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleMerchants"), RO_SHUFFLE_MERCHANTS_OFF)) { - case RO_SHUFFLE_MERCHANTS_OFF: - mOptions[RSK_SHUFFLE_MERCHANTS].AddFlag(IMFLAG_SEPARATOR_BOTTOM); - mOptions[RSK_MERCHANT_PRICES].Hide(); - mOptions[RSK_MERCHANT_PRICES_AFFORDABLE].Hide(); - mOptions[RSK_MERCHANT_PRICES_FIXED_PRICE].Hide(); - mOptions[RSK_MERCHANT_PRICES_RANGE_1].Hide(); - mOptions[RSK_MERCHANT_PRICES_RANGE_2].Hide(); - mOptions[RSK_MERCHANT_PRICES_NO_WALLET_WEIGHT].Hide(); - mOptions[RSK_MERCHANT_PRICES_CHILD_WALLET_WEIGHT].Hide(); - mOptions[RSK_MERCHANT_PRICES_ADULT_WALLET_WEIGHT].Hide(); - mOptions[RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT].Hide(); - mOptions[RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT].Hide(); - break; - default: - mOptions[RSK_SHUFFLE_MERCHANTS].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); - mOptions[RSK_MERCHANT_PRICES].Unhide(); - switch (CVarGetInteger(CVAR_RANDOMIZER_SETTING("MerchantPrices"), RO_PRICE_VANILLA)) { - case RO_PRICE_FIXED: - mOptions[RSK_MERCHANT_PRICES_FIXED_PRICE].Unhide(); - mOptions[RSK_MERCHANT_PRICES_RANGE_1].Hide(); - mOptions[RSK_MERCHANT_PRICES_RANGE_2].Hide(); - mOptions[RSK_MERCHANT_PRICES_NO_WALLET_WEIGHT].Hide(); - mOptions[RSK_MERCHANT_PRICES_CHILD_WALLET_WEIGHT].Hide(); - mOptions[RSK_MERCHANT_PRICES_ADULT_WALLET_WEIGHT].Hide(); - mOptions[RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT].Hide(); - mOptions[RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT].Hide(); - if (isTycoon ? mOptions[RSK_MERCHANT_PRICES_FIXED_PRICE].GetOptionCount() == 501 - : mOptions[RSK_MERCHANT_PRICES_FIXED_PRICE].GetOptionCount() == 1000) { - mOptions[RSK_MERCHANT_PRICES_FIXED_PRICE].ChangeOptions(isTycoon ? NumOpts(0, 999) - : NumOpts(0, 500)); - } - mOptions[RSK_MERCHANT_PRICES_AFFORDABLE].Hide(); - break; - case RO_PRICE_RANGE: - mOptions[RSK_MERCHANT_PRICES_FIXED_PRICE].Hide(); - mOptions[RSK_MERCHANT_PRICES_RANGE_1].Unhide(); - mOptions[RSK_MERCHANT_PRICES_RANGE_2].Unhide(); - mOptions[RSK_MERCHANT_PRICES_NO_WALLET_WEIGHT].Hide(); - mOptions[RSK_MERCHANT_PRICES_CHILD_WALLET_WEIGHT].Hide(); - mOptions[RSK_MERCHANT_PRICES_ADULT_WALLET_WEIGHT].Hide(); - mOptions[RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT].Hide(); - mOptions[RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT].Hide(); - if (isTycoon ? mOptions[RSK_MERCHANT_PRICES_RANGE_1].GetOptionCount() == 101 - : mOptions[RSK_MERCHANT_PRICES_RANGE_1].GetOptionCount() == 200) { - mOptions[RSK_MERCHANT_PRICES_RANGE_1].ChangeOptions(isTycoon ? NumOpts(0, 995, 5) - : NumOpts(0, 500, 5)); - mOptions[RSK_MERCHANT_PRICES_RANGE_2].ChangeOptions(isTycoon ? NumOpts(0, 995, 5) - : NumOpts(0, 500, 5)); - } - mOptions[RSK_MERCHANT_PRICES_AFFORDABLE].Unhide(); - break; - case RO_PRICE_SET_BY_WALLET: - mOptions[RSK_MERCHANT_PRICES_FIXED_PRICE].Hide(); - mOptions[RSK_MERCHANT_PRICES_RANGE_1].Hide(); - mOptions[RSK_MERCHANT_PRICES_RANGE_2].Hide(); - mOptions[RSK_MERCHANT_PRICES_NO_WALLET_WEIGHT].Unhide(); - mOptions[RSK_MERCHANT_PRICES_CHILD_WALLET_WEIGHT].Unhide(); - mOptions[RSK_MERCHANT_PRICES_ADULT_WALLET_WEIGHT].Unhide(); - mOptions[RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT].Unhide(); - if (isTycoon) { - mOptions[RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT].Unhide(); - } else { - mOptions[RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT].Hide(); - } - mOptions[RSK_MERCHANT_PRICES_AFFORDABLE].Unhide(); - break; - default: - mOptions[RSK_MERCHANT_PRICES_FIXED_PRICE].Hide(); - mOptions[RSK_MERCHANT_PRICES_RANGE_1].Hide(); - mOptions[RSK_MERCHANT_PRICES_RANGE_2].Hide(); - mOptions[RSK_MERCHANT_PRICES_NO_WALLET_WEIGHT].Hide(); - mOptions[RSK_MERCHANT_PRICES_CHILD_WALLET_WEIGHT].Hide(); - mOptions[RSK_MERCHANT_PRICES_ADULT_WALLET_WEIGHT].Hide(); - mOptions[RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT].Hide(); - mOptions[RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT].Hide(); - mOptions[RSK_MERCHANT_PRICES_AFFORDABLE].Unhide(); - break; - } - break; - } - // Hide fishing pond settings if we aren't shuffling the fishing pond - switch (CVarGetInteger(CVAR_RANDOMIZER_SETTING("Fishsanity"), RO_FISHSANITY_OFF)) { - case RO_FISHSANITY_POND: - case RO_FISHSANITY_BOTH: - mOptions[RSK_FISHSANITY].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); - mOptions[RSK_FISHSANITY_POND_COUNT].Unhide(); - mOptions[RSK_FISHSANITY_AGE_SPLIT].Unhide(); - break; - default: - mOptions[RSK_FISHSANITY].AddFlag(IMFLAG_SEPARATOR_BOTTOM); - mOptions[RSK_FISHSANITY_POND_COUNT].Hide(); - mOptions[RSK_FISHSANITY_AGE_SPLIT].Hide(); - } - // Disable fishing pole hint if the fishing pole is not shuffled - if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleFishingPole"), RO_GENERIC_OFF)) { - mOptions[RSK_FISHING_POLE_HINT].Enable(); - } else { - mOptions[RSK_FISHING_POLE_HINT].Disable("This option is disabled since the fishing pole is not shuffled."); - } - // Shuffle 100 GS Reward - Force-Enabled if Ganon's Boss Key is on the 100 GS Reward - if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"), RO_GANON_BOSS_KEY_VANILLA) == - RO_GANON_BOSS_KEY_KAK_TOKENS) { - mOptions[RSK_SHUFFLE_100_GS_REWARD].Disable( - "This option is force-enabled because \"Ganon's Boss Key\" is set to \"100 GS Reward\"."); - } else { - mOptions[RSK_SHUFFLE_100_GS_REWARD].Enable(); - } - // Default state for Keyrings GUI - mOptions[RSK_KEYRINGS].AddFlag(IMFLAG_SEPARATOR_BOTTOM); - mOptions[RSK_KEYRINGS_RANDOM_COUNT].Hide(); - mOptions[RSK_KEYRINGS_GERUDO_FORTRESS].Hide(); - mOptions[RSK_KEYRINGS_FOREST_TEMPLE].Hide(); - mOptions[RSK_KEYRINGS_FIRE_TEMPLE].Hide(); - mOptions[RSK_KEYRINGS_WATER_TEMPLE].Hide(); - mOptions[RSK_KEYRINGS_SPIRIT_TEMPLE].Hide(); - mOptions[RSK_KEYRINGS_SHADOW_TEMPLE].Hide(); - mOptions[RSK_KEYRINGS_BOTTOM_OF_THE_WELL].Hide(); - mOptions[RSK_KEYRINGS_GTG].Hide(); - mOptions[RSK_KEYRINGS_GANONS_CASTLE].Hide(); - switch (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleKeyRings"), RO_KEYRINGS_OFF)) { - case RO_KEYRINGS_COUNT: - // Show count slider. - mOptions[RSK_KEYRINGS].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); - mOptions[RSK_KEYRINGS_RANDOM_COUNT].Unhide(); - break; - case RO_KEYRINGS_SELECTION: - // Show checkboxes for each dungeon with keys. - mOptions[RSK_KEYRINGS].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); - mOptions[RSK_KEYRINGS_GERUDO_FORTRESS].Unhide(); - mOptions[RSK_KEYRINGS_FOREST_TEMPLE].Unhide(); - mOptions[RSK_KEYRINGS_FIRE_TEMPLE].Unhide(); - mOptions[RSK_KEYRINGS_WATER_TEMPLE].Unhide(); - mOptions[RSK_KEYRINGS_SPIRIT_TEMPLE].Unhide(); - mOptions[RSK_KEYRINGS_SHADOW_TEMPLE].Unhide(); - mOptions[RSK_KEYRINGS_BOTTOM_OF_THE_WELL].Unhide(); - mOptions[RSK_KEYRINGS_GTG].Unhide(); - mOptions[RSK_KEYRINGS_GANONS_CASTLE].Unhide(); - default: - break; - } - const uint8_t maxKeyringCount = - (CVarGetInteger(CVAR_RANDOMIZER_SETTING("FortressCarpenters"), RO_GF_CARPENTERS_NORMAL) == - RO_GF_CARPENTERS_NORMAL && - CVarGetInteger(CVAR_RANDOMIZER_SETTING("GerudoKeys"), RO_GERUDO_KEYS_VANILLA) != RO_GERUDO_KEYS_VANILLA) - ? 9 - : 8; - if (mOptions[RSK_KEYRINGS_RANDOM_COUNT].GetOptionCount() != maxKeyringCount + 1) { - mOptions[RSK_KEYRINGS_RANDOM_COUNT].ChangeOptions(NumOpts(0, maxKeyringCount)); - } - if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("FortressCarpenters"), RO_GF_CARPENTERS_NORMAL) != - RO_GF_CARPENTERS_NORMAL || - CVarGetInteger(CVAR_RANDOMIZER_SETTING("GerudoKeys"), RO_GERUDO_KEYS_VANILLA) == RO_GERUDO_KEYS_VANILLA) { - mOptions[RSK_KEYRINGS_GERUDO_FORTRESS].Disable( - "Disabled because the currently selected Gerudo Fortress Carpenters\n" - "setting and/or Gerudo Fortress Keys setting is incompatible with\n" - "having a Gerudo Fortress Keyring."); - } else { - mOptions[RSK_KEYRINGS_GERUDO_FORTRESS].Enable(); - } - if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("TriforceHunt"), RO_TRIFORCE_HUNT_OFF)) { - mOptions[RSK_GANONS_BOSS_KEY].Disable( - "This option is disabled because Triforce Hunt is enabled." - "Ganon's Boss key\nwill instead be given to you after Triforce Hunt completion."); - } else { - mOptions[RSK_GANONS_BOSS_KEY].Enable(); - } - mOptions[RSK_GANONS_BOSS_KEY].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); - mOptions[RSK_LACS_OPTIONS].Hide(); - mOptions[RSK_LACS_STONE_COUNT].Hide(); - mOptions[RSK_LACS_MEDALLION_COUNT].Hide(); - mOptions[RSK_LACS_REWARD_COUNT].Hide(); - mOptions[RSK_LACS_DUNGEON_COUNT].Hide(); - mOptions[RSK_LACS_TOKEN_COUNT].Hide(); - const uint8_t lacsOpts = CVarGetInteger(CVAR_RANDOMIZER_SETTING("LacsRewardOptions"), RO_LACS_STANDARD_REWARD); - switch (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"), RO_GANON_BOSS_KEY_VANILLA)) { - case RO_GANON_BOSS_KEY_LACS_STONES: - mOptions[RSK_LACS_OPTIONS].Unhide(); - mOptions[RSK_LACS_STONE_COUNT].Unhide(); - if (lacsOpts == RO_LACS_GREG_REWARD) { - if (mOptions[RSK_LACS_STONE_COUNT].GetOptionCount() == 4) { - mOptions[RSK_LACS_STONE_COUNT].ChangeOptions(NumOpts(0, 4)); - } - } else { - if (mOptions[RSK_LACS_STONE_COUNT].GetOptionCount() == 5) { - mOptions[RSK_LACS_STONE_COUNT].ChangeOptions(NumOpts(0, 3)); - } - } - break; - case RO_GANON_BOSS_KEY_LACS_MEDALLIONS: - mOptions[RSK_LACS_OPTIONS].Unhide(); - mOptions[RSK_LACS_MEDALLION_COUNT].Unhide(); - if (lacsOpts == RO_LACS_GREG_REWARD) { - if (mOptions[RSK_LACS_MEDALLION_COUNT].GetOptionCount() == 7) { - mOptions[RSK_LACS_MEDALLION_COUNT].ChangeOptions(NumOpts(0, 7)); - } - } else { - if (mOptions[RSK_LACS_MEDALLION_COUNT].GetOptionCount() == 8) { - mOptions[RSK_LACS_MEDALLION_COUNT].ChangeOptions(NumOpts(0, 6)); - } - } - break; - case RO_GANON_BOSS_KEY_LACS_REWARDS: - mOptions[RSK_LACS_OPTIONS].Unhide(); - mOptions[RSK_LACS_REWARD_COUNT].Unhide(); - if (lacsOpts == RO_LACS_GREG_REWARD) { - if (mOptions[RSK_LACS_REWARD_COUNT].GetOptionCount() == 10) { - mOptions[RSK_LACS_REWARD_COUNT].ChangeOptions(NumOpts(0, 10)); - } - } else { - if (mOptions[RSK_LACS_REWARD_COUNT].GetOptionCount() == 11) { - mOptions[RSK_LACS_REWARD_COUNT].ChangeOptions(NumOpts(0, 9)); - } - } - break; - case RO_GANON_BOSS_KEY_LACS_DUNGEONS: - mOptions[RSK_LACS_OPTIONS].Unhide(); - mOptions[RSK_LACS_DUNGEON_COUNT].Unhide(); - if (lacsOpts == RO_LACS_GREG_REWARD) { - if (mOptions[RSK_LACS_DUNGEON_COUNT].GetOptionCount() == 9) { - mOptions[RSK_LACS_DUNGEON_COUNT].ChangeOptions(NumOpts(0, 9)); - } - } else { - if (mOptions[RSK_LACS_DUNGEON_COUNT].GetOptionCount() == 10) { - mOptions[RSK_LACS_DUNGEON_COUNT].ChangeOptions(NumOpts(0, 8)); - } - } - break; - case RO_GANON_BOSS_KEY_LACS_TOKENS: - mOptions[RSK_LACS_TOKEN_COUNT].Unhide(); - break; - default: - mOptions[RSK_GANONS_BOSS_KEY].AddFlag(IMFLAG_SEPARATOR_BOTTOM); - break; - } - // Skip Child Stealth - Disabled when Skip Child Zelda is active - if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("SkipChildZelda"), RO_GENERIC_DONT_SKIP)) { - mOptions[RSK_SKIP_CHILD_STEALTH].Disable("This option is disabled because \"Skip Child Zelda\" is enabled."); - } else { - mOptions[RSK_SKIP_CHILD_STEALTH].Enable(); - } - if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("GossipStoneHints"), RO_GOSSIP_STONES_NEED_NOTHING) == - RO_GOSSIP_STONES_NONE) { - mOptions[RSK_HINT_CLARITY].Hide(); - mOptions[RSK_HINT_DISTRIBUTION].Hide(); - } else { - mOptions[RSK_HINT_CLARITY].Unhide(); - mOptions[RSK_HINT_DISTRIBUTION].Unhide(); - } - - if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleWarpSongs"), RO_GENERIC_ON)) { - mOptions[RSK_WARP_SONG_HINTS].Enable(); - } else { - mOptions[RSK_WARP_SONG_HINTS].Disable("This option is disabled since warp song locations not shuffled."); - } - - if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleCows"), RO_GENERIC_OFF)) { - mOptions[RSK_MALON_HINT].Enable(); - } else { - mOptions[RSK_MALON_HINT].Disable("Malon's hint points to a cow, so requires cows to be shuffled."); - } - - if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("Shuffle100GSReward"), RO_GENERIC_OFF)) { - mOptions[RSK_KAK_100_SKULLS_HINT].Enable(); - } else { - mOptions[RSK_KAK_100_SKULLS_HINT].Disable("There is no point to hinting 100 skulls if it is not shuffled."); - } - - if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("Fishsanity"), RO_FISHSANITY_OFF) == RO_FISHSANITY_HYRULE_LOACH) { - mOptions[RSK_LOACH_HINT].Enable(); - } else { - mOptions[RSK_LOACH_HINT].Disable( - "Loach hint is only avaliable with \"Fishsanity\" set to \"Shuffle only Hyrule Loach\"\nas that's the only " - "setting where you present the loach to the fishing pond owner."); - } - - if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("BigPoeTargetCount"), 10) == 0) { - mOptions[RSK_BIG_POES_HINT].Disable("Poe Collector will just give you the item instead with 0 big poes."); - } else { - mOptions[RSK_BIG_POES_HINT].Enable(); - } - if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleBeehives"), RO_GENERIC_OFF)) { - mOptions[RSK_SLINGBOW_BREAK_BEEHIVES].Enable(); - } else { - mOptions[RSK_SLINGBOW_BREAK_BEEHIVES].Disable( - "This option is disabled because Shuffle Beehives is not enabled."); - } -======= - ->>>>>>> } void Context::FinalizeSettings(const std::set& excludedLocations, From e0348c02eae5a6f2f202070b73be09e4bfd0e722 Mon Sep 17 00:00:00 2001 From: TheLynk Date: Wed, 14 Jan 2026 19:29:38 +0100 Subject: [PATCH 33/45] Good Luck Update | V:12 small issue is found is if open chest is not shuffle the randomizer run is imbattable --- soh/soh/Enhancements/Presets/Presets.cpp | 2 +- .../vanilla-behavior/GIVanillaBehavior.h | 2 +- soh/soh/Enhancements/gameplaystats.cpp | 2 +- .../randomizer/3drando/item_pool.cpp | 1 + .../Enhancements/randomizer/ShuffleRocks.cpp | 5 +- soh/soh/Enhancements/randomizer/draw.cpp | 3 + .../dungeons/forest_temple.cpp | 2 +- .../overworld/gerudo_valley.cpp | 11 + soh/soh/Enhancements/randomizer/logic.cpp | 2 + soh/soh/Enhancements/randomizer/savefile.cpp | 303 +++++++++--------- 10 files changed, 176 insertions(+), 157 deletions(-) diff --git a/soh/soh/Enhancements/Presets/Presets.cpp b/soh/soh/Enhancements/Presets/Presets.cpp index 78bbfaf9247..fee5246ace2 100644 --- a/soh/soh/Enhancements/Presets/Presets.cpp +++ b/soh/soh/Enhancements/Presets/Presets.cpp @@ -393,7 +393,7 @@ void PresetsCustomWidget(WidgetInfo& info) { UIWidgets::CheckboxOptions().Color(THEME_COLOR)); bool hideBuiltIn = CVarGetInteger(CVAR_GENERAL("HideBuiltInPresets"), 0); UIWidgets::PushStyleTabs(THEME_COLOR); - if (ImGui::BeginTable("PresetWidgetTable", PRESET_SECTION_MAX + 3)) { + if (ImGui::BeginTable("PresetWidgetTable", PRESET_SECTION_MAX + 4)) { ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthFixed, 400); for (int i = PRESET_SECTION_SETTINGS; i < PRESET_SECTION_MAX; i++) { ImGui::TableSetupColumn(blockInfo[i].names[0].c_str()); diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index 681d202d329..a98b684055b 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -342,7 +342,7 @@ typedef enum { // #### `args` // - None VB_ROLL, - + // #### `result` // ```c // true diff --git a/soh/soh/Enhancements/gameplaystats.cpp b/soh/soh/Enhancements/gameplaystats.cpp index 936a309c193..1c6ad2d2fe2 100644 --- a/soh/soh/Enhancements/gameplaystats.cpp +++ b/soh/soh/Enhancements/gameplaystats.cpp @@ -448,7 +448,7 @@ void DrawGameplayStatsHeader() { // if tag is empty (not a release build) if (gGitCommitTag[0] == 0) { GameplayStatsRow("Git Branch:", (char*)gGitBranch); - GameplayStatsRow("Version : 11 | Git Commit Hash:", (char*)gGitCommitHash); + GameplayStatsRow("Version : 12 | Git Commit Hash:", (char*)gGitCommitHash); } else { GameplayStatsRow("Build Version:", (char*)gBuildVersion); } diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index cba51277266..4860a571f09 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -937,3 +937,4 @@ void GenerateItemPool() { assert(itemPool.size() == locCount); } +} diff --git a/soh/soh/Enhancements/randomizer/ShuffleRocks.cpp b/soh/soh/Enhancements/randomizer/ShuffleRocks.cpp index ba2fc032fa0..64c68563205 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleRocks.cpp +++ b/soh/soh/Enhancements/randomizer/ShuffleRocks.cpp @@ -21,13 +21,12 @@ extern void EnItem00_DrawRandomizedItem(EnItem00* enItem00, PlayState* play); extern "C" void DrawItemCircle(PlayState* play, float scale, RockIdentity rockIdentity) { GraphicsContext* __gfxCtx = play->state.gfxCtx; - int csmc = CVarGetInteger(CVAR_ENHANCEMENT("ChestSizeAndTextureMatchContents"), CSMC_DISABLED); + int csmc = CVarGetInteger(CVAR_ENHANCEMENT("ChestSizeAndTextureMatchContents"), 0); int requiresStoneAgony = CVarGetInteger(CVAR_ENHANCEMENT("ChestSizeDependsStoneOfAgony"), 0); u8 r1 = 200, g1 = 200, b1 = 200, r2 = 100, g2 = 100, b2 = 100; - if ((csmc == CSMC_BOTH || csmc == CSMC_TEXTURE) && - (!requiresStoneAgony || (requiresStoneAgony && CHECK_QUEST_ITEM(QUEST_STONE_OF_AGONY)))) { + if ((!requiresStoneAgony || (requiresStoneAgony && CHECK_QUEST_ITEM(QUEST_STONE_OF_AGONY)))) { auto itemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(rockIdentity.randomizerCheck, true, GI_NONE); GetItemCategory getItemCategory = itemEntry.getItemCategory; diff --git a/soh/soh/Enhancements/randomizer/draw.cpp b/soh/soh/Enhancements/randomizer/draw.cpp index f24e4b2bce0..645b9d8cec1 100644 --- a/soh/soh/Enhancements/randomizer/draw.cpp +++ b/soh/soh/Enhancements/randomizer/draw.cpp @@ -1195,6 +1195,9 @@ extern "C" void Randomizer_DrawOpenChest(PlayState* play, GetItemEntry* getItemE gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gGiSmallKeyDL); gSPGrayscale(POLY_OPA_DISP++, false); + CLOSE_DISPS(play->state.gfxCtx); +} + extern "C" void Randomizer_DrawKneePads(PlayState* play, GetItemEntry* getItemEntry) { OPEN_DISPS(play->state.gfxCtx); diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp index 951ccc60189..8ec32fc509c 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp @@ -614,7 +614,7 @@ void RegionTable_Init_ForestTemple() { Entrance(RR_FOREST_TEMPLE_MQ_NE_COURTYARD_ISLAND, []{return logic->CanUse(RG_LONGSHOT);}), }); - areaTable[RR_FOREST_TEMPLE_MQ_NE_COURTYARD_DOORFRAME] = Region("Forest Temple MQ NE Courtyard Doorframe", SCENE_FOREST_TEMPLE, {}, + areaTable[RR_FOREST_TEMPLE_MQ_NE_COURTYARD_DOORFRAME] = Region("Forest Temple MQ NE Courtyard Doorframe", SCENE_FOREST_TEMPLE, {}, { //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->CanKillEnemy(RE_GOLD_SKULLTULA, ED_BOMB_THROW) || logic->CanUse(RG_MEGATON_HAMMER) || (logic->CanStandingShield() && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MASTER_SWORD) || (logic->IsChild && logic->CanUse(RG_KOKIRI_SWORD))))), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp index ac3f3e31b2b..9db0e0436e2 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp @@ -89,6 +89,17 @@ void RegionTable_Init_GerudoValley() { LOCATION(RC_GV_CRATE_BRIDGE_2, logic->IsChild && logic->CanBreakCrates()), LOCATION(RC_GV_CRATE_BRIDGE_3, logic->IsChild && logic->CanBreakCrates()), LOCATION(RC_GV_CRATE_BRIDGE_4, logic->IsChild && logic->CanBreakCrates()), + LOCATION(RC_GV_ROCK_ACROSS_BRIDGE_1, logic->IsAdult), + LOCATION(RC_GV_ROCK_ACROSS_BRIDGE_2, logic->IsAdult), + LOCATION(RC_GV_ROCK_ACROSS_BRIDGE_3, logic->IsAdult), + LOCATION(RC_GV_ROCK_ACROSS_BRIDGE_4, logic->IsAdult), + LOCATION(RC_GV_BOULDER_ACROSS_BRIDGE, logic->IsAdult && logic->BlastOrSmash()), + LOCATION(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_1, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_2, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_3, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_4, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_5, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_6, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), }, { //Exits Entrance(RR_GF_OUTSKIRTS, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index c5dfdd27e90..bc366367143 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -2603,6 +2603,8 @@ void Logic::Reset(bool resetSaveContext /*= true*/) { // If we're not shuffling roll, we start with it if (ctx->GetOption(RSK_SHUFFLE_ROLL).Is(false)) { SetRandoInf(RAND_INF_CAN_ROLL, true); + } + // If we're not shuffling crawl, we start with it if (ctx->GetOption(RSK_SHUFFLE_CRAWL).Is(false)) { SetRandoInf(RAND_INF_CAN_CRAWL, true); diff --git a/soh/soh/Enhancements/randomizer/savefile.cpp b/soh/soh/Enhancements/randomizer/savefile.cpp index 7c5f1be8958..992ab921653 100644 --- a/soh/soh/Enhancements/randomizer/savefile.cpp +++ b/soh/soh/Enhancements/randomizer/savefile.cpp @@ -319,175 +319,178 @@ extern "C" void Randomizer_InitSaveFile() { if (Randomizer_GetSettingValue(RSK_SHUFFLE_OPEN_CHEST) == RO_GENERIC_OFF) { Flags_SetRandomizerInf(RAND_INF_CAN_OPEN_CHEST); - if (Randomizer_GetSettingValue(RSK_SHUFFLE_CRAWL) == RO_GENERIC_OFF) { - Flags_SetRandomizerInf(RAND_INF_CAN_CRAWL); - } + if (Randomizer_GetSettingValue(RSK_SHUFFLE_CRAWL) == RO_GENERIC_OFF) { + Flags_SetRandomizerInf(RAND_INF_CAN_CRAWL); + } - if (Randomizer_GetSettingValue(RSK_SHUFFLE_CHILD_WALLET) == RO_GENERIC_OFF) { - Flags_SetRandomizerInf(RAND_INF_HAS_WALLET); - } + if (Randomizer_GetSettingValue(RSK_SHUFFLE_CHILD_WALLET) == RO_GENERIC_OFF) { + Flags_SetRandomizerInf(RAND_INF_HAS_WALLET); + } - if (Randomizer_GetSettingValue(RSK_SHUFFLE_FISHING_POLE) == RO_GENERIC_OFF) { - Flags_SetRandomizerInf(RAND_INF_FISHING_POLE_FOUND); - } + if (Randomizer_GetSettingValue(RSK_SHUFFLE_FISHING_POLE) == RO_GENERIC_OFF) { + Flags_SetRandomizerInf(RAND_INF_FISHING_POLE_FOUND); + } - // Give Link's pocket item - GiveLinksPocketItem(); + // Give Link's pocket item + GiveLinksPocketItem(); - // Remove One Time Scrubs with Scrubsanity off - if (Randomizer_GetSettingValue(RSK_SHUFFLE_SCRUBS) == RO_SCRUBS_OFF) { - Flags_SetItemGetInf(ITEMGETINF_DEKU_SCRUB_HEART_PIECE); - Flags_SetInfTable(INFTABLE_BOUGHT_STICK_UPGRADE); - Flags_SetInfTable(INFTABLE_BOUGHT_NUT_UPGRADE); - } + // Remove One Time Scrubs with Scrubsanity off + if (Randomizer_GetSettingValue(RSK_SHUFFLE_SCRUBS) == RO_SCRUBS_OFF) { + Flags_SetItemGetInf(ITEMGETINF_DEKU_SCRUB_HEART_PIECE); + Flags_SetInfTable(INFTABLE_BOUGHT_STICK_UPGRADE); + Flags_SetInfTable(INFTABLE_BOUGHT_NUT_UPGRADE); + } - int startingAge = OTRGlobals::Instance->gRandoContext->GetOption(RSK_SELECTED_STARTING_AGE).Get(); - gSaveContext.savedSceneNum = -1; - switch (startingAge) { - case RO_AGE_ADULT: // Adult - gSaveContext.linkAge = LINK_AGE_ADULT; - gSaveContext.entranceIndex = ENTR_TEMPLE_OF_TIME_WARP_PAD; - gSaveContext.cutsceneIndex = 0; - break; - case RO_AGE_CHILD: // Child - gSaveContext.linkAge = LINK_AGE_CHILD; - break; - default: - break; - } + int startingAge = OTRGlobals::Instance->gRandoContext->GetOption(RSK_SELECTED_STARTING_AGE).Get(); + gSaveContext.savedSceneNum = -1; + switch (startingAge) { + case RO_AGE_ADULT: // Adult + gSaveContext.linkAge = LINK_AGE_ADULT; + gSaveContext.entranceIndex = ENTR_TEMPLE_OF_TIME_WARP_PAD; + gSaveContext.cutsceneIndex = 0; + break; + case RO_AGE_CHILD: // Child + gSaveContext.linkAge = LINK_AGE_CHILD; + break; + default: + break; + } - if (Randomizer_GetSettingValue(RSK_SHUFFLE_OVERWORLD_SPAWNS)) { - // Override the spawn entrance so entrance rando can take control, - // and to prevent remember save location from breaking initial spawn. - gSaveContext.entranceIndex = -1; - } + if (Randomizer_GetSettingValue(RSK_SHUFFLE_OVERWORLD_SPAWNS)) { + // Override the spawn entrance so entrance rando can take control, + // and to prevent remember save location from breaking initial spawn. + gSaveContext.entranceIndex = -1; + } - for (auto trialFlag : { EVENTCHKINF_COMPLETED_LIGHT_TRIAL, EVENTCHKINF_COMPLETED_FOREST_TRIAL, - EVENTCHKINF_COMPLETED_FIRE_TRIAL, EVENTCHKINF_COMPLETED_WATER_TRIAL, - EVENTCHKINF_COMPLETED_SPIRIT_TRIAL, EVENTCHKINF_COMPLETED_SHADOW_TRIAL }) { - if (!OTRGlobals::Instance->gRandomizer->IsTrialRequired(trialFlag)) { - Flags_SetEventChkInf(trialFlag); + for (auto trialFlag : { EVENTCHKINF_COMPLETED_LIGHT_TRIAL, EVENTCHKINF_COMPLETED_FOREST_TRIAL, + EVENTCHKINF_COMPLETED_FIRE_TRIAL, EVENTCHKINF_COMPLETED_WATER_TRIAL, + EVENTCHKINF_COMPLETED_SPIRIT_TRIAL, EVENTCHKINF_COMPLETED_SHADOW_TRIAL }) { + if (!OTRGlobals::Instance->gRandomizer->IsTrialRequired(trialFlag)) { + Flags_SetEventChkInf(trialFlag); + } } - } - if (Randomizer_GetSettingValue(RSK_SKIP_CHILD_ZELDA)) { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_SONG_FROM_IMPA, (GetItemID)RG_ZELDAS_LULLABY); - StartingItemGive(getItemEntry, RC_SONG_FROM_IMPA); - getItemEntry = Randomizer_GetItemFromKnownCheck(RC_HC_MALON_EGG, (GetItemID)RG_WEIRD_EGG); - StartingItemGive(getItemEntry, RC_HC_ZELDAS_LETTER); - getItemEntry = Randomizer_GetItemFromKnownCheck(RC_HC_ZELDAS_LETTER, (GetItemID)RG_ZELDAS_LETTER); - StartingItemGive(getItemEntry, RC_HC_MALON_EGG); - - // Malon/Talon back at ranch. - Flags_SetEventChkInf(EVENTCHKINF_OBTAINED_POCKET_EGG); - Flags_SetRandomizerInf(RAND_INF_WEIRD_EGG); - Flags_SetEventChkInf(EVENTCHKINF_TALON_WOKEN_IN_CASTLE); - Flags_SetEventChkInf(EVENTCHKINF_TALON_RETURNED_FROM_CASTLE); - - // Set "Got Zelda's Letter" flag. Also ensures Saria is back at SFM. - Flags_SetEventChkInf(EVENTCHKINF_OBTAINED_ZELDAS_LETTER); - Flags_SetRandomizerInf(RAND_INF_ZELDAS_LETTER); - Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_LETTER_ZELDA); - - // Got item from Impa. - Flags_SetEventChkInf(EVENTCHKINF_LEARNED_ZELDAS_LULLABY); - - gSaveContext.sceneFlags[SCENE_HYRULE_CASTLE].swch |= (1 << 0x4); // Move milk crates in Hyrule Castle to moat. - - // Set this at the end to ensure we always start with the letter. - // This is for the off chance, we got the Weird Egg from Impa (which should never happen). - INV_CONTENT(ITEM_LETTER_ZELDA) = ITEM_LETTER_ZELDA; - } + if (Randomizer_GetSettingValue(RSK_SKIP_CHILD_ZELDA)) { + GetItemEntry getItemEntry = + Randomizer_GetItemFromKnownCheck(RC_SONG_FROM_IMPA, (GetItemID)RG_ZELDAS_LULLABY); + StartingItemGive(getItemEntry, RC_SONG_FROM_IMPA); + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_HC_MALON_EGG, (GetItemID)RG_WEIRD_EGG); + StartingItemGive(getItemEntry, RC_HC_ZELDAS_LETTER); + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_HC_ZELDAS_LETTER, (GetItemID)RG_ZELDAS_LETTER); + StartingItemGive(getItemEntry, RC_HC_MALON_EGG); + + // Malon/Talon back at ranch. + Flags_SetEventChkInf(EVENTCHKINF_OBTAINED_POCKET_EGG); + Flags_SetRandomizerInf(RAND_INF_WEIRD_EGG); + Flags_SetEventChkInf(EVENTCHKINF_TALON_WOKEN_IN_CASTLE); + Flags_SetEventChkInf(EVENTCHKINF_TALON_RETURNED_FROM_CASTLE); + + // Set "Got Zelda's Letter" flag. Also ensures Saria is back at SFM. + Flags_SetEventChkInf(EVENTCHKINF_OBTAINED_ZELDAS_LETTER); + Flags_SetRandomizerInf(RAND_INF_ZELDAS_LETTER); + Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_LETTER_ZELDA); + + // Got item from Impa. + Flags_SetEventChkInf(EVENTCHKINF_LEARNED_ZELDAS_LULLABY); + + gSaveContext.sceneFlags[SCENE_HYRULE_CASTLE].swch |= + (1 << 0x4); // Move milk crates in Hyrule Castle to moat. + + // Set this at the end to ensure we always start with the letter. + // This is for the off chance, we got the Weird Egg from Impa (which should never happen). + INV_CONTENT(ITEM_LETTER_ZELDA) = ITEM_LETTER_ZELDA; + } - if (Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD) && startingAge == RO_AGE_ADULT) { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_TOT_MASTER_SWORD, GI_NONE); - StartingItemGive(getItemEntry, RC_TOT_MASTER_SWORD); - Flags_SetRandomizerInf(RAND_INF_TOT_MASTER_SWORD); - } + if (Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD) && startingAge == RO_AGE_ADULT) { + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_TOT_MASTER_SWORD, GI_NONE); + StartingItemGive(getItemEntry, RC_TOT_MASTER_SWORD); + Flags_SetRandomizerInf(RAND_INF_TOT_MASTER_SWORD); + } - HIGH_SCORE(HS_POE_POINTS) = 1000 - (100 * Randomizer_GetSettingValue(RSK_BIG_POE_COUNT)); + HIGH_SCORE(HS_POE_POINTS) = 1000 - (100 * Randomizer_GetSettingValue(RSK_BIG_POE_COUNT)); - if (Randomizer_GetSettingValue(RSK_SKIP_EPONA_RACE)) { - Flags_SetEventChkInf(EVENTCHKINF_EPONA_OBTAINED); - } + if (Randomizer_GetSettingValue(RSK_SKIP_EPONA_RACE)) { + Flags_SetEventChkInf(EVENTCHKINF_EPONA_OBTAINED); + } - // Open lowest Vanilla Fire Temple locked door (to prevent key logic lockouts). - // Not done on Keysanity since this lockout is a non-issue when Fire Keys can be found outside the temple. - u8 keysanity = Randomizer_GetSettingValue(RSK_KEYSANITY) == RO_DUNGEON_ITEM_LOC_ANYWHERE || - Randomizer_GetSettingValue(RSK_KEYSANITY) == RO_DUNGEON_ITEM_LOC_OVERWORLD || - Randomizer_GetSettingValue(RSK_KEYSANITY) == RO_DUNGEON_ITEM_LOC_ANY_DUNGEON; - if (!ResourceMgr_IsSceneMasterQuest(SCENE_FIRE_TEMPLE) && !keysanity) { - gSaveContext.sceneFlags[SCENE_FIRE_TEMPLE].swch |= (1 << 0x17); - } + // Open lowest Vanilla Fire Temple locked door (to prevent key logic lockouts). + // Not done on Keysanity since this lockout is a non-issue when Fire Keys can be found outside the temple. + u8 keysanity = Randomizer_GetSettingValue(RSK_KEYSANITY) == RO_DUNGEON_ITEM_LOC_ANYWHERE || + Randomizer_GetSettingValue(RSK_KEYSANITY) == RO_DUNGEON_ITEM_LOC_OVERWORLD || + Randomizer_GetSettingValue(RSK_KEYSANITY) == RO_DUNGEON_ITEM_LOC_ANY_DUNGEON; + if (!ResourceMgr_IsSceneMasterQuest(SCENE_FIRE_TEMPLE) && !keysanity) { + gSaveContext.sceneFlags[SCENE_FIRE_TEMPLE].swch |= (1 << 0x17); + } - // Opens locked Water Temple door in vanilla to prevent softlocks. - // West door on the middle level that leads to the water raising thing. - // Happens in 3DS rando and N64 rando as well. - if (!ResourceMgr_IsSceneMasterQuest(SCENE_WATER_TEMPLE)) { - gSaveContext.sceneFlags[SCENE_WATER_TEMPLE].swch |= (1 << 0x15); - } + // Opens locked Water Temple door in vanilla to prevent softlocks. + // West door on the middle level that leads to the water raising thing. + // Happens in 3DS rando and N64 rando as well. + if (!ResourceMgr_IsSceneMasterQuest(SCENE_WATER_TEMPLE)) { + gSaveContext.sceneFlags[SCENE_WATER_TEMPLE].swch |= (1 << 0x15); + } - int doorOfTime = Randomizer_GetSettingValue(RSK_DOOR_OF_TIME); - switch (doorOfTime) { - case RO_DOOROFTIME_OPEN: - Flags_SetEventChkInf(EVENTCHKINF_OPENED_THE_DOOR_OF_TIME); - break; - } + int doorOfTime = Randomizer_GetSettingValue(RSK_DOOR_OF_TIME); + switch (doorOfTime) { + case RO_DOOROFTIME_OPEN: + Flags_SetEventChkInf(EVENTCHKINF_OPENED_THE_DOOR_OF_TIME); + break; + } - if (Randomizer_GetSettingValue(RSK_KAK_GATE) == RO_KAK_GATE_OPEN) { - Flags_SetInfTable(INFTABLE_SHOWED_ZELDAS_LETTER_TO_GATE_GUARD); - Flags_UnsetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_LETTER_ZELDA); - } + if (Randomizer_GetSettingValue(RSK_KAK_GATE) == RO_KAK_GATE_OPEN) { + Flags_SetInfTable(INFTABLE_SHOWED_ZELDAS_LETTER_TO_GATE_GUARD); + Flags_UnsetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_LETTER_ZELDA); + } - if (Randomizer_GetSettingValue(RSK_GERUDO_FORTRESS) == RO_GF_CARPENTERS_FAST || - Randomizer_GetSettingValue(RSK_GERUDO_FORTRESS) == RO_GF_CARPENTERS_FREE) { - Flags_SetEventChkInf(EVENTCHKINF_CARPENTERS_FREE(1)); - Flags_SetEventChkInf(EVENTCHKINF_CARPENTERS_FREE(2)); - Flags_SetEventChkInf(EVENTCHKINF_CARPENTERS_FREE(3)); - gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x02); // heard yells and unlocked doors - gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x03); - gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x04); - gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x06); - gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x07); - gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x08); - gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x10); - gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x12); - gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x13); - gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].collect |= (1 << 0x0A); // picked up keys - gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].collect |= (1 << 0x0E); - gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].collect |= (1 << 0x0F); - } + if (Randomizer_GetSettingValue(RSK_GERUDO_FORTRESS) == RO_GF_CARPENTERS_FAST || + Randomizer_GetSettingValue(RSK_GERUDO_FORTRESS) == RO_GF_CARPENTERS_FREE) { + Flags_SetEventChkInf(EVENTCHKINF_CARPENTERS_FREE(1)); + Flags_SetEventChkInf(EVENTCHKINF_CARPENTERS_FREE(2)); + Flags_SetEventChkInf(EVENTCHKINF_CARPENTERS_FREE(3)); + gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x02); // heard yells and unlocked doors + gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x03); + gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x04); + gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x06); + gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x07); + gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x08); + gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x10); + gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x12); + gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x13); + gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].collect |= (1 << 0x0A); // picked up keys + gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].collect |= (1 << 0x0E); + gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].collect |= (1 << 0x0F); + } - if (Randomizer_GetSettingValue(RSK_GERUDO_FORTRESS) == RO_GF_CARPENTERS_FREE) { - Flags_SetEventChkInf(EVENTCHKINF_CARPENTERS_FREE(0)); - gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x01); // heard yell and unlocked door - gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x05); - gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x11); - gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].collect |= (1 << 0x0C); // picked up key + if (Randomizer_GetSettingValue(RSK_GERUDO_FORTRESS) == RO_GF_CARPENTERS_FREE) { + Flags_SetEventChkInf(EVENTCHKINF_CARPENTERS_FREE(0)); + gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x01); // heard yell and unlocked door + gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x05); + gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x11); + gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].collect |= (1 << 0x0C); // picked up key - if (!Randomizer_GetSettingValue(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD)) { - Item_Give(NULL, ITEM_GERUDO_CARD); + if (!Randomizer_GetSettingValue(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD)) { + Item_Give(NULL, ITEM_GERUDO_CARD); + } } - } - // complete mask quest - if (Randomizer_GetSettingValue(RSK_COMPLETE_MASK_QUEST)) { - Flags_SetInfTable(INFTABLE_GATE_GUARD_PUT_ON_KEATON_MASK); - Flags_SetEventChkInf(EVENTCHKINF_PAID_BACK_BUNNY_HOOD_FEE); - - Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_KEATON); - Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_SKULL); - Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_SPOOKY); - Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_BUNNY); - Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_GORON); - Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_ZORA); - Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_GERUDO); - Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_TRUTH); - - gSaveContext.itemGetInf[3] |= 0x100; // Sold Keaton Mask - gSaveContext.itemGetInf[3] |= 0x200; // Sold Skull Mask - gSaveContext.itemGetInf[3] |= 0x400; // Sold Spooky Mask - gSaveContext.itemGetInf[3] |= 0x800; // Bunny Hood related - gSaveContext.itemGetInf[3] |= 0x8000; // Obtained Mask of Truth + // complete mask quest + if (Randomizer_GetSettingValue(RSK_COMPLETE_MASK_QUEST)) { + Flags_SetInfTable(INFTABLE_GATE_GUARD_PUT_ON_KEATON_MASK); + Flags_SetEventChkInf(EVENTCHKINF_PAID_BACK_BUNNY_HOOD_FEE); + + Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_KEATON); + Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_SKULL); + Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_SPOOKY); + Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_BUNNY); + Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_GORON); + Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_ZORA); + Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_GERUDO); + Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_TRUTH); + + gSaveContext.itemGetInf[3] |= 0x100; // Sold Keaton Mask + gSaveContext.itemGetInf[3] |= 0x200; // Sold Skull Mask + gSaveContext.itemGetInf[3] |= 0x400; // Sold Spooky Mask + gSaveContext.itemGetInf[3] |= 0x800; // Bunny Hood related + gSaveContext.itemGetInf[3] |= 0x8000; // Obtained Mask of Truth + } } -} +} \ No newline at end of file From 5d0d3873f6a8c29c350ce838e6051f440fa222a7 Mon Sep 17 00:00:00 2001 From: TheLynk Date: Thu, 15 Jan 2026 08:55:44 +0100 Subject: [PATCH 34/45] Merge remote-tracking branch 'upstream/develop' into Shuffle-Roll Part 2 --- .../Enhancements/randomizer/3drando/item_pool.cpp | 2 +- .../location_access/overworld/kokiri_forest.cpp | 14 +++++++------- soh/soh/Enhancements/randomizer/randomizer.cpp | 2 +- soh/soh/Enhancements/randomizer/settings.cpp | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index a54b15884d8..0d408ee9dc1 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -397,7 +397,7 @@ void GenerateItemPool() { } if (ctx->GetOption(RSK_SHUFFLE_ROLL)) { - AddItemToMainPool(RG_ROLL); + AddItemToPool(RG_ROLL, 2, 1, 1, 1); } if (ctx->GetOption(RSK_SHUFFLE_BEEHIVES)) { diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp index 3b252a5b8bb..25013db1d37 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp @@ -27,13 +27,13 @@ void RegionTable_Init_KokiriForest() { LOCATION(RC_KF_SOUTH_GRASS_EAST_RUPEE, logic->IsChild), LOCATION(RC_KF_NORTH_GRASS_WEST_RUPEE, logic->IsChild), LOCATION(RC_KF_NORTH_GRASS_EAST_RUPEE, logic->IsChild), - LOCATION(RC_KF_BEAN_RUPEE_1, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST) || (logic->CanUse(RG_HOVER_BOOTS) && logic->HasItem(RG_ROLL)) || logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_KF_BEAN_RUPEE_2, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST) || (logic->CanUse(RG_HOVER_BOOTS) && logic->HasItem(RG_ROLL)) || logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_KF_BEAN_RUPEE_3, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST) || (logic->CanUse(RG_HOVER_BOOTS) && logic->HasItem(RG_ROLL)) || logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_KF_BEAN_RUPEE_4, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST) || (logic->CanUse(RG_HOVER_BOOTS) && logic->HasItem(RG_ROLL)) || logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_KF_BEAN_RUPEE_5, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST) || (logic->CanUse(RG_HOVER_BOOTS) && logic->HasItem(RG_ROLL)) || logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_KF_BEAN_RUPEE_6, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST) || (logic->CanUse(RG_HOVER_BOOTS) && logic->HasItem(RG_ROLL)) || logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_KF_BEAN_RED_RUPEE, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST) || (logic->CanUse(RG_HOVER_BOOTS) && logic->HasItem(RG_ROLL)) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_1, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || (logic->CanUse(RG_HOVER_BOOTS) && logic->HasItem(RG_ROLL)) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_2, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || (logic->CanUse(RG_HOVER_BOOTS) && logic->HasItem(RG_ROLL)) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_3, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || (logic->CanUse(RG_HOVER_BOOTS) && logic->HasItem(RG_ROLL)) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_4, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || (logic->CanUse(RG_HOVER_BOOTS) && logic->HasItem(RG_ROLL)) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_5, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || (logic->CanUse(RG_HOVER_BOOTS) && logic->HasItem(RG_ROLL)) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_6, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || (logic->CanUse(RG_HOVER_BOOTS) && logic->HasItem(RG_ROLL)) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RED_RUPEE, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || (logic->CanUse(RG_HOVER_BOOTS) && logic->HasItem(RG_ROLL)) || 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), diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index e56f240b6ba..a0a1097f2c0 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -4945,7 +4945,7 @@ CustomMessage Randomizer::GetGoronMessage(u16 index) { void Randomizer::CreateCustomMessages() { // RANDTODO: Translate into french and german and replace GIMESSAGE_UNTRANSLATED // with GIMESSAGE(getItemID, itemID, english, german, french). - const std::array getItemMessages = { { + const std::array getItemMessages = { { GIMESSAGE(RG_GREG_RUPEE, ITEM_MASK_GORON, "You found %gGreg%w!", "%gGreg%w! Du hast ihn&wirklich gefunden!", "Félicitation! Vous avez trouvé %gGreg%w!"), GIMESSAGE(RG_MASTER_SWORD, ITEM_SWORD_MASTER, "You found the %gMaster Sword%w!", diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index a687e1b7d6f..8b99a9b5cc7 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -2310,7 +2310,6 @@ void Settings::CreateOptions() { WidgetContainerType::TABLE); mOptionGroups[RSG_MENU_SECTION_BASIC_SHUFFLES] = OptionGroup::SubGroup("Shuffle Items", - &mOptions[RSK_SHUFFLE_SWIM], { &mOptions[RSK_SHUFFLE_SONGS], &mOptions[RSK_SHUFFLE_TOKENS], @@ -2392,6 +2391,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_OCARINA_BUTTONS], &mOptions[RSK_SHUFFLE_SWIM], &mOptions[RSK_SHUFFLE_CRAWL], + &mOptions[RSK_SHUFFLE_ROLL], &mOptions[RSK_SHUFFLE_BEAN_SOULS], &mOptions[RSK_ROCS_FEATHER], &mOptions[RSK_BOMBCHU_BAG], From 30de6d93ae67c4d6812e548ee5c3d601b40a1e84 Mon Sep 17 00:00:00 2001 From: TheLynk Date: Thu, 15 Jan 2026 09:15:18 +0100 Subject: [PATCH 35/45] Add Animation Capture Tool.cpp & remove useless code in draw.cpp --- .../randomizer/animation_capture_tool.cpp | 55 +++++++++++++++++++ soh/soh/Enhancements/randomizer/draw.cpp | 7 +-- 2 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 soh/soh/Enhancements/randomizer/animation_capture_tool.cpp diff --git a/soh/soh/Enhancements/randomizer/animation_capture_tool.cpp b/soh/soh/Enhancements/randomizer/animation_capture_tool.cpp new file mode 100644 index 00000000000..e79139309b3 --- /dev/null +++ b/soh/soh/Enhancements/randomizer/animation_capture_tool.cpp @@ -0,0 +1,55 @@ +// Animation capture tool | OUTIL DE CAPTURE +// I provide here the code which allowed me to have all the data for the roll animation for my Shuffle Roll model +// following the request of Serprex + +// and in this example I had temporarily put it in the Draw.cpp file and I called the function when Link performed a +// roll et dans cet exemple je l'avais mis temporairement dans le fichier Draw.cpp et j'appelais la fonction au moment +// que Link fessait une roulade + +#define NUM_FRAMES_TO_CAPTURE 10 +static Vec3s capturedRollFrames[NUM_FRAMES_TO_CAPTURE][LIMB_COUNT_LINK]; +static int captureFrameCount = 0; +static bool captureComplete = false; +static bool captureStarted = false; + +extern "C" void CaptureRollAnimation(PlayState* play) { + if (captureComplete) + return; + + Player* player = GET_PLAYER(play); + if (player == NULL || player->skelAnime.jointTable == NULL) + return; + + // Checks if the player is rolling | Vérifie si le joueur roule + bool isRolling = (player->actionFunc == Player_Action_Roll); + + if (isRolling) { + if (!captureStarted) { + captureStarted = true; + osSyncPrintf("\n========== DÉBUT CAPTURE ANIMATION ROLL ==========\n"); + } + + // Captures a frame every 2 game frames | Capture une frame toutes les 2 frames de jeu + if ((play->state.frames % 2) == 0 && captureFrameCount < NUM_FRAMES_TO_CAPTURE) { + osSyncPrintf("\n// Frame %d\n", captureFrameCount); + osSyncPrintf("{\n"); + + for (int i = 0; i < LIMB_COUNT_LINK; i++) { + Vec3s joint = player->skelAnime.jointTable[i]; + capturedRollFrames[captureFrameCount][i] = joint; + + osSyncPrintf(" { %d, %d, %d }, // Limb %d\n", joint.x, joint.y, joint.z, i); + } + + osSyncPrintf("},\n"); + + captureFrameCount++; + + if (captureFrameCount >= NUM_FRAMES_TO_CAPTURE) { + captureComplete = true; + osSyncPrintf("\n========== FIN CAPTURE - %d FRAMES CAPTURÉES ==========\n", NUM_FRAMES_TO_CAPTURE); + osSyncPrintf("Copie ces données et envoie-les moi !\n\n"); + } + } + } +} diff --git a/soh/soh/Enhancements/randomizer/draw.cpp b/soh/soh/Enhancements/randomizer/draw.cpp index f729c0e114f..79398a91b80 100644 --- a/soh/soh/Enhancements/randomizer/draw.cpp +++ b/soh/soh/Enhancements/randomizer/draw.cpp @@ -35,7 +35,6 @@ extern "C" { #include "objects/object_tw/object_tw.h" #include "objects/object_ganon2/object_ganon2.h" #include "objects/object_gi_shield_1/object_gi_shield_1.h" -#include "objects/object_vase/object_vase.h" #include "objects/object_link_child/object_link_child.h" #include "roll_animation_data.h" @@ -1171,16 +1170,16 @@ extern "C" void Randomizer_DrawRollAbility(PlayState* play, GetItemEntry* getIte ROLL_ANIMATION_LIMBS); } - // Animation manuelle avec les frames capturées + // Manual animation with captured frames if (lastUpdate != play->state.frames) { lastUpdate = play->state.frames; - // Avance d'une frame toutes les 2 frames de jeu + // Advances one frame every 2 frames of play if ((play->state.frames % 2) == 0) { currentFrame = (currentFrame + 1) % ROLL_ANIMATION_FRAMES; } - // Copie les données de la frame actuelle + // Copies data from current frame for (int i = 0; i < ROLL_ANIMATION_LIMBS; i++) { jointTable[i] = rollAnimationData[currentFrame][i]; } From 08fcf0817ecdb7297d9766c1ce519f691976d06d Mon Sep 17 00:00:00 2001 From: TheLynk Date: Thu, 15 Jan 2026 10:21:01 +0100 Subject: [PATCH 36/45] Update animation_capture_tool.cpp --- soh/soh/Enhancements/randomizer/animation_capture_tool.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/soh/soh/Enhancements/randomizer/animation_capture_tool.cpp b/soh/soh/Enhancements/randomizer/animation_capture_tool.cpp index e79139309b3..1c06e7ead99 100644 --- a/soh/soh/Enhancements/randomizer/animation_capture_tool.cpp +++ b/soh/soh/Enhancements/randomizer/animation_capture_tool.cpp @@ -6,6 +6,7 @@ // roll et dans cet exemple je l'avais mis temporairement dans le fichier Draw.cpp et j'appelais la fonction au moment // que Link fessait une roulade +/* #define NUM_FRAMES_TO_CAPTURE 10 static Vec3s capturedRollFrames[NUM_FRAMES_TO_CAPTURE][LIMB_COUNT_LINK]; static int captureFrameCount = 0; @@ -53,3 +54,4 @@ extern "C" void CaptureRollAnimation(PlayState* play) { } } } +*/ \ No newline at end of file From 80f242e2b10167f00408ffc0f0f81109f47949a1 Mon Sep 17 00:00:00 2001 From: TheLynk <44308308+TheLynk@users.noreply.github.com> Date: Sat, 17 Jan 2026 09:42:53 +0100 Subject: [PATCH 37/45] Update soh/soh/Enhancements/randomizer/animation_capture_tool.cpp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Philip Dubé --- .../Enhancements/randomizer/animation_capture_tool.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/animation_capture_tool.cpp b/soh/soh/Enhancements/randomizer/animation_capture_tool.cpp index 1c06e7ead99..a91936a7e03 100644 --- a/soh/soh/Enhancements/randomizer/animation_capture_tool.cpp +++ b/soh/soh/Enhancements/randomizer/animation_capture_tool.cpp @@ -1,10 +1,5 @@ -// Animation capture tool | OUTIL DE CAPTURE -// I provide here the code which allowed me to have all the data for the roll animation for my Shuffle Roll model -// following the request of Serprex - -// and in this example I had temporarily put it in the Draw.cpp file and I called the function when Link performed a -// roll et dans cet exemple je l'avais mis temporairement dans le fichier Draw.cpp et j'appelais la fonction au moment -// que Link fessait une roulade +// I provide here the code which allowed me to have all the data for the roll animation for roll_animation_data.h +// I had temporarily put it in the Draw.cpp file and I called the function when Link performed a roll /* #define NUM_FRAMES_TO_CAPTURE 10 From e60f573cf96477230392fd1c4cc7be526e584bcf Mon Sep 17 00:00:00 2001 From: TheLynk Date: Wed, 21 Jan 2026 16:47:04 +0100 Subject: [PATCH 38/45] Clang Format --- soh/soh/Enhancements/randomizer/logic.cpp | 2 +- soh/soh/Enhancements/randomizer/savefile.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index cfb5cfd8b1b..28f7ad3a0fc 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -2683,7 +2683,7 @@ void Logic::Reset(bool resetSaveContext /*= true*/) { if (ctx->GetOption(RSK_SHUFFLE_ROLL).Is(false)) { SetRandoInf(RAND_INF_CAN_ROLL, true); } - + // If we're not shuffling open chest, we start with it if (ctx->GetOption(RSK_SHUFFLE_OPEN_CHEST).Is(false)) { SetRandoInf(RAND_INF_CAN_OPEN_CHEST, true); diff --git a/soh/soh/Enhancements/randomizer/savefile.cpp b/soh/soh/Enhancements/randomizer/savefile.cpp index dbf99115f85..b9fc298e6dd 100644 --- a/soh/soh/Enhancements/randomizer/savefile.cpp +++ b/soh/soh/Enhancements/randomizer/savefile.cpp @@ -328,7 +328,7 @@ extern "C" void Randomizer_InitSaveFile() { if (Randomizer_GetSettingValue(RSK_SHUFFLE_ROLL) == RO_GENERIC_OFF) { Flags_SetRandomizerInf(RAND_INF_CAN_ROLL); } - + if (Randomizer_GetSettingValue(RSK_SHUFFLE_OPEN_CHEST) == RO_GENERIC_OFF) { Flags_SetRandomizerInf(RAND_INF_CAN_OPEN_CHEST); } From 07019237d02cfe64e2be2936d6af23b22ff0cccb Mon Sep 17 00:00:00 2001 From: TheLynk Date: Wed, 21 Jan 2026 16:53:40 +0100 Subject: [PATCH 39/45] Fix crash and Add Ice traps Text for Roll --- soh/soh/Enhancements/randomizer/3drando/shops.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/soh/soh/Enhancements/randomizer/3drando/shops.cpp b/soh/soh/Enhancements/randomizer/3drando/shops.cpp index 10b1a6a7df4..d977702644b 100644 --- a/soh/soh/Enhancements/randomizer/3drando/shops.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/shops.cpp @@ -1005,6 +1005,10 @@ void InitTrickNames() { // TODO_TRANSLATE Text{ "Crouch" }, }; + trickNameTable[RG_ROLL] = { + // TODO_TRANSLATE + Text{ "Roll" }, + }; trickNameTable[RG_OPEN_CHEST] = { // TODO_TRANSLATE Text{ "Open Cheats" }, From f010acc351b1a46346b65b1c68bbc93dec25ff3d Mon Sep 17 00:00:00 2001 From: TheLynk Date: Wed, 21 Jan 2026 18:48:28 +0100 Subject: [PATCH 40/45] Add Roll in Kaleido Tracker --- soh/soh/Enhancements/kaleido.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/soh/soh/Enhancements/kaleido.cpp b/soh/soh/Enhancements/kaleido.cpp index e541be5a2c7..b846cbcb600 100644 --- a/soh/soh/Enhancements/kaleido.cpp +++ b/soh/soh/Enhancements/kaleido.cpp @@ -203,6 +203,11 @@ Kaleido::Kaleido() { 32, aButtonColor, FlagType::FLAG_RANDOMIZER_INF, RAND_INF_CAN_GRAB, "Grab")); } + if (ctx->GetOption(RSK_SHUFFLE_ROLL)) { + mEntries.push_back(std::make_shared(gButtonBackgroundTex, G_IM_FMT_IA, G_IM_SIZ_8b, 32, + 32, aButtonColor, FlagType::FLAG_RANDOMIZER_INF, + RAND_INF_CAN_ROLL, "Roll")); + } if (ctx->GetOption(RSK_SHUFFLE_OPEN_CHEST)) { mEntries.push_back(std::make_shared( gMapChestIconTex, G_IM_FMT_RGBA, G_IM_SIZ_16b, 8, 8, Color_RGBA8{ 255, 255, 255, 255 }, From 1f2c3832762ae2a50683c781e1a03958ac648dc7 Mon Sep 17 00:00:00 2001 From: TheLynk Date: Fri, 23 Jan 2026 11:25:31 +0100 Subject: [PATCH 41/45] Add Roll in Item Tracker --- .../randomizer/randomizer_item_tracker.cpp | 12 ++++++++++++ soh/soh/SohGui/ImGuiUtils.cpp | 1 + 2 files changed, 13 insertions(+) diff --git a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp index 525e5082cae..061e904163c 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp @@ -153,6 +153,10 @@ std::vector climbItems = { ITEM_TRACKER_ITEM(RG_CLIMB, 0, DrawItem), }; +std::vector rollItems = { + ITEM_TRACKER_ITEM(RG_ROLL, 0, DrawItem), +}; + std::vector grabItems = { ITEM_TRACKER_ITEM(RG_POWER_BRACELET, 0, DrawItem), }; @@ -1142,6 +1146,11 @@ void DrawItem(ItemTrackerItem item) { hasItem = Flags_GetRandomizerInf(RAND_INF_CAN_CLIMB); itemName = "Climb"; break; + case RG_ROLL: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_CAN_ROLL); + itemName = "Roll"; + break; case RG_POWER_BRACELET: actualItemId = item.id; hasItem = Flags_GetRandomizerInf(RAND_INF_CAN_GRAB); @@ -1578,6 +1587,9 @@ void UpdateVectors() { if (IS_RANDO && RAND_GET_OPTION(RSK_SHUFFLE_CLIMB)) { mainWindowItems.insert(mainWindowItems.end(), climbItems.begin(), climbItems.end()); } + if (IS_RANDO && RAND_GET_OPTION(RSK_SHUFFLE_ROLL)) { + mainWindowItems.insert(mainWindowItems.end(), rollItems.begin(), rollItems.end()); + } if (IS_RANDO && RAND_GET_OPTION(RSK_SHUFFLE_CRAWL)) { mainWindowItems.insert(mainWindowItems.end(), crawlItems.begin(), crawlItems.end()); } diff --git a/soh/soh/SohGui/ImGuiUtils.cpp b/soh/soh/SohGui/ImGuiUtils.cpp index eaf63c6eacb..143fc2bc356 100644 --- a/soh/soh/SohGui/ImGuiUtils.cpp +++ b/soh/soh/SohGui/ImGuiUtils.cpp @@ -154,6 +154,7 @@ std::map customItemsMapping = { std::map actionShuffleMapping = { { RG_CRAWL, { RG_CRAWL, "RG_CRAWL", "RG_CRAWL_Faded", gButtonBackgroundTex } }, { RG_CLIMB, { RG_CLIMB, "RG_CLIMB", "RG_CLIMB_Faded", gButtonBackgroundTex } }, + { RG_ROLL, { RG_ROLL, "RG_ROLL", "RG_ROLL_Faded", gButtonBackgroundTex } }, { RG_POWER_BRACELET, { RG_POWER_BRACELET, "RG_POWER_BRACELET", "RG_POWER_BRACELET_Faded", gButtonBackgroundTex } }, }; From d1f5bfcec23202949645e5a749c46cf9c5f4c849 Mon Sep 17 00:00:00 2001 From: TheLynk Date: Fri, 23 Jan 2026 23:21:19 +0100 Subject: [PATCH 42/45] To many addition | V:13 --- soh/soh/Enhancements/ExtraTraps.cpp | 81 ++----------------- soh/soh/Enhancements/gameplaystats.cpp | 2 +- .../randomizer/3drando/item_pool.cpp | 3 +- .../location_access/dungeons/water_temple.cpp | 4 +- .../overworld/castle_grounds.cpp | 4 + soh/soh/Enhancements/randomizer/logic.cpp | 6 +- soh/soh/Enhancements/randomizer/savefile.cpp | 20 ++--- soh/soh/SohGui/SohMenuEnhancements.cpp | 11 --- 8 files changed, 26 insertions(+), 105 deletions(-) diff --git a/soh/soh/Enhancements/ExtraTraps.cpp b/soh/soh/Enhancements/ExtraTraps.cpp index ad81fcb3f7a..1bd91aaf499 100644 --- a/soh/soh/Enhancements/ExtraTraps.cpp +++ b/soh/soh/Enhancements/ExtraTraps.cpp @@ -9,8 +9,6 @@ extern "C" { #include "macros.h" extern PlayState* gPlayState; GetItemEntry ItemTable_RetrieveEntry(s16 modIndex, s16 getItemID); -GetItemID RetrieveGetItemIDFromItemID(ItemID itemID); -RandomizerGet RetrieveRandomizerGetFromItemID(ItemID itemID); } #define CVAR_EXTRA_TRAPS_NAME CVAR_ENHANCEMENT("ExtraTraps.Enabled") @@ -28,49 +26,19 @@ typedef enum { ADD_AMMO_TRAP, ADD_KILL_TRAP, ADD_TELEPORT_TRAP, - ADD_POCKET_TRAP, - ADD_PERMADEATH_TRAP, ADD_TRAP_MAX } AltTrapType; static AltTrapType roll = ADD_TRAP_MAX; static int statusTimer = -1; static int eventTimer = -1; -static int permaDeathTimer = -1; -bool shouldFileDelete = false; const char* altTrapTypeCvars[] = { - CVAR_ENHANCEMENT("ExtraTraps.Ice"), CVAR_ENHANCEMENT("ExtraTraps.Burn"), - CVAR_ENHANCEMENT("ExtraTraps.Shock"), CVAR_ENHANCEMENT("ExtraTraps.Knockback"), - CVAR_ENHANCEMENT("ExtraTraps.Speed"), CVAR_ENHANCEMENT("ExtraTraps.Bomb"), - CVAR_ENHANCEMENT("ExtraTraps.Void"), CVAR_ENHANCEMENT("ExtraTraps.Ammo"), - CVAR_ENHANCEMENT("ExtraTraps.Kill"), CVAR_ENHANCEMENT("ExtraTraps.Teleport"), - CVAR_ENHANCEMENT("ExtraTraps.Pocket"), CVAR_ENHANCEMENT("ExtraTraps.Permadeath"), -}; - -static std::unordered_map itemToQuestMap = { - { ITEM_MEDALLION_FOREST, QUEST_MEDALLION_FOREST }, - { ITEM_MEDALLION_FIRE, QUEST_MEDALLION_FIRE }, - { ITEM_MEDALLION_WATER, QUEST_MEDALLION_WATER }, - { ITEM_MEDALLION_SPIRIT, QUEST_MEDALLION_SPIRIT }, - { ITEM_MEDALLION_SHADOW, QUEST_MEDALLION_SHADOW }, - { ITEM_MEDALLION_LIGHT, QUEST_MEDALLION_LIGHT }, - { ITEM_SONG_MINUET, QUEST_SONG_MINUET }, - { ITEM_SONG_BOLERO, QUEST_SONG_BOLERO }, - { ITEM_SONG_SERENADE, QUEST_SONG_SERENADE }, - { ITEM_SONG_REQUIEM, QUEST_SONG_REQUIEM }, - { ITEM_SONG_NOCTURNE, QUEST_SONG_NOCTURNE }, - { ITEM_SONG_PRELUDE, QUEST_SONG_PRELUDE }, - { ITEM_SONG_LULLABY, QUEST_SONG_LULLABY }, - { ITEM_SONG_EPONA, QUEST_SONG_EPONA }, - { ITEM_SONG_SARIA, QUEST_SONG_SARIA }, - { ITEM_SONG_SUN, QUEST_SONG_SUN }, - { ITEM_SONG_TIME, QUEST_SONG_TIME }, - { ITEM_SONG_STORMS, QUEST_SONG_STORMS }, - { ITEM_KOKIRI_EMERALD, QUEST_KOKIRI_EMERALD }, - { ITEM_GORON_RUBY, QUEST_GORON_RUBY }, - { ITEM_ZORA_SAPPHIRE, QUEST_ZORA_SAPPHIRE }, - { ITEM_GERUDO_CARD, QUEST_GERUDO_CARD }, + CVAR_ENHANCEMENT("ExtraTraps.Ice"), CVAR_ENHANCEMENT("ExtraTraps.Burn"), + CVAR_ENHANCEMENT("ExtraTraps.Shock"), CVAR_ENHANCEMENT("ExtraTraps.Knockback"), + CVAR_ENHANCEMENT("ExtraTraps.Speed"), CVAR_ENHANCEMENT("ExtraTraps.Bomb"), + CVAR_ENHANCEMENT("ExtraTraps.Void"), CVAR_ENHANCEMENT("ExtraTraps.Ammo"), + CVAR_ENHANCEMENT("ExtraTraps.Kill"), CVAR_ENHANCEMENT("ExtraTraps.Teleport"), }; std::vector getEnabledAddTraps() { @@ -135,18 +103,6 @@ static void RollRandomTrap(uint64_t seed) { case ADD_TELEPORT_TRAP: eventTimer = 3; break; - case ADD_POCKET_TRAP: - ExecutePocketTrap(); - break; - case ADD_PERMADEATH_TRAP: - permaDeathTimer = 180; - shouldFileDelete = true; - Notification::Emit({ .itemIcon = (const char*)gItemIcons[ITEM_BOMB], - .message = "Collect a Check or Perma Death executes in ", - .messageColor = UIWidgets::ColorValues.at(UIWidgets::Colors::White), - .suffix = "60 seconds.", - .suffixColor = UIWidgets::ColorValues.at(UIWidgets::Colors::Red) }); - break; default: break; } @@ -211,17 +167,6 @@ static void OnPlayerUpdate() { break; } } - if (permaDeathTimer == 0) { - if (shouldFileDelete) { - SaveManager::Instance->DeleteZeldaFile(gSaveContext.fileNum); - std::reinterpret_pointer_cast( - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Console")) - ->Dispatch("reset"); - } - } - if (permaDeathTimer >= 0) { - permaDeathTimer--; - } if (statusTimer >= 0) { statusTimer--; } @@ -250,20 +195,6 @@ void RegisterExtraTraps() { GameInteractor::RawAction::FreezePlayer(); } }); - - COND_HOOK(OnFlagSet, CVAR_EXTRA_TRAPS_NAME, [](int16_t flagType, int16_t flag) { - SPDLOG_INFO("Flag Set Here {}", std::to_string(flagType).c_str()); - if (flagType != FLAG_SCENE_CLEAR) { - shouldFileDelete = false; - } - }); - - COND_HOOK(OnSceneFlagSet, CVAR_EXTRA_TRAPS_NAME, [](int16_t sceneNum, int16_t flagType, int16_t flag) { - SPDLOG_INFO("Scene Flag Set Here {}", std::to_string(flagType).c_str()); - if (flagType != FLAG_SCENE_CLEAR) { - shouldFileDelete = false; - } - }); } -static RegisterShipInitFunc initFunc(RegisterExtraTraps, { CVAR_EXTRA_TRAPS_NAME }); +static RegisterShipInitFunc initFunc(RegisterExtraTraps, { CVAR_EXTRA_TRAPS_NAME }); \ No newline at end of file diff --git a/soh/soh/Enhancements/gameplaystats.cpp b/soh/soh/Enhancements/gameplaystats.cpp index 8f3544631bf..b9115affb92 100644 --- a/soh/soh/Enhancements/gameplaystats.cpp +++ b/soh/soh/Enhancements/gameplaystats.cpp @@ -448,7 +448,7 @@ void DrawGameplayStatsHeader() { // if tag is empty (not a release build) if (gGitCommitTag[0] == 0) { GameplayStatsRow("Git Branch:", (char*)gGitBranch); - GameplayStatsRow("Version : 12 | Git Commit Hash:", (char*)gGitCommitHash); + GameplayStatsRow("Version : 13 | Git Commit Hash:", (char*)gGitCommitHash); } else { GameplayStatsRow("Build Version:", (char*)gBuildVersion); } diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index d6281d2377a..90cf15c00fe 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -951,5 +951,4 @@ void GenerateItemPool() { } assert(itemPool.size() == locCount); -} -} +} \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp index a5af0061f3f..83a6dd9087a 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp @@ -377,7 +377,7 @@ void RegionTable_Init_WaterTemple() { LOCATION(RC_WATER_TEMPLE_DRAGON_CHEST, logic->HasItem(RG_BRONZE_SCALE) && logic->HasItem(RG_OPEN_CHEST) && ((logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_IRON_BOOTS)) || (((logic->IsAdult && ctx->GetTrickOption(RT_WATER_ADULT_DRAGON)) || (logic->IsChild && ctx->GetTrickOption(RT_WATER_CHILD_DRAGON))) && - logic->CanHitSwitch(ED_BOOMERANG, true) && (logic->HasItem(RG_SILVER_SCALE) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8))))) && logic->HasItem(RG_OPEN_CHEST)), + logic->CanHitSwitch(ED_BOOMERANG, true) && (logic->HasItem(RG_SILVER_SCALE) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8)))) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_WATER_TEMPLE_OUTSIDE_DRAGON_ROOM, []{return true;}), @@ -605,7 +605,7 @@ void RegionTable_Init_WaterTemple() { LOCATION(RC_WATER_TEMPLE_RIVER_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_WATER_TEMPLE_DRAGON_CHEST, logic->IsAdult && logic->CanHitSwitch(ED_LONGSHOT) && logic->HasItem(RG_BRONZE_SCALE) && logic->HasItem(RG_OPEN_CHEST) && ((ctx->GetTrickOption(RT_WATER_ADULT_DRAGON) && (logic->HasItem(RG_SILVER_SCALE) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8))) || - ctx->GetTrickOption(RT_WATER_DRAGON_JUMP_DIVE))) && logic->HasItem(RG_OPEN_CHEST)), + ctx->GetTrickOption(RT_WATER_DRAGON_JUMP_DIVE)) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits Entrance(RR_WATER_TEMPLE_DRAGON_ROOM, []{return logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_LONGSHOT) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS) && logic->CanJumpslash());}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp index a92603fe023..91253666891 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp @@ -59,6 +59,10 @@ void RegionTable_Init_CastleGrounds() { LOCATION(RC_HC_NEAR_GUARDS_TREE_6, logic->CanBonkTrees()), LOCATION(RC_HC_NL_TREE_1, false), LOCATION(RC_HC_NL_TREE_2, false), + LOCATION(RC_HC_ROCK_1, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_HC_ROCK_2, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_HC_ROCK_3, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_HC_BOULDER, logic->BlastOrSmash()), }, { //Exits Entrance(RR_HC_GATE, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index 47c60dc3030..15589e7ed8a 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -246,8 +246,6 @@ bool Logic::HasItem(RandomizerGet itemName) { return CurrentUpgrade(UPG_WALLET) >= 2; case RG_TYCOON_WALLET: return CurrentUpgrade(UPG_WALLET) >= 3; - case RG_OPEN_CHEST: - return CheckRandoInf(RAND_INF_CAN_OPEN_CHEST); // Scales case RG_BRONZE_SCALE: return CheckRandoInf(RAND_INF_CAN_SWIM); @@ -255,16 +253,16 @@ bool Logic::HasItem(RandomizerGet itemName) { return CurrentUpgrade(UPG_SCALE) >= 1; case RG_GOLDEN_SCALE: return CurrentUpgrade(UPG_SCALE) >= 2; + case RG_CLIMB: return CheckRandoInf(RAND_INF_CAN_CLIMB); - case RG_ROLL: return CheckRandoInf(RAND_INF_CAN_ROLL); - case RG_CRAWL: return CheckRandoInf(RAND_INF_CAN_CRAWL); case RG_OPEN_CHEST: return CheckRandoInf(RAND_INF_CAN_OPEN_CHEST); + case RG_POCKET_EGG: return CheckRandoInf(RAND_INF_ADULT_TRADES_HAS_POCKET_EGG) || CheckRandoInf(RAND_INF_ADULT_TRADES_HAS_POCKET_CUCCO); diff --git a/soh/soh/Enhancements/randomizer/savefile.cpp b/soh/soh/Enhancements/randomizer/savefile.cpp index 156611c34ed..bc899e74fa3 100644 --- a/soh/soh/Enhancements/randomizer/savefile.cpp +++ b/soh/soh/Enhancements/randomizer/savefile.cpp @@ -323,13 +323,13 @@ extern "C" void Randomizer_InitSaveFile() { if (Randomizer_GetSettingValue(RSK_SHUFFLE_CRAWL) == RO_GENERIC_OFF) { Flags_SetRandomizerInf(RAND_INF_CAN_CRAWL); - if (Randomizer_GetSettingValue(RSK_SHUFFLE_ROLL) == RO_GENERIC_OFF) { - Flags_SetRandomizerInf(RAND_INF_CAN_ROLL); - } + if (Randomizer_GetSettingValue(RSK_SHUFFLE_ROLL) == RO_GENERIC_OFF) { + Flags_SetRandomizerInf(RAND_INF_CAN_ROLL); + } - if (Randomizer_GetSettingValue(RSK_SHUFFLE_OPEN_CHEST) == RO_GENERIC_OFF) { - Flags_SetRandomizerInf(RAND_INF_CAN_OPEN_CHEST); - } + if (Randomizer_GetSettingValue(RSK_SHUFFLE_OPEN_CHEST) == RO_GENERIC_OFF) { + Flags_SetRandomizerInf(RAND_INF_CAN_OPEN_CHEST); + } if (Randomizer_GetSettingValue(RSK_SHUFFLE_CHILD_WALLET) == RO_GENERIC_OFF) { Flags_SetRandomizerInf(RAND_INF_HAS_WALLET); @@ -480,10 +480,10 @@ extern "C" void Randomizer_InitSaveFile() { } } - // complete mask quest - if (Randomizer_GetSettingValue(RSK_MASK_QUEST) == RO_MASK_QUEST_COMPLETED) { - Flags_SetInfTable(INFTABLE_GATE_GUARD_PUT_ON_KEATON_MASK); - Flags_SetEventChkInf(EVENTCHKINF_PAID_BACK_BUNNY_HOOD_FEE); + // complete mask quest + if (Randomizer_GetSettingValue(RSK_MASK_QUEST) == RO_MASK_QUEST_COMPLETED) { + Flags_SetInfTable(INFTABLE_GATE_GUARD_PUT_ON_KEATON_MASK); + Flags_SetEventChkInf(EVENTCHKINF_PAID_BACK_BUNNY_HOOD_FEE); Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_KEATON); Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_SKULL); diff --git a/soh/soh/SohGui/SohMenuEnhancements.cpp b/soh/soh/SohGui/SohMenuEnhancements.cpp index 0be2e2fc6c6..bb603240da2 100644 --- a/soh/soh/SohGui/SohMenuEnhancements.cpp +++ b/soh/soh/SohGui/SohMenuEnhancements.cpp @@ -1663,17 +1663,6 @@ void SohMenu::AddMenuEnhancements() { .CVar(CVAR_ENHANCEMENT("ExtraTraps.Teleport")) .PreFunc( [](WidgetInfo& info) { info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) == 0; }); - AddWidget(path, "Nightmare Traps:", WIDGET_TEXT).PreFunc([](WidgetInfo& info) { - info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) == 0; - }); - AddWidget(path, "Pocket Traps", WIDGET_CVAR_CHECKBOX) - .CVar(CVAR_ENHANCEMENT("ExtraTraps.Pocket")) - .PreFunc( - [](WidgetInfo& info) { info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) == 0; }); - AddWidget(path, "Perma Death Traps", WIDGET_CVAR_CHECKBOX) - .CVar(CVAR_ENHANCEMENT("ExtraTraps.Permadeath")) - .PreFunc( - [](WidgetInfo& info) { info.isHidden = CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) == 0; }); path.column = SECTION_COLUMN_2; AddWidget(path, "Enemy Randomizer", WIDGET_CVAR_COMBOBOX) From e4d72b28fb7dafecb9b2d037115600501d83eab3 Mon Sep 17 00:00:00 2001 From: TheLynk Date: Fri, 23 Jan 2026 23:48:48 +0100 Subject: [PATCH 43/45] Update Logic | V:13.1 --- soh/soh/Enhancements/gameplaystats.cpp | 2 +- .../overworld/death_mountain_crater.cpp | 30 +++++++------- .../overworld/death_mountain_trail.cpp | 26 ++++++------ .../overworld/desert_colossus.cpp | 34 ++++++++-------- .../overworld/gerudo_valley.cpp | 20 +++++----- .../location_access/overworld/graveyard.cpp | 2 +- .../overworld/hyrule_field.cpp | 16 ++++---- .../location_access/overworld/kakariko.cpp | 4 +- .../overworld/kokiri_forest.cpp | 24 +++++------ .../location_access/overworld/lake_hylia.cpp | 2 +- .../overworld/zoras_domain.cpp | 16 ++++---- .../location_access/overworld/zoras_river.cpp | 40 +++++++++---------- 12 files changed, 108 insertions(+), 108 deletions(-) diff --git a/soh/soh/Enhancements/gameplaystats.cpp b/soh/soh/Enhancements/gameplaystats.cpp index b9115affb92..d1402a03c8e 100644 --- a/soh/soh/Enhancements/gameplaystats.cpp +++ b/soh/soh/Enhancements/gameplaystats.cpp @@ -448,7 +448,7 @@ void DrawGameplayStatsHeader() { // if tag is empty (not a release build) if (gGitCommitTag[0] == 0) { GameplayStatsRow("Git Branch:", (char*)gGitBranch); - GameplayStatsRow("Version : 13 | Git Commit Hash:", (char*)gGitCommitHash); + GameplayStatsRow("Version : 13.1 | Git Commit Hash:", (char*)gGitCommitHash); } else { GameplayStatsRow("Build Version:", (char*)gBuildVersion); } diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_crater.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_crater.cpp index 6bc7e84c0a0..ea8e6c726ea 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_crater.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_crater.cpp @@ -6,16 +6,16 @@ using namespace Rando; void RegionTable_Init_DeathMountainCrater() { // clang-format off areaTable[RR_DMC_UPPER_NEARBY] = Region("DMC Upper Nearby", SCENE_DEATH_MOUNTAIN_CRATER, {}, { - LOCATION(RC_DMC_CIRCLE_ROCK_1, true), - LOCATION(RC_DMC_CIRCLE_ROCK_2, true), - LOCATION(RC_DMC_CIRCLE_ROCK_3, true), - LOCATION(RC_DMC_CIRCLE_ROCK_4, true), - LOCATION(RC_DMC_CIRCLE_ROCK_5, true), - LOCATION(RC_DMC_CIRCLE_ROCK_6, true), - LOCATION(RC_DMC_CIRCLE_ROCK_7, true), - LOCATION(RC_DMC_CIRCLE_ROCK_8, true), - LOCATION(RC_DMC_GOSSIP_ROCK_1, logic->IsChild), - LOCATION(RC_DMC_GOSSIP_ROCK_2, logic->IsChild), + LOCATION(RC_DMC_CIRCLE_ROCK_1, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_DMC_CIRCLE_ROCK_2, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_DMC_CIRCLE_ROCK_3, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_DMC_CIRCLE_ROCK_4, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_DMC_CIRCLE_ROCK_5, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_DMC_CIRCLE_ROCK_6, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_DMC_CIRCLE_ROCK_7, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_DMC_CIRCLE_ROCK_8, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_DMC_GOSSIP_ROCK_1, logic->IsChild && (logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash())), + LOCATION(RC_DMC_GOSSIP_ROCK_2, logic->IsChild && (logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash())), LOCATION(RC_DMC_BOULDER_1, logic->BlastOrSmash()), LOCATION(RC_DMC_BOULDER_2, logic->BlastOrSmash()), LOCATION(RC_DMC_BOULDER_3, logic->BlastOrSmash()), @@ -112,11 +112,11 @@ void RegionTable_Init_DeathMountainCrater() { LOCATION(RC_DMC_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), LOCATION(RC_DMC_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), LOCATION(RC_DMC_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), - LOCATION(RC_DMC_ROCK_BY_FIRE_TEMPLE_1, logic->IsAdult), - LOCATION(RC_DMC_ROCK_BY_FIRE_TEMPLE_2, logic->IsAdult), - LOCATION(RC_DMC_ROCK_BY_FIRE_TEMPLE_3, logic->IsAdult), - LOCATION(RC_DMC_ROCK_BY_FIRE_TEMPLE_4, logic->IsAdult), - LOCATION(RC_DMC_ROCK_BY_FIRE_TEMPLE_5, logic->IsAdult), + LOCATION(RC_DMC_ROCK_BY_FIRE_TEMPLE_1, logic->IsAdult && (logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash())), + LOCATION(RC_DMC_ROCK_BY_FIRE_TEMPLE_2, logic->IsAdult && (logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash())), + LOCATION(RC_DMC_ROCK_BY_FIRE_TEMPLE_3, logic->IsAdult && (logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash())), + LOCATION(RC_DMC_ROCK_BY_FIRE_TEMPLE_4, logic->IsAdult && (logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash())), + LOCATION(RC_DMC_ROCK_BY_FIRE_TEMPLE_5, logic->IsAdult && (logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash())), }, { //Exits Entrance(RR_DMC_CENTRAL_NEARBY, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_trail.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_trail.cpp index a2644cbd610..41315385183 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_trail.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_trail.cpp @@ -21,19 +21,19 @@ void RegionTable_Init_DeathMountainTrail() { LOCATION(RC_DMT_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET))), LOCATION(RC_DMT_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET))), LOCATION(RC_DMT_FLAG_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)), - LOCATION(RC_DMT_ROCK_1, true), - LOCATION(RC_DMT_ROCK_2, true), - LOCATION(RC_DMT_ROCK_3, true), - LOCATION(RC_DMT_ROCK_4, true), - LOCATION(RC_DMT_ROCK_5, true), - LOCATION(RC_DMT_CIRCLE_ROCK_1, true), - LOCATION(RC_DMT_CIRCLE_ROCK_2, true), - LOCATION(RC_DMT_CIRCLE_ROCK_3, true), - LOCATION(RC_DMT_CIRCLE_ROCK_4, true), - LOCATION(RC_DMT_CIRCLE_ROCK_5, true), - LOCATION(RC_DMT_CIRCLE_ROCK_6, true), - LOCATION(RC_DMT_CIRCLE_ROCK_7, true), - LOCATION(RC_DMT_CIRCLE_ROCK_8, true), + LOCATION(RC_DMT_ROCK_1, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_DMT_ROCK_2, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_DMT_ROCK_3, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_DMT_ROCK_4, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_DMT_ROCK_5, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_DMT_CIRCLE_ROCK_1, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_DMT_CIRCLE_ROCK_2, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_DMT_CIRCLE_ROCK_3, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_DMT_CIRCLE_ROCK_4, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_DMT_CIRCLE_ROCK_5, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_DMT_CIRCLE_ROCK_6, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_DMT_CIRCLE_ROCK_7, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_DMT_CIRCLE_ROCK_8, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), LOCATION(RC_DMT_BOULDER_1, logic->BlastOrSmash()), LOCATION(RC_DMT_BOULDER_2, logic->BlastOrSmash()), LOCATION(RC_DMT_BOULDER_3, logic->IsChild && logic->BlastOrSmash()), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/desert_colossus.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/desert_colossus.cpp index 59d3e829d78..257660c8f38 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/desert_colossus.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/desert_colossus.cpp @@ -20,23 +20,23 @@ void RegionTable_Init_DesertColossus() { LOCATION(RC_COLOSSUS_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), LOCATION(RC_COLOSSUS_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_COLOSSUS_SILVER_BOULDER, logic->CanUse(RG_SILVER_GAUNTLETS)), - LOCATION(RC_COLOSSUS_ROCK, true), - LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_1, true), - LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_2, true), - LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_3, true), - LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_4, true), - LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_5, true), - LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_6, true), - LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_7, true), - LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_8, true), - LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_1, true), - LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_2, true), - LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_3, true), - LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_4, true), - LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_5, true), - LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_6, true), - LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_7, true), - LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_8, true), + LOCATION(RC_COLOSSUS_ROCK, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_1, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_2, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_3, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_4, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_5, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_6, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_7, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_8, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_1, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_2, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_3, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_4, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_5, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_6, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_7, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_8, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), LOCATION(RC_COLOSSUS_GOSSIP_STONE, true), }, { //Exits diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp index 4586fa44fa8..926266f6d87 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp @@ -11,12 +11,12 @@ void RegionTable_Init_GerudoValley() { }, { //Locations LOCATION(RC_GV_GS_SMALL_BRIDGE, logic->IsChild && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), - LOCATION(RC_GV_ROCK_1, true), - LOCATION(RC_GV_ROCK_2, true), - LOCATION(RC_GV_ROCK_3, true), - LOCATION(RC_GV_UNDERWATER_ROCK_1, logic->IsAdult || logic->CanUse(RG_BOMBCHU_5)), - LOCATION(RC_GV_UNDERWATER_ROCK_2, logic->IsAdult || logic->CanUse(RG_BOMBCHU_5)), - LOCATION(RC_GV_UNDERWATER_ROCK_3, logic->IsAdult || logic->CanUse(RG_BOMBCHU_5)), + LOCATION(RC_GV_ROCK_1, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_GV_ROCK_2, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_GV_ROCK_3, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_GV_UNDERWATER_ROCK_1, (logic->IsAdult && logic->HasItem(RG_POWER_BRACELET)) || logic->CanUse(RG_BOMBCHU_5)), + LOCATION(RC_GV_UNDERWATER_ROCK_2, (logic->IsAdult && logic->HasItem(RG_POWER_BRACELET)) || logic->CanUse(RG_BOMBCHU_5)), + LOCATION(RC_GV_UNDERWATER_ROCK_3, (logic->IsAdult && logic->HasItem(RG_POWER_BRACELET))|| logic->CanUse(RG_BOMBCHU_5)), LOCATION(RC_GV_BOULDER_1, logic->IsAdult && logic->BlastOrSmash()), LOCATION(RC_GV_BOULDER_2, logic->IsAdult && logic->BlastOrSmash()), LOCATION(RC_GV_BRONZE_BOULDER_1, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), @@ -107,10 +107,10 @@ void RegionTable_Init_GerudoValley() { LOCATION(RC_GV_CRATE_BRIDGE_2, logic->IsChild && logic->CanBreakCrates()), LOCATION(RC_GV_CRATE_BRIDGE_3, logic->IsChild && logic->CanBreakCrates()), LOCATION(RC_GV_CRATE_BRIDGE_4, logic->IsChild && logic->CanBreakCrates()), - LOCATION(RC_GV_ROCK_ACROSS_BRIDGE_1, logic->IsAdult), - LOCATION(RC_GV_ROCK_ACROSS_BRIDGE_2, logic->IsAdult), - LOCATION(RC_GV_ROCK_ACROSS_BRIDGE_3, logic->IsAdult), - LOCATION(RC_GV_ROCK_ACROSS_BRIDGE_4, logic->IsAdult), + LOCATION(RC_GV_ROCK_ACROSS_BRIDGE_1, logic->IsAdult && (logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash())), + LOCATION(RC_GV_ROCK_ACROSS_BRIDGE_2, logic->IsAdult && (logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash())), + LOCATION(RC_GV_ROCK_ACROSS_BRIDGE_3, logic->IsAdult && (logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash())), + LOCATION(RC_GV_ROCK_ACROSS_BRIDGE_4, logic->IsAdult && (logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash())), LOCATION(RC_GV_BOULDER_ACROSS_BRIDGE, logic->IsAdult && logic->BlastOrSmash()), LOCATION(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_1, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), LOCATION(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_2, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp index cbaaed21747..64405008676 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp @@ -32,7 +32,7 @@ void RegionTable_Init_Graveyard() { LOCATION(RC_GY_GRASS_11, logic->CanCutShrubs()), LOCATION(RC_GY_GRASS_12, logic->CanCutShrubs()), LOCATION(RC_GRAVEYARD_CRATE, ((logic->IsAdult && CanPlantBean(RR_THE_GRAVEYARD, RG_GRAVEYARD_BEAN_SOUL)) || logic->CanUse(RG_LONGSHOT)) && logic->CanBreakCrates()), - LOCATION(RC_GY_ROCK, true), + LOCATION(RC_GY_ROCK, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), }, { //Exits Entrance(RR_GRAVEYARD_SHIELD_GRAVE, []{return (logic->IsAdult || logic->AtNight) && logic->HasItem(RG_POWER_BRACELET);}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp index c87439e57b7..83ae5e9506e 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp @@ -111,14 +111,14 @@ void RegionTable_Init_HyruleField() { LOCATION(RC_HF_CHILD_SOUTHEAST_TREE_6, logic->IsChild && logic->CanBonkTrees()), LOCATION(RC_HF_TEKTITE_GROTTO_TREE, logic->CanBonkTrees()), LOCATION(RC_HF_SILVER_BOULDER, logic->CanUse(RG_SILVER_GAUNTLETS)), - LOCATION(RC_HF_ROCK_1, true), - LOCATION(RC_HF_ROCK_2, true), - LOCATION(RC_HF_ROCK_3, true), - LOCATION(RC_HF_ROCK_4, true), - LOCATION(RC_HF_ROCK_5, true), - LOCATION(RC_HF_ROCK_6, true), - LOCATION(RC_HF_ROCK_7, true), - LOCATION(RC_HF_ROCK_8, true), + LOCATION(RC_HF_ROCK_1, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_HF_ROCK_2, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_HF_ROCK_3, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_HF_ROCK_4, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_HF_ROCK_5, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_HF_ROCK_6, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_HF_ROCK_7, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_HF_ROCK_8, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), LOCATION(RC_HF_BOULDER_NORTH, logic->BlastOrSmash()), LOCATION(RC_HF_BOULDER_BY_MARKET, logic->BlastOrSmash()), LOCATION(RC_HF_BOULDER_SOUTH, logic->BlastOrSmash()), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp index 72813aaaa6e..717c013fed1 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp @@ -61,8 +61,8 @@ void RegionTable_Init_Kakariko() { LOCATION(RC_KAK_NEAR_BAZAAR_CHILD_CRATE, logic->IsChild && logic->CanBreakCrates()), LOCATION(RC_KAK_TREE, logic->CanBonkTrees()), LOCATION(RC_KAK_SILVER_BOULDER, logic->IsAdult && logic->CanUse(RG_SILVER_GAUNTLETS)), - LOCATION(RC_KAK_ROCK_1, true), - LOCATION(RC_KAK_ROCK_2, true), + LOCATION(RC_KAK_ROCK_1, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_KAK_ROCK_2, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), }, { //Exits Entrance(RR_HYRULE_FIELD, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp index 80e6eaf6495..be37c373694 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp @@ -67,18 +67,18 @@ void RegionTable_Init_KokiriForest() { LOCATION(RC_KF_ADULT_GRASS_18, logic->IsAdult && logic->CanCutShrubs()), LOCATION(RC_KF_ADULT_GRASS_19, logic->IsAdult && logic->CanCutShrubs()), LOCATION(RC_KF_ADULT_GRASS_20, logic->IsAdult && logic->CanCutShrubs()), - LOCATION(RC_KF_CIRCLE_ROCK_1, true), - LOCATION(RC_KF_CIRCLE_ROCK_2, true), - LOCATION(RC_KF_CIRCLE_ROCK_3, true), - LOCATION(RC_KF_CIRCLE_ROCK_4, true), - LOCATION(RC_KF_CIRCLE_ROCK_5, true), - LOCATION(RC_KF_CIRCLE_ROCK_6, true), - LOCATION(RC_KF_CIRCLE_ROCK_7, true), - LOCATION(RC_KF_CIRCLE_ROCK_8, true), - LOCATION(RC_KF_ROCK_BY_SARIAS_HOUSE, logic->IsChild), - LOCATION(RC_KF_ROCK_BEHIND_SARIAS_HOUSE, logic->IsChild), - LOCATION(RC_KF_ROCK_BY_MIDOS_HOUSE, logic->IsChild), - LOCATION(RC_KF_ROCK_BY_KNOW_IT_ALLS_HOUSE, logic->IsChild), + LOCATION(RC_KF_CIRCLE_ROCK_1, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_KF_CIRCLE_ROCK_2, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_KF_CIRCLE_ROCK_3, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_KF_CIRCLE_ROCK_4, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_KF_CIRCLE_ROCK_5, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_KF_CIRCLE_ROCK_6, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_KF_CIRCLE_ROCK_7, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_KF_CIRCLE_ROCK_8, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_KF_ROCK_BY_SARIAS_HOUSE, logic->IsChild && (logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash())), + LOCATION(RC_KF_ROCK_BEHIND_SARIAS_HOUSE, logic->IsChild && (logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash())), + LOCATION(RC_KF_ROCK_BY_MIDOS_HOUSE, logic->IsChild && (logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash())), + LOCATION(RC_KF_ROCK_BY_KNOW_IT_ALLS_HOUSE, logic->IsChild && (logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash())), }, { //Exits Entrance(RR_KF_BOULDER_LOOP, []{return logic->CanUse(RG_CRAWL);}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp index c1769cd817e..32536763ec8 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp @@ -104,7 +104,7 @@ void RegionTable_Init_LakeHylia() { areaTable[RR_LH_FISHING_ISLAND] = Region("LH Fishing Island", SCENE_LAKE_HYLIA, {}, { //Locations - LOCATION(RC_LA_ROCK, true), + LOCATION(RC_LA_ROCK, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), }, { //Exits Entrance(RR_LAKE_HYLIA, []{return logic->HasItem(RG_BRONZE_SCALE);}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp index cefd92efa00..984d61b8839 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp @@ -35,14 +35,14 @@ void RegionTable_Init_ZorasDomain() { LOCATION(RC_ZD_NEAR_SHOP_POT_3, logic->CanBreakPots()), LOCATION(RC_ZD_NEAR_SHOP_POT_4, logic->CanBreakPots()), LOCATION(RC_ZD_NEAR_SHOP_POT_5, logic->CanBreakPots()), - LOCATION(RC_ZD_CIRCLE_ROCK_1, true), - LOCATION(RC_ZD_CIRCLE_ROCK_2, true), - LOCATION(RC_ZD_CIRCLE_ROCK_3, true), - LOCATION(RC_ZD_CIRCLE_ROCK_4, true), - LOCATION(RC_ZD_CIRCLE_ROCK_5, true), - LOCATION(RC_ZD_CIRCLE_ROCK_6, true), - LOCATION(RC_ZD_CIRCLE_ROCK_7, true), - LOCATION(RC_ZD_CIRCLE_ROCK_8, true), + LOCATION(RC_ZD_CIRCLE_ROCK_1, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_ZD_CIRCLE_ROCK_2, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_ZD_CIRCLE_ROCK_3, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_ZD_CIRCLE_ROCK_4, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_ZD_CIRCLE_ROCK_5, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_ZD_CIRCLE_ROCK_6, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_ZD_CIRCLE_ROCK_7, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_ZD_CIRCLE_ROCK_8, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), }, { //Exits Entrance(RR_ZR_BEHIND_WATERFALL, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp index f92d568b13f..ff1eaea9e32 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp @@ -58,27 +58,27 @@ void RegionTable_Init_ZoraRiver() { 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_CIRCLE_ROCK_1, true), - LOCATION(RC_ZR_CIRCLE_ROCK_2, true), - LOCATION(RC_ZR_CIRCLE_ROCK_3, true), - LOCATION(RC_ZR_CIRCLE_ROCK_4, true), - LOCATION(RC_ZR_CIRCLE_ROCK_5, true), - LOCATION(RC_ZR_CIRCLE_ROCK_6, true), - LOCATION(RC_ZR_CIRCLE_ROCK_7, true), - LOCATION(RC_ZR_CIRCLE_ROCK_8, true), + LOCATION(RC_ZR_CIRCLE_ROCK_1, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_ZR_CIRCLE_ROCK_2, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_ZR_CIRCLE_ROCK_3, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_ZR_CIRCLE_ROCK_4, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_ZR_CIRCLE_ROCK_5, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_ZR_CIRCLE_ROCK_6, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_ZR_CIRCLE_ROCK_7, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_ZR_CIRCLE_ROCK_8, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), LOCATION(RC_ZR_UPPER_CIRCLE_BOULDER, logic->BlastOrSmash()), - LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_1, true), - LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_2, true), - LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_3, true), - LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_4, true), - LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_5, true), - LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_6, true), - LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_7, true), - LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_8, true), - LOCATION(RC_ZR_ROCK, true), - LOCATION(RC_ZR_UNDERWATER_ROCK_1, logic->IsAdult || logic->CanUse(RG_BOMBCHU_5)), - LOCATION(RC_ZR_UNDERWATER_ROCK_2, logic->IsAdult || logic->CanUse(RG_BOMBCHU_5)), - LOCATION(RC_ZR_UNDERWATER_ROCK_3, logic->IsAdult || logic->CanUse(RG_BOMBCHU_5)), + LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_1, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_2, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_3, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_4, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_5, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_6, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_7, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_8, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_ZR_ROCK, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_ZR_UNDERWATER_ROCK_1, (logic->IsAdult && logic->HasItem(RG_POWER_BRACELET)) || logic->CanUse(RG_BOMBCHU_5)), + LOCATION(RC_ZR_UNDERWATER_ROCK_2, (logic->IsAdult && logic->HasItem(RG_POWER_BRACELET)) || logic->CanUse(RG_BOMBCHU_5)), + LOCATION(RC_ZR_UNDERWATER_ROCK_3, (logic->IsAdult && logic->HasItem(RG_POWER_BRACELET)) || logic->CanUse(RG_BOMBCHU_5)), LOCATION(RC_ZR_UNDERWATER_ROCK_4, logic->IsAdult || logic->CanUse(RG_BOMBCHU_5)), LOCATION(RC_ZR_NEAR_DOMAIN_GOSSIP_STONE, true), LOCATION(RC_ZR_NEAR_FREESTANDING_POH_GRASS, logic->CanUse(RG_BOOMERANG)), From 2984315742651b0dfd7d526f5fff01589ae5dae6 Mon Sep 17 00:00:00 2001 From: TheLynk Date: Sat, 24 Jan 2026 00:13:43 +0100 Subject: [PATCH 44/45] Revert "Merge branch 'V3-Anchor-Fusion-All-New-Option' into Shuffle-Roll" This reverts commit a8fee8ed4acc89444c6a102908c0dd06b198e56a, reversing changes made to 1f2c3832762ae2a50683c781e1a03958ac648dc7. --- .../Cheats/NoLikeLikeItemSteal.cpp | 17 - soh/soh/Enhancements/DropThrowOnlyActors.cpp | 17 - soh/soh/Enhancements/ExtraTraps.cpp | 2 +- soh/soh/Enhancements/Presets/Presets.cpp | 57 +- soh/soh/Enhancements/QoL/ResetNaviTimer.cpp | 2 +- .../audio/DisableNaviCallAudio.cpp | 13 - .../cosmetics/CosmeticsEditor.cpp | 4 - .../{ => cosmetics}/CustomSkeletons.cpp | 0 .../Enhancements/cosmetics/InvisibleNavi.cpp | 63 -- .../Enhancements/debugger/debugSaveEditor.cpp | 1 + .../vanilla-behavior/GIVanillaBehavior.h | 106 --- soh/soh/Enhancements/gameplaystats.cpp | 2 +- .../hint_list/hint_list_exclude_dungeon.cpp | 19 - .../hint_list/hint_list_exclude_overworld.cpp | 107 --- .../3drando/hint_list/hint_list_item.cpp | 2 - .../randomizer/3drando/item_pool.cpp | 16 +- .../Enhancements/randomizer/SeedContext.cpp | 12 +- .../Enhancements/randomizer/ShuffleRocks.cpp | 725 ------------------ .../Enhancements/randomizer/ShuffleRocks.h | 15 - soh/soh/Enhancements/randomizer/draw.cpp | 69 +- soh/soh/Enhancements/randomizer/draw.h | 1 - .../Enhancements/randomizer/hook_handlers.cpp | 3 - soh/soh/Enhancements/randomizer/item_list.cpp | 5 +- soh/soh/Enhancements/randomizer/location.cpp | 17 - soh/soh/Enhancements/randomizer/location.h | 28 +- .../dungeons/bottom_of_the_well.cpp | 9 - .../location_access/dungeons/deku_tree.cpp | 3 - .../dungeons/dodongos_cavern.cpp | 32 +- .../location_access/dungeons/fire_temple.cpp | 2 +- .../dungeons/forest_temple.cpp | 3 +- .../dungeons/gerudo_training_ground.cpp | 2 +- .../dungeons/jabujabus_belly.cpp | 8 - .../dungeons/spirit_temple.cpp | 6 - .../location_access/dungeons/water_temple.cpp | 20 +- .../overworld/castle_grounds.cpp | 21 +- .../overworld/death_mountain_crater.cpp | 29 +- .../overworld/death_mountain_trail.cpp | 29 - .../overworld/desert_colossus.cpp | 18 - .../overworld/gerudo_fortress.cpp | 5 +- .../overworld/gerudo_valley.cpp | 26 +- .../location_access/overworld/goron_city.cpp | 52 +- .../location_access/overworld/graveyard.cpp | 1 - .../overworld/hyrule_field.cpp | 16 - .../location_access/overworld/kakariko.cpp | 3 - .../overworld/kokiri_forest.cpp | 12 - .../location_access/overworld/lake_hylia.cpp | 5 +- .../location_access/overworld/lost_woods.cpp | 3 - .../overworld/zoras_domain.cpp | 8 - .../overworld/zoras_fountain.cpp | 3 - .../location_access/overworld/zoras_river.cpp | 54 +- soh/soh/Enhancements/randomizer/logic.cpp | 12 - .../randomizer/option_descriptions.cpp | 3 - .../Enhancements/randomizer/randomizer.cpp | 297 +------ soh/soh/Enhancements/randomizer/randomizer.h | 1 - .../Enhancements/randomizer/randomizerTypes.h | 345 --------- .../randomizer/randomizer_check_tracker.cpp | 31 - .../Enhancements/randomizer/randomizer_inf.h | 283 ------- .../randomizer/randomizer_item_tracker.cpp | 1 - soh/soh/Enhancements/randomizer/savefile.cpp | 311 ++++---- soh/soh/Enhancements/randomizer/settings.cpp | 10 - soh/soh/Enhancements/randomizer/static_data.h | 1 - soh/soh/SohGui/SohMenuEnhancements.cpp | 7 - soh/src/code/z_parameter.c | 2 +- soh/src/overlays/actors/ovl_En_Elf/z_en_elf.c | 94 +-- .../overlays/actors/ovl_En_Ishi/z_en_ishi.c | 5 - soh/src/overlays/actors/ovl_En_Rr/z_en_rr.c | 136 ++-- .../actors/ovl_Obj_Bombiwa/z_obj_bombiwa.c | 3 +- .../actors/ovl_Obj_Hamishi/z_obj_hamishi.c | 3 +- .../ovl_Object_Kankyo/z_object_kankyo.c | 31 +- 69 files changed, 371 insertions(+), 2878 deletions(-) delete mode 100644 soh/soh/Enhancements/Cheats/NoLikeLikeItemSteal.cpp delete mode 100644 soh/soh/Enhancements/DropThrowOnlyActors.cpp delete mode 100644 soh/soh/Enhancements/audio/DisableNaviCallAudio.cpp rename soh/soh/Enhancements/{ => cosmetics}/CustomSkeletons.cpp (100%) delete mode 100644 soh/soh/Enhancements/cosmetics/InvisibleNavi.cpp delete mode 100644 soh/soh/Enhancements/randomizer/ShuffleRocks.cpp delete mode 100644 soh/soh/Enhancements/randomizer/ShuffleRocks.h diff --git a/soh/soh/Enhancements/Cheats/NoLikeLikeItemSteal.cpp b/soh/soh/Enhancements/Cheats/NoLikeLikeItemSteal.cpp deleted file mode 100644 index 825ecbe1bfb..00000000000 --- a/soh/soh/Enhancements/Cheats/NoLikeLikeItemSteal.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include -#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" -#include "soh/ShipInit.hpp" - -extern "C" { -#include "macros.h" -} - -static constexpr int32_t CVAR_NOLIKELIKEITEMSTEAL_DEFAULT = 0; -#define CVAR_NOLIKELIKEITEMSTEAL_NAME CVAR_CHEAT("NoLikeLikeItemSteal") -#define CVAR_NOLIKELIKEITEMSTEAL_VALUE CVarGetInteger(CVAR_NOLIKELIKEITEMSTEAL_NAME, CVAR_NOLIKELIKEITEMSTEAL_DEFAULT) - -void RegisterNoLikeLikeItemSteal() { - COND_VB_SHOULD(VB_LIKE_LIKE_STEAL_EQUIPMENT, CVAR_NOLIKELIKEITEMSTEAL_VALUE, { *should = false; }); -} - -static RegisterShipInitFunc initFunc(RegisterNoLikeLikeItemSteal, { CVAR_NOLIKELIKEITEMSTEAL_NAME }); \ No newline at end of file diff --git a/soh/soh/Enhancements/DropThrowOnlyActors.cpp b/soh/soh/Enhancements/DropThrowOnlyActors.cpp deleted file mode 100644 index 260f1f183d8..00000000000 --- a/soh/soh/Enhancements/DropThrowOnlyActors.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" -#include "soh/ShipInit.hpp" - -void OnAllowThrowOnlyDrop(void* actor) { - Actor* thisx = (Actor*)actor; - if (CVarGetInteger(CVAR_ENHANCEMENT("DropThrowOnlyObjects"), 0)) { - thisx->flags &= ~ACTOR_FLAG_THROW_ONLY; - } else { - thisx->flags |= ACTOR_FLAG_THROW_ONLY; - } -} - -void RegisterAllowThrowOnlyDrop() { - GameInteractor::Instance->RegisterGameHook(OnAllowThrowOnlyDrop); -} - -static RegisterShipInitFunc initFunc(RegisterAllowThrowOnlyDrop, { CVAR_ENHANCEMENT("DropThrowOnlyObjects") }); \ No newline at end of file diff --git a/soh/soh/Enhancements/ExtraTraps.cpp b/soh/soh/Enhancements/ExtraTraps.cpp index 1bd91aaf499..0be9f2bd31b 100644 --- a/soh/soh/Enhancements/ExtraTraps.cpp +++ b/soh/soh/Enhancements/ExtraTraps.cpp @@ -197,4 +197,4 @@ void RegisterExtraTraps() { }); } -static RegisterShipInitFunc initFunc(RegisterExtraTraps, { CVAR_EXTRA_TRAPS_NAME }); \ No newline at end of file +static RegisterShipInitFunc initFunc(RegisterExtraTraps, { CVAR_EXTRA_TRAPS_NAME }); diff --git a/soh/soh/Enhancements/Presets/Presets.cpp b/soh/soh/Enhancements/Presets/Presets.cpp index fee5246ace2..e611a028a2f 100644 --- a/soh/soh/Enhancements/Presets/Presets.cpp +++ b/soh/soh/Enhancements/Presets/Presets.cpp @@ -250,25 +250,18 @@ void SavePreset(std::string& presetName) { } presets[presetName].presetValues["presetName"] = presetName; presets[presetName].presetValues["fileType"] = FILE_TYPE_PRESET; - std::ofstream file(FormatPresetPath(presetName)); + std::ofstream file( + fmt::format("{}/{}.json", Ship::Context::GetInstance()->LocateFileAcrossAppDirs("presets"), presetName)); file << presets[presetName].presetValues.dump(4); file.close(); LoadPresets(); } -void DeletePreset(std::string& presetName) { - std::string presetPath = FormatPresetPath(presetName); - if (fs::exists(presetPath)) { - fs::remove(presetPath); - } - presets.erase(presetName); -} - -static std::string newPresetName, oldPresetName; +static std::string newPresetName; static bool saveSection[PRESET_SECTION_MAX]; -void DrawEditPresetPopup() { - bool nameExists = presets.contains(newPresetName) && newPresetName != oldPresetName; +void DrawNewPresetPopup() { + bool nameExists = presets.contains(newPresetName); UIWidgets::InputString("Preset Name", &newPresetName, UIWidgets::InputOptions() .Color(THEME_COLOR) @@ -277,7 +270,7 @@ void DrawEditPresetPopup() { .LabelPosition(UIWidgets::LabelPositions::Near) .ErrorText("Preset name already exists") .HasError(nameExists)); - nameExists = presets.contains(newPresetName) && newPresetName != oldPresetName; + nameExists = presets.contains(newPresetName); bool noneSelected = true; for (int i = PRESET_SECTION_SETTINGS; i < PRESET_SECTION_MAX; i++) { if (saveSection[i]) { @@ -355,15 +348,10 @@ void DrawEditPresetPopup() { presets[newPresetName].fileName = newPresetName; std::fill_n(presets[newPresetName].apply, PRESET_SECTION_MAX, true); SavePreset(newPresetName); - if (newPresetName != oldPresetName) { - DeletePreset(oldPresetName); - } newPresetName = ""; - oldPresetName = ""; ImGui::CloseCurrentPopup(); } if (UIWidgets::Button("Cancel", UIWidgets::ButtonOptions().Padding({ 6.0f, 6.0f }).Color(THEME_COLOR))) { - oldPresetName = ""; ImGui::CloseCurrentPopup(); } ImGui::EndPopup(); @@ -376,32 +364,25 @@ void PresetsCustomWidget(WidgetInfo& info) { .disabledTooltip = "Disabled because of race lockout" } }) .Size(UIWidgets::Sizes::Inline) .Color(THEME_COLOR))) { - oldPresetName = ""; - newPresetName = ""; - std::fill_n(saveSection, PRESET_SECTION_MAX, true); - ImGui::OpenPopup("editPreset"); - } else if (oldPresetName != "") { - ImGui::OpenPopup("editPreset"); + ImGui::OpenPopup("newPreset"); } - if (ImGui::BeginPopup("editPreset", ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | - ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar | - ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoTitleBar)) { - DrawEditPresetPopup(); + if (ImGui::BeginPopup("newPreset", ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | + ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar | + ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoTitleBar)) { + DrawNewPresetPopup(); } ImGui::SameLine(); UIWidgets::CVarCheckbox("Hide built-in presets", CVAR_GENERAL("HideBuiltInPresets"), UIWidgets::CheckboxOptions().Color(THEME_COLOR)); bool hideBuiltIn = CVarGetInteger(CVAR_GENERAL("HideBuiltInPresets"), 0); UIWidgets::PushStyleTabs(THEME_COLOR); - if (ImGui::BeginTable("PresetWidgetTable", PRESET_SECTION_MAX + 4)) { + if (ImGui::BeginTable("PresetWidgetTable", PRESET_SECTION_MAX + 3)) { ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthFixed, 400); for (int i = PRESET_SECTION_SETTINGS; i < PRESET_SECTION_MAX; i++) { ImGui::TableSetupColumn(blockInfo[i].names[0].c_str()); } ImGui::TableSetupColumn("Apply", ImGuiTableColumnFlags_WidthFixed, ImGui::CalcTextSize("Apply").x + ImGui::GetStyle().FramePadding.x * 2); - ImGui::TableSetupColumn("Edit", ImGuiTableColumnFlags_WidthFixed, - ImGui::CalcTextSize("Edit").x + ImGui::GetStyle().FramePadding.x * 2); ImGui::TableSetupColumn("Delete", ImGuiTableColumnFlags_WidthFixed, ImGui::CalcTextSize("Delete").x + ImGui::GetStyle().FramePadding.x * 2); BlankButton(); @@ -450,17 +431,13 @@ void PresetsCustomWidget(WidgetInfo& info) { ImGui::TableNextColumn(); UIWidgets::PushStyleButton(THEME_COLOR); if (!info.isBuiltIn) { - if (UIWidgets::Button(("Edit##" + name).c_str(), UIWidgets::ButtonOptions().Padding({ 6.0f, 6.0f }))) { - std::copy(info.apply, info.apply + PRESET_SECTION_MAX, saveSection); - newPresetName = name; - oldPresetName = name; - } - UIWidgets::PopStyleButton(); - ImGui::TableNextColumn(); - UIWidgets::PushStyleButton(THEME_COLOR); if (UIWidgets::Button(("Delete##" + name).c_str(), UIWidgets::ButtonOptions().Padding({ 6.0f, 6.0f }))) { - DeletePreset(info.fileName); + auto path = FormatPresetPath(info.fileName); + if (fs::exists(path)) { + fs::remove(path); + } + presets.erase(name); UIWidgets::PopStyleButton(); break; } diff --git a/soh/soh/Enhancements/QoL/ResetNaviTimer.cpp b/soh/soh/Enhancements/QoL/ResetNaviTimer.cpp index 6f88067757c..b3048be538f 100644 --- a/soh/soh/Enhancements/QoL/ResetNaviTimer.cpp +++ b/soh/soh/Enhancements/QoL/ResetNaviTimer.cpp @@ -14,4 +14,4 @@ static void RegisterResetNaviTimer() { COND_HOOK(OnSceneInit, CVAR_RESET_NAVI_VALUE, [](int32_t) { gSaveContext.naviTimer = 0; }); } -static RegisterShipInitFunc initFunc(RegisterResetNaviTimer, { CVAR_RESET_NAVI_NAME }); \ No newline at end of file +static RegisterShipInitFunc initFunc(RegisterResetNaviTimer, { CVAR_RESET_NAVI_NAME }); diff --git a/soh/soh/Enhancements/audio/DisableNaviCallAudio.cpp b/soh/soh/Enhancements/audio/DisableNaviCallAudio.cpp deleted file mode 100644 index 2a2cfbc5780..00000000000 --- a/soh/soh/Enhancements/audio/DisableNaviCallAudio.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" -#include "soh/ShipInit.hpp" - -static constexpr int32_t CVAR_DISABLENAVICALLAUDIO_DEFAULT = 0; -#define CVAR_DISABLENAVICALLAUDIO_NAME CVAR_AUDIO("DisableNaviCallAudio") -#define CVAR_DISABLENAVICALLAUDIO_VALUE \ - CVarGetInteger(CVAR_DISABLENAVICALLAUDIO_NAME, CVAR_DISABLENAVICALLAUDIO_DEFAULT) - -void RegisterDisableNaviCallAudio() { - COND_VB_SHOULD(VB_PLAY_NAVI_CALL_SOUND, CVAR_DISABLENAVICALLAUDIO_VALUE, { *should = false; }); -} - -static RegisterShipInitFunc initFunc(RegisterDisableNaviCallAudio, { CVAR_DISABLENAVICALLAUDIO_NAME }); \ No newline at end of file diff --git a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp index f2f77a68ebd..49e74f69cf1 100644 --- a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp +++ b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp @@ -1889,10 +1889,6 @@ void DrawSillyTab() { UIWidgets::Separator(true, true, 2.0f, 2.0f); - UIWidgets::CVarCheckbox( - "Invisible Navi", CVAR_COSMETIC("InvisibleNavi"), - UIWidgets::CheckboxOptions().Color(THEME_COLOR).Tooltip("Makes Navi invisible and disables her sounds.")); - UIWidgets::CVarCheckbox("Let It Snow", CVAR_GENERAL("LetItSnow"), UIWidgets::CheckboxOptions() .Color(THEME_COLOR) diff --git a/soh/soh/Enhancements/CustomSkeletons.cpp b/soh/soh/Enhancements/cosmetics/CustomSkeletons.cpp similarity index 100% rename from soh/soh/Enhancements/CustomSkeletons.cpp rename to soh/soh/Enhancements/cosmetics/CustomSkeletons.cpp diff --git a/soh/soh/Enhancements/cosmetics/InvisibleNavi.cpp b/soh/soh/Enhancements/cosmetics/InvisibleNavi.cpp deleted file mode 100644 index ce1006e83e3..00000000000 --- a/soh/soh/Enhancements/cosmetics/InvisibleNavi.cpp +++ /dev/null @@ -1,63 +0,0 @@ -#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" -#include "soh/ShipInit.hpp" - -extern "C" { -#include "src/overlays/actors/ovl_En_Elf/z_en_elf.h" -} - -static constexpr int32_t CVAR_INVISIBLENAVI_DEFAULT = 0; -#define CVAR_INVISIBLENAVI_NAME CVAR_COSMETIC("InvisibleNavi") -#define CVAR_INVISIBLENAVI_VALUE CVarGetInteger(CVAR_INVISIBLENAVI_NAME, CVAR_INVISIBLENAVI_DEFAULT) - -void RegisterInvisibleNavi() { - COND_VB_SHOULD(VB_FAIRY_DRAW, CVAR_INVISIBLENAVI_VALUE, { - EnElf* enElf = va_arg(args, EnElf*); - if (enElf->actor.params == FAIRY_NAVI) { - *should = false; - } - }); - - COND_VB_SHOULD(VB_FAIRY_SPAWN_SPARKLES, CVAR_INVISIBLENAVI_VALUE, { - EnElf* enElf = va_arg(args, EnElf*); - if (enElf->actor.params == FAIRY_NAVI) { - *should = false; - } - }); - - COND_VB_SHOULD(VB_FAIRY_PLAY_C_UP_TALK_SOUND, CVAR_INVISIBLENAVI_VALUE, { - EnElf* enElf = va_arg(args, EnElf*); - if (enElf->actor.params == FAIRY_NAVI) { - *should = false; - } - }); - - COND_VB_SHOULD(VB_FAIRY_PLAY_DASH_SOUND, CVAR_INVISIBLENAVI_VALUE, { - EnElf* enElf = va_arg(args, EnElf*); - if (enElf->actor.params == FAIRY_NAVI) { - *should = false; - } - }); - - COND_VB_SHOULD(VB_FAIRY_PLAY_VANISH_SOUND, CVAR_INVISIBLENAVI_VALUE, { - EnElf* enElf = va_arg(args, EnElf*); - if (enElf->actor.params == FAIRY_NAVI) { - *should = false; - } - }); - - COND_VB_SHOULD(VB_FAIRY_UPDATE_LIGHTS, CVAR_INVISIBLENAVI_VALUE, { - EnElf* enElf = va_arg(args, EnElf*); - if (enElf->actor.params == FAIRY_NAVI) { - // Force Navi's light radius to zero. - Lights_PointGlowSetInfo(&enElf->lightInfoGlow, enElf->actor.world.pos.x, enElf->actor.world.pos.y, - enElf->actor.world.pos.z, 255, 255, 255, 0); - *should = false; - } - }); - - COND_VB_SHOULD(VB_PLAY_NAVI_CALL_SOUND, CVAR_INVISIBLENAVI_VALUE, { *should = false; }); - - COND_VB_SHOULD(VB_PLAY_INTRO_NAVI_SOUNDS, CVAR_INVISIBLENAVI_VALUE, { *should = false; }); -} - -static RegisterShipInitFunc initFunc(RegisterInvisibleNavi, { CVAR_INVISIBLENAVI_NAME }); \ No newline at end of file diff --git a/soh/soh/Enhancements/debugger/debugSaveEditor.cpp b/soh/soh/Enhancements/debugger/debugSaveEditor.cpp index b2f30502530..4d5b459b460 100644 --- a/soh/soh/Enhancements/debugger/debugSaveEditor.cpp +++ b/soh/soh/Enhancements/debugger/debugSaveEditor.cpp @@ -1927,6 +1927,7 @@ void SaveEditorWindow::DrawElement() { DrawPlayerTab(); ImGui::EndTabItem(); } + ImGui::EndTabBar(); } diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index 435bad16991..22cab367710 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -236,15 +236,6 @@ typedef enum { // - `*Actor` (interactRangeActor) VB_BOTTLE_ACTOR, - // #### `result` - // Actor is ACTOR_OBJ_BOMBIWA, or ACTOR_OBJ_HAMISHI - // ```c - // Flags_GetSwitch(play, this->actor.params & 0x3F) - // ``` - // #### `args` - // - `*Actor` (interactRangeActor) - VB_BOULDER_BREAK_FLAG, - // #### `result` // ```c // true @@ -343,14 +334,6 @@ typedef enum { // - `*ObjKibako2` VB_CRATE_SETUP_DRAW, - // #### `result` - // ```c - // true - // ``` - // #### `args` - // - None - VB_ROLL, - // #### `result` // ```c // true @@ -595,14 +578,6 @@ typedef enum { // - `int32_t` (startMode) VB_EXECUTE_PLAYER_STARTMODE_FUNC, - // #### `result` - // ```c - // ((this->unk_2A8 != 8) && !(this->fairyFlags & 8)) - // ``` - // #### `args` - // - `*EnElf` - VB_FAIRY_DRAW, - // #### `result` // ```c // true @@ -611,47 +586,6 @@ typedef enum { // - `*EnElf` VB_FAIRY_HEAL, - // #### `result` - // ```c - // true - // ``` - // #### `args` - // - `*EnElf` - // - `int32_t` (sparkleLife) - VB_FAIRY_SPAWN_SPARKLES, - - // #### `result` - // ```c - // true - // ``` - // #### `args` - // - `*EnElf` - VB_FAIRY_PLAY_C_UP_TALK_SOUND, - - // #### `result` - // ```c - // true - // ``` - // #### `args` - // - `*EnElf` - VB_FAIRY_PLAY_DASH_SOUND, - - // #### `result` - // ```c - // true - // ``` - // #### `args` - // - `*EnElf` - VB_FAIRY_PLAY_VANISH_SOUND, - - // #### `result` - // ```c - // true - // ``` - // #### `args` - // - `*EnElf` - VB_FAIRY_UPDATE_LIGHTS, - // #### `result` // ```c // false @@ -1770,14 +1704,6 @@ typedef enum { // - None VB_PLAY_GORON_FREE_CS, - // #### `result` - // ```c - // true - // ``` - // #### `args` - // - `*ObjectKankyo` - VB_PLAY_INTRO_NAVI_SOUNDS, - // #### `result` // ```c // true @@ -1802,14 +1728,6 @@ typedef enum { // - None VB_PLAY_NABOORU_CAPTURED_CS, - // #### `result` - // ```c - // true - // ``` - // #### `args` - // - `int32_t` (naviCallState) (promoted from `uint16_t` by va_arg) - VB_PLAY_NAVI_CALL_SOUND, - // #### `result` // ```c // true @@ -2034,14 +1952,6 @@ typedef enum { // - None VB_REVERT_SPOILING_ITEMS, - // #### `result` - // ```c - // false - // ``` - // #### `args` - // - `*EnIshi` - VB_ROCK_DROP_ITEM, - // #### `result` // ```c // !Flags_GetInfTable(INFTABLE_145) @@ -2476,14 +2386,6 @@ typedef enum { // - `*Actor` VB_RECIEVE_FALL_DAMAGE, - // #### `result` - // ```c - // true - // ``` - // #### `args` - // - `*EnRr` - VB_LIKE_LIKE_DROP_COLLECTIBLE, - // #### `result` // ```c // true @@ -2492,14 +2394,6 @@ typedef enum { // - `*EnRr` VB_LIKE_LIKE_GRAB_PLAYER, - // #### `result` - // ```c - // true - // ``` - // #### `args` - // - `*EnRr` - VB_LIKE_LIKE_STEAL_EQUIPMENT, - // #### `result` // ```c // entry != NULL diff --git a/soh/soh/Enhancements/gameplaystats.cpp b/soh/soh/Enhancements/gameplaystats.cpp index d1402a03c8e..6b2e1c72140 100644 --- a/soh/soh/Enhancements/gameplaystats.cpp +++ b/soh/soh/Enhancements/gameplaystats.cpp @@ -448,7 +448,7 @@ void DrawGameplayStatsHeader() { // if tag is empty (not a release build) if (gGitCommitTag[0] == 0) { GameplayStatsRow("Git Branch:", (char*)gGitBranch); - GameplayStatsRow("Version : 13.1 | Git Commit Hash:", (char*)gGitCommitHash); + GameplayStatsRow("Git Commit Hash:", (char*)gGitCommitHash); } else { GameplayStatsRow("Build Version:", (char*)gBuildVersion); } 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 87880711616..aa375716f68 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_dungeon.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_dungeon.cpp @@ -131,10 +131,6 @@ void StaticData::HintTable_Init_Exclude_Dungeon() { /*german*/ "Man erzählt sich, daß eine #Kiste im Deku-Baum# #[[1]]# enthielte.", /*french*/ "Selon moi, une #caisse dans l'Arbre Mojo# contient #[[1]]#.", {QM_RED, QM_GREEN})); - hintTextTable[RHT_DEKU_BOULDER] = HintText(CustomMessage("They say that a #boulder in the Deku Tree# contains #[[1]]#.", - /*german*/ "!!!", - /*french*/ "!!!", {QM_RED, QM_GREEN})); - /*-------------------------- | DODONGOS CAVERN | ---------------------------*/ @@ -317,10 +313,6 @@ void StaticData::HintTable_Init_Exclude_Dungeon() { /*german*/ "Man erzählt sich, daß eine #Kiste in Dodongos Höhle# #[[1]]# enthielte.", /*french*/ "Selon moi, une #caisse dans la Caverne Dodongo# contient #[[1]]#.", {QM_RED, QM_GREEN})); - hintTextTable[RHT_DODONGOS_BOULDER] = HintText(CustomMessage("They say that a #boulder in Dodongo's Cavern# contains #[[1]]#.", - /*german*/ "!!!", - /*french*/ "!!!", {QM_RED, QM_GREEN})); - /*-------------------------- | JABU JABUS BELLY | ---------------------------*/ @@ -488,10 +480,6 @@ void StaticData::HintTable_Init_Exclude_Dungeon() { /*german*/ "Man erzählt sich, daß eine #Kiste in Jabu-Jabus Bauch# #[[1]]# enthielte.", /*french*/ "Selon moi, une #caisse dans le Ventre de Jabu-Jabu# contient #[[1]]#.", {QM_RED, QM_GREEN})); - hintTextTable[RHT_JABU_BOULDER] = HintText(CustomMessage("They say that a #boulder in Jabu Jabu's Belly# contains #[[1]]#.", - /*german*/ "!!!", - /*french*/ "!!!", {QM_RED, QM_GREEN})); - /*-------------------------- | FOREST TEMPLE | ---------------------------*/ @@ -1334,10 +1322,6 @@ void StaticData::HintTable_Init_Exclude_Dungeon() { /*german*/ "Man erzählt sich, daß eine #Kiste im Geistertempel# #[[1]]# enthielte.", /*french*/ "Selon moi, une #caisse dans le Temple de l'Esprit# contient #[[1]]#.", {QM_RED, QM_GREEN})); - hintTextTable[RHT_SPIRIT_TEMPLE_BOULDER] = HintText(CustomMessage("They say that a #boulder in the Spirit Temple# contains #[[1]]#.", - /*german*/ "!!!", - /*french*/ "!!!", {QM_RED, QM_GREEN})); - /*-------------------------- | SHADOW TEMPLE | ---------------------------*/ @@ -1751,9 +1735,6 @@ void StaticData::HintTable_Init_Exclude_Dungeon() { /*german*/ "Man erzählt sich, daß etwas #Gras auf dem Grund des Brunnens# #[[1]]# verstecke.", /*french*/ "Selon moi, de l'#herbe dans le Puits# cache #[[1]]#.", {QM_RED, QM_GREEN})); - hintTextTable[RHT_BOTW_BOULDER] = HintText(CustomMessage("They say that a #boulder in Bottom of the Well# contains #[[1]]#.", - /*german*/ "!!!", - /*french*/ "!!!", {QM_RED, QM_GREEN})); /*-------------------------- | ICE CAVERN | diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_overworld.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_overworld.cpp index d1cfdd1f866..487c761584b 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 @@ -2126,113 +2126,6 @@ void StaticData::HintTable_Init_Exclude_Overworld() { HintText(CustomMessage("They say that a #tree in Lon Lon Ranch# contains #[[1]]#.", /*german*/ "", /*french*/ "Selon moi, un #arbre au Ranch Lon Lon# cache #[[1]]#.", { QM_RED, QM_GREEN })); - hintTextTable[RHT_KF_ROCK] = HintText(CustomMessage("They say that a #rock in Kokiri Forest# contains #[[1]]#.", - /*german*/ "", - /*french*/ "Selon moi, une #roche dans la Fôret Kokiri# contient #[[1]]#.", {QM_RED, QM_GREEN})); - hintTextTable[RHT_LW_BOULDER] = HintText(CustomMessage("They say that a #boulder in the Lost Woods# contains #[[1]]#.", - /*german*/ "", - /*french*/ "", {QM_RED, QM_GREEN})); - hintTextTable[RHT_HC_ROCK] = HintText(CustomMessage("They say that a #rock at Hyrule Castle# contains #[[1]]#.", - /*german*/ "", - /*french*/ "", {QM_RED, QM_GREEN})); - hintTextTable[RHT_HC_BOULDER] = HintText(CustomMessage("They say that a #boulder at Hyrule Castle# contains #[[1]]#.", - /*german*/ "", - /*french*/ "", {QM_RED, QM_GREEN})); - hintTextTable[RHT_OGC_BRONZE_BOULDER] = HintText(CustomMessage("They say that a #bronze boulder outside Ganon's Castle# contains #[[1]]#.", - /*german*/ "", - /*french*/ "", {QM_RED, QM_GREEN})); - hintTextTable[RHT_OGC_SILVER_BOULDER] = HintText(CustomMessage("They say that a #silver boulder outside Ganon's Castle# contains #[[1]]#.", - /*german*/ "", - /*french*/ "", {QM_RED, QM_GREEN})); - hintTextTable[RHT_DMC_ROCK] = HintText(CustomMessage("They say that a #rock in Death Mountain Crater# contains #[[1]]#.", - /*german*/ "", - /*french*/ "", {QM_RED, QM_GREEN})); - hintTextTable[RHT_DMC_BOULDER] = HintText(CustomMessage("They say that a #boulder in Death Mountain Crater# contains #[[1]]#.", - /*german*/ "", - /*french*/ "", {QM_RED, QM_GREEN})); - hintTextTable[RHT_DMC_BRONZE_BOULDER] = HintText(CustomMessage("They say that a #bronze boulder in Death Mountain Crater# contains #[[1]]#.", - /*german*/ "", - /*french*/ "", {QM_RED, QM_GREEN})); - hintTextTable[RHT_GV_SILVER_BOULDER] = HintText(CustomMessage("They say that a #silver boulder in Gerudo Valley# contains #[[1]]#.", - /*german*/ "", - /*french*/ "", {QM_RED, QM_GREEN})); - hintTextTable[RHT_GV_ROCK] = HintText(CustomMessage("They say that a #rock in Gerudo Valley# contains #[[1]]#.", - /*german*/ "", - /*french*/ "", {QM_RED, QM_GREEN})); - hintTextTable[RHT_GV_BOULDER] = HintText(CustomMessage("They say that a #boulder in Gerudo Valley# contains #[[1]]#.", - /*german*/ "", - /*french*/ "", {QM_RED, QM_GREEN})); - hintTextTable[RHT_GV_BRONZE_BOULDER] = HintText(CustomMessage("They say that a #bronze boulder in Gerudo Valley# contains #[[1]]#.", - /*german*/ "", - /*french*/ "", {QM_RED, QM_GREEN})); - hintTextTable[RHT_HF_SILVER_BOULDER] = HintText(CustomMessage("They say that a #silver boulder on Hyrule Field# contains #[[1]]#.", - /*german*/ "", - /*french*/ "", {QM_RED, QM_GREEN})); - hintTextTable[RHT_HF_ROCK] = HintText(CustomMessage("They say that a #rock on Hyrule Field# contains #[[1]]#.", - /*german*/ "", - /*french*/ "", {QM_RED, QM_GREEN})); - hintTextTable[RHT_HF_BOULDER] = HintText(CustomMessage("They say that a #boulder on Hyrule Field# contains #[[1]]#.", - /*german*/ "", - /*french*/ "", {QM_RED, QM_GREEN})); - hintTextTable[RHT_HF_BRONZE_BOULDER] = HintText(CustomMessage("They say that a #bronze boulder on Hyrule Field# contains #[[1]]#.", - /*german*/ "", - /*french*/ "", {QM_RED, QM_GREEN})); - hintTextTable[RHT_KAK_SILVER_BOULDER] = HintText(CustomMessage("They say that a #silver boulder at Kakariko Village# contains #[[1]]#.", - /*german*/ "", - /*french*/ "", {QM_RED, QM_GREEN})); - hintTextTable[RHT_KAK_ROCK] = HintText(CustomMessage("They say that a #rock at Kakariko Village# contains #[[1]]#.", - /*german*/ "", - /*french*/ "", {QM_RED, QM_GREEN})); - hintTextTable[RHT_GY_ROCK] = HintText(CustomMessage("They say that a #rock in a graveyard# contains #[[1]]#.", - /*german*/ "", - /*french*/ "", {QM_RED, QM_GREEN})); - - hintTextTable[RHT_LA_ROCK] = HintText(CustomMessage("They say that a #rock at Lake Hylia# contains #[[1]]#.", - /*german*/ "", - /*french*/ "", {QM_RED, QM_GREEN})); - - hintTextTable[RHT_ZD_ROCK] = HintText(CustomMessage("They say that a #rock in Zora's Domain# contains #[[1]]#.", - /*german*/ "", - /*french*/ "", {QM_RED, QM_GREEN})); - hintTextTable[RHT_ZF_BOULDER] = HintText(CustomMessage("They say that a #boulder in Zora's Fountain# contains #[[1]]#.", - /*german*/ "", - /*french*/ "", {QM_RED, QM_GREEN})); - hintTextTable[RHT_ZF_SILVER_BOULDER] = HintText(CustomMessage("They say that a #silver boulder in Zora's Fountain# contains #[[1]]#.", - /*german*/ "", - /*french*/ "", {QM_RED, QM_GREEN})); - hintTextTable[RHT_ZR_ROCK] = HintText(CustomMessage("They say that a #rock along a river# contains #[[1]]#.", - /*german*/ "", - /*french*/ "", {QM_RED, QM_GREEN})); - hintTextTable[RHT_ZR_BOULDER] = HintText(CustomMessage("They say that a #boulder along a river# contains #[[1]]#.", - /*german*/ "", - /*french*/ "", {QM_RED, QM_GREEN})); - hintTextTable[RHT_DMT_ROCK] = HintText(CustomMessage("They say that a #rock on Death Mountain Trail# contains #[[1]]#.", - /*german*/ "", - /*french*/ "", {QM_RED, QM_GREEN})); - hintTextTable[RHT_DMT_BOULDER] = HintText(CustomMessage("They say that a #boulder on Death Mountain Trail# contains #[[1]]#.", - /*german*/ "", - /*french*/ "", {QM_RED, QM_GREEN})); - hintTextTable[RHT_DMT_BRONZE_BOULDER] = HintText(CustomMessage("They say that a #bronze boulder on Death Mountain Trail# contains #[[1]]#.", - /*german*/ "", - /*french*/ "", {QM_RED, QM_GREEN})); - hintTextTable[RHT_GC_ROCK] = HintText(CustomMessage("They say that a #rock in Goron City# contains #[[1]]#.", - /*german*/ "", - /*french*/ "", {QM_RED, QM_GREEN})); - hintTextTable[RHT_GC_BOULDER] = HintText(CustomMessage("They say that a #boulder in Goron City# contains #[[1]]#.", - /*german*/ "", - /*french*/ "", {QM_RED, QM_GREEN})); - hintTextTable[RHT_GC_BRONZE_BOULDER] = HintText(CustomMessage("They say that a #bronze boulder in Goron City# contains #[[1]]#.", - /*german*/ "", - /*french*/ "", {QM_RED, QM_GREEN})); - hintTextTable[RHT_GC_SILVER_BOULDER] = HintText(CustomMessage("They say that a #silver boulder in Goron City# contains #[[1]]#.", - /*german*/ "", - /*french*/ "", {QM_RED, QM_GREEN})); - hintTextTable[RHT_COLOSSUS_SILVER_BOULDER] = HintText(CustomMessage("They say that a #silver boulder in a desert# contains #[[1]]#.", - /*german*/ "", - /*french*/ "", {QM_RED, QM_GREEN})); - hintTextTable[RHT_COLOSSUS_ROCK] = HintText(CustomMessage("They say that a #rock in a desert# contains #[[1]]#.", - /*german*/ "", - /*french*/ "", {QM_RED, QM_GREEN})); hintTextTable[RHT_BUSH_HYRULE_FIELD] = HintText(CustomMessage("They say that a #bush in Hyrle Field# contains #[[1]]#.", diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp index 8e1554a146f..730cf881340 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp @@ -2125,8 +2125,6 @@ void StaticData::HintTable_Init_Item() { //RANDOTODO if these are ever used for anything other than name, they want abscure and ambiguous hints - hintTextTable[RHT_ROLL] = HintText(CustomMessage("the ability to roll", /*german*/"die Fähigkeit zu rollen", /*french*/"la capacité de faire des roulades")); - //RANDOTODO if these are ever used for anything other than name, they want abscure and ambiguous hints hintTextTable[RHT_QUIVER_INF] = HintText(CustomMessage("an infinite Quiver", /*german*/"der unendliche Köcher", /*french*/"un Carquois Infini")); hintTextTable[RHT_BOMB_BAG_INF] = HintText(CustomMessage("an infinite Bomb Bag", /*german*/"die unendliche Bombentasche", /*french*/"un Sac de Bombe sans fond")); diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index 720d8c57298..e99e0e19b14 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -408,9 +408,6 @@ void GenerateItemPool() { if (ctx->GetOption(RSK_SHUFFLE_CLIMB)) { AddItemToPool(RG_CLIMB, 2, 1, 1, 1); } - if (ctx->GetOption(RSK_SHUFFLE_ROLL)) { - AddItemToPool(RG_ROLL, 2, 1, 1, 1); - } if (ctx->GetOption(RSK_SHUFFLE_CRAWL)) { AddItemToPool(RG_CRAWL, 2, 1, 1, 1); } @@ -454,17 +451,6 @@ void GenerateItemPool() { ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_NO_LOGIC) && dungeonCratesActive); PlaceItemsForType(RCTYPE_SMALL_CRATE, overworldCratesActive, dungeonCratesActive); - // Shuffle Rocks - bool rocksActive = ctx->GetOption(RSK_SHUFFLE_ROCKS).Get(); - PlaceItemsForType(RCTYPE_ROCK, rocksActive, rocksActive); - - // Shuffle Boulders - bool overworldBouldersActive = ctx->GetOption(RSK_SHUFFLE_BOULDERS).Is(RO_SHUFFLE_BOULDERS_OVERWORLD) || - ctx->GetOption(RSK_SHUFFLE_BOULDERS).Is(RO_SHUFFLE_BOULDERS_ALL); - bool dungeonBouldersActive = ctx->GetOption(RSK_SHUFFLE_BOULDERS).Is(RO_SHUFFLE_BOULDERS_DUNGEONS) || - ctx->GetOption(RSK_SHUFFLE_BOULDERS).Is(RO_SHUFFLE_BOULDERS_ALL); - PlaceItemsForType(RCTYPE_BOULDER, overworldBouldersActive, dungeonBouldersActive); - if (ctx->GetOption(RSK_FISHSANITY).Is(RO_FISHSANITY_HYRULE_LOACH)) { AddFixedItemToPool(RG_PURPLE_RUPEE, 1); } else { @@ -955,4 +941,4 @@ void GenerateItemPool() { } assert(itemPool.size() == locCount); -} \ No newline at end of file +} diff --git a/soh/soh/Enhancements/randomizer/SeedContext.cpp b/soh/soh/Enhancements/randomizer/SeedContext.cpp index 21658b3f709..41a6cb02b3d 100644 --- a/soh/soh/Enhancements/randomizer/SeedContext.cpp +++ b/soh/soh/Enhancements/randomizer/SeedContext.cpp @@ -50,8 +50,6 @@ Context::Context() { &mOptions[RSK_SHUFFLE_COWS], &mOptions[RSK_SHUFFLE_POTS], &mOptions[RSK_SHUFFLE_CRATES], - &mOptions[RSK_SHUFFLE_ROCKS], - &mOptions[RSK_SHUFFLE_BOULDERS], &mOptions[RSK_SHUFFLE_FREESTANDING], &mOptions[RSK_SHUFFLE_MERCHANTS], &mOptions[RSK_SHUFFLE_FROG_SONG_RUPEES], @@ -216,8 +214,6 @@ void Context::GenerateLocationPool() { (location.GetRCType() == RCTYPE_TREE && !mOptions[RSK_SHUFFLE_TREES]) || (location.GetRCType() == RCTYPE_NLTREE && (!mOptions[RSK_SHUFFLE_TREES] || mOptions[RSK_LOGIC_RULES].IsNot(RO_LOGIC_NO_LOGIC))) || - (location.GetRCType() == RCTYPE_ROCK && !mOptions[RSK_SHUFFLE_ROCKS]) || - (location.GetRCType() == RCTYPE_BOULDER && mOptions[RSK_SHUFFLE_BOULDERS].Is(RO_SHUFFLE_BOULDERS_OFF)) || (location.GetRCType() == RCTYPE_BUSH && !mOptions[RSK_SHUFFLE_BUSHES]) || (location.GetRCType() == RCTYPE_FREESTANDING && mOptions[RSK_SHUFFLE_FREESTANDING].Is(RO_SHUFFLE_FREESTANDING_OFF)) || @@ -236,9 +232,7 @@ void Context::GenerateLocationPool() { mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_DUNGEONS) && mOptions[RSK_LOGIC_RULES].Is(RO_LOGIC_NO_LOGIC)) || (location.GetRCType() == RCTYPE_SMALL_CRATE && - mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_DUNGEONS)) && - (location.GetRCType() == RCTYPE_BOULDER && - mOptions[RSK_SHUFFLE_BOULDERS].Is(RO_SHUFFLE_BOULDERS_DUNGEONS))) { + mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_DUNGEONS))) { continue; } // If we've gotten past all the conditions where an overworld location should not be @@ -259,9 +253,7 @@ void Context::GenerateLocationPool() { mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_OVERWORLD) && mOptions[RSK_LOGIC_RULES].Is(RO_LOGIC_NO_LOGIC)) || (location.GetRCType() == RCTYPE_SMALL_CRATE && - mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_OVERWORLD)) && - (location.GetRCType() == RCTYPE_BOULDER && - mOptions[RSK_SHUFFLE_BOULDERS].Is(RO_SHUFFLE_BOULDERS_OVERWORLD))) { + mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_OVERWORLD))) { continue; } // also add to that dungeon's location list. diff --git a/soh/soh/Enhancements/randomizer/ShuffleRocks.cpp b/soh/soh/Enhancements/randomizer/ShuffleRocks.cpp deleted file mode 100644 index 64c68563205..00000000000 --- a/soh/soh/Enhancements/randomizer/ShuffleRocks.cpp +++ /dev/null @@ -1,725 +0,0 @@ -#include "ShuffleRocks.h" -#include "soh/Enhancements/enhancementTypes.h" -#include "soh_assets.h" -#include "static_data.h" -#include "soh/ObjectExtension/ObjectExtension.h" - -extern "C" { -#include "variables.h" -#include "overlays/actors/ovl_En_Ishi/z_en_ishi.h" -#include "overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.h" -#include "overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.h" -#include "objects/gameplay_field_keep/gameplay_field_keep.h" -#include "objects/gameplay_keep/gameplay_keep.h" -#include "objects/object_bombiwa/object_bombiwa.h" -extern PlayState* gPlayState; -} - -#define RAND_GET_OPTION(option) Rando::Context::GetInstance()->GetOption(option).Get() - -extern void EnItem00_DrawRandomizedItem(EnItem00* enItem00, PlayState* play); - -extern "C" void DrawItemCircle(PlayState* play, float scale, RockIdentity rockIdentity) { - GraphicsContext* __gfxCtx = play->state.gfxCtx; - int csmc = CVarGetInteger(CVAR_ENHANCEMENT("ChestSizeAndTextureMatchContents"), 0); - int requiresStoneAgony = CVarGetInteger(CVAR_ENHANCEMENT("ChestSizeDependsStoneOfAgony"), 0); - - u8 r1 = 200, g1 = 200, b1 = 200, r2 = 100, g2 = 100, b2 = 100; - - if ((!requiresStoneAgony || (requiresStoneAgony && CHECK_QUEST_ITEM(QUEST_STONE_OF_AGONY)))) { - auto itemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(rockIdentity.randomizerCheck, true, GI_NONE); - GetItemCategory getItemCategory = itemEntry.getItemCategory; - - switch (getItemCategory) { - case ITEM_CATEGORY_LESSER: - switch (itemEntry.itemId) { - case ITEM_HEART_PIECE: - case ITEM_HEART_PIECE_2: - case ITEM_HEART_CONTAINER: - r1 = 160; - g1 = 80; - b1 = 20; - r2 = 40; - g2 = 160; - b2 = 160; - break; - default: - r1 = 160; - g1 = 140; - b1 = 80; - r2 = 80; - g2 = 70; - b2 = 40; - break; - } - break; - case ITEM_CATEGORY_SMALL_KEY: - r1 = 144; - g1 = 144; - b1 = 144; - r2 = 128; - g2 = 128; - b2 = 128; - break; - case ITEM_CATEGORY_BOSS_KEY: - r1 = 240; - g1 = 220; - b1 = 0; - r2 = 128; - g2 = 128; - b2 = 128; - break; - case ITEM_CATEGORY_SKULLTULA_TOKEN: - r1 = 24; - g1 = 20; - b1 = 0; - r2 = 96; - g2 = 80; - b2 = 0; - break; - case ITEM_CATEGORY_MAJOR: - r1 = 240; - g1 = 220; - b1 = 0; - r2 = 240; - g2 = 220; - b2 = 0; - break; - default: - break; - } - } - - Matrix_Scale(scale, 1.0, scale, MTXMODE_APPLY); - gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPSegment(POLY_XLU_DISP++, 0x08, - (uintptr_t)Gfx_TwoTexScroll(play->state.gfxCtx, 0, 0, 0, 16, 32, 1, 0, (play->gameplayFrames * 10) % 128, - 16, 32)); - gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, r1, g1, b1, 255); - gDPSetEnvColor(POLY_XLU_DISP++, r2, g2, b2, 255); - gSPDisplayList(POLY_XLU_DISP++, (Gfx*)gHoverBootsCircleDL); -} - -extern "C" void EnIshi_RandomizerDraw(Actor* thisx, PlayState* play) { - auto rockActor = ((EnIshi*)thisx); - const auto rockIdentity = ObjectExtension::GetInstance().Get(thisx); - - OPEN_DISPS(play->state.gfxCtx); - Gfx_SetupDL_25Opa(play->state.gfxCtx); - - if (rockActor->actor.params & 1) { - gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, 255); - gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gSilverRockDL); - } else { - Gfx_DrawDListOpa(play, (Gfx*)gFieldKakeraDL); - } - - if (rockIdentity != nullptr && rockIdentity->randomizerCheck != RC_MAX && - Flags_GetRandomizerInf(rockIdentity->randomizerInf) == 0) { - - Matrix_Translate(rockActor->actor.world.pos.x, - rockActor->actor.world.pos.y + (rockActor->actor.params & 1 ? 32 : 8), - rockActor->actor.world.pos.z, MTXMODE_NEW); - DrawItemCircle(play, (rockActor->actor.params & 1 ? 8 : 2), *rockIdentity); - } - - CLOSE_DISPS(play->state.gfxCtx); -} - -extern "C" void ObjBombiwa_RandomizerDraw(Actor* thisx, PlayState* play) { - auto rockActor = ((ObjBombiwa*)thisx); - const auto rockIdentity = ObjectExtension::GetInstance().Get(thisx); - - OPEN_DISPS(play->state.gfxCtx); - Gfx_SetupDL_25Opa(play->state.gfxCtx); - - Gfx_DrawDListOpa(play, (Gfx*)object_bombiwa_DL_0009E0); - gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_MODELVIEW | G_MTX_LOAD); - gSPDisplayList(POLY_OPA_DISP++, (Gfx*)object_bombiwa_DL_0009E0); - - if (rockIdentity != nullptr && rockIdentity->randomizerCheck != RC_MAX && - Flags_GetRandomizerInf(rockIdentity->randomizerInf) == 0) { - Matrix_Translate(rockActor->actor.world.pos.x, rockActor->actor.world.pos.y + 32, rockActor->actor.world.pos.z, - MTXMODE_NEW); - DrawItemCircle(play, 8, *rockIdentity); - } - - CLOSE_DISPS(play->state.gfxCtx); -} - -extern "C" void ObjHamishi_RandomizerDraw(Actor* thisx, PlayState* play) { - auto rockActor = ((ObjHamishi*)thisx); - const auto rockIdentity = ObjectExtension::GetInstance().Get(thisx); - - OPEN_DISPS(play->state.gfxCtx); - Gfx_SetupDL_25Opa(play->state.gfxCtx); - - gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 170, 130, 255); - gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gSilverRockDL); - - if (rockIdentity != nullptr && rockIdentity->randomizerCheck != RC_MAX && - Flags_GetRandomizerInf(rockIdentity->randomizerInf) == 0) { - Matrix_Translate(rockActor->actor.world.pos.x, rockActor->actor.world.pos.y + 32, rockActor->actor.world.pos.z, - MTXMODE_NEW); - DrawItemCircle(play, 8, *rockIdentity); - } - - CLOSE_DISPS(play->state.gfxCtx); -} - -uint8_t Rock_RandomizerHoldsItem(RockIdentity rockIdentity, PlayState* play, bool isBoulder) { - RandomizerCheck rc = rockIdentity.randomizerCheck; - if (rc == RC_MAX || rc == RC_UNKNOWN_CHECK) - return false; - - uint8_t isDungeon = Rando::StaticData::GetLocation(rc)->IsDungeon(); - uint8_t setting = - Rando::Context::GetInstance()->GetOption(isBoulder ? RSK_SHUFFLE_BOULDERS : RSK_SHUFFLE_ROCKS).Get(); - - // Don't pull randomized item if rock isn't randomized or is already checked - return IS_RANDO && - ((!isBoulder && setting) || (isBoulder && (setting == RO_SHUFFLE_BOULDERS_ALL || - (isDungeon && setting == RO_SHUFFLE_BOULDERS_DUNGEONS) || - (!isDungeon && setting == RO_SHUFFLE_BOULDERS_OVERWORLD)))) && - !Flags_GetRandomizerInf(rockIdentity.randomizerInf); -} - -void Rock_RandomizerSpawnCollectible(Actor* actor, RockIdentity rockIdentity, PlayState* play) { - LUSLOG_INFO("ROCKdrop %d\t:\t%d, %d", rockIdentity.randomizerCheck, (s16)actor->world.pos.x, - (s16)actor->world.pos.z); - EnItem00* item00 = (EnItem00*)Item_DropCollectible2(play, &actor->world.pos, ITEM00_SOH_DUMMY); - item00->randoInf = rockIdentity.randomizerInf; - item00->itemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(rockIdentity.randomizerCheck, true, GI_NONE); - item00->actor.draw = (ActorFunc)EnItem00_DrawRandomizedItem; - item00->actor.velocity.y = 9.0f; - item00->actor.speedXZ = 2.0f; - item00->actor.world.rot.y = Rand_CenteredFloat(65536.0f); -} - -void EnIshi_RandomizerInit(void* actorRef) { - Actor* actor = static_cast(actorRef); - - if (actor->id != ACTOR_EN_ISHI) - return; - - EnIshi* rockActor = static_cast(actorRef); - - auto rockIdentity = OTRGlobals::Instance->gRandomizer->IdentifyRock(gPlayState->sceneNum, (s16)actor->world.pos.x, - (s16)actor->world.pos.z); - if (rockIdentity.randomizerCheck == RC_MAX) { - LUSLOG_WARN("ROCK ishi %d\t:\t%d, %d", rockIdentity.randomizerCheck, actor->params & 1, - (s16)actor->world.pos.x, (s16)actor->world.pos.z); - } else { - LUSLOG_INFO("ROCK ishi%d %d\t:\t%d, %d", rockIdentity.randomizerCheck, actor->params & 1, - (s16)actor->world.pos.x, (s16)actor->world.pos.z); - } - - if (Rock_RandomizerHoldsItem(rockIdentity, gPlayState, actor->params & 1)) { - ObjectExtension::GetInstance().Set(actor, std::move(rockIdentity)); - rockActor->actor.draw = EnIshi_RandomizerDraw; - } -} - -void ObjBombiwa_RandomizerInit(void* actorRef) { - Actor* actor = static_cast(actorRef); - - if (actor->id != ACTOR_OBJ_BOMBIWA) - return; - - ObjBombiwa* rockActor = static_cast(actorRef); - - auto rockIdentity = OTRGlobals::Instance->gRandomizer->IdentifyRock(gPlayState->sceneNum, (s16)actor->world.pos.x, - (s16)actor->world.pos.z); - if (rockIdentity.randomizerCheck == RC_MAX) { - LUSLOG_INFO("ROCK bombiwa\t:\t%d, %d", rockIdentity.randomizerCheck, (s16)actor->world.pos.x, - (s16)actor->world.pos.z); - } else { - LUSLOG_INFO("ROCK bombiwa%d\t:\t%d, %d", rockIdentity.randomizerCheck, (s16)actor->world.pos.x, - (s16)actor->world.pos.z); - } - if (Rock_RandomizerHoldsItem(rockIdentity, gPlayState, true)) { - ObjectExtension::GetInstance().Set(actor, std::move(rockIdentity)); - rockActor->actor.draw = ObjBombiwa_RandomizerDraw; - } -} - -void ObjHamishi_RandomizerInit(void* actorRef) { - Actor* actor = static_cast(actorRef); - - if (actor->id != ACTOR_OBJ_HAMISHI) - return; - - ObjHamishi* rockActor = static_cast(actorRef); - - auto rockIdentity = OTRGlobals::Instance->gRandomizer->IdentifyRock(gPlayState->sceneNum, (s16)actor->world.pos.x, - (s16)actor->world.pos.z); - if (rockIdentity.randomizerCheck == RC_MAX) { - LUSLOG_WARN("ROCK hamishi\t:\t%d, %d", rockIdentity.randomizerCheck, (s16)actor->world.pos.x, - (s16)actor->world.pos.z); - } else { - LUSLOG_INFO("ROCK hamishi%d\t:\t%d, %d", rockIdentity.randomizerCheck, (s16)actor->world.pos.x, - (s16)actor->world.pos.z); - } - if (Rock_RandomizerHoldsItem(rockIdentity, gPlayState, true)) { - ObjectExtension::GetInstance().Set(actor, std::move(rockIdentity)); - rockActor->actor.draw = ObjHamishi_RandomizerDraw; - } -} - -void ObjBombiwa_RandomizerKill(void* actorRef) { - Actor* actor = static_cast(actorRef); - - if (actor->id != ACTOR_OBJ_BOMBIWA) - return; - - ObjBombiwa* rockActor = static_cast(actorRef); - const auto rockIdentity = ObjectExtension::GetInstance().Get(actorRef); - - if (rockIdentity != nullptr && Rock_RandomizerHoldsItem(*rockIdentity, gPlayState, true)) { - Rock_RandomizerSpawnCollectible(&rockActor->actor, *rockIdentity, gPlayState); - rockIdentity->randomizerCheck = RC_MAX; - rockIdentity->randomizerInf = RAND_INF_MAX; - } -} - -void ObjHamishi_RandomizerKill(void* actorRef) { - Actor* actor = static_cast(actorRef); - - if (actor->id != ACTOR_OBJ_HAMISHI) - return; - - ObjHamishi* rockActor = static_cast(actorRef); - const auto rockIdentity = ObjectExtension::GetInstance().Get(actorRef); - - if (rockIdentity != nullptr && Rock_RandomizerHoldsItem(*rockIdentity, gPlayState, true)) { - Rock_RandomizerSpawnCollectible(&rockActor->actor, *rockIdentity, gPlayState); - rockIdentity->randomizerCheck = RC_MAX; - rockIdentity->randomizerInf = RAND_INF_MAX; - } -} - -void RegisterShuffleRock() { - bool shouldRegister = IS_RANDO && (RAND_GET_OPTION(RSK_SHUFFLE_ROCKS) || RAND_GET_OPTION(RSK_SHUFFLE_BOULDERS)); - bool shouldRegisterBoulder = IS_RANDO && RAND_GET_OPTION(RSK_SHUFFLE_BOULDERS); - - COND_ID_HOOK(OnActorInit, ACTOR_EN_ISHI, shouldRegister, EnIshi_RandomizerInit); - COND_ID_HOOK(OnActorInit, ACTOR_OBJ_BOMBIWA, shouldRegisterBoulder, ObjBombiwa_RandomizerInit); - COND_ID_HOOK(OnActorInit, ACTOR_OBJ_HAMISHI, shouldRegisterBoulder, ObjHamishi_RandomizerInit); - COND_ID_HOOK(OnActorKill, ACTOR_OBJ_BOMBIWA, shouldRegisterBoulder, ObjBombiwa_RandomizerKill); - COND_ID_HOOK(OnActorKill, ACTOR_OBJ_HAMISHI, shouldRegisterBoulder, ObjHamishi_RandomizerKill); - - COND_VB_SHOULD(VB_ROCK_DROP_ITEM, shouldRegister, { - EnIshi* rockActor = va_arg(args, EnIshi*); - const auto rockIdentity = ObjectExtension::GetInstance().Get(rockActor); - if (rockIdentity != nullptr && - Rock_RandomizerHoldsItem(*rockIdentity, gPlayState, rockActor->actor.params & 1)) { - Rock_RandomizerSpawnCollectible(&rockActor->actor, *rockIdentity, gPlayState); - rockIdentity->randomizerCheck = RC_MAX; - rockIdentity->randomizerInf = RAND_INF_MAX; - *should = false; - } - }); - - COND_VB_SHOULD(VB_BOULDER_BREAK_FLAG, shouldRegisterBoulder, { - Actor* rockActor = va_arg(args, Actor*); - // hook called before OnActorInit sets up object extension - auto rockIdentity = OTRGlobals::Instance->gRandomizer->IdentifyRock( - gPlayState->sceneNum, (s16)rockActor->world.pos.x, (s16)rockActor->world.pos.z); - if (rockIdentity.randomizerCheck != RC_UNKNOWN_CHECK && - Rock_RandomizerHoldsItem(rockIdentity, gPlayState, true)) { - *should = false; - } - }); -} - -void Rando::StaticData::RegisterRockLocations() { -#define ROCKLOC(id, area, scene, hint, x, z) \ - (locationTable[RC_##id] = Location::Rock(RC_##id, RCQUEST_BOTH, area, scene, TWO_ACTOR_PARAMS(x, z), #id, hint, \ - RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_##id))) -#define BOLDLOC(id, area, scene, hint, x, z) \ - (locationTable[RC_##id] = Location::Boulder(RC_##id, RCQUEST_BOTH, area, scene, TWO_ACTOR_PARAMS(x, z), #id, hint, \ - SpoilerCollectionCheck::RandomizerInf(RAND_INF_##id))) - ROCKLOC(KF_CIRCLE_ROCK_1, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, RHT_KF_ROCK, -292, -350); - ROCKLOC(KF_CIRCLE_ROCK_2, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, RHT_KF_ROCK, -235, -373); - ROCKLOC(KF_CIRCLE_ROCK_3, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, RHT_KF_ROCK, -212, -430); - ROCKLOC(KF_CIRCLE_ROCK_4, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, RHT_KF_ROCK, -235, -486); - ROCKLOC(KF_CIRCLE_ROCK_5, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, RHT_KF_ROCK, -292, -510); - ROCKLOC(KF_CIRCLE_ROCK_6, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, RHT_KF_ROCK, -348, -486); - ROCKLOC(KF_CIRCLE_ROCK_7, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, RHT_KF_ROCK, -372, -430); - ROCKLOC(KF_CIRCLE_ROCK_8, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, RHT_KF_ROCK, -348, -373); - ROCKLOC(KF_ROCK_BY_SARIAS_HOUSE, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, RHT_KF_ROCK, 248, 601); - ROCKLOC(KF_ROCK_BEHIND_SARIAS_HOUSE, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, RHT_KF_ROCK, 726, 961); - ROCKLOC(KF_ROCK_BY_MIDOS_HOUSE, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, RHT_KF_ROCK, -672, -623); - ROCKLOC(KF_ROCK_BY_KNOW_IT_ALLS_HOUSE, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, RHT_KF_ROCK, -1361, 145); - BOLDLOC(LW_BOULDER_BY_GORON_CITY, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, RHT_LW_BOULDER, 915, -925); - BOLDLOC(LW_BOULDER_BY_SACRED_FOREST_MEADOW, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, RHT_LW_BOULDER, 670, -2520); - BOLDLOC(LW_RUPEE_BOULDER, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, RHT_LW_BOULDER, 1720, -2510); - - locationTable[RC_HC_ROCK_1] = Location::Rock( - RC_HC_ROCK_1, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(-216, 2977), - "HC Rock 1", RHT_HC_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_ROCK_1)); - locationTable[RC_HC_ROCK_2] = Location::Rock( - RC_HC_ROCK_2, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(-110, 3006), - "HC Rock 2", RHT_HC_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_ROCK_2)); - locationTable[RC_HC_ROCK_3] = Location::Rock( - RC_HC_ROCK_3, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(-129, 2897), - "HC Rock 3", RHT_HC_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_ROCK_3)); - BOLDLOC(HC_BOULDER, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, RHT_HC_BOULDER, 2730, 2540); - BOLDLOC(OGC_BRONZE_BOULDER_1, RCAREA_HYRULE_CASTLE, SCENE_OUTSIDE_GANONS_CASTLE, RHT_OGC_BRONZE_BOULDER, 2324, 533); - BOLDLOC(OGC_BRONZE_BOULDER_2, RCAREA_HYRULE_CASTLE, SCENE_OUTSIDE_GANONS_CASTLE, RHT_OGC_BRONZE_BOULDER, 1590, 787); - BOLDLOC(OGC_BRONZE_BOULDER_3, RCAREA_HYRULE_CASTLE, SCENE_OUTSIDE_GANONS_CASTLE, RHT_OGC_BRONZE_BOULDER, 1661, 748); - BOLDLOC(OGC_SILVER_BOULDER_1, RCAREA_HYRULE_CASTLE, SCENE_OUTSIDE_GANONS_CASTLE, RHT_OGC_SILVER_BOULDER, 1606, 685); - BOLDLOC(OGC_SILVER_BOULDER_2, RCAREA_HYRULE_CASTLE, SCENE_OUTSIDE_GANONS_CASTLE, RHT_OGC_SILVER_BOULDER, 1766, 726); - BOLDLOC(OGC_SILVER_BOULDER_3, RCAREA_HYRULE_CASTLE, SCENE_OUTSIDE_GANONS_CASTLE, RHT_OGC_SILVER_BOULDER, 1701, 661); - BOLDLOC(OGC_SILVER_BOULDER_4, RCAREA_HYRULE_CASTLE, SCENE_OUTSIDE_GANONS_CASTLE, RHT_OGC_SILVER_BOULDER, 2260, 560); - - ROCKLOC(DMC_ROCK_BY_FIRE_TEMPLE_1, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, -50, - -714); - ROCKLOC(DMC_ROCK_BY_FIRE_TEMPLE_2, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, -26, - -807); - ROCKLOC(DMC_ROCK_BY_FIRE_TEMPLE_3, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, 61, - -763); - ROCKLOC(DMC_ROCK_BY_FIRE_TEMPLE_4, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, 71, - -610); - ROCKLOC(DMC_ROCK_BY_FIRE_TEMPLE_5, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, 79, - -700); - ROCKLOC(DMC_CIRCLE_ROCK_1, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, 40, 1850); - ROCKLOC(DMC_CIRCLE_ROCK_2, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, 96, 1826); - ROCKLOC(DMC_CIRCLE_ROCK_3, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, 120, 1770); - ROCKLOC(DMC_CIRCLE_ROCK_4, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, 96, 1713); - ROCKLOC(DMC_CIRCLE_ROCK_5, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, 40, 1690); - ROCKLOC(DMC_CIRCLE_ROCK_6, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, -16, 1713); - ROCKLOC(DMC_CIRCLE_ROCK_7, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, -40, 1770); - ROCKLOC(DMC_CIRCLE_ROCK_8, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, -16, 1826); - ROCKLOC(DMC_GOSSIP_ROCK_1, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, 1261, 1533); - ROCKLOC(DMC_GOSSIP_ROCK_2, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, 1356, 1541); - BOLDLOC(DMC_BOULDER_1, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_BOULDER, -504, 1070); - BOLDLOC(DMC_BOULDER_2, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_BOULDER, 236, 1199); - BOLDLOC(DMC_BOULDER_3, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_BOULDER, 40, 1770); - BOLDLOC(DMC_BRONZE_BOULDER_1, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_BRONZE_BOULDER, - -1699, -472); - BOLDLOC(DMC_BRONZE_BOULDER_2, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_BRONZE_BOULDER, - -1332, 921); - BOLDLOC(DMC_BRONZE_BOULDER_3, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_BRONZE_BOULDER, - -1303, 975); - BOLDLOC(DMC_BRONZE_BOULDER_4, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_BRONZE_BOULDER, - -1060, 944); - - BOLDLOC(GV_SILVER_BOULDER, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_SILVER_BOULDER, 280, 1470); - ROCKLOC(GV_ROCK_1, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_ROCK, 2738, 297); - ROCKLOC(GV_ROCK_2, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_ROCK, 2715, 316); - ROCKLOC(GV_ROCK_3, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_ROCK, 2699, 275); - ROCKLOC(GV_UNDERWATER_ROCK_1, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_ROCK, 1559, -63); - ROCKLOC(GV_UNDERWATER_ROCK_2, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_ROCK, 1605, 26); - ROCKLOC(GV_UNDERWATER_ROCK_3, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_ROCK, 1686, -33); - ROCKLOC(GV_ROCK_ACROSS_BRIDGE_1, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_ROCK, -666, -899); - ROCKLOC(GV_ROCK_ACROSS_BRIDGE_2, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_ROCK, -526, -890); - ROCKLOC(GV_ROCK_ACROSS_BRIDGE_3, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_ROCK, -607, -791); - ROCKLOC(GV_ROCK_ACROSS_BRIDGE_4, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_ROCK, -458, -782); - BOLDLOC(GV_BOULDER_1, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_BOULDER, 751, 569); - BOLDLOC(GV_BOULDER_2, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_BOULDER, 545, -510); - BOLDLOC(GV_BOULDER_ACROSS_BRIDGE, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_BOULDER, -954, 577); - BOLDLOC(GV_BRONZE_BOULDER_1, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_BRONZE_BOULDER, 861, -778); - BOLDLOC(GV_BRONZE_BOULDER_2, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_BRONZE_BOULDER, 735, 375); - BOLDLOC(GV_BRONZE_BOULDER_ACROSS_BRIDGE_1, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_BRONZE_BOULDER, -1352, - 767); - BOLDLOC(GV_BRONZE_BOULDER_ACROSS_BRIDGE_2, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_BRONZE_BOULDER, -1695, - -350); - BOLDLOC(GV_BRONZE_BOULDER_ACROSS_BRIDGE_3, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_BRONZE_BOULDER, -1001, - 637); - BOLDLOC(GV_BRONZE_BOULDER_ACROSS_BRIDGE_4, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_BRONZE_BOULDER, -1291, - 787); - BOLDLOC(GV_BRONZE_BOULDER_ACROSS_BRIDGE_5, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_BRONZE_BOULDER, -1416, - 778); - BOLDLOC(GV_BRONZE_BOULDER_ACROSS_BRIDGE_6, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_BRONZE_BOULDER, -1256, - 856); - - BOLDLOC(HF_SILVER_BOULDER, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_SILVER_BOULDER, 674, 8256); - ROCKLOC(HF_ROCK_1, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_ROCK, -7875, 6995); - ROCKLOC(HF_ROCK_2, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_ROCK, -7818, 6971); - ROCKLOC(HF_ROCK_3, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_ROCK, -7795, 6915); - ROCKLOC(HF_ROCK_4, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_ROCK, -7818, 6858); - ROCKLOC(HF_ROCK_5, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_ROCK, -7875, 6835); - ROCKLOC(HF_ROCK_6, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_ROCK, -7931, 6858); - ROCKLOC(HF_ROCK_7, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_ROCK, -7955, 6915); - ROCKLOC(HF_ROCK_8, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_ROCK, -7931, 6971); - BOLDLOC(HF_BOULDER_NORTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_BOULDER, -4450, -425); - BOLDLOC(HF_BOULDER_BY_MARKET, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_BOULDER, -1425, 810); - BOLDLOC(HF_BOULDER_SOUTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_BOULDER, -270, 12350); - BOLDLOC(HF_BRONZE_BOULDER_1, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_BRONZE_BOULDER, -7870, 6920); - BOLDLOC(HF_BRONZE_BOULDER_2, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_BRONZE_BOULDER, -7804, 7983); - BOLDLOC(HF_BRONZE_BOULDER_3, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_BRONZE_BOULDER, -8397, 7947); - BOLDLOC(HF_BRONZE_BOULDER_4, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_BRONZE_BOULDER, -6461, 8220); - - BOLDLOC(KAK_SILVER_BOULDER, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, RHT_KAK_SILVER_BOULDER, 1436, 1361); - ROCKLOC(KAK_ROCK_1, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, RHT_KAK_ROCK, 220, -1236); - ROCKLOC(KAK_ROCK_2, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, RHT_KAK_ROCK, -664, 1288); - ROCKLOC(GY_ROCK, RCAREA_GRAVEYARD, SCENE_GRAVEYARD, RHT_GY_ROCK, -1193, 693); - ROCKLOC(LA_ROCK, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, RHT_LA_ROCK, 1222, 3953); - - ROCKLOC(ZD_CIRCLE_ROCK_1, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, RHT_ZD_ROCK, 462, -696); - ROCKLOC(ZD_CIRCLE_ROCK_2, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, RHT_ZD_ROCK, 518, -719); - ROCKLOC(ZD_CIRCLE_ROCK_3, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, RHT_ZD_ROCK, 542, -776); - ROCKLOC(ZD_CIRCLE_ROCK_4, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, RHT_ZD_ROCK, 518, -832); - ROCKLOC(ZD_CIRCLE_ROCK_5, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, RHT_ZD_ROCK, 462, -856); - ROCKLOC(ZD_CIRCLE_ROCK_6, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, RHT_ZD_ROCK, 405, -832); - ROCKLOC(ZD_CIRCLE_ROCK_7, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, RHT_ZD_ROCK, 382, -776); - ROCKLOC(ZD_CIRCLE_ROCK_8, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, RHT_ZD_ROCK, 405, -719); - BOLDLOC(ZF_BOULDER, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, RHT_ZF_BOULDER, 189, 2586); - BOLDLOC(ZF_SILVER_BOULDER, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, RHT_ZF_SILVER_BOULDER, 316, 2634); - BOLDLOC(ZF_UNDERGROUND_BOULDER, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, RHT_ZF_BOULDER, 317, 2631); - BOLDLOC(ZR_BOULDER_1, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_BOULDER, -1456, 434); - BOLDLOC(ZR_BOULDER_2, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_BOULDER, -1518, 435); - BOLDLOC(ZR_BOULDER_3, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_BOULDER, -1576, 430); - BOLDLOC(ZR_BOULDER_4, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_BOULDER, -1400, 482); - ROCKLOC(ZR_CIRCLE_ROCK_1, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, -1635, -53); - ROCKLOC(ZR_CIRCLE_ROCK_2, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, -1578, -76); - ROCKLOC(ZR_CIRCLE_ROCK_3, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, -1555, -133); - ROCKLOC(ZR_CIRCLE_ROCK_4, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, -1578, -189); - ROCKLOC(ZR_CIRCLE_ROCK_5, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, -1635, -213); - ROCKLOC(ZR_CIRCLE_ROCK_6, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, -1691, -189); - ROCKLOC(ZR_CIRCLE_ROCK_7, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, -1715, -133); - ROCKLOC(ZR_CIRCLE_ROCK_8, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, -1691, -76); - ROCKLOC(ZR_UPPER_CIRCLE_BOULDER, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_BOULDER, 672, -366); - ROCKLOC(ZR_UPPER_CIRCLE_ROCK_1, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 668, -290); - ROCKLOC(ZR_UPPER_CIRCLE_ROCK_2, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 724, -313); - ROCKLOC(ZR_UPPER_CIRCLE_ROCK_3, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 748, -370); - ROCKLOC(ZR_UPPER_CIRCLE_ROCK_4, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 724, -426); - ROCKLOC(ZR_UPPER_CIRCLE_ROCK_5, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 668, -450); - ROCKLOC(ZR_UPPER_CIRCLE_ROCK_6, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 611, -426); - ROCKLOC(ZR_UPPER_CIRCLE_ROCK_7, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 588, -370); - ROCKLOC(ZR_UPPER_CIRCLE_ROCK_8, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 611, -313); - ROCKLOC(ZR_ROCK, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 2044, -786); - ROCKLOC(ZR_UNDERWATER_ROCK_1, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 2425, -446); - ROCKLOC(ZR_UNDERWATER_ROCK_2, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 2425, -524); - ROCKLOC(ZR_UNDERWATER_ROCK_3, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 2503, -571); - ROCKLOC(ZR_UNDERWATER_ROCK_4, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 2550, -415); - - // 5 rocks by dc - ROCKLOC(DMT_ROCK_1, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -1816, -513); - ROCKLOC(DMT_ROCK_2, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -1831, -614); - ROCKLOC(DMT_ROCK_3, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -1857, -536); - ROCKLOC(DMT_ROCK_4, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -1878, -465); - ROCKLOC(DMT_ROCK_5, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -1787, -550); - // child only - ROCKLOC(DMT_SUMMIT_ROCK, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -327, -4286); - // ring in front of gc - ROCKLOC(DMT_CIRCLE_ROCK_1, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -383, -1126); - ROCKLOC(DMT_CIRCLE_ROCK_2, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -326, -1149); - ROCKLOC(DMT_CIRCLE_ROCK_3, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -303, -1206); - ROCKLOC(DMT_CIRCLE_ROCK_4, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -326, -1262); - ROCKLOC(DMT_CIRCLE_ROCK_5, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -383, -1286); - ROCKLOC(DMT_CIRCLE_ROCK_6, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -439, -1262); - ROCKLOC(DMT_CIRCLE_ROCK_7, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -463, -1206); - ROCKLOC(DMT_CIRCLE_ROCK_8, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -439, -1149); - BOLDLOC(DMT_BOULDER_1, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BOULDER, -625, -55); - BOLDLOC(DMT_BOULDER_2, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BOULDER, -808, -59); - BOLDLOC(DMT_BOULDER_3, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BOULDER, -1060, -51); - BOLDLOC(DMT_COW_BOULDER, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BOULDER, -688, -285); - BOLDLOC(DMT_BRONZE_BOULDER_1, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BRONZE_BOULDER, - -1175, -803); - BOLDLOC(DMT_BRONZE_BOULDER_2, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BRONZE_BOULDER, - -1948, 1706); - BOLDLOC(DMT_BRONZE_BOULDER_3, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BRONZE_BOULDER, - -2019, 1101); - BOLDLOC(DMT_BRONZE_BOULDER_4, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BRONZE_BOULDER, - -1658, -88); - BOLDLOC(DMT_BRONZE_BOULDER_5, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BRONZE_BOULDER, - -1753, 445); - BOLDLOC(DMT_BRONZE_BOULDER_6, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BRONZE_BOULDER, - -1018, 1283); - BOLDLOC(DMT_BRONZE_BOULDER_7, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BRONZE_BOULDER, - -1986, 727); - BOLDLOC(DMT_BRONZE_BOULDER_8, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BRONZE_BOULDER, -23, - -3196); - BOLDLOC(DMT_BRONZE_BOULDER_9, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BRONZE_BOULDER, -343, - -2794); - BOLDLOC(DMT_BRONZE_BOULDER_10, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BRONZE_BOULDER, - -154, -2484); - BOLDLOC(DMT_BRONZE_BOULDER_11, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BRONZE_BOULDER, - -1590, -402); - BOLDLOC(GC_LW_BOULDER_1, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, 416, 1049); - BOLDLOC(GC_LW_BOULDER_2, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, 470, 1031); - BOLDLOC(GC_LW_BOULDER_3, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, 367, 1078); - BOLDLOC(GC_ENTRANCE_BOULDER_1, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -670, 470); - BOLDLOC(GC_ENTRANCE_BOULDER_2, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -607, 419); - BOLDLOC(GC_ENTRANCE_BOULDER_3, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -756, 474); - BOLDLOC(GC_MAZE_SILVER_BOULDER_1, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1479, -794); - BOLDLOC(GC_MAZE_SILVER_BOULDER_2, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1478, -855); - BOLDLOC(GC_MAZE_SILVER_BOULDER_3, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1474, -624); - BOLDLOC(GC_MAZE_SILVER_BOULDER_4, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1471, -993); - BOLDLOC(GC_MAZE_SILVER_BOULDER_5, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1467, -1064); - BOLDLOC(GC_MAZE_SILVER_BOULDER_6, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1460, -1121); - BOLDLOC(GC_MAZE_SILVER_BOULDER_7, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1451, -567); - BOLDLOC(GC_MAZE_SILVER_BOULDER_8, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1448, -672); - BOLDLOC(GC_MAZE_SILVER_BOULDER_9, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1440, -1174); - BOLDLOC(GC_MAZE_SILVER_BOULDER_10, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1437, -1342); - BOLDLOC(GC_MAZE_SILVER_BOULDER_11, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1424, -1245); - BOLDLOC(GC_MAZE_SILVER_BOULDER_12, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1424, -609); - BOLDLOC(GC_MAZE_SILVER_BOULDER_13, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1399, -1300); - BOLDLOC(GC_MAZE_SILVER_BOULDER_14, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1394, -654); - BOLDLOC(GC_MAZE_SILVER_BOULDER_15, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1343, -698); - BOLDLOC(GC_MAZE_SILVER_BOULDER_16, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1319, -1086); - BOLDLOC(GC_MAZE_SILVER_BOULDER_17, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1312, -1039); - BOLDLOC(GC_MAZE_SILVER_BOULDER_18, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1306, -837); - BOLDLOC(GC_MAZE_SILVER_BOULDER_19, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1279, -656); - BOLDLOC(GC_MAZE_SILVER_BOULDER_20, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1255, -840); - BOLDLOC(GC_MAZE_SILVER_BOULDER_21, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1246, -1075); - BOLDLOC(GC_MAZE_SILVER_BOULDER_22, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1244, -589); - BOLDLOC(GC_MAZE_SILVER_BOULDER_23, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1210, -852); - BOLDLOC(GC_MAZE_SILVER_BOULDER_24, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1206, -627); - BOLDLOC(GC_MAZE_SILVER_BOULDER_25, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1187, -896); - BOLDLOC(GC_MAZE_SILVER_BOULDER_26, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1157, -954); - BOLDLOC(GC_MAZE_SILVER_BOULDER_27, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1130, -1137); - BOLDLOC(GC_MAZE_SILVER_BOULDER_28, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1120, -1001); - BOLDLOC(GC_MAZE_SILVER_BOULDER_29, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1179, -1098); - BOLDLOC(GC_MAZE_BOULDER_1, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -1342, -628); - BOLDLOC(GC_MAZE_BOULDER_2, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -1456, -501); - BOLDLOC(GC_MAZE_BOULDER_3, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -1233, -511); - BOLDLOC(GC_MAZE_BOULDER_4, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -1137, -657); - BOLDLOC(GC_MAZE_BOULDER_5, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -1124, -913); - BOLDLOC(GC_MAZE_BOULDER_6, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -1326, -771); - BOLDLOC(GC_MAZE_BOULDER_7, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -1469, -737); - BOLDLOC(GC_MAZE_BOULDER_8, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -1476, -921); - BOLDLOC(GC_MAZE_BOULDER_9, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -1391, -1087); - BOLDLOC(GC_MAZE_BOULDER_10, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -1222, -997); - BOLDLOC(GC_MAZE_BRONZE_BOULDER_1, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BRONZE_BOULDER, -1541, -631); - BOLDLOC(GC_MAZE_BRONZE_BOULDER_2, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BRONZE_BOULDER, -1536, -861); - BOLDLOC(GC_MAZE_BRONZE_BOULDER_3, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BRONZE_BOULDER, -1536, -1102); - BOLDLOC(GC_MAZE_BRONZE_BOULDER_4, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BRONZE_BOULDER, -1534, -752); - BOLDLOC(GC_MAZE_BRONZE_BOULDER_5, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BRONZE_BOULDER, -1536, -991); - ROCKLOC(GC_MAZE_ROCK, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_ROCK, -1197, -1329); - BOLDLOC(COLOSSUS_SILVER_BOULDER, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_SILVER_BOULDER, 61, - -1301); - ROCKLOC(COLOSSUS_ROCK, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, 1537, 667); - ROCKLOC(COLOSSUS_CIRCLE_1_ROCK_1, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -250, -1272); - ROCKLOC(COLOSSUS_CIRCLE_1_ROCK_2, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -193, -1295); - ROCKLOC(COLOSSUS_CIRCLE_1_ROCK_3, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -170, -1352); - ROCKLOC(COLOSSUS_CIRCLE_1_ROCK_4, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -193, -1408); - ROCKLOC(COLOSSUS_CIRCLE_1_ROCK_5, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -250, -1432); - ROCKLOC(COLOSSUS_CIRCLE_1_ROCK_6, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -306, -1408); - ROCKLOC(COLOSSUS_CIRCLE_1_ROCK_7, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -330, -1352); - ROCKLOC(COLOSSUS_CIRCLE_1_ROCK_8, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -306, -1295); - ROCKLOC(COLOSSUS_CIRCLE_2_ROCK_1, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -834, -766); - ROCKLOC(COLOSSUS_CIRCLE_2_ROCK_2, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -777, -789); - ROCKLOC(COLOSSUS_CIRCLE_2_ROCK_3, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -754, -846); - ROCKLOC(COLOSSUS_CIRCLE_2_ROCK_4, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -777, -902); - ROCKLOC(COLOSSUS_CIRCLE_2_ROCK_5, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -834, -926); - ROCKLOC(COLOSSUS_CIRCLE_2_ROCK_6, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -890, -902); - ROCKLOC(COLOSSUS_CIRCLE_2_ROCK_7, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -914, -846); - ROCKLOC(COLOSSUS_CIRCLE_2_ROCK_8, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -890, -789); - ROCKLOC(HC_STORMS_GROTTO_ROCK_1, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, RHT_HC_STORMS_GROTTO_ROCK, 1811, 813); - ROCKLOC(HC_STORMS_GROTTO_ROCK_2, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, RHT_HC_STORMS_GROTTO_ROCK, 1867, 789); - ROCKLOC(HC_STORMS_GROTTO_ROCK_3, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, RHT_HC_STORMS_GROTTO_ROCK, 1891, 733); - ROCKLOC(HC_STORMS_GROTTO_ROCK_4, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, RHT_HC_STORMS_GROTTO_ROCK, 1867, 676); - ROCKLOC(HC_STORMS_GROTTO_ROCK_5, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, RHT_HC_STORMS_GROTTO_ROCK, 1811, 653); - ROCKLOC(HC_STORMS_GROTTO_ROCK_6, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, RHT_HC_STORMS_GROTTO_ROCK, 1754, 676); - ROCKLOC(HC_STORMS_GROTTO_ROCK_7, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, RHT_HC_STORMS_GROTTO_ROCK, 1731, 733); - ROCKLOC(HC_STORMS_GROTTO_ROCK_8, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, RHT_HC_STORMS_GROTTO_ROCK, 1754, 789); - locationTable[RC_BOTW_BOULDER_1] = - Location::Boulder(RC_BOTW_BOULDER_1, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, - TWO_ACTOR_PARAMS(-684, -734), "BOTW Boulder 1", RHT_BOTW_BOULDER, - SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTW_BOULDER_1)); - locationTable[RC_BOTW_BOULDER_2] = - Location::Boulder(RC_BOTW_BOULDER_2, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, - TWO_ACTOR_PARAMS(-632, -805), "BOTW Boulder 2", RHT_BOTW_BOULDER, - SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTW_BOULDER_2)); - locationTable[RC_BOTW_BOULDER_3] = - Location::Boulder(RC_BOTW_BOULDER_3, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, - TWO_ACTOR_PARAMS(333, -681), "BOTW Boulder 3", RHT_BOTW_BOULDER, - SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTW_BOULDER_3)); - locationTable[RC_BOTW_BOULDER_4] = - Location::Boulder(RC_BOTW_BOULDER_4, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, - TWO_ACTOR_PARAMS(409, -637), "BOTW Boulder 4", RHT_BOTW_BOULDER, - SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTW_BOULDER_4)); - locationTable[RC_BOTW_BOULDER_5] = - Location::Boulder(RC_BOTW_BOULDER_5, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, - TWO_ACTOR_PARAMS(334, -8), "BOTW Boulder 5", RHT_BOTW_BOULDER, - SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTW_BOULDER_5)); - locationTable[RC_BOTW_BOULDER_6] = - Location::Boulder(RC_BOTW_BOULDER_6, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, - TWO_ACTOR_PARAMS(312, 64), "BOTW Boulder 6", RHT_BOTW_BOULDER, - SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTW_BOULDER_6)); -#define MQBOLD(id, area, hint, x, z) \ - (locationTable[RC_##id] = \ - Location::Boulder(RC_##id, RCQUEST_MQ, RCAREA_##area, SCENE_##area, TWO_ACTOR_PARAMS(x, z), #id, hint, \ - SpoilerCollectionCheck::RandomizerInf(RAND_INF_##id))) - MQBOLD(DEKU_TREE_MQ_BOULDER_1, DEKU_TREE, RHT_DEKU_BOULDER, -1237, 1558); - MQBOLD(DEKU_TREE_MQ_BOULDER_2, DEKU_TREE, RHT_DEKU_BOULDER, -1183, 1522); - MQBOLD(DEKU_TREE_MQ_BOULDER_3, DEKU_TREE, RHT_DEKU_BOULDER, -1129, 1469); - MQBOLD(DODONGOS_CAVERN_MQ_LOBBY_BOULDER_1, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, -435, -1720); - MQBOLD(DODONGOS_CAVERN_MQ_LOBBY_BOULDER_2, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 432, -1719); - MQBOLD(DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_1, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 807, -874); - MQBOLD(DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_2, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 802, -972); - MQBOLD(DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_3, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 783, -923); - MQBOLD(DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_1, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 2464, -402); - MQBOLD(DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_2, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 2942, -495); - MQBOLD(DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_1, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 4219, -1651); - MQBOLD(DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_2, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 4178, -1602); - MQBOLD(DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_3, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 4162, -1581); - MQBOLD(DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_4, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 4133, -1561); - MQBOLD(DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_5, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 4091, -1510); - MQBOLD(DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_6, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 4067, -1487); - MQBOLD(DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_7, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 4028, -1472); - MQBOLD(DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_8, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 3965, -1473); - MQBOLD(DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_9, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 3898, -1467); - MQBOLD(DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_10, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 3832, -1437); - MQBOLD(DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_11, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 3799, -1383); - MQBOLD(DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_12, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 3760, -1318); - MQBOLD(DODONGOS_CAVERN_MQ_TWO_FLAMES_BOULDER, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 2737, -1058); - locationTable[RC_JABU_JABUS_BELLY_MQ_ENTRANCE_BOULDER] = - Location::Boulder(RC_JABU_JABUS_BELLY_MQ_ENTRANCE_BOULDER, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, - TWO_ACTOR_PARAMS(-1, -296), "RC_JABU_JABUS_BELLY_MQ_ENTRANCE_BOULDER", RHT_JABU_BOULDER, - SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_ENTRANCE_BOULDER)); - locationTable[RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_1] = Location::Boulder( - RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_1, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, - TWO_ACTOR_PARAMS(350, -3533), "RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_1", RHT_JABU_BOULDER, - SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_1)); - locationTable[RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_2] = Location::Boulder( - RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_2, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, - TWO_ACTOR_PARAMS(-192, -3211), "RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_2", RHT_JABU_BOULDER, - SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_2)); - locationTable[RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_1] = Location::Boulder( - RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_1, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, - TWO_ACTOR_PARAMS(245, -2792), "RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_1", RHT_JABU_BOULDER, - SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_1)); - locationTable[RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_2] = Location::Boulder( - RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_2, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, - TWO_ACTOR_PARAMS(220, -2790), "RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_2", RHT_JABU_BOULDER, - SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_2)); - locationTable[RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_3] = Location::Boulder( - RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_3, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, - TWO_ACTOR_PARAMS(274, -2790), "RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_3", RHT_JABU_BOULDER, - SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_3)); - locationTable[RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_1] = Location::Boulder( - RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_1, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, - TWO_ACTOR_PARAMS(31, -5177), "RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_1", RHT_JABU_BOULDER, - SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_1)); - locationTable[RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_2] = Location::Boulder( - RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_2, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, - TWO_ACTOR_PARAMS(-37, -5173), "RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_2", RHT_JABU_BOULDER, - SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_2)); - locationTable[RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_BOULDER] = Location::Boulder( - RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_BOULDER, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, - TWO_ACTOR_PARAMS(-885, -5907), "RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_BOULDER", RHT_JABU_BOULDER, - SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_TAILPASARAN_BOULDER)); - locationTable[RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_WALL_BOULDER] = Location::Boulder( - RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_WALL_BOULDER, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, - TWO_ACTOR_PARAMS(-411, -5682), "RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_WALL_BOULDER", RHT_JABU_BOULDER, - SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_TAILPASARAN_WALL_BOULDER)); - // skip spirit temple boulder, so adult can clear without collecting check for child to pass - MQBOLD(SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_1, SPIRIT_TEMPLE, RHT_SPIRIT_TEMPLE_BOULDER, -160, 270); - MQBOLD(SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_2, SPIRIT_TEMPLE, RHT_SPIRIT_TEMPLE_BOULDER, 160, 270); - MQBOLD(SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_3, SPIRIT_TEMPLE, RHT_SPIRIT_TEMPLE_BOULDER, 350, 220); - MQBOLD(SPIRIT_TEMPLE_MQ_ENTRANCE_CEILING_BOULDER, SPIRIT_TEMPLE, RHT_SPIRIT_TEMPLE_BOULDER, 0, -60); - MQBOLD(SPIRIT_TEMPLE_MQ_EARLY_ADULT_BOULDER, SPIRIT_TEMPLE, RHT_SPIRIT_TEMPLE_BOULDER, 1070, -290); - MQBOLD(BOTW_MQ_BOULDER_1, BOTTOM_OF_THE_WELL, RHT_BOTW_BOULDER, -370, -160); - MQBOLD(BOTW_MQ_BOULDER_2, BOTTOM_OF_THE_WELL, RHT_BOTW_BOULDER, -521, -353); - MQBOLD(BOTW_MQ_BOULDER_3, BOTTOM_OF_THE_WELL, RHT_BOTW_BOULDER, -541, -404); -} - -static ObjectExtension::Register RegisterRockIdentity; -static RegisterShipInitFunc initFunc(RegisterShuffleRock, { "IS_RANDO" }); -static RegisterShipInitFunc initFunc2(Rando::StaticData::RegisterRockLocations); \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/ShuffleRocks.h b/soh/soh/Enhancements/randomizer/ShuffleRocks.h deleted file mode 100644 index ad7ea4d7a83..00000000000 --- a/soh/soh/Enhancements/randomizer/ShuffleRocks.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef SHUFFLEROCKS_H -#define SHUFFLEROCKS_H - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif -void EnIshi_RandomizerInit(void* actorRef); -#ifdef __cplusplus -}; -#endif - -#endif // SHUFFLEROCKS_H \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/draw.cpp b/soh/soh/Enhancements/randomizer/draw.cpp index 63a2cfe9c9a..ad7ddae9b78 100644 --- a/soh/soh/Enhancements/randomizer/draw.cpp +++ b/soh/soh/Enhancements/randomizer/draw.cpp @@ -36,10 +36,9 @@ extern "C" { #include "overlays/actors/ovl_Boss_Goma/z_boss_goma.h" #include "objects/object_tw/object_tw.h" #include "objects/object_ganon2/object_ganon2.h" -#include "objects/object_vase/object_vase.h" +#include "objects/object_gi_shield_1/object_gi_shield_1.h" #include "objects/object_link_child/object_link_child.h" #include "roll_animation_data.h" -#include "objects/object_gi_shield_1/object_gi_shield_1.h" extern PlayState* gPlayState; extern SaveContext gSaveContext; @@ -123,17 +122,6 @@ extern "C" void Randomizer_DrawSmallKey(PlayState* play, GetItemEntry* getItemEn CLOSE_DISPS(play->state.gfxCtx); } -extern "C" void Randomizer_DrawBeanSprout(PlayState* play, GetItemEntry* getItemEntry) { - OPEN_DISPS(play->state.gfxCtx); - - Gfx_SetupDL_25Opa(play->state.gfxCtx); - Matrix_Scale(0.3f, 0.3f, 0.3f, MTXMODE_APPLY); - gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_MODELVIEW | G_MTX_LOAD); - gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gMagicBeanSeedlingDL); - - CLOSE_DISPS(play->state.gfxCtx); -} - extern "C" void Randomizer_DrawMap(PlayState* play, GetItemEntry* getItemEntry) { s16 color_slot = getItemEntry->drawItemId - RG_DEKU_TREE_MAP; s16 colors[12][3] = { @@ -962,6 +950,17 @@ extern "C" void DrawGanon(PlayState* play) { CLOSE_DISPS(play->state.gfxCtx); } +extern "C" void Randomizer_DrawBeanSprout(PlayState* play, GetItemEntry* getItemEntry) { + OPEN_DISPS(play->state.gfxCtx); + + Gfx_SetupDL_25Opa(play->state.gfxCtx); + Matrix_Scale(0.3f, 0.3f, 0.3f, MTXMODE_APPLY); + gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_MODELVIEW | G_MTX_LOAD); + gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gMagicBeanSeedlingDL); + + CLOSE_DISPS(play->state.gfxCtx); +} + extern "C" void Randomizer_DrawBossSoul(PlayState* play, GetItemEntry* getItemEntry) { s16 slot; if (getItemEntry->getItemId != RG_ICE_TRAP) { @@ -1176,48 +1175,6 @@ extern "C" void Randomizer_DrawLadder(PlayState* play, GetItemEntry* getItemEntr CLOSE_DISPS(play->state.gfxCtx); } -extern "C" void Randomizer_DrawRollAbility(PlayState* play, GetItemEntry* getItemEntry) { - static bool initialized = false; - static SkelAnime skelAnime; - static Vec3s jointTable[ROLL_ANIMATION_LIMBS]; - static Vec3s morphTable[ROLL_ANIMATION_LIMBS]; - static u32 lastUpdate = 0; - static int currentFrame = 0; - - if (!initialized) { - initialized = true; - SkelAnime_InitFlex(play, &skelAnime, (FlexSkeletonHeader*)gLinkChildSkel, NULL, jointTable, morphTable, - ROLL_ANIMATION_LIMBS); - } - - // Animation manuelle avec les frames capturées - if (lastUpdate != play->state.frames) { - lastUpdate = play->state.frames; - - // Avance d'une frame toutes les 2 frames de jeu - if ((play->state.frames % 2) == 0) { - currentFrame = (currentFrame + 1) % ROLL_ANIMATION_FRAMES; - } - - // Copie les données de la frame actuelle - for (int i = 0; i < ROLL_ANIMATION_LIMBS; i++) { - jointTable[i] = rollAnimationData[currentFrame][i]; - } - } - - OPEN_DISPS(play->state.gfxCtx); - - Gfx_SetupDL_25Opa(play->state.gfxCtx); - - Matrix_Translate(0.0f, -30.0f, 0.0f, MTXMODE_APPLY); - Matrix_RotateY(play->gameplayFrames * 0.05f, MTXMODE_APPLY); - Matrix_Scale(0.01f, 0.01f, 0.01f, MTXMODE_APPLY); - - SkelAnime_DrawFlexOpa(play, skelAnime.skeleton, jointTable, skelAnime.dListCount, NULL, NULL, NULL); - - CLOSE_DISPS(play->state.gfxCtx); -} - extern "C" void Randomizer_DrawKneePads(PlayState* play, GetItemEntry* getItemEntry) { OPEN_DISPS(play->state.gfxCtx); @@ -1441,4 +1398,4 @@ extern "C" void Randomizer_DrawOverworldKey(PlayState* play, GetItemEntry* getIt gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gHouseKeyDL); CLOSE_DISPS(play->state.gfxCtx); -} \ No newline at end of file +} diff --git a/soh/soh/Enhancements/randomizer/draw.h b/soh/soh/Enhancements/randomizer/draw.h index da70990c4e3..5ec3dc49f78 100644 --- a/soh/soh/Enhancements/randomizer/draw.h +++ b/soh/soh/Enhancements/randomizer/draw.h @@ -24,7 +24,6 @@ void Randomizer_DrawOcarinaButton(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawBronzeScale(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawPowerBracelet(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawLadder(PlayState* play, GetItemEntry* getItemEntry); -void Randomizer_DrawRollAbility(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawKneePads(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawRollAbility(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawOpenChest(PlayState* play, GetItemEntry* getItemEntry); diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 44edf4dd6d9..7b632266c95 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -850,9 +850,6 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l va_copy(args, originalArgs); switch (id) { - case VB_ROLL: - *should = !RAND_GET_OPTION(RSK_SHUFFLE_ROLL) || Flags_GetRandomizerInf(RAND_INF_CAN_ROLL); - case VB_CLIMB: if (RAND_GET_OPTION(RSK_SHUFFLE_CLIMB) && !Flags_GetRandomizerInf(RAND_INF_CAN_CLIMB)) { s32* x = va_arg(args, s32*); diff --git a/soh/soh/Enhancements/randomizer/item_list.cpp b/soh/soh/Enhancements/randomizer/item_list.cpp index a770bc26da0..16f3893c395 100644 --- a/soh/soh/Enhancements/randomizer/item_list.cpp +++ b/soh/soh/Enhancements/randomizer/item_list.cpp @@ -376,11 +376,10 @@ void Rando::StaticData::InitItemTable() { itemTable[RG_CRAWL].SetCustomDrawFunc(Randomizer_DrawKneePads); itemTable[RG_OPEN_CHEST] = Item(RG_OPEN_CHEST, Text{ "Open Chests", TODO_TRANSLATE, TODO_TRANSLATE }, ITEMTYPE_ITEM, GI_KEY_SMALL, true, LOGIC_NONE, RHT_OPEN_CHEST, RG_OPEN_CHEST, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_OPEN_CHEST].SetCustomDrawFunc(Randomizer_DrawOpenChest); - itemTable[RG_ROLL] = Item(RG_ROLL, Text{ "Roll", "Rouler", "Rolle" }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, LOGIC_NONE, RHT_ROLL, RG_ROLL, OBJECT_GI_SCALE, GID_SCALE_SILVER, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_ROLL].SetCustomDrawFunc(Randomizer_DrawRollAbility); - - itemTable[RG_PROGRESSIVE_BOMBCHU_BAG] = Item(RG_PROGRESSIVE_BOMBCHU_BAG, Text{ "Bombchu Bag", "Sac de Missiles Teigneux", "Krabbelminentasche" }, ITEMTYPE_ITEM, RG_PROGRESSIVE_BOMBCHU_BAG, true, LOGIC_BOMBCHUS, RHT_BOMBCHU_BAG, RG_PROGRESSIVE_BOMBCHU_BAG, OBJECT_GI_BOMB_2, GID_BOMBCHU, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + + itemTable[RG_PROGRESSIVE_BOMBCHU_BAG] = Item(RG_PROGRESSIVE_BOMBCHU_BAG, Text{ "Bombchu Bag", "Sac de Missiles Teigneux", "Krabbelminentasche" }, ITEMTYPE_ITEM, RG_PROGRESSIVE_BOMBCHU_BAG, true, LOGIC_BOMBCHUS, RHT_BOMBCHU_BAG, RG_PROGRESSIVE_BOMBCHU_BAG, OBJECT_GI_BOMB_2, GID_BOMBCHU, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"a ", "eine ", "un "}); itemTable[RG_PROGRESSIVE_BOMBCHU_BAG].SetCustomDrawFunc(Randomizer_DrawBombchuBag); itemTable[RG_QUIVER_INF] = Item(RG_QUIVER_INF, Text{ "Infinite Quiver", "Carquois Infini", "Unendlicher Köcher" }, ITEMTYPE_ITEM, RG_QUIVER_INF, true, LOGIC_PROGRESSIVE_BOW, RHT_QUIVER_INF, RG_QUIVER_INF, OBJECT_GI_ARROWCASE, GID_QUIVER_50, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "den ", "le "}); diff --git a/soh/soh/Enhancements/randomizer/location.cpp b/soh/soh/Enhancements/randomizer/location.cpp index 25c687f2b6f..e129a6b264b 100644 --- a/soh/soh/Enhancements/randomizer/location.cpp +++ b/soh/soh/Enhancements/randomizer/location.cpp @@ -581,23 +581,6 @@ Rando::Location Rando::Location::NLTree(RandomizerCheck rc, RandomizerCheckQuest false, collectionCheck }; } -Rando::Location Rando::Location::Rock(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, - SceneID scene_, int32_t actorParams_, std::string&& shortName_, - RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, - SpoilerCollectionCheck collectionCheck) { - return { rc, quest_, RCTYPE_ROCK, area_, ACTOR_EN_ISHI, - scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem, - false, collectionCheck }; -} - -Rando::Location Rando::Location::Boulder(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, - SceneID scene_, int32_t actorParams_, std::string&& shortName_, - RandomizerHintTextKey hintKey, SpoilerCollectionCheck collectionCheck) { - return { rc, quest_, RCTYPE_BOULDER, area_, ACTOR_EN_ISHI, - scene_, actorParams_, std::move(shortName_), hintKey, RG_BOMBS_5, - false, collectionCheck }; -} - Rando::Location Rando::Location::Bush(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, diff --git a/soh/soh/Enhancements/randomizer/location.h b/soh/soh/Enhancements/randomizer/location.h index e1406c56581..24b192cc342 100644 --- a/soh/soh/Enhancements/randomizer/location.h +++ b/soh/soh/Enhancements/randomizer/location.h @@ -67,7 +67,15 @@ class Location { actorParams(actorParams_), shortName(std::move(shortName_)), spoilerName(std::move(spoilerName_)), hintKey(hintKey_), vanillaItem(vanillaItem_), isVanillaCompletion(isVanillaCompletion_), collectionCheck(collectionCheck_), vanillaPrice(vanillaPrice_) { - excludedOption = LocationOption(rc, spoilerName); + if (spoilerName.length() < 23) { + excludedOption = LocationOption(rc, spoilerName); + } else { + const size_t lastSpace = spoilerName.rfind(' ', 23); + std::string settingText = spoilerName; + settingText.replace(lastSpace, 1, "\n "); + + excludedOption = LocationOption(rc, spoilerName); + } } Location(const RandomizerCheck rc_, const RandomizerCheckQuest quest_, const RandomizerCheckType checkType_, @@ -79,7 +87,15 @@ class Location { actorParams(actorParams_), shortName(shortName_), spoilerName(SpoilerNameFromShortName(shortName_, area_)), hintKey(hintKey_), vanillaItem(vanillaItem_), isVanillaCompletion(isVanillaCompletion_), collectionCheck(collectionCheck_), vanillaPrice(vanillaPrice_) { - excludedOption = LocationOption(rc, spoilerName); + if (spoilerName.length() < 23) { + excludedOption = LocationOption(rc, spoilerName); + } else { + const size_t lastSpace = spoilerName.rfind(' ', 23); + std::string settingText = spoilerName; + settingText.replace(lastSpace, 1, "\n "); + + excludedOption = LocationOption(rc, spoilerName); + } } static std::string SpoilerNameFromShortName(std::string shortName, RandomizerCheckArea area) { @@ -237,14 +253,6 @@ class Location { int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck); - static Location Rock(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, - int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey, - RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck); - - static Location Boulder(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, - int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey, - SpoilerCollectionCheck collectionCheck); - static Location Bush(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck); diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/bottom_of_the_well.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/bottom_of_the_well.cpp index 17cf8b830f5..f0c5b1af162 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/bottom_of_the_well.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/bottom_of_the_well.cpp @@ -231,12 +231,6 @@ void RegionTable_Init_BottomOfTheWell() { LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_7, logic->CanCutShrubs()), LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_8, logic->CanCutShrubs()), LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_9, logic->CanCutShrubs()), - LOCATION(RC_BOTW_BOULDER_1, logic->BlastOrSmash()), - LOCATION(RC_BOTW_BOULDER_2, logic->BlastOrSmash()), - LOCATION(RC_BOTW_BOULDER_3, logic->BlastOrSmash() || logic->CanUse(RG_DINS_FIRE) || (logic->CanUse(RG_STICKS) && ctx->GetTrickOption(RT_BOTW_BASEMENT))), - LOCATION(RC_BOTW_BOULDER_4, logic->BlastOrSmash()), - LOCATION(RC_BOTW_BOULDER_5, logic->BlastOrSmash()), - LOCATION(RC_BOTW_BOULDER_6, logic->BlastOrSmash()), }, { //Exits Entrance(RR_BOTW_B3_OOZE, []{return AnyAgeTime([]{return logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET);});}), @@ -284,9 +278,6 @@ void RegionTable_Init_BottomOfTheWell() { LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_OUTER_LOBBY_POT, AnyAgeTime([]{return logic->BlastOrSmash();}) && logic->CanHitEyeTargets()), LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_BOMB_LEFT_HEART, logic->HasExplosives()), LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_BOMB_RIGHT_HEART, logic->HasExplosives()), - LOCATION(RC_BOTW_MQ_BOULDER_1, logic->BlastOrSmash()), - LOCATION(RC_BOTW_MQ_BOULDER_2, logic->BlastOrSmash()), - LOCATION(RC_BOTW_MQ_BOULDER_3, logic->BlastOrSmash()), }, { //Exits Entrance(RR_BOTW_ENTRYWAY, []{return logic->CanUse(RG_CRAWL) && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT));}), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp index 5cfaf3200b3..2e1dfd7d6d5 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp @@ -325,9 +325,6 @@ void RegionTable_Init_DekuTree() { //Locations LOCATION(RC_DEKU_TREE_MQ_GS_PAST_BOULDER_VINES, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)), LOCATION(RC_DEKU_TREE_MQ_COMPASS_ROOM_HEART, true), - LOCATION(RC_DEKU_TREE_MQ_BOULDER_1, true), - LOCATION(RC_DEKU_TREE_MQ_BOULDER_2, true), - LOCATION(RC_DEKU_TREE_MQ_BOULDER_3, true), }, { //Exits Entrance(RR_DEKU_TREE_MQ_COMPASS_ROOM, []{return logic->BlastOrSmash();}), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp index 456cb738039..46b27b2ba17 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp @@ -291,8 +291,6 @@ void RegionTable_Init_DodongosCavern() { LOCATION(RC_DODONGOS_CAVERN_MQ_MAP_CHEST, (logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET)) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR, logic->CanStunDeku() && GetCheckPrice() <= GetWalletCapacity()), LOCATION(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT, logic->CanStunDeku() && GetCheckPrice() <= GetWalletCapacity()), - LOCATION(RC_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_1, logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET)), - LOCATION(RC_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_2, logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET)), }, { //Exits Entrance(RR_DODONGOS_CAVERN_MQ_BEGINNING, []{return true;}), @@ -330,12 +328,7 @@ void RegionTable_Init_DodongosCavern() { //Events EventAccess(LOGIC_DC_MQ_CLEAR_UPPER_LOBBY_ROCKS, []{return logic->BlastOrSmash() || logic->CanUse(RG_DINS_FIRE);}), EventAccess(LOGIC_DC_EYES_LIT, []{return logic->HasExplosives() || (logic->Get(LOGIC_DC_MQ_CLEAR_UPPER_LOBBY_ROCKS) && logic->HasItem(RG_GORONS_BRACELET) && ((logic->IsAdult && ctx->GetTrickOption(RT_DC_MQ_ADULT_EYES)) || (logic->IsChild && ctx->GetTrickOption(RT_DC_MQ_CHILD_EYES))));}), - }, { - //Locations - LOCATION(RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_1, logic->Get(LOGIC_DC_MQ_CLEAR_UPPER_LOBBY_ROCKS)), - LOCATION(RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_2, logic->Get(LOGIC_DC_MQ_CLEAR_UPPER_LOBBY_ROCKS)), - LOCATION(RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_3, logic->Get(LOGIC_DC_MQ_CLEAR_UPPER_LOBBY_ROCKS)), - }, { + }, {}, { //Exits Entrance(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return true;}), Entrance(RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_UPPER, []{return logic->Get(LOGIC_DC_MQ_CLEAR_UPPER_LOBBY_ROCKS);}), @@ -459,18 +452,6 @@ void RegionTable_Init_DodongosCavern() { LOCATION(RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_3, logic->CanBreakPots()), LOCATION(RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_4, logic->CanBreakPots()), LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_HEART, logic->BlastOrSmash()), - LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_1, logic->BlastOrSmash() && logic->TakeDamage()), - LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_2, logic->BlastOrSmash() && logic->TakeDamage()), - LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_3, logic->BlastOrSmash() && logic->TakeDamage()), - LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_4, logic->BlastOrSmash() && logic->TakeDamage()), - LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_5, logic->BlastOrSmash()), - LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_6, logic->BlastOrSmash()), - LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_7, logic->BlastOrSmash() && logic->TakeDamage()), - LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_8, logic->BlastOrSmash() && logic->TakeDamage()), - LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_9, logic->BlastOrSmash() && logic->TakeDamage()), - LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_10, logic->BlastOrSmash() && logic->TakeDamage()), - LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_11, logic->BlastOrSmash() && logic->TakeDamage()), - LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_12, logic->BlastOrSmash() && logic->TakeDamage()), }, { //Exits //Falling down gets you stuck with nothing there, not a useful exit for logic @@ -484,7 +465,6 @@ void RegionTable_Init_DodongosCavern() { LOCATION(RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_2, logic->CanBreakPots()), LOCATION(RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_CRATE_1, logic->CanBreakCrates()), LOCATION(RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_CRATE_2, logic->CanBreakCrates()), - LOCATION(RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_BOULDER, logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET)), }, { //Exits Entrance(RR_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS, []{return true;}), @@ -511,12 +491,10 @@ void RegionTable_Init_DodongosCavern() { areaTable[RR_DODONGOS_CAVERN_MQ_LOWER_RIGHT_SIDE] = Region("Dodongos Cavern MQ Lower Right Side", SCENE_DODONGOS_CAVERN, {}, { //Locations - LOCATION(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_1, logic->CanBreakPots()), - LOCATION(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_2, logic->CanBreakPots()), - LOCATION(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_3, logic->CanBreakPots()), - LOCATION(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_4, logic->CanBreakPots()), - LOCATION(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_1, logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET) || logic->CanUse(RG_DINS_FIRE)), - LOCATION(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_2, logic->CanDetonateBombFlowers() || logic->HasItem(RG_GORONS_BRACELET) || (ctx->GetTrickOption(RT_BLUE_FIRE_MUD_WALLS) && logic->CanUse(RG_BOTTLE_WITH_BLUE_FIRE) && (logic->EffectiveHealth() != 1 || logic->CanUse(RG_NAYRUS_LOVE)))), + LOCATION(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_1, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_2, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_3, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_4, logic->CanBreakPots()), }, { //Exits Entrance(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp index 6217ee201d7..557ddb180f1 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp @@ -305,7 +305,7 @@ void RegionTable_Init_FireTemple() { Entrance(RR_FIRE_TEMPLE_NEAR_BOSS_ROOM, []{return logic->Get(LOGIC_FIRE_HIT_PLATFORM) && (logic->IsAdult || logic->CanUse(RG_HOVER_BOOTS) || logic->TakeDamage());}), Entrance(RR_FIRE_TEMPLE_CORRIDOR, []{return true;}), Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_PLATFORMS, []{return logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && (logic->Get(LOGIC_FIRE_HIT_ABOVE_MAZE_PLATFORM) || logic->CanGroundJump()));}), - Entrance(RR_FIRE_TEMPLE_CAGELESS_CHEST_ROOM, []{return logic->HasItem(RG_OPEN_CHEST);}), + Entrance(RR_FIRE_TEMPLE_CAGELESS_CHEST_ROOM, []{return true;}), Entrance(RR_FIRE_TEMPLE_SOT_CAGE_LOWER, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 8);}), Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_SWITCH, []{return (bool)ctx->GetTrickOption(RT_FIRE_SKIP_FLAME_WALLS);}), }); diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp index eef59b0a30a..7498652d3be 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp @@ -197,7 +197,7 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_SEWER] = Region("Forest Temple Sewer", SCENE_FOREST_TEMPLE, {}, { //Locations - LOCATION(RC_FOREST_TEMPLE_WELL_CHEST, logic->CanOpenUnderwaterChest() && logic->WaterTimer() >= 8 && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_FOREST_TEMPLE_WELL_CHEST, logic->CanOpenUnderwaterChest() && logic->WaterTimer() >= 8), LOCATION(RC_FOREST_TEMPLE_WELL_WEST_HEART, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8), LOCATION(RC_FOREST_TEMPLE_WELL_EAST_HEART, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8), }, { @@ -672,6 +672,7 @@ void RegionTable_Init_ForestTemple() { }); areaTable[RR_FOREST_TEMPLE_MQ_NE_COURTYARD_DOORFRAME] = Region("Forest Temple MQ NE Courtyard Doorframe", SCENE_FOREST_TEMPLE, {}, { + //Locations //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->CanKillEnemy(RE_GOLD_SKULLTULA, ED_BOMB_THROW) || logic->CanUse(RG_MEGATON_HAMMER) || (logic->CanStandingShield() && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MASTER_SWORD) || (logic->IsChild && logic->CanUse(RG_KOKIRI_SWORD))))), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp index ef58d8e1e68..46cff241abf 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp @@ -409,4 +409,4 @@ void RegionTable_Init_GerudoTrainingGround() { #pragma endregion // clang-format on -} \ No newline at end of file +} diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/jabujabus_belly.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/jabujabus_belly.cpp index b4132c32cd2..32b888d8749 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/jabujabus_belly.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/jabujabus_belly.cpp @@ -272,7 +272,6 @@ void RegionTable_Init_JabuJabusBelly() { LOCATION(RC_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_2, logic->CanBreakPots()), LOCATION(RC_JABU_JABUS_BELLY_MQ_FIRST_GRASS_1, logic->CanCutShrubs()), LOCATION(RC_JABU_JABUS_BELLY_MQ_FIRST_GRASS_2, logic->CanCutShrubs()), - LOCATION(RC_JABU_JABUS_BELLY_MQ_ENTRANCE_BOULDER, logic->BlastOrSmash()), }, { //Exits Entrance(RR_JABU_JABUS_BELLY_ENTRYWAY, []{return true;}), @@ -343,11 +342,6 @@ void RegionTable_Init_JabuJabusBelly() { LOCATION(RC_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_1, logic->CanCutShrubs()), LOCATION(RC_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_2, logic->CanCutShrubs()), LOCATION(RC_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_3, logic->CanCutShrubs()), - LOCATION(RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_1, logic->BlastOrSmash()), - LOCATION(RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_2, logic->BlastOrSmash()), - LOCATION(RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_1, logic->HasExplosives()), - LOCATION(RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_2, logic->HasExplosives()), - LOCATION(RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_3, logic->HasExplosives()), }, { //Exits Entrance(RR_JABU_JABUS_BELLY_MQ_HOLES_ROOM, []{return logic->HasItem(RG_CLIMB);}), @@ -444,8 +438,6 @@ void RegionTable_Init_JabuJabusBelly() { LOCATION(RC_JABU_JABUS_BELLY_MQ_FALLING_LIKE_LIKE_GRASS, logic->CanCutShrubs()), LOCATION(RC_JABU_JABUS_BELLY_MQ_TRIPLE_HALLWAY_SMALL_CRATE_1, logic->CanBreakSmallCrates()), LOCATION(RC_JABU_JABUS_BELLY_MQ_TRIPLE_HALLWAY_SMALL_CRATE_2, logic->CanBreakSmallCrates()), - LOCATION(RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_1, logic->BlastOrSmash()), - LOCATION(RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_2, logic->BlastOrSmash()), }, { //Exits Entrance(RR_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp index 27b99689bd8..703c21a3162 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp @@ -560,10 +560,6 @@ void RegionTable_Init_SpiritTemple() { LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_2, logic->CanBreakPots()), LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_3, logic->CanBreakPots()), LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_4, logic->CanBreakPots()), - LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_1, logic->BlastOrSmash()), - LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_2, logic->BlastOrSmash()), - LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_3, logic->BlastOrSmash()), - LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_CEILING_BOULDER, logic->CanUse(RG_BOMBCHU_5)), }, { //Exits Entrance(RR_SPIRIT_TEMPLE_ENTRYWAY, []{return true;}), @@ -582,7 +578,6 @@ void RegionTable_Init_SpiritTemple() { LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_SLUGMA_POT, logic->CanBreakPots()), LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_LEFT_HEART, logic->CanHitEyeTargets()), LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_RIGHT_HEART, logic->CanHitEyeTargets()), - LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_HAMMER_SWITCH_CHEST, logic->Get(LOGIC_SPIRIT_MQ_TIME_TRAVEL_CHEST) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits //Nabooru's legs are technically visible one way collision here, but I'm not sure if this counts @@ -909,7 +904,6 @@ void RegionTable_Init_SpiritTemple() { //Locations LOCATION(RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_1, logic->CanBreakPots()), LOCATION(RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_2, logic->CanBreakPots()), - LOCATION(RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_BOULDER, logic->BlastOrSmash()), }, { //Exits Entrance(RR_SPIRIT_TEMPLE_MQ_FOYER, []{return logic->CanUse(RG_MEGATON_HAMMER) || (ctx->GetTrickOption(RT_HOVER_BOOST_SIMPLE) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanStandingShield() && (logic->CanUseSword() || logic->CanUse(RG_STICKS)));}), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp index 1e07234c453..e833fb2e42d 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp @@ -215,7 +215,7 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_BOULDERS_SOUTH] = Region("Water Temple Boulders South", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST, logic->CanUse(RG_LONGSHOT) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST, logic->CanUse(RG_LONGSHOT)), }, { //Exits Entrance(RR_WATER_TEMPLE_BEHIND_SPIKE_MOAT, []{return logic->SmallKeys(SCENE_WATER_TEMPLE, 4);}), @@ -285,11 +285,11 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_CANAL_ALCOVE] = Region("Water Temple Canal Alcove", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST, (logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG) || + LOCATION(RC_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG) || //child can also do a hovers backwalk backflip to reach the token after killing the skull ((logic->IsAdult || (ctx->GetTrickOption(RT_GROUND_JUMP_HARD) && logic->CanGroundJump())) && //killing with bombchu from here is hard due to the terrain, but adult can do it much easier from the river so it's only relevant for child - logic->CanUse(RG_HOVER_BOOTS) && logic->CanKillEnemy(RE_GOLD_SKULLTULA, logic->HasItem(RG_BRONZE_SCALE) && logic->IsAdult ? ED_SHORT_JUMPSLASH : ED_BOOMERANG))) && logic->HasItem(RG_OPEN_CHEST)), + logic->CanUse(RG_HOVER_BOOTS) && logic->CanKillEnemy(RE_GOLD_SKULLTULA, logic->HasItem(RG_BRONZE_SCALE) && logic->IsAdult ? ED_SHORT_JUMPSLASH : ED_BOOMERANG))), }, { //Exits Entrance(RR_WATER_TEMPLE_3_JETS_SWITCH, []{return true;}), @@ -299,7 +299,7 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_BOULDER_CANAL] = Region("Water Temple Boulder Canal", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST, ((logic->IsAdult && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)) || (logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT))) && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST, (logic->IsAdult && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)) || (logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT))), }, { //Exits //making the jump as adult without jumpslash is possible, but hard enough to be a trick @@ -311,7 +311,7 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_BEHIND_CANAL] = Region("Water Temple Behind Canal", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST, logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT) && logic->WaterTimer() >= 8 && logic->HasItem(RG_OPEN_CHEST)), + LOCATION(RC_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST, logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT) && logic->WaterTimer() >= 8), }, { //Exits Entrance(RR_WATER_TEMPLE_BOULDER_CANAL, []{return logic->HasItem(RG_BRONZE_SCALE);}), @@ -377,7 +377,7 @@ void RegionTable_Init_WaterTemple() { LOCATION(RC_WATER_TEMPLE_DRAGON_CHEST, logic->HasItem(RG_BRONZE_SCALE) && logic->HasItem(RG_OPEN_CHEST) && ((logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_IRON_BOOTS)) || (((logic->IsAdult && ctx->GetTrickOption(RT_WATER_ADULT_DRAGON)) || (logic->IsChild && ctx->GetTrickOption(RT_WATER_CHILD_DRAGON))) && - logic->CanHitSwitch(ED_BOOMERANG, true) && (logic->HasItem(RG_SILVER_SCALE) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8)))) && logic->HasItem(RG_OPEN_CHEST)), + logic->CanHitSwitch(ED_BOOMERANG, true) && (logic->HasItem(RG_SILVER_SCALE) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8))))), }, { //Exits Entrance(RR_WATER_TEMPLE_OUTSIDE_DRAGON_ROOM, []{return true;}), @@ -605,7 +605,7 @@ void RegionTable_Init_WaterTemple() { LOCATION(RC_WATER_TEMPLE_RIVER_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_WATER_TEMPLE_DRAGON_CHEST, logic->IsAdult && logic->CanHitSwitch(ED_LONGSHOT) && logic->HasItem(RG_BRONZE_SCALE) && logic->HasItem(RG_OPEN_CHEST) && ((ctx->GetTrickOption(RT_WATER_ADULT_DRAGON) && (logic->HasItem(RG_SILVER_SCALE) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8))) || - ctx->GetTrickOption(RT_WATER_DRAGON_JUMP_DIVE)) && logic->HasItem(RG_OPEN_CHEST)), + ctx->GetTrickOption(RT_WATER_DRAGON_JUMP_DIVE))), }, { //Exits Entrance(RR_WATER_TEMPLE_DRAGON_ROOM, []{return logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_LONGSHOT) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS) && logic->CanJumpslash());}), @@ -1226,10 +1226,8 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_MQ_TRIANGLE_TORCH_ROOM] = Region("Water Temple MQ Triangle Torch Room", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_1, (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)) || - (logic->CanUse(RG_BOMBCHU_5) && logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_2, (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)) || - (logic->CanUse(RG_BOMBCHU_5) && logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_1, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), + LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_2, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_3, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_4, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_5, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp index 91253666891..d707aa8c817 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp @@ -59,10 +59,6 @@ void RegionTable_Init_CastleGrounds() { LOCATION(RC_HC_NEAR_GUARDS_TREE_6, logic->CanBonkTrees()), LOCATION(RC_HC_NL_TREE_1, false), LOCATION(RC_HC_NL_TREE_2, false), - LOCATION(RC_HC_ROCK_1, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_HC_ROCK_2, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_HC_ROCK_3, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_HC_BOULDER, logic->BlastOrSmash()), }, { //Exits Entrance(RR_HC_GATE, []{return true;}), @@ -144,14 +140,6 @@ void RegionTable_Init_CastleGrounds() { LOCATION(RC_HC_STORMS_GROTTO_POT_2, logic->CanBreakPots()), LOCATION(RC_HC_STORMS_GROTTO_POT_3, logic->CanBreakPots()), LOCATION(RC_HC_STORMS_GROTTO_POT_4, logic->CanBreakPots()), - LOCATION(RC_HC_STORMS_GROTTO_ROCK_1, true), - LOCATION(RC_HC_STORMS_GROTTO_ROCK_2, true), - LOCATION(RC_HC_STORMS_GROTTO_ROCK_3, true), - LOCATION(RC_HC_STORMS_GROTTO_ROCK_4, true), - LOCATION(RC_HC_STORMS_GROTTO_ROCK_5, true), - LOCATION(RC_HC_STORMS_GROTTO_ROCK_6, true), - LOCATION(RC_HC_STORMS_GROTTO_ROCK_7, true), - LOCATION(RC_HC_STORMS_GROTTO_ROCK_8, true), }, { //Exits Entrance(RR_HC_STORMS_GROTTO, []{return true;}), @@ -162,14 +150,7 @@ void RegionTable_Init_CastleGrounds() { EventAccess(LOGIC_BUILD_RAINBOW_BRIDGE, []{return logic->CanBuildRainbowBridge();}), }, { //Locations - LOCATION(RC_OGC_GS, logic->CanJumpslashExceptHammer() || logic->CanUseProjectile() || (logic->CanShield() && logic->CanUse(RG_MEGATON_HAMMER)) || logic->CanUse(RG_DINS_FIRE)), - LOCATION(RC_OGC_BRONZE_BOULDER_1, logic->CanUse(RG_MEGATON_HAMMER)), - LOCATION(RC_OGC_BRONZE_BOULDER_2, logic->CanUse(RG_MEGATON_HAMMER)), - LOCATION(RC_OGC_BRONZE_BOULDER_3, logic->CanUse(RG_MEGATON_HAMMER)), - LOCATION(RC_OGC_SILVER_BOULDER_1, logic->CanUse(RG_SILVER_GAUNTLETS)), - LOCATION(RC_OGC_SILVER_BOULDER_2, logic->CanUse(RG_SILVER_GAUNTLETS)), - LOCATION(RC_OGC_SILVER_BOULDER_3, logic->CanUse(RG_SILVER_GAUNTLETS)), - LOCATION(RC_OGC_SILVER_BOULDER_4, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_OGC_GS, logic->CanJumpslashExceptHammer() || logic->CanUseProjectile() || (logic->CanShield() && logic->CanUse(RG_MEGATON_HAMMER)) || logic->CanUse(RG_DINS_FIRE)), }, { //Exits Entrance(RR_CASTLE_GROUNDS, []{return logic->AtNight;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_crater.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_crater.cpp index ea8e6c726ea..7c54b069fbd 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_crater.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_crater.cpp @@ -5,21 +5,7 @@ using namespace Rando; void RegionTable_Init_DeathMountainCrater() { // clang-format off - areaTable[RR_DMC_UPPER_NEARBY] = Region("DMC Upper Nearby", SCENE_DEATH_MOUNTAIN_CRATER, {}, { - LOCATION(RC_DMC_CIRCLE_ROCK_1, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_DMC_CIRCLE_ROCK_2, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_DMC_CIRCLE_ROCK_3, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_DMC_CIRCLE_ROCK_4, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_DMC_CIRCLE_ROCK_5, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_DMC_CIRCLE_ROCK_6, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_DMC_CIRCLE_ROCK_7, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_DMC_CIRCLE_ROCK_8, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_DMC_GOSSIP_ROCK_1, logic->IsChild && (logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash())), - LOCATION(RC_DMC_GOSSIP_ROCK_2, logic->IsChild && (logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash())), - LOCATION(RC_DMC_BOULDER_1, logic->BlastOrSmash()), - LOCATION(RC_DMC_BOULDER_2, logic->BlastOrSmash()), - LOCATION(RC_DMC_BOULDER_3, logic->BlastOrSmash()), - }, { + areaTable[RR_DMC_UPPER_NEARBY] = Region("DMC Upper Nearby", SCENE_DEATH_MOUNTAIN_CRATER, {}, {}, { //Exits Entrance(RR_DMC_UPPER_LOCAL, []{return logic->FireTimer() >= 48;}), Entrance(RR_DEATH_MOUNTAIN_SUMMIT, []{return true;}), @@ -62,14 +48,6 @@ void RegionTable_Init_DeathMountainCrater() { LOCATION(RC_DMC_NEAR_GC_POT_2, logic->CanBreakPots()), LOCATION(RC_DMC_NEAR_GC_POT_3, logic->CanBreakPots()), LOCATION(RC_DMC_NEAR_GC_POT_4, logic->CanBreakPots()), - LOCATION(RC_DMC_NEAR_GC_POT_1, logic->CanBreakPots()), - LOCATION(RC_DMC_NEAR_GC_POT_2, logic->CanBreakPots()), - LOCATION(RC_DMC_NEAR_GC_POT_3, logic->CanBreakPots()), - LOCATION(RC_DMC_NEAR_GC_POT_4, logic->CanBreakPots()), - LOCATION(RC_DMC_BRONZE_BOULDER_1, logic->CanUse(RG_MEGATON_HAMMER)), - LOCATION(RC_DMC_BRONZE_BOULDER_2, logic->CanUse(RG_MEGATON_HAMMER)), - LOCATION(RC_DMC_BRONZE_BOULDER_3, logic->CanUse(RG_MEGATON_HAMMER)), - LOCATION(RC_DMC_BRONZE_BOULDER_4, logic->CanUse(RG_MEGATON_HAMMER)), }, { //Exits Entrance(RR_DMC_LOWER_LOCAL, []{return logic->FireTimer() >= 48;}), @@ -112,11 +90,6 @@ void RegionTable_Init_DeathMountainCrater() { LOCATION(RC_DMC_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), LOCATION(RC_DMC_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), LOCATION(RC_DMC_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), - LOCATION(RC_DMC_ROCK_BY_FIRE_TEMPLE_1, logic->IsAdult && (logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash())), - LOCATION(RC_DMC_ROCK_BY_FIRE_TEMPLE_2, logic->IsAdult && (logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash())), - LOCATION(RC_DMC_ROCK_BY_FIRE_TEMPLE_3, logic->IsAdult && (logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash())), - LOCATION(RC_DMC_ROCK_BY_FIRE_TEMPLE_4, logic->IsAdult && (logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash())), - LOCATION(RC_DMC_ROCK_BY_FIRE_TEMPLE_5, logic->IsAdult && (logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash())), }, { //Exits Entrance(RR_DMC_CENTRAL_NEARBY, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_trail.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_trail.cpp index 41315385183..baecc3b6cf5 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_trail.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_trail.cpp @@ -21,33 +21,6 @@ void RegionTable_Init_DeathMountainTrail() { LOCATION(RC_DMT_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET))), LOCATION(RC_DMT_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET))), LOCATION(RC_DMT_FLAG_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)), - LOCATION(RC_DMT_ROCK_1, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_DMT_ROCK_2, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_DMT_ROCK_3, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_DMT_ROCK_4, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_DMT_ROCK_5, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_DMT_CIRCLE_ROCK_1, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_DMT_CIRCLE_ROCK_2, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_DMT_CIRCLE_ROCK_3, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_DMT_CIRCLE_ROCK_4, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_DMT_CIRCLE_ROCK_5, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_DMT_CIRCLE_ROCK_6, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_DMT_CIRCLE_ROCK_7, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_DMT_CIRCLE_ROCK_8, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_DMT_BOULDER_1, logic->BlastOrSmash()), - LOCATION(RC_DMT_BOULDER_2, logic->BlastOrSmash()), - LOCATION(RC_DMT_BOULDER_3, logic->IsChild && logic->BlastOrSmash()), - LOCATION(RC_DMT_BRONZE_BOULDER_1, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), - LOCATION(RC_DMT_BRONZE_BOULDER_2, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), - LOCATION(RC_DMT_BRONZE_BOULDER_3, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), - LOCATION(RC_DMT_BRONZE_BOULDER_4, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), - LOCATION(RC_DMT_BRONZE_BOULDER_5, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), - LOCATION(RC_DMT_BRONZE_BOULDER_6, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), - LOCATION(RC_DMT_BRONZE_BOULDER_7, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), - LOCATION(RC_DMT_BRONZE_BOULDER_8, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), - LOCATION(RC_DMT_BRONZE_BOULDER_9, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), - LOCATION(RC_DMT_BRONZE_BOULDER_10, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), - LOCATION(RC_DMT_BRONZE_BOULDER_11, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), }, { //Exits Entrance(RR_KAK_BEHIND_GATE, []{return true;}), @@ -78,8 +51,6 @@ void RegionTable_Init_DeathMountainTrail() { LOCATION(RC_DMT_TRADE_CLAIM_CHECK, logic->IsAdult && logic->CanUse(RG_CLAIM_CHECK)), LOCATION(RC_DMT_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), LOCATION(RC_DMT_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), - LOCATION(RC_DMT_COW_BOULDER, logic->BlastOrSmash()), - LOCATION(RC_DMT_SUMMIT_ROCK, logic->IsChild), LOCATION(RC_DMT_GOSSIP_STONE, true), }, { //Exits diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/desert_colossus.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/desert_colossus.cpp index 257660c8f38..4afeb119fd8 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/desert_colossus.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/desert_colossus.cpp @@ -19,24 +19,6 @@ void RegionTable_Init_DesertColossus() { LOCATION(RC_COLOSSUS_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DESERT_COLOSSUS_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_COLOSSUS_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), LOCATION(RC_COLOSSUS_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), - LOCATION(RC_COLOSSUS_SILVER_BOULDER, logic->CanUse(RG_SILVER_GAUNTLETS)), - LOCATION(RC_COLOSSUS_ROCK, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_1, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_2, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_3, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_4, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_5, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_6, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_7, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_8, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_1, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_2, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_3, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_4, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_5, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_6, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_7, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_8, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), LOCATION(RC_COLOSSUS_GOSSIP_STONE, true), }, { //Exits diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp index 21cf773e341..c31b533522c 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp @@ -225,8 +225,9 @@ void RegionTable_Init_GerudoFortress() { LOCATION(RC_GF_HBA_CANOPY_EAST_CRATE, logic->CanBreakCrates()), LOCATION(RC_GF_HBA_CANOPY_WEST_CRATE, logic->CanBreakCrates()), LOCATION(RC_GF_NORTH_TARGET_EAST_CRATE, logic->CanBreakCrates()), - LOCATION(RC_GF_NORTH_TARGET_WEST_CRATE, (logic->IsAdult || (logic->BlastOrSmash() || logic->HookshotOrBoomerang() || logic->CanUse(RG_HOVER_BOOTS))) && logic->CanBreakCrates()), - LOCATION(RC_GF_NORTH_TARGET_CHILD_CRATE, logic->IsChild && logic->BlastOrSmash() && logic->CanBreakCrates()), + LOCATION(RC_GF_NORTH_TARGET_WEST_CRATE, logic->IsAdult || (logic->BlastOrSmash() || logic->HookshotOrBoomerang() || logic->CanUse(RG_HOVER_BOOTS))), + //implies logic->CanBreakCrates() + LOCATION(RC_GF_NORTH_TARGET_CHILD_CRATE, logic->IsChild && logic->BlastOrSmash()), LOCATION(RC_GF_SOUTH_TARGET_EAST_CRATE, logic->CanBreakCrates()), LOCATION(RC_GF_SOUTH_TARGET_WEST_CRATE, logic->CanBreakCrates()), }, { diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp index 926266f6d87..2bdee3085cb 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp @@ -11,16 +11,6 @@ void RegionTable_Init_GerudoValley() { }, { //Locations LOCATION(RC_GV_GS_SMALL_BRIDGE, logic->IsChild && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), - LOCATION(RC_GV_ROCK_1, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_GV_ROCK_2, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_GV_ROCK_3, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_GV_UNDERWATER_ROCK_1, (logic->IsAdult && logic->HasItem(RG_POWER_BRACELET)) || logic->CanUse(RG_BOMBCHU_5)), - LOCATION(RC_GV_UNDERWATER_ROCK_2, (logic->IsAdult && logic->HasItem(RG_POWER_BRACELET)) || logic->CanUse(RG_BOMBCHU_5)), - LOCATION(RC_GV_UNDERWATER_ROCK_3, (logic->IsAdult && logic->HasItem(RG_POWER_BRACELET))|| logic->CanUse(RG_BOMBCHU_5)), - LOCATION(RC_GV_BOULDER_1, logic->IsAdult && logic->BlastOrSmash()), - LOCATION(RC_GV_BOULDER_2, logic->IsAdult && logic->BlastOrSmash()), - LOCATION(RC_GV_BRONZE_BOULDER_1, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), - LOCATION(RC_GV_BRONZE_BOULDER_2, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), }, { //Exits Entrance(RR_HYRULE_FIELD, []{return true;}), @@ -76,10 +66,7 @@ void RegionTable_Init_GerudoValley() { Entrance(RR_GV_UPPER_STREAM_WATER, []{return true;}), }); - areaTable[RR_GV_GROTTO_LEDGE] = Region("GV Grotto Ledge", SCENE_GERUDO_VALLEY, {}, { - //Locations - LOCATION(RC_GV_SILVER_BOULDER, logic->CanUse(RG_SILVER_GAUNTLETS)), - }, { + areaTable[RR_GV_GROTTO_LEDGE] = Region("GV Grotto Ledge", SCENE_GERUDO_VALLEY, {}, {}, { //Exits Entrance(RR_GV_UPPER_STREAM, []{return ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives() && logic->TakeDamage();}), Entrance(RR_GV_LOWER_STREAM, []{return logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS);}), @@ -107,17 +94,6 @@ void RegionTable_Init_GerudoValley() { LOCATION(RC_GV_CRATE_BRIDGE_2, logic->IsChild && logic->CanBreakCrates()), LOCATION(RC_GV_CRATE_BRIDGE_3, logic->IsChild && logic->CanBreakCrates()), LOCATION(RC_GV_CRATE_BRIDGE_4, logic->IsChild && logic->CanBreakCrates()), - LOCATION(RC_GV_ROCK_ACROSS_BRIDGE_1, logic->IsAdult && (logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash())), - LOCATION(RC_GV_ROCK_ACROSS_BRIDGE_2, logic->IsAdult && (logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash())), - LOCATION(RC_GV_ROCK_ACROSS_BRIDGE_3, logic->IsAdult && (logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash())), - LOCATION(RC_GV_ROCK_ACROSS_BRIDGE_4, logic->IsAdult && (logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash())), - LOCATION(RC_GV_BOULDER_ACROSS_BRIDGE, logic->IsAdult && logic->BlastOrSmash()), - LOCATION(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_1, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), - LOCATION(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_2, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), - LOCATION(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_3, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), - LOCATION(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_4, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), - LOCATION(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_5, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), - LOCATION(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_6, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), }, { //Exits Entrance(RR_GF_OUTSKIRTS, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/goron_city.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/goron_city.cpp index bd957984028..2d162294126 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/goron_city.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/goron_city.cpp @@ -35,57 +35,7 @@ void RegionTable_Init_GoronCity() { LOCATION(RC_GC_UPPER_STAIRCASE_POT_2, logic->CanBreakPots()), LOCATION(RC_GC_UPPER_STAIRCASE_POT_3, logic->CanBreakPots()), LOCATION(RC_GC_MAZE_CRATE, logic->BlastOrSmash() || (logic->CanUse(RG_SILVER_GAUNTLETS) && logic->CanBreakCrates())), - LOCATION(RC_GC_ENTRANCE_BOULDER_1, logic->BlastOrSmash()), - LOCATION(RC_GC_ENTRANCE_BOULDER_2, logic->BlastOrSmash()), - LOCATION(RC_GC_ENTRANCE_BOULDER_3, logic->BlastOrSmash()), - LOCATION(RC_GC_LW_BOULDER_1, logic->Get(LOGIC_GORON_CITY_WOODS_WARP_OPEN)), - LOCATION(RC_GC_LW_BOULDER_2, logic->Get(LOGIC_GORON_CITY_WOODS_WARP_OPEN)), - LOCATION(RC_GC_LW_BOULDER_3, logic->Get(LOGIC_GORON_CITY_WOODS_WARP_OPEN)), - LOCATION(RC_GC_MAZE_SILVER_BOULDER_1, logic->CanUse(RG_SILVER_GAUNTLETS)), - LOCATION(RC_GC_MAZE_SILVER_BOULDER_2, logic->CanUse(RG_SILVER_GAUNTLETS)), - LOCATION(RC_GC_MAZE_SILVER_BOULDER_3, logic->CanUse(RG_SILVER_GAUNTLETS)), - LOCATION(RC_GC_MAZE_SILVER_BOULDER_4, logic->CanUse(RG_SILVER_GAUNTLETS)), - LOCATION(RC_GC_MAZE_SILVER_BOULDER_5, logic->CanUse(RG_SILVER_GAUNTLETS)), - LOCATION(RC_GC_MAZE_SILVER_BOULDER_6, logic->CanUse(RG_SILVER_GAUNTLETS)), - LOCATION(RC_GC_MAZE_SILVER_BOULDER_7, logic->CanUse(RG_SILVER_GAUNTLETS)), - LOCATION(RC_GC_MAZE_SILVER_BOULDER_8, logic->CanUse(RG_SILVER_GAUNTLETS)), - LOCATION(RC_GC_MAZE_SILVER_BOULDER_9, logic->CanUse(RG_SILVER_GAUNTLETS)), - LOCATION(RC_GC_MAZE_SILVER_BOULDER_10, logic->CanUse(RG_SILVER_GAUNTLETS)), - LOCATION(RC_GC_MAZE_SILVER_BOULDER_11, logic->CanUse(RG_SILVER_GAUNTLETS)), - LOCATION(RC_GC_MAZE_SILVER_BOULDER_12, logic->CanUse(RG_SILVER_GAUNTLETS)), - LOCATION(RC_GC_MAZE_SILVER_BOULDER_13, logic->CanUse(RG_SILVER_GAUNTLETS)), - LOCATION(RC_GC_MAZE_SILVER_BOULDER_14, logic->CanUse(RG_SILVER_GAUNTLETS)), - LOCATION(RC_GC_MAZE_SILVER_BOULDER_15, logic->CanUse(RG_SILVER_GAUNTLETS)), - LOCATION(RC_GC_MAZE_SILVER_BOULDER_16, logic->CanUse(RG_SILVER_GAUNTLETS)), - LOCATION(RC_GC_MAZE_SILVER_BOULDER_17, logic->CanUse(RG_SILVER_GAUNTLETS)), - LOCATION(RC_GC_MAZE_SILVER_BOULDER_18, logic->CanUse(RG_SILVER_GAUNTLETS)), - LOCATION(RC_GC_MAZE_SILVER_BOULDER_19, logic->CanUse(RG_SILVER_GAUNTLETS)), - LOCATION(RC_GC_MAZE_SILVER_BOULDER_20, logic->CanUse(RG_SILVER_GAUNTLETS)), - LOCATION(RC_GC_MAZE_SILVER_BOULDER_21, logic->CanUse(RG_SILVER_GAUNTLETS)), - LOCATION(RC_GC_MAZE_SILVER_BOULDER_22, logic->CanUse(RG_SILVER_GAUNTLETS)), - LOCATION(RC_GC_MAZE_SILVER_BOULDER_23, logic->CanUse(RG_SILVER_GAUNTLETS)), - LOCATION(RC_GC_MAZE_SILVER_BOULDER_24, logic->CanUse(RG_SILVER_GAUNTLETS)), - LOCATION(RC_GC_MAZE_SILVER_BOULDER_25, logic->CanUse(RG_SILVER_GAUNTLETS)), - LOCATION(RC_GC_MAZE_SILVER_BOULDER_26, logic->CanUse(RG_SILVER_GAUNTLETS)), - LOCATION(RC_GC_MAZE_SILVER_BOULDER_27, logic->CanUse(RG_SILVER_GAUNTLETS)), - LOCATION(RC_GC_MAZE_SILVER_BOULDER_28, logic->CanUse(RG_SILVER_GAUNTLETS)), - LOCATION(RC_GC_MAZE_SILVER_BOULDER_29, logic->CanUse(RG_SILVER_GAUNTLETS)), - LOCATION(RC_GC_MAZE_BOULDER_1, logic->BlastOrSmash()), - LOCATION(RC_GC_MAZE_BOULDER_2, logic->BlastOrSmash()), - LOCATION(RC_GC_MAZE_BOULDER_3, logic->BlastOrSmash()), - LOCATION(RC_GC_MAZE_BOULDER_4, logic->BlastOrSmash()), - LOCATION(RC_GC_MAZE_BOULDER_5, logic->BlastOrSmash()), - LOCATION(RC_GC_MAZE_BOULDER_6, logic->BlastOrSmash()), - LOCATION(RC_GC_MAZE_BOULDER_7, logic->BlastOrSmash()), - LOCATION(RC_GC_MAZE_BOULDER_8, logic->BlastOrSmash()), - LOCATION(RC_GC_MAZE_BOULDER_9, logic->BlastOrSmash()), - LOCATION(RC_GC_MAZE_BOULDER_10, logic->BlastOrSmash()), - LOCATION(RC_GC_MAZE_BRONZE_BOULDER_1, logic->CanUse(RG_MEGATON_HAMMER)), - LOCATION(RC_GC_MAZE_BRONZE_BOULDER_2, logic->CanUse(RG_MEGATON_HAMMER)), - LOCATION(RC_GC_MAZE_BRONZE_BOULDER_3, logic->CanUse(RG_MEGATON_HAMMER)), - LOCATION(RC_GC_MAZE_BRONZE_BOULDER_4, logic->CanUse(RG_MEGATON_HAMMER)), - LOCATION(RC_GC_MAZE_BRONZE_BOULDER_5, logic->CanUse(RG_MEGATON_HAMMER)), - LOCATION(RC_GC_MAZE_ROCK, logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)), + }, { //Exits Entrance(RR_DEATH_MOUNTAIN_TRAIL, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp index 64405008676..b6fe4eb4ee4 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp @@ -32,7 +32,6 @@ void RegionTable_Init_Graveyard() { LOCATION(RC_GY_GRASS_11, logic->CanCutShrubs()), LOCATION(RC_GY_GRASS_12, logic->CanCutShrubs()), LOCATION(RC_GRAVEYARD_CRATE, ((logic->IsAdult && CanPlantBean(RR_THE_GRAVEYARD, RG_GRAVEYARD_BEAN_SOUL)) || logic->CanUse(RG_LONGSHOT)) && logic->CanBreakCrates()), - LOCATION(RC_GY_ROCK, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), }, { //Exits Entrance(RR_GRAVEYARD_SHIELD_GRAVE, []{return (logic->IsAdult || logic->AtNight) && logic->HasItem(RG_POWER_BRACELET);}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp index 83ae5e9506e..7de7da9c872 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp @@ -110,22 +110,6 @@ void RegionTable_Init_HyruleField() { LOCATION(RC_HF_CHILD_SOUTHEAST_TREE_5, logic->IsChild && logic->CanBonkTrees()), LOCATION(RC_HF_CHILD_SOUTHEAST_TREE_6, logic->IsChild && logic->CanBonkTrees()), LOCATION(RC_HF_TEKTITE_GROTTO_TREE, logic->CanBonkTrees()), - LOCATION(RC_HF_SILVER_BOULDER, logic->CanUse(RG_SILVER_GAUNTLETS)), - LOCATION(RC_HF_ROCK_1, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_HF_ROCK_2, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_HF_ROCK_3, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_HF_ROCK_4, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_HF_ROCK_5, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_HF_ROCK_6, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_HF_ROCK_7, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_HF_ROCK_8, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_HF_BOULDER_NORTH, logic->BlastOrSmash()), - LOCATION(RC_HF_BOULDER_BY_MARKET, logic->BlastOrSmash()), - LOCATION(RC_HF_BOULDER_SOUTH, logic->BlastOrSmash()), - LOCATION(RC_HF_BRONZE_BOULDER_1, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), - LOCATION(RC_HF_BRONZE_BOULDER_2, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), - LOCATION(RC_HF_BRONZE_BOULDER_3, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), - LOCATION(RC_HF_BRONZE_BOULDER_4, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), LOCATION(RC_HF_BUSH_NEAR_LAKE_1, true), LOCATION(RC_HF_BUSH_NEAR_LAKE_2, true), LOCATION(RC_HF_BUSH_NEAR_LAKE_3, true), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp index 717c013fed1..d0b14b85577 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp @@ -60,9 +60,6 @@ void RegionTable_Init_Kakariko() { LOCATION(RC_KAK_NEAR_BOARDING_HOUSE_CHILD_CRATE, logic->IsChild && logic->CanBreakCrates()), LOCATION(RC_KAK_NEAR_BAZAAR_CHILD_CRATE, logic->IsChild && logic->CanBreakCrates()), LOCATION(RC_KAK_TREE, logic->CanBonkTrees()), - LOCATION(RC_KAK_SILVER_BOULDER, logic->IsAdult && logic->CanUse(RG_SILVER_GAUNTLETS)), - LOCATION(RC_KAK_ROCK_1, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_KAK_ROCK_2, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), }, { //Exits Entrance(RR_HYRULE_FIELD, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp index 05d4a84382a..568167955e6 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp @@ -67,18 +67,6 @@ void RegionTable_Init_KokiriForest() { LOCATION(RC_KF_ADULT_GRASS_18, logic->IsAdult && logic->CanCutShrubs()), LOCATION(RC_KF_ADULT_GRASS_19, logic->IsAdult && logic->CanCutShrubs()), LOCATION(RC_KF_ADULT_GRASS_20, logic->IsAdult && logic->CanCutShrubs()), - LOCATION(RC_KF_CIRCLE_ROCK_1, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_KF_CIRCLE_ROCK_2, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_KF_CIRCLE_ROCK_3, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_KF_CIRCLE_ROCK_4, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_KF_CIRCLE_ROCK_5, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_KF_CIRCLE_ROCK_6, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_KF_CIRCLE_ROCK_7, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_KF_CIRCLE_ROCK_8, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_KF_ROCK_BY_SARIAS_HOUSE, logic->IsChild && (logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash())), - LOCATION(RC_KF_ROCK_BEHIND_SARIAS_HOUSE, logic->IsChild && (logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash())), - LOCATION(RC_KF_ROCK_BY_MIDOS_HOUSE, logic->IsChild && (logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash())), - LOCATION(RC_KF_ROCK_BY_KNOW_IT_ALLS_HOUSE, logic->IsChild && (logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash())), }, { //Exits Entrance(RR_KF_BOULDER_LOOP, []{return logic->CanUse(RG_CRAWL);}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp index 32536763ec8..1af3012febb 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp @@ -102,10 +102,7 @@ void RegionTable_Init_LakeHylia() { Entrance(RR_WATER_TEMPLE_ENTRYWAY, []{return logic->CanUse(RG_HOOKSHOT) && ((logic->CanUse(RG_IRON_BOOTS) || (ctx->GetTrickOption(RT_LH_WATER_HOOKSHOT) && logic->HasItem(RG_GOLDEN_SCALE))) || (logic->IsAdult && logic->CanUse(RG_LONGSHOT) && logic->HasItem(RG_GOLDEN_SCALE)));}), }); - areaTable[RR_LH_FISHING_ISLAND] = Region("LH Fishing Island", SCENE_LAKE_HYLIA, {}, { - //Locations - LOCATION(RC_LA_ROCK, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - }, { + areaTable[RR_LH_FISHING_ISLAND] = Region("LH Fishing Island", SCENE_LAKE_HYLIA, {}, {}, { //Exits Entrance(RR_LAKE_HYLIA, []{return logic->HasItem(RG_BRONZE_SCALE);}), Entrance(RR_LH_FISHING_POND, []{return logic->CanOpenOverworldDoor(RG_FISHING_HOLE_KEY);}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/lost_woods.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/lost_woods.cpp index b7f70e0dfb2..e54642e7544 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/lost_woods.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/lost_woods.cpp @@ -48,7 +48,6 @@ void RegionTable_Init_LostWoods() { LOCATION(RC_LW_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()), LOCATION(RC_LW_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_LW_SHORTCUT_STORMS_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)), - LOCATION(RC_LW_BOULDER_BY_GORON_CITY, logic->BlastOrSmash()), LOCATION(RC_LW_GOSSIP_STONE, true), LOCATION(RC_LW_GRASS_1, logic->CanCutShrubs()), LOCATION(RC_LW_GRASS_2, logic->CanCutShrubs()), @@ -82,8 +81,6 @@ void RegionTable_Init_LostWoods() { LOCATION(RC_LW_GRASS_7, logic->CanCutShrubs()), LOCATION(RC_LW_GRASS_8, logic->CanCutShrubs()), LOCATION(RC_LW_GRASS_9, logic->CanCutShrubs()), - LOCATION(RC_LW_BOULDER_BY_SACRED_FOREST_MEADOW, logic->BlastOrSmash()), - LOCATION(RC_LW_RUPEE_BOULDER, logic->BlastOrSmash()), }, { //Exits Entrance(RR_LW_FOREST_EXIT, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp index 984d61b8839..0f06309b8aa 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp @@ -35,14 +35,6 @@ void RegionTable_Init_ZorasDomain() { LOCATION(RC_ZD_NEAR_SHOP_POT_3, logic->CanBreakPots()), LOCATION(RC_ZD_NEAR_SHOP_POT_4, logic->CanBreakPots()), LOCATION(RC_ZD_NEAR_SHOP_POT_5, logic->CanBreakPots()), - LOCATION(RC_ZD_CIRCLE_ROCK_1, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_ZD_CIRCLE_ROCK_2, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_ZD_CIRCLE_ROCK_3, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_ZD_CIRCLE_ROCK_4, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_ZD_CIRCLE_ROCK_5, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_ZD_CIRCLE_ROCK_6, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_ZD_CIRCLE_ROCK_7, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_ZD_CIRCLE_ROCK_8, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), }, { //Exits Entrance(RR_ZR_BEHIND_WATERFALL, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp index f43308ab7c4..7f7d543f135 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp @@ -23,9 +23,6 @@ void RegionTable_Init_ZorasFountain() { 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_TREE, logic->IsChild && logic->CanBonkTrees()), - LOCATION(RC_ZF_BOULDER, logic->BlastOrSmash()), - LOCATION(RC_ZF_SILVER_BOULDER, logic->CanUse(RG_SILVER_GAUNTLETS)), - LOCATION(RC_ZF_UNDERGROUND_BOULDER, logic->CanUse(RG_SILVER_GAUNTLETS) && logic->BlastOrSmash()), LOCATION(RC_ZF_BUSH_1, logic->IsChild), LOCATION(RC_ZF_BUSH_2, logic->IsChild), LOCATION(RC_ZF_BUSH_3, logic->IsChild), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp index ff1eaea9e32..5065c78ee23 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp @@ -7,24 +7,20 @@ void RegionTable_Init_ZoraRiver() { // clang-format off areaTable[RR_ZR_FRONT] = Region("ZR Front", SCENE_ZORAS_RIVER, {}, { //Locations - LOCATION(RC_ZR_GS_TREE, logic->IsChild && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_CLOSE) && logic->CanBonkTrees()), - LOCATION(RC_ZR_GRASS_1, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_2, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_3, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_4, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_5, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_6, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_7, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_8, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_9, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_10, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_11, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_12, logic->CanCutShrubs()), - LOCATION(RC_ZR_TREE, logic->IsChild && logic->CanBonkTrees()), - LOCATION(RC_ZR_BOULDER_1, logic->IsChild && logic->BlastOrSmash()), - LOCATION(RC_ZR_BOULDER_2, logic->IsChild && logic->BlastOrSmash()), - LOCATION(RC_ZR_BOULDER_3, logic->IsChild && logic->BlastOrSmash()), - LOCATION(RC_ZR_BOULDER_4, logic->IsChild && logic->BlastOrSmash()), + LOCATION(RC_ZR_GS_TREE, logic->IsChild && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_CLOSE) && logic->CanBonkTrees()), + LOCATION(RC_ZR_GRASS_1, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_2, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_3, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_4, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_5, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_6, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_7, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_8, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_9, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_10, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_11, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_12, logic->CanCutShrubs()), + LOCATION(RC_ZR_TREE, logic->IsChild && logic->CanBonkTrees()), }, { //Exits Entrance(RR_ZORAS_RIVER, []{return logic->IsAdult || logic->BlastOrSmash();}), @@ -58,28 +54,6 @@ void RegionTable_Init_ZoraRiver() { 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_CIRCLE_ROCK_1, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_ZR_CIRCLE_ROCK_2, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_ZR_CIRCLE_ROCK_3, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_ZR_CIRCLE_ROCK_4, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_ZR_CIRCLE_ROCK_5, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_ZR_CIRCLE_ROCK_6, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_ZR_CIRCLE_ROCK_7, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_ZR_CIRCLE_ROCK_8, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_ZR_UPPER_CIRCLE_BOULDER, logic->BlastOrSmash()), - LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_1, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_2, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_3, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_4, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_5, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_6, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_7, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_8, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_ZR_ROCK, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), - LOCATION(RC_ZR_UNDERWATER_ROCK_1, (logic->IsAdult && logic->HasItem(RG_POWER_BRACELET)) || logic->CanUse(RG_BOMBCHU_5)), - LOCATION(RC_ZR_UNDERWATER_ROCK_2, (logic->IsAdult && logic->HasItem(RG_POWER_BRACELET)) || logic->CanUse(RG_BOMBCHU_5)), - LOCATION(RC_ZR_UNDERWATER_ROCK_3, (logic->IsAdult && logic->HasItem(RG_POWER_BRACELET)) || logic->CanUse(RG_BOMBCHU_5)), - LOCATION(RC_ZR_UNDERWATER_ROCK_4, logic->IsAdult || logic->CanUse(RG_BOMBCHU_5)), LOCATION(RC_ZR_NEAR_DOMAIN_GOSSIP_STONE, true), LOCATION(RC_ZR_NEAR_FREESTANDING_POH_GRASS, logic->CanUse(RG_BOOMERANG)), }, { diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index 400119233d6..28f7ad3a0fc 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -253,18 +253,14 @@ bool Logic::HasItem(RandomizerGet itemName) { return CurrentUpgrade(UPG_SCALE) >= 1; case RG_GOLDEN_SCALE: return CurrentUpgrade(UPG_SCALE) >= 2; - case RG_CLIMB: return CheckRandoInf(RAND_INF_CAN_CLIMB); - case RG_ROLL: - return CheckRandoInf(RAND_INF_CAN_ROLL); case RG_CRAWL: return CheckRandoInf(RAND_INF_CAN_CRAWL); case RG_ROLL: return CheckRandoInf(RAND_INF_CAN_ROLL); case RG_OPEN_CHEST: return CheckRandoInf(RAND_INF_CAN_OPEN_CHEST); - case RG_POCKET_EGG: return CheckRandoInf(RAND_INF_ADULT_TRADES_HAS_POCKET_EGG) || CheckRandoInf(RAND_INF_ADULT_TRADES_HAS_POCKET_CUCCO); @@ -1769,9 +1765,6 @@ void Logic::ApplyItemEffect(Item& item, bool state) { case RG_CLIMB: SetRandoInf(RAND_INF_CAN_CLIMB, state); break; - case RG_ROLL: - SetRandoInf(RAND_INF_CAN_ROLL, state); - break; case RG_CRAWL: SetRandoInf(RAND_INF_CAN_CRAWL, state); break; @@ -2681,11 +2674,6 @@ void Logic::Reset(bool resetSaveContext /*= true*/) { SetRandoInf(RAND_INF_CAN_CLIMB, true); } - // If we're not shuffling roll, we start with it - if (ctx->GetOption(RSK_SHUFFLE_ROLL).Is(false)) { - SetRandoInf(RAND_INF_CAN_ROLL, true); - } - // If we're not shuffling crawl, we start with it if (ctx->GetOption(RSK_SHUFFLE_CRAWL).Is(false)) { SetRandoInf(RAND_INF_CAN_CRAWL, true); diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp index ba9d0b46eee..d7f9b0f243d 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -261,7 +261,6 @@ void Settings::CreateOptionDescriptions() { mOptionDescriptions[RSK_SHUFFLE_GRAB] = "Shuffle the ability to grab as a progressive upgrade before Goron Bracelet."; mOptionDescriptions[RSK_SHUFFLE_CLIMB] = "Shuffle the ability to climb ladders into the item pool."; - mOptionDescriptions[RSK_SHUFFLE_ROLL] = "Shuffles the ability do a roll into the item pool."; mOptionDescriptions[RSK_SHUFFLE_CRAWL] = "Shuffles the ability to use crawlspaces into the item pool."; mOptionDescriptions[RSK_SHUFFLE_ROLL] = "Shuffles the ability do a roll into the item pool."; mOptionDescriptions[RSK_SHUFFLE_OPEN_CHEST] = "Shuffles the ability to open chests into the item pool."; @@ -517,8 +516,6 @@ void Settings::CreateOptionDescriptions() { "Overworld - Only shuffle grass/bushes that are outside of dungeons.\n" "\n" "All Grass/Bushes - Shuffle all grass/bushes."; - mOptionDescriptions[RSK_SHUFFLE_ROCKS] = "Shuffle rock locations."; - mOptionDescriptions[RSK_SHUFFLE_BOULDERS] = "Shuffle boulder locations."; mOptionDescriptions[RSK_SHUFFLE_DUNGEON_REWARDS] = "Shuffles the location of Spiritual Stones and medallions.\n" "Vanilla - Spiritual Stones and medallions will be given from their respective boss.\n" diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 568273acbb8..affc1c4978f 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -2916,286 +2916,6 @@ std::map rcToRandomizerInf = { { RC_ZR_TREE, RAND_INF_ZR_TREE }, { RC_KAK_TREE, RAND_INF_KAK_TREE }, { RC_LLR_TREE, RAND_INF_LLR_TREE }, - { RC_KF_CIRCLE_ROCK_1, RAND_INF_KF_CIRCLE_ROCK_1 }, - { RC_KF_CIRCLE_ROCK_2, RAND_INF_KF_CIRCLE_ROCK_2 }, - { RC_KF_CIRCLE_ROCK_3, RAND_INF_KF_CIRCLE_ROCK_3 }, - { RC_KF_CIRCLE_ROCK_4, RAND_INF_KF_CIRCLE_ROCK_4 }, - { RC_KF_CIRCLE_ROCK_5, RAND_INF_KF_CIRCLE_ROCK_5 }, - { RC_KF_CIRCLE_ROCK_6, RAND_INF_KF_CIRCLE_ROCK_6 }, - { RC_KF_CIRCLE_ROCK_7, RAND_INF_KF_CIRCLE_ROCK_7 }, - { RC_KF_CIRCLE_ROCK_8, RAND_INF_KF_CIRCLE_ROCK_8 }, - { RC_KF_ROCK_BY_SARIAS_HOUSE, RAND_INF_KF_ROCK_BY_SARIAS_HOUSE }, - { RC_KF_ROCK_BEHIND_SARIAS_HOUSE, RAND_INF_KF_ROCK_BEHIND_SARIAS_HOUSE }, - { RC_KF_ROCK_BY_MIDOS_HOUSE, RAND_INF_KF_ROCK_BY_MIDOS_HOUSE }, - { RC_KF_ROCK_BY_KNOW_IT_ALLS_HOUSE, RAND_INF_KF_ROCK_BY_KNOW_IT_ALLS_HOUSE }, - { RC_LW_BOULDER_BY_GORON_CITY, RAND_INF_LW_BOULDER_BY_GORON_CITY }, - { RC_LW_BOULDER_BY_SACRED_FOREST_MEADOW, RAND_INF_LW_BOULDER_BY_SACRED_FOREST_MEADOW }, - { RC_LW_RUPEE_BOULDER, RAND_INF_LW_RUPEE_BOULDER }, - { RC_HC_ROCK_1, RAND_INF_HC_ROCK_1 }, - { RC_HC_ROCK_2, RAND_INF_HC_ROCK_2 }, - { RC_HC_ROCK_3, RAND_INF_HC_ROCK_3 }, - { RC_HC_BOULDER, RAND_INF_HC_BOULDER }, - { RC_OGC_BRONZE_BOULDER_1, RAND_INF_OGC_BRONZE_BOULDER_1 }, - { RC_OGC_BRONZE_BOULDER_2, RAND_INF_OGC_BRONZE_BOULDER_2 }, - { RC_OGC_BRONZE_BOULDER_3, RAND_INF_OGC_BRONZE_BOULDER_3 }, - { RC_OGC_SILVER_BOULDER_1, RAND_INF_OGC_SILVER_BOULDER_1 }, - { RC_OGC_SILVER_BOULDER_2, RAND_INF_OGC_SILVER_BOULDER_2 }, - { RC_OGC_SILVER_BOULDER_3, RAND_INF_OGC_SILVER_BOULDER_3 }, - { RC_OGC_SILVER_BOULDER_4, RAND_INF_OGC_SILVER_BOULDER_4 }, - { RC_DMC_CIRCLE_ROCK_1, RAND_INF_DMC_CIRCLE_ROCK_1 }, - { RC_DMC_CIRCLE_ROCK_2, RAND_INF_DMC_CIRCLE_ROCK_2 }, - { RC_DMC_CIRCLE_ROCK_3, RAND_INF_DMC_CIRCLE_ROCK_3 }, - { RC_DMC_CIRCLE_ROCK_4, RAND_INF_DMC_CIRCLE_ROCK_4 }, - { RC_DMC_CIRCLE_ROCK_5, RAND_INF_DMC_CIRCLE_ROCK_5 }, - { RC_DMC_CIRCLE_ROCK_6, RAND_INF_DMC_CIRCLE_ROCK_6 }, - { RC_DMC_CIRCLE_ROCK_7, RAND_INF_DMC_CIRCLE_ROCK_7 }, - { RC_DMC_CIRCLE_ROCK_8, RAND_INF_DMC_CIRCLE_ROCK_8 }, - { RC_DMC_ROCK_BY_FIRE_TEMPLE_1, RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_1 }, - { RC_DMC_ROCK_BY_FIRE_TEMPLE_2, RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_2 }, - { RC_DMC_ROCK_BY_FIRE_TEMPLE_3, RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_3 }, - { RC_DMC_ROCK_BY_FIRE_TEMPLE_4, RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_4 }, - { RC_DMC_ROCK_BY_FIRE_TEMPLE_5, RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_5 }, - { RC_DMC_GOSSIP_ROCK_1, RAND_INF_DMC_GOSSIP_ROCK_1 }, - { RC_DMC_GOSSIP_ROCK_2, RAND_INF_DMC_GOSSIP_ROCK_2 }, - { RC_DMC_BOULDER_1, RAND_INF_DMC_BOULDER_1 }, - { RC_DMC_BOULDER_2, RAND_INF_DMC_BOULDER_2 }, - { RC_DMC_BOULDER_3, RAND_INF_DMC_BOULDER_3 }, - { RC_DMC_BRONZE_BOULDER_1, RAND_INF_DMC_BRONZE_BOULDER_1 }, - { RC_DMC_BRONZE_BOULDER_2, RAND_INF_DMC_BRONZE_BOULDER_2 }, - { RC_DMC_BRONZE_BOULDER_3, RAND_INF_DMC_BRONZE_BOULDER_3 }, - { RC_DMC_BRONZE_BOULDER_4, RAND_INF_DMC_BRONZE_BOULDER_4 }, - { RC_GV_SILVER_BOULDER, RAND_INF_GV_SILVER_BOULDER }, - { RC_GV_ROCK_1, RAND_INF_GV_ROCK_1 }, - { RC_GV_ROCK_2, RAND_INF_GV_ROCK_2 }, - { RC_GV_ROCK_3, RAND_INF_GV_ROCK_3 }, - { RC_GV_UNDERWATER_ROCK_1, RAND_INF_GV_UNDERWATER_ROCK_1 }, - { RC_GV_UNDERWATER_ROCK_2, RAND_INF_GV_UNDERWATER_ROCK_2 }, - { RC_GV_UNDERWATER_ROCK_3, RAND_INF_GV_UNDERWATER_ROCK_3 }, - { RC_GV_ROCK_ACROSS_BRIDGE_1, RAND_INF_GV_ROCK_ACROSS_BRIDGE_1 }, - { RC_GV_ROCK_ACROSS_BRIDGE_2, RAND_INF_GV_ROCK_ACROSS_BRIDGE_2 }, - { RC_GV_ROCK_ACROSS_BRIDGE_3, RAND_INF_GV_ROCK_ACROSS_BRIDGE_3 }, - { RC_GV_ROCK_ACROSS_BRIDGE_4, RAND_INF_GV_ROCK_ACROSS_BRIDGE_4 }, - { RC_GV_BOULDER_1, RAND_INF_GV_BOULDER_1 }, - { RC_GV_BOULDER_2, RAND_INF_GV_BOULDER_2 }, - { RC_GV_BOULDER_ACROSS_BRIDGE, RAND_INF_GV_BOULDER_ACROSS_BRIDGE }, - { RC_GV_BRONZE_BOULDER_1, RAND_INF_GV_BRONZE_BOULDER_1 }, - { RC_GV_BRONZE_BOULDER_2, RAND_INF_GV_BRONZE_BOULDER_2 }, - { RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_1, RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_1 }, - { RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_2, RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_2 }, - { RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_3, RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_3 }, - { RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_4, RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_4 }, - { RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_5, RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_5 }, - { RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_6, RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_6 }, - { RC_HF_SILVER_BOULDER, RAND_INF_HF_SILVER_BOULDER }, - { RC_HF_ROCK_1, RAND_INF_HF_ROCK_1 }, - { RC_HF_ROCK_2, RAND_INF_HF_ROCK_2 }, - { RC_HF_ROCK_3, RAND_INF_HF_ROCK_3 }, - { RC_HF_ROCK_4, RAND_INF_HF_ROCK_4 }, - { RC_HF_ROCK_5, RAND_INF_HF_ROCK_5 }, - { RC_HF_ROCK_6, RAND_INF_HF_ROCK_6 }, - { RC_HF_ROCK_7, RAND_INF_HF_ROCK_7 }, - { RC_HF_ROCK_8, RAND_INF_HF_ROCK_8 }, - { RC_HF_BOULDER_NORTH, RAND_INF_HF_BOULDER_NORTH }, - { RC_HF_BOULDER_BY_MARKET, RAND_INF_HF_BOULDER_BY_MARKET }, - { RC_HF_BOULDER_SOUTH, RAND_INF_HF_BOULDER_SOUTH }, - { RC_HF_BRONZE_BOULDER_1, RAND_INF_HF_BRONZE_BOULDER_1 }, - { RC_HF_BRONZE_BOULDER_2, RAND_INF_HF_BRONZE_BOULDER_2 }, - { RC_HF_BRONZE_BOULDER_3, RAND_INF_HF_BRONZE_BOULDER_3 }, - { RC_HF_BRONZE_BOULDER_4, RAND_INF_HF_BRONZE_BOULDER_4 }, - { RC_KAK_SILVER_BOULDER, RAND_INF_KAK_SILVER_BOULDER }, - { RC_KAK_ROCK_1, RAND_INF_KAK_ROCK_1 }, - { RC_KAK_ROCK_2, RAND_INF_KAK_ROCK_2 }, - { RC_GY_ROCK, RAND_INF_GY_ROCK }, - { RC_LA_ROCK, RAND_INF_LA_ROCK }, - { RC_ZD_CIRCLE_ROCK_1, RAND_INF_ZD_CIRCLE_ROCK_1 }, - { RC_ZD_CIRCLE_ROCK_2, RAND_INF_ZD_CIRCLE_ROCK_2 }, - { RC_ZD_CIRCLE_ROCK_3, RAND_INF_ZD_CIRCLE_ROCK_3 }, - { RC_ZD_CIRCLE_ROCK_4, RAND_INF_ZD_CIRCLE_ROCK_4 }, - { RC_ZD_CIRCLE_ROCK_5, RAND_INF_ZD_CIRCLE_ROCK_5 }, - { RC_ZD_CIRCLE_ROCK_6, RAND_INF_ZD_CIRCLE_ROCK_6 }, - { RC_ZD_CIRCLE_ROCK_7, RAND_INF_ZD_CIRCLE_ROCK_7 }, - { RC_ZD_CIRCLE_ROCK_8, RAND_INF_ZD_CIRCLE_ROCK_8 }, - { RC_ZF_BOULDER, RAND_INF_ZF_BOULDER }, - { RC_ZF_SILVER_BOULDER, RAND_INF_ZF_SILVER_BOULDER }, - { RC_ZF_UNDERGROUND_BOULDER, RAND_INF_ZF_UNDERGROUND_BOULDER }, - { RC_ZR_BOULDER_1, RAND_INF_ZR_BOULDER_1 }, - { RC_ZR_BOULDER_2, RAND_INF_ZR_BOULDER_2 }, - { RC_ZR_BOULDER_3, RAND_INF_ZR_BOULDER_3 }, - { RC_ZR_BOULDER_4, RAND_INF_ZR_BOULDER_4 }, - { RC_ZR_CIRCLE_ROCK_1, RAND_INF_ZR_CIRCLE_ROCK_1 }, - { RC_ZR_CIRCLE_ROCK_2, RAND_INF_ZR_CIRCLE_ROCK_2 }, - { RC_ZR_CIRCLE_ROCK_3, RAND_INF_ZR_CIRCLE_ROCK_3 }, - { RC_ZR_CIRCLE_ROCK_4, RAND_INF_ZR_CIRCLE_ROCK_4 }, - { RC_ZR_CIRCLE_ROCK_5, RAND_INF_ZR_CIRCLE_ROCK_5 }, - { RC_ZR_CIRCLE_ROCK_6, RAND_INF_ZR_CIRCLE_ROCK_6 }, - { RC_ZR_CIRCLE_ROCK_7, RAND_INF_ZR_CIRCLE_ROCK_7 }, - { RC_ZR_CIRCLE_ROCK_8, RAND_INF_ZR_CIRCLE_ROCK_8 }, - { RC_ZR_UPPER_CIRCLE_BOULDER, RAND_INF_ZR_UPPER_CIRCLE_BOULDER }, - { RC_ZR_UPPER_CIRCLE_ROCK_1, RAND_INF_ZR_UPPER_CIRCLE_ROCK_1 }, - { RC_ZR_UPPER_CIRCLE_ROCK_2, RAND_INF_ZR_UPPER_CIRCLE_ROCK_2 }, - { RC_ZR_UPPER_CIRCLE_ROCK_3, RAND_INF_ZR_UPPER_CIRCLE_ROCK_3 }, - { RC_ZR_UPPER_CIRCLE_ROCK_4, RAND_INF_ZR_UPPER_CIRCLE_ROCK_4 }, - { RC_ZR_UPPER_CIRCLE_ROCK_5, RAND_INF_ZR_UPPER_CIRCLE_ROCK_5 }, - { RC_ZR_UPPER_CIRCLE_ROCK_6, RAND_INF_ZR_UPPER_CIRCLE_ROCK_6 }, - { RC_ZR_UPPER_CIRCLE_ROCK_7, RAND_INF_ZR_UPPER_CIRCLE_ROCK_7 }, - { RC_ZR_UPPER_CIRCLE_ROCK_8, RAND_INF_ZR_UPPER_CIRCLE_ROCK_8 }, - { RC_ZR_ROCK, RAND_INF_ZR_ROCK }, - { RC_ZR_UNDERWATER_ROCK_1, RAND_INF_ZR_UNDERWATER_ROCK_1 }, - { RC_ZR_UNDERWATER_ROCK_2, RAND_INF_ZR_UNDERWATER_ROCK_2 }, - { RC_ZR_UNDERWATER_ROCK_3, RAND_INF_ZR_UNDERWATER_ROCK_3 }, - { RC_ZR_UNDERWATER_ROCK_4, RAND_INF_ZR_UNDERWATER_ROCK_4 }, - { RC_DMT_ROCK_1, RAND_INF_DMT_ROCK_1 }, - { RC_DMT_ROCK_2, RAND_INF_DMT_ROCK_2 }, - { RC_DMT_ROCK_3, RAND_INF_DMT_ROCK_3 }, - { RC_DMT_ROCK_4, RAND_INF_DMT_ROCK_4 }, - { RC_DMT_ROCK_5, RAND_INF_DMT_ROCK_5 }, - { RC_DMT_SUMMIT_ROCK, RAND_INF_DMT_SUMMIT_ROCK }, - { RC_DMT_CIRCLE_ROCK_1, RAND_INF_DMT_CIRCLE_ROCK_1 }, - { RC_DMT_CIRCLE_ROCK_2, RAND_INF_DMT_CIRCLE_ROCK_2 }, - { RC_DMT_CIRCLE_ROCK_3, RAND_INF_DMT_CIRCLE_ROCK_3 }, - { RC_DMT_CIRCLE_ROCK_4, RAND_INF_DMT_CIRCLE_ROCK_4 }, - { RC_DMT_CIRCLE_ROCK_5, RAND_INF_DMT_CIRCLE_ROCK_5 }, - { RC_DMT_CIRCLE_ROCK_6, RAND_INF_DMT_CIRCLE_ROCK_6 }, - { RC_DMT_CIRCLE_ROCK_7, RAND_INF_DMT_CIRCLE_ROCK_7 }, - { RC_DMT_CIRCLE_ROCK_8, RAND_INF_DMT_CIRCLE_ROCK_8 }, - { RC_DMT_BOULDER_1, RAND_INF_DMT_BOULDER_1 }, - { RC_DMT_BOULDER_2, RAND_INF_DMT_BOULDER_2 }, - { RC_DMT_BOULDER_3, RAND_INF_DMT_BOULDER_3 }, - { RC_DMT_COW_BOULDER, RAND_INF_DMT_COW_BOULDER }, - { RC_DMT_BRONZE_BOULDER_1, RAND_INF_DMT_BRONZE_BOULDER_1 }, - { RC_DMT_BRONZE_BOULDER_2, RAND_INF_DMT_BRONZE_BOULDER_2 }, - { RC_DMT_BRONZE_BOULDER_3, RAND_INF_DMT_BRONZE_BOULDER_3 }, - { RC_DMT_BRONZE_BOULDER_4, RAND_INF_DMT_BRONZE_BOULDER_4 }, - { RC_DMT_BRONZE_BOULDER_5, RAND_INF_DMT_BRONZE_BOULDER_5 }, - { RC_DMT_BRONZE_BOULDER_6, RAND_INF_DMT_BRONZE_BOULDER_6 }, - { RC_DMT_BRONZE_BOULDER_7, RAND_INF_DMT_BRONZE_BOULDER_7 }, - { RC_DMT_BRONZE_BOULDER_8, RAND_INF_DMT_BRONZE_BOULDER_8 }, - { RC_DMT_BRONZE_BOULDER_9, RAND_INF_DMT_BRONZE_BOULDER_9 }, - { RC_DMT_BRONZE_BOULDER_10, RAND_INF_DMT_BRONZE_BOULDER_10 }, - { RC_DMT_BRONZE_BOULDER_11, RAND_INF_DMT_BRONZE_BOULDER_11 }, - { RC_GC_LW_BOULDER_1, RAND_INF_GC_LW_BOULDER_1 }, - { RC_GC_LW_BOULDER_2, RAND_INF_GC_LW_BOULDER_2 }, - { RC_GC_LW_BOULDER_3, RAND_INF_GC_LW_BOULDER_3 }, - { RC_GC_ENTRANCE_BOULDER_1, RAND_INF_GC_ENTRANCE_BOULDER_1 }, - { RC_GC_ENTRANCE_BOULDER_2, RAND_INF_GC_ENTRANCE_BOULDER_2 }, - { RC_GC_ENTRANCE_BOULDER_3, RAND_INF_GC_ENTRANCE_BOULDER_3 }, - { RC_GC_MAZE_SILVER_BOULDER_1, RAND_INF_GC_MAZE_SILVER_BOULDER_1 }, - { RC_GC_MAZE_SILVER_BOULDER_2, RAND_INF_GC_MAZE_SILVER_BOULDER_2 }, - { RC_GC_MAZE_SILVER_BOULDER_3, RAND_INF_GC_MAZE_SILVER_BOULDER_3 }, - { RC_GC_MAZE_SILVER_BOULDER_4, RAND_INF_GC_MAZE_SILVER_BOULDER_4 }, - { RC_GC_MAZE_SILVER_BOULDER_5, RAND_INF_GC_MAZE_SILVER_BOULDER_5 }, - { RC_GC_MAZE_SILVER_BOULDER_6, RAND_INF_GC_MAZE_SILVER_BOULDER_6 }, - { RC_GC_MAZE_SILVER_BOULDER_7, RAND_INF_GC_MAZE_SILVER_BOULDER_7 }, - { RC_GC_MAZE_SILVER_BOULDER_8, RAND_INF_GC_MAZE_SILVER_BOULDER_8 }, - { RC_GC_MAZE_SILVER_BOULDER_9, RAND_INF_GC_MAZE_SILVER_BOULDER_9 }, - { RC_GC_MAZE_SILVER_BOULDER_10, RAND_INF_GC_MAZE_SILVER_BOULDER_10 }, - { RC_GC_MAZE_SILVER_BOULDER_11, RAND_INF_GC_MAZE_SILVER_BOULDER_11 }, - { RC_GC_MAZE_SILVER_BOULDER_12, RAND_INF_GC_MAZE_SILVER_BOULDER_12 }, - { RC_GC_MAZE_SILVER_BOULDER_13, RAND_INF_GC_MAZE_SILVER_BOULDER_13 }, - { RC_GC_MAZE_SILVER_BOULDER_14, RAND_INF_GC_MAZE_SILVER_BOULDER_14 }, - { RC_GC_MAZE_SILVER_BOULDER_15, RAND_INF_GC_MAZE_SILVER_BOULDER_15 }, - { RC_GC_MAZE_SILVER_BOULDER_16, RAND_INF_GC_MAZE_SILVER_BOULDER_16 }, - { RC_GC_MAZE_SILVER_BOULDER_17, RAND_INF_GC_MAZE_SILVER_BOULDER_17 }, - { RC_GC_MAZE_SILVER_BOULDER_18, RAND_INF_GC_MAZE_SILVER_BOULDER_18 }, - { RC_GC_MAZE_SILVER_BOULDER_19, RAND_INF_GC_MAZE_SILVER_BOULDER_19 }, - { RC_GC_MAZE_SILVER_BOULDER_20, RAND_INF_GC_MAZE_SILVER_BOULDER_20 }, - { RC_GC_MAZE_SILVER_BOULDER_21, RAND_INF_GC_MAZE_SILVER_BOULDER_21 }, - { RC_GC_MAZE_SILVER_BOULDER_22, RAND_INF_GC_MAZE_SILVER_BOULDER_22 }, - { RC_GC_MAZE_SILVER_BOULDER_23, RAND_INF_GC_MAZE_SILVER_BOULDER_23 }, - { RC_GC_MAZE_SILVER_BOULDER_24, RAND_INF_GC_MAZE_SILVER_BOULDER_24 }, - { RC_GC_MAZE_SILVER_BOULDER_25, RAND_INF_GC_MAZE_SILVER_BOULDER_25 }, - { RC_GC_MAZE_SILVER_BOULDER_26, RAND_INF_GC_MAZE_SILVER_BOULDER_26 }, - { RC_GC_MAZE_SILVER_BOULDER_27, RAND_INF_GC_MAZE_SILVER_BOULDER_27 }, - { RC_GC_MAZE_SILVER_BOULDER_28, RAND_INF_GC_MAZE_SILVER_BOULDER_28 }, - { RC_GC_MAZE_SILVER_BOULDER_29, RAND_INF_GC_MAZE_SILVER_BOULDER_29 }, - { RC_GC_MAZE_BOULDER_1, RAND_INF_GC_MAZE_BOULDER_1 }, - { RC_GC_MAZE_BOULDER_2, RAND_INF_GC_MAZE_BOULDER_2 }, - { RC_GC_MAZE_BOULDER_3, RAND_INF_GC_MAZE_BOULDER_3 }, - { RC_GC_MAZE_BOULDER_4, RAND_INF_GC_MAZE_BOULDER_4 }, - { RC_GC_MAZE_BOULDER_5, RAND_INF_GC_MAZE_BOULDER_5 }, - { RC_GC_MAZE_BOULDER_6, RAND_INF_GC_MAZE_BOULDER_6 }, - { RC_GC_MAZE_BOULDER_7, RAND_INF_GC_MAZE_BOULDER_7 }, - { RC_GC_MAZE_BOULDER_8, RAND_INF_GC_MAZE_BOULDER_8 }, - { RC_GC_MAZE_BOULDER_9, RAND_INF_GC_MAZE_BOULDER_9 }, - { RC_GC_MAZE_BOULDER_10, RAND_INF_GC_MAZE_BOULDER_10 }, - { RC_GC_MAZE_BRONZE_BOULDER_1, RAND_INF_GC_MAZE_BRONZE_BOULDER_1 }, - { RC_GC_MAZE_BRONZE_BOULDER_2, RAND_INF_GC_MAZE_BRONZE_BOULDER_2 }, - { RC_GC_MAZE_BRONZE_BOULDER_3, RAND_INF_GC_MAZE_BRONZE_BOULDER_3 }, - { RC_GC_MAZE_BRONZE_BOULDER_4, RAND_INF_GC_MAZE_BRONZE_BOULDER_4 }, - { RC_GC_MAZE_BRONZE_BOULDER_5, RAND_INF_GC_MAZE_BRONZE_BOULDER_5 }, - { RC_GC_MAZE_ROCK, RAND_INF_GC_MAZE_ROCK }, - { RC_COLOSSUS_SILVER_BOULDER, RAND_INF_COLOSSUS_SILVER_BOULDER }, - { RC_COLOSSUS_ROCK, RAND_INF_COLOSSUS_ROCK }, - { RC_COLOSSUS_CIRCLE_1_ROCK_1, RAND_INF_COLOSSUS_CIRCLE_1_ROCK_1 }, - { RC_COLOSSUS_CIRCLE_1_ROCK_2, RAND_INF_COLOSSUS_CIRCLE_1_ROCK_2 }, - { RC_COLOSSUS_CIRCLE_1_ROCK_3, RAND_INF_COLOSSUS_CIRCLE_1_ROCK_3 }, - { RC_COLOSSUS_CIRCLE_1_ROCK_4, RAND_INF_COLOSSUS_CIRCLE_1_ROCK_4 }, - { RC_COLOSSUS_CIRCLE_1_ROCK_5, RAND_INF_COLOSSUS_CIRCLE_1_ROCK_5 }, - { RC_COLOSSUS_CIRCLE_1_ROCK_6, RAND_INF_COLOSSUS_CIRCLE_1_ROCK_6 }, - { RC_COLOSSUS_CIRCLE_1_ROCK_7, RAND_INF_COLOSSUS_CIRCLE_1_ROCK_7 }, - { RC_COLOSSUS_CIRCLE_1_ROCK_8, RAND_INF_COLOSSUS_CIRCLE_1_ROCK_8 }, - { RC_COLOSSUS_CIRCLE_2_ROCK_1, RAND_INF_COLOSSUS_CIRCLE_2_ROCK_1 }, - { RC_COLOSSUS_CIRCLE_2_ROCK_2, RAND_INF_COLOSSUS_CIRCLE_2_ROCK_2 }, - { RC_COLOSSUS_CIRCLE_2_ROCK_3, RAND_INF_COLOSSUS_CIRCLE_2_ROCK_3 }, - { RC_COLOSSUS_CIRCLE_2_ROCK_4, RAND_INF_COLOSSUS_CIRCLE_2_ROCK_4 }, - { RC_COLOSSUS_CIRCLE_2_ROCK_5, RAND_INF_COLOSSUS_CIRCLE_2_ROCK_5 }, - { RC_COLOSSUS_CIRCLE_2_ROCK_6, RAND_INF_COLOSSUS_CIRCLE_2_ROCK_6 }, - { RC_COLOSSUS_CIRCLE_2_ROCK_7, RAND_INF_COLOSSUS_CIRCLE_2_ROCK_7 }, - { RC_COLOSSUS_CIRCLE_2_ROCK_8, RAND_INF_COLOSSUS_CIRCLE_2_ROCK_8 }, - { RC_HC_STORMS_GROTTO_ROCK_1, RAND_INF_HC_STORMS_GROTTO_ROCK_1 }, - { RC_HC_STORMS_GROTTO_ROCK_2, RAND_INF_HC_STORMS_GROTTO_ROCK_2 }, - { RC_HC_STORMS_GROTTO_ROCK_3, RAND_INF_HC_STORMS_GROTTO_ROCK_3 }, - { RC_HC_STORMS_GROTTO_ROCK_4, RAND_INF_HC_STORMS_GROTTO_ROCK_4 }, - { RC_HC_STORMS_GROTTO_ROCK_5, RAND_INF_HC_STORMS_GROTTO_ROCK_5 }, - { RC_HC_STORMS_GROTTO_ROCK_6, RAND_INF_HC_STORMS_GROTTO_ROCK_6 }, - { RC_HC_STORMS_GROTTO_ROCK_7, RAND_INF_HC_STORMS_GROTTO_ROCK_7 }, - { RC_HC_STORMS_GROTTO_ROCK_8, RAND_INF_HC_STORMS_GROTTO_ROCK_8 }, - { RC_BOTW_BOULDER_1, RAND_INF_BOTW_BOULDER_1 }, - { RC_BOTW_BOULDER_2, RAND_INF_BOTW_BOULDER_2 }, - { RC_BOTW_BOULDER_3, RAND_INF_BOTW_BOULDER_3 }, - { RC_BOTW_BOULDER_4, RAND_INF_BOTW_BOULDER_4 }, - { RC_BOTW_BOULDER_5, RAND_INF_BOTW_BOULDER_5 }, - { RC_BOTW_BOULDER_6, RAND_INF_BOTW_BOULDER_6 }, - { RC_DEKU_TREE_MQ_BOULDER_1, RAND_INF_DEKU_TREE_MQ_BOULDER_1 }, - { RC_DEKU_TREE_MQ_BOULDER_2, RAND_INF_DEKU_TREE_MQ_BOULDER_2 }, - { RC_DEKU_TREE_MQ_BOULDER_3, RAND_INF_DEKU_TREE_MQ_BOULDER_3 }, - { RC_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_1, RAND_INF_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_1 }, - { RC_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_2, RAND_INF_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_2 }, - { RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_1, RAND_INF_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_1 }, - { RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_2, RAND_INF_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_2 }, - { RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_3, RAND_INF_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_3 }, - { RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_1, RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_1 }, - { RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_2, RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_2 }, - { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_1, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_1 }, - { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_2, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_2 }, - { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_3, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_3 }, - { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_4, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_4 }, - { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_5, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_5 }, - { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_6, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_6 }, - { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_7, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_7 }, - { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_8, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_8 }, - { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_9, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_9 }, - { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_10, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_10 }, - { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_11, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_11 }, - { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_12, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_12 }, - { RC_JABU_JABUS_BELLY_MQ_ENTRANCE_BOULDER, RAND_INF_JABU_JABUS_BELLY_MQ_ENTRANCE_BOULDER }, - { RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_1, RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_1 }, - { RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_2, RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_2 }, - { RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_1, RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_1 }, - { RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_2, RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_2 }, - { RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_3, RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_3 }, - { RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_1, RAND_INF_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_1 }, - { RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_2, RAND_INF_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_2 }, - { RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_BOULDER, RAND_INF_JABU_JABUS_BELLY_MQ_TAILPASARAN_BOULDER }, - { RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_WALL_BOULDER, RAND_INF_JABU_JABUS_BELLY_MQ_TAILPASARAN_WALL_BOULDER }, - { RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_1, RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_1 }, - { RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_2, RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_2 }, - { RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_3, RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_3 }, - { RC_SPIRIT_TEMPLE_MQ_ENTRANCE_CEILING_BOULDER, RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_CEILING_BOULDER }, - { RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_BOULDER, RAND_INF_SPIRIT_TEMPLE_MQ_EARLY_ADULT_BOULDER }, - { RC_BOTW_MQ_BOULDER_1, RAND_INF_BOTW_MQ_BOULDER_1 }, - { RC_BOTW_MQ_BOULDER_2, RAND_INF_BOTW_MQ_BOULDER_2 }, - { RC_BOTW_MQ_BOULDER_3, RAND_INF_BOTW_MQ_BOULDER_3 }, { RC_HF_BUSH_NEAR_LAKE_1, RAND_INF_HF_BUSH_NEAR_LAKE_1 }, { RC_HF_BUSH_NEAR_LAKE_2, RAND_INF_HF_BUSH_NEAR_LAKE_2 }, { RC_HF_BUSH_NEAR_LAKE_3, RAND_INF_HF_BUSH_NEAR_LAKE_3 }, @@ -3285,6 +3005,7 @@ CheckIdentity Randomizer::IdentifyBeehive(s32 sceneNum, s16 xPosition, s32 respa } Rando::Location* Randomizer::GetCheckObjectFromActor(s16 actorId, s16 sceneNum, s32 actorParams = 0x00) { + auto fs = OTRGlobals::Instance->gRandoContext->GetFishsanity(); RandomizerCheck specialRc = RC_UNKNOWN_CHECK; // TODO: Migrate these special cases into table, or at least document why they are special switch (sceneNum) { @@ -3703,22 +3424,6 @@ CheckIdentity Randomizer::IdentifyTree(s32 sceneNum, s32 posX, s32 posZ) { return treeIdentity; } -RockIdentity Randomizer::IdentifyRock(s32 sceneNum, s32 posX, s32 posZ) { - struct RockIdentity rockIdentity; - - rockIdentity.randomizerInf = RAND_INF_MAX; - rockIdentity.randomizerCheck = RC_UNKNOWN_CHECK; - - Rando::Location* location = GetCheckObjectFromActor(ACTOR_EN_ISHI, sceneNum, TWO_ACTOR_PARAMS(posX, posZ)); - - if (location->GetRandomizerCheck() != RC_UNKNOWN_CHECK) { - rockIdentity.randomizerInf = rcToRandomizerInf[location->GetRandomizerCheck()]; - rockIdentity.randomizerCheck = location->GetRandomizerCheck(); - } - - return rockIdentity; -} - u8 Randomizer::GetRandoSettingValue(RandomizerSettingKey randoSettingKey) { return Rando::Context::GetInstance()->GetOption(randoSettingKey).Get(); } diff --git a/soh/soh/Enhancements/randomizer/randomizer.h b/soh/soh/Enhancements/randomizer/randomizer.h index 3cf750bccb2..b64a804e4ef 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.h +++ b/soh/soh/Enhancements/randomizer/randomizer.h @@ -43,7 +43,6 @@ class Randomizer { CheckIdentity IdentifyCrate(s32 sceneNum, s32 posX, s32 posZ); CheckIdentity IdentifySmallCrate(s32 sceneNum, s32 posX, s32 posZ); CheckIdentity IdentifyTree(s32 sceneNum, s32 posX, s32 posZ); - RockIdentity IdentifyRock(s32 sceneNum, s32 posX, s32 posZ); GetItemEntry GetItemFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogItemId, bool checkObtainability = true); GetItemEntry GetItemFromActor(s16 actorId, s16 sceneNum, s16 actorParams, GetItemID ogItemId, diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 6a3dca7975e..82f7ef4ed88 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -468,8 +468,6 @@ typedef enum { RCTYPE_BEAN_FAIRY, // Fairies from Beans RCTYPE_SONG_FAIRY, // Fairies from Songs RCTYPE_GRASS, // Grass - RCTYPE_ROCK, // Rocks - RCTYPE_BOULDER, // Boulders } RandomizerCheckType; typedef enum { RCQUEST_VANILLA, RCQUEST_MQ, RCQUEST_BOTH } RandomizerCheckQuest; @@ -4123,288 +4121,6 @@ typedef enum { RC_DEKU_TREE_QUEEN_GOHMA_GRASS_8, // End Grass - RC_KF_CIRCLE_ROCK_1, - RC_KF_CIRCLE_ROCK_2, - RC_KF_CIRCLE_ROCK_3, - RC_KF_CIRCLE_ROCK_4, - RC_KF_CIRCLE_ROCK_5, - RC_KF_CIRCLE_ROCK_6, - RC_KF_CIRCLE_ROCK_7, - RC_KF_CIRCLE_ROCK_8, - RC_KF_ROCK_BY_SARIAS_HOUSE, - RC_KF_ROCK_BEHIND_SARIAS_HOUSE, - RC_KF_ROCK_BY_MIDOS_HOUSE, - RC_KF_ROCK_BY_KNOW_IT_ALLS_HOUSE, - RC_LW_BOULDER_BY_GORON_CITY, - RC_LW_BOULDER_BY_SACRED_FOREST_MEADOW, - RC_LW_RUPEE_BOULDER, - RC_HC_ROCK_1, - RC_HC_ROCK_2, - RC_HC_ROCK_3, - RC_HC_BOULDER, - RC_OGC_BRONZE_BOULDER_1, - RC_OGC_BRONZE_BOULDER_2, - RC_OGC_BRONZE_BOULDER_3, - RC_OGC_SILVER_BOULDER_1, - RC_OGC_SILVER_BOULDER_2, - RC_OGC_SILVER_BOULDER_3, - RC_OGC_SILVER_BOULDER_4, - RC_DMC_CIRCLE_ROCK_1, - RC_DMC_CIRCLE_ROCK_2, - RC_DMC_CIRCLE_ROCK_3, - RC_DMC_CIRCLE_ROCK_4, - RC_DMC_CIRCLE_ROCK_5, - RC_DMC_CIRCLE_ROCK_6, - RC_DMC_CIRCLE_ROCK_7, - RC_DMC_CIRCLE_ROCK_8, - RC_DMC_ROCK_BY_FIRE_TEMPLE_1, - RC_DMC_ROCK_BY_FIRE_TEMPLE_2, - RC_DMC_ROCK_BY_FIRE_TEMPLE_3, - RC_DMC_ROCK_BY_FIRE_TEMPLE_4, - RC_DMC_ROCK_BY_FIRE_TEMPLE_5, - RC_DMC_GOSSIP_ROCK_1, - RC_DMC_GOSSIP_ROCK_2, - RC_DMC_BOULDER_1, - RC_DMC_BOULDER_2, - RC_DMC_BOULDER_3, - RC_DMC_BRONZE_BOULDER_1, - RC_DMC_BRONZE_BOULDER_2, - RC_DMC_BRONZE_BOULDER_3, - RC_DMC_BRONZE_BOULDER_4, - RC_GV_SILVER_BOULDER, - RC_GV_ROCK_1, - RC_GV_ROCK_2, - RC_GV_ROCK_3, - RC_GV_UNDERWATER_ROCK_1, - RC_GV_UNDERWATER_ROCK_2, - RC_GV_UNDERWATER_ROCK_3, - RC_GV_ROCK_ACROSS_BRIDGE_1, - RC_GV_ROCK_ACROSS_BRIDGE_2, - RC_GV_ROCK_ACROSS_BRIDGE_3, - RC_GV_ROCK_ACROSS_BRIDGE_4, - RC_GV_BOULDER_1, - RC_GV_BOULDER_2, - RC_GV_BOULDER_ACROSS_BRIDGE, - RC_GV_BRONZE_BOULDER_1, - RC_GV_BRONZE_BOULDER_2, - RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_1, - RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_2, - RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_3, - RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_4, - RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_5, - RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_6, - RC_HF_SILVER_BOULDER, - RC_HF_ROCK_1, - RC_HF_ROCK_2, - RC_HF_ROCK_3, - RC_HF_ROCK_4, - RC_HF_ROCK_5, - RC_HF_ROCK_6, - RC_HF_ROCK_7, - RC_HF_ROCK_8, - RC_HF_BOULDER_NORTH, - RC_HF_BOULDER_BY_MARKET, - RC_HF_BOULDER_SOUTH, - RC_HF_BRONZE_BOULDER_1, - RC_HF_BRONZE_BOULDER_2, - RC_HF_BRONZE_BOULDER_3, - RC_HF_BRONZE_BOULDER_4, - RC_KAK_SILVER_BOULDER, - RC_KAK_ROCK_1, - RC_KAK_ROCK_2, - RC_GY_ROCK, - RC_LA_ROCK, - RC_ZD_CIRCLE_ROCK_1, - RC_ZD_CIRCLE_ROCK_2, - RC_ZD_CIRCLE_ROCK_3, - RC_ZD_CIRCLE_ROCK_4, - RC_ZD_CIRCLE_ROCK_5, - RC_ZD_CIRCLE_ROCK_6, - RC_ZD_CIRCLE_ROCK_7, - RC_ZD_CIRCLE_ROCK_8, - RC_ZF_BOULDER, - RC_ZF_SILVER_BOULDER, - RC_ZF_UNDERGROUND_BOULDER, - RC_ZR_BOULDER_1, - RC_ZR_BOULDER_2, - RC_ZR_BOULDER_3, - RC_ZR_BOULDER_4, - RC_ZR_CIRCLE_ROCK_1, - RC_ZR_CIRCLE_ROCK_2, - RC_ZR_CIRCLE_ROCK_3, - RC_ZR_CIRCLE_ROCK_4, - RC_ZR_CIRCLE_ROCK_5, - RC_ZR_CIRCLE_ROCK_6, - RC_ZR_CIRCLE_ROCK_7, - RC_ZR_CIRCLE_ROCK_8, - RC_ZR_UPPER_CIRCLE_BOULDER, - RC_ZR_UPPER_CIRCLE_ROCK_1, - RC_ZR_UPPER_CIRCLE_ROCK_2, - RC_ZR_UPPER_CIRCLE_ROCK_3, - RC_ZR_UPPER_CIRCLE_ROCK_4, - RC_ZR_UPPER_CIRCLE_ROCK_5, - RC_ZR_UPPER_CIRCLE_ROCK_6, - RC_ZR_UPPER_CIRCLE_ROCK_7, - RC_ZR_UPPER_CIRCLE_ROCK_8, - RC_ZR_ROCK, - RC_ZR_UNDERWATER_ROCK_1, - RC_ZR_UNDERWATER_ROCK_2, - RC_ZR_UNDERWATER_ROCK_3, - RC_ZR_UNDERWATER_ROCK_4, - RC_DMT_ROCK_1, - RC_DMT_ROCK_2, - RC_DMT_ROCK_3, - RC_DMT_ROCK_4, - RC_DMT_ROCK_5, - RC_DMT_SUMMIT_ROCK, - RC_DMT_CIRCLE_ROCK_1, - RC_DMT_CIRCLE_ROCK_2, - RC_DMT_CIRCLE_ROCK_3, - RC_DMT_CIRCLE_ROCK_4, - RC_DMT_CIRCLE_ROCK_5, - RC_DMT_CIRCLE_ROCK_6, - RC_DMT_CIRCLE_ROCK_7, - RC_DMT_CIRCLE_ROCK_8, - RC_DMT_BOULDER_1, - RC_DMT_BOULDER_2, - RC_DMT_BOULDER_3, - RC_DMT_COW_BOULDER, - RC_DMT_BRONZE_BOULDER_1, - RC_DMT_BRONZE_BOULDER_2, - RC_DMT_BRONZE_BOULDER_3, - RC_DMT_BRONZE_BOULDER_4, - RC_DMT_BRONZE_BOULDER_5, - RC_DMT_BRONZE_BOULDER_6, - RC_DMT_BRONZE_BOULDER_7, - RC_DMT_BRONZE_BOULDER_8, - RC_DMT_BRONZE_BOULDER_9, - RC_DMT_BRONZE_BOULDER_10, - RC_DMT_BRONZE_BOULDER_11, - RC_GC_LW_BOULDER_1, - RC_GC_LW_BOULDER_2, - RC_GC_LW_BOULDER_3, - RC_GC_ENTRANCE_BOULDER_1, - RC_GC_ENTRANCE_BOULDER_2, - RC_GC_ENTRANCE_BOULDER_3, - RC_GC_MAZE_SILVER_BOULDER_1, - RC_GC_MAZE_SILVER_BOULDER_2, - RC_GC_MAZE_SILVER_BOULDER_3, - RC_GC_MAZE_SILVER_BOULDER_4, - RC_GC_MAZE_SILVER_BOULDER_5, - RC_GC_MAZE_SILVER_BOULDER_6, - RC_GC_MAZE_SILVER_BOULDER_7, - RC_GC_MAZE_SILVER_BOULDER_8, - RC_GC_MAZE_SILVER_BOULDER_9, - RC_GC_MAZE_SILVER_BOULDER_10, - RC_GC_MAZE_SILVER_BOULDER_11, - RC_GC_MAZE_SILVER_BOULDER_12, - RC_GC_MAZE_SILVER_BOULDER_13, - RC_GC_MAZE_SILVER_BOULDER_14, - RC_GC_MAZE_SILVER_BOULDER_15, - RC_GC_MAZE_SILVER_BOULDER_16, - RC_GC_MAZE_SILVER_BOULDER_17, - RC_GC_MAZE_SILVER_BOULDER_18, - RC_GC_MAZE_SILVER_BOULDER_19, - RC_GC_MAZE_SILVER_BOULDER_20, - RC_GC_MAZE_SILVER_BOULDER_21, - RC_GC_MAZE_SILVER_BOULDER_22, - RC_GC_MAZE_SILVER_BOULDER_23, - RC_GC_MAZE_SILVER_BOULDER_24, - RC_GC_MAZE_SILVER_BOULDER_25, - RC_GC_MAZE_SILVER_BOULDER_26, - RC_GC_MAZE_SILVER_BOULDER_27, - RC_GC_MAZE_SILVER_BOULDER_28, - RC_GC_MAZE_SILVER_BOULDER_29, - RC_GC_MAZE_BOULDER_1, - RC_GC_MAZE_BOULDER_2, - RC_GC_MAZE_BOULDER_3, - RC_GC_MAZE_BOULDER_4, - RC_GC_MAZE_BOULDER_5, - RC_GC_MAZE_BOULDER_6, - RC_GC_MAZE_BOULDER_7, - RC_GC_MAZE_BOULDER_8, - RC_GC_MAZE_BOULDER_9, - RC_GC_MAZE_BOULDER_10, - RC_GC_MAZE_BRONZE_BOULDER_1, - RC_GC_MAZE_BRONZE_BOULDER_2, - RC_GC_MAZE_BRONZE_BOULDER_3, - RC_GC_MAZE_BRONZE_BOULDER_4, - RC_GC_MAZE_BRONZE_BOULDER_5, - RC_GC_MAZE_ROCK, - RC_COLOSSUS_SILVER_BOULDER, - RC_COLOSSUS_ROCK, - RC_COLOSSUS_CIRCLE_1_ROCK_1, - RC_COLOSSUS_CIRCLE_1_ROCK_2, - RC_COLOSSUS_CIRCLE_1_ROCK_3, - RC_COLOSSUS_CIRCLE_1_ROCK_4, - RC_COLOSSUS_CIRCLE_1_ROCK_5, - RC_COLOSSUS_CIRCLE_1_ROCK_6, - RC_COLOSSUS_CIRCLE_1_ROCK_7, - RC_COLOSSUS_CIRCLE_1_ROCK_8, - RC_COLOSSUS_CIRCLE_2_ROCK_1, - RC_COLOSSUS_CIRCLE_2_ROCK_2, - RC_COLOSSUS_CIRCLE_2_ROCK_3, - RC_COLOSSUS_CIRCLE_2_ROCK_4, - RC_COLOSSUS_CIRCLE_2_ROCK_5, - RC_COLOSSUS_CIRCLE_2_ROCK_6, - RC_COLOSSUS_CIRCLE_2_ROCK_7, - RC_COLOSSUS_CIRCLE_2_ROCK_8, - RC_HC_STORMS_GROTTO_ROCK_1, - RC_HC_STORMS_GROTTO_ROCK_2, - RC_HC_STORMS_GROTTO_ROCK_3, - RC_HC_STORMS_GROTTO_ROCK_4, - RC_HC_STORMS_GROTTO_ROCK_5, - RC_HC_STORMS_GROTTO_ROCK_6, - RC_HC_STORMS_GROTTO_ROCK_7, - RC_HC_STORMS_GROTTO_ROCK_8, - RC_BOTW_BOULDER_1, - RC_BOTW_BOULDER_2, - RC_BOTW_BOULDER_3, - RC_BOTW_BOULDER_4, - RC_BOTW_BOULDER_5, - RC_BOTW_BOULDER_6, - RC_DEKU_TREE_MQ_BOULDER_1, - RC_DEKU_TREE_MQ_BOULDER_2, - RC_DEKU_TREE_MQ_BOULDER_3, - RC_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_1, - RC_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_2, - RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_1, - RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_2, - RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_3, - RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_1, - RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_2, - RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_1, - RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_2, - RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_3, - RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_4, - RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_5, - RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_6, - RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_7, - RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_8, - RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_9, - RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_10, - RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_11, - RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_12, - RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_BOULDER, - RC_JABU_JABUS_BELLY_MQ_ENTRANCE_BOULDER, - RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_1, - RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_2, - RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_1, - RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_2, - RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_3, - RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_1, - RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_2, - RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_BOULDER, - RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_WALL_BOULDER, - RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_1, - RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_2, - RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_3, - RC_SPIRIT_TEMPLE_MQ_ENTRANCE_CEILING_BOULDER, - RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_BOULDER, - RC_BOTW_MQ_BOULDER_1, - RC_BOTW_MQ_BOULDER_2, - RC_BOTW_MQ_BOULDER_3, - RC_MAX } RandomizerCheck; @@ -4918,7 +4634,6 @@ typedef enum { RG_BRONZE_SCALE, RG_POWER_BRACELET, RG_CLIMB, - RG_ROLL, RG_CRAWL, RG_ROLL, RG_OPEN_CHEST, @@ -6129,7 +5844,6 @@ typedef enum { RHT_OCARINA_C_DOWN_BUTTON, RHT_OCARINA_C_LEFT_BUTTON, RHT_OCARINA_C_RIGHT_BUTTON, - RHT_BRONZE_SCALE, RHT_MASK_KEATON, RHT_MASK_SKULL, RHT_MASK_SPOOKY, @@ -6139,7 +5853,6 @@ typedef enum { RHT_MASK_GERUDO, RHT_MASK_TRUTH, RHT_CLIMB, - RHT_ROLL, RHT_CRAWL, RHT_ROLL, RHT_OPEN_CHEST, @@ -6613,48 +6326,6 @@ typedef enum { RHT_DODONGOS_CAVERN_GRASS, RHT_BOTTOM_OF_THE_WELL_GRASS, RHT_JABU_JABUS_BELLY_GRASS, - - RHT_KF_ROCK, - RHT_LW_BOULDER, - RHT_HC_ROCK, - RHT_HC_BOULDER, - RHT_OGC_BRONZE_BOULDER, - RHT_OGC_SILVER_BOULDER, - RHT_DMC_ROCK, - RHT_DMC_BOULDER, - RHT_DMC_BRONZE_BOULDER, - RHT_GV_SILVER_BOULDER, - RHT_GV_ROCK, - RHT_GV_BOULDER, - RHT_GV_BRONZE_BOULDER, - RHT_HF_SILVER_BOULDER, - RHT_HF_ROCK, - RHT_HF_BOULDER, - RHT_HF_BRONZE_BOULDER, - RHT_KAK_SILVER_BOULDER, - RHT_KAK_ROCK, - RHT_GY_ROCK, - RHT_LA_ROCK, - RHT_ZD_ROCK, - RHT_ZF_BOULDER, - RHT_ZF_SILVER_BOULDER, - RHT_ZR_BOULDER, - RHT_ZR_ROCK, - RHT_DMT_ROCK, - RHT_DMT_BOULDER, - RHT_DMT_BRONZE_BOULDER, - RHT_GC_BOULDER, - RHT_GC_SILVER_BOULDER, - RHT_GC_BRONZE_BOULDER, - RHT_GC_ROCK, - RHT_COLOSSUS_SILVER_BOULDER, - RHT_COLOSSUS_ROCK, - RHT_HC_STORMS_GROTTO_ROCK, - RHT_BOTW_BOULDER, - RHT_DEKU_BOULDER, - RHT_DODONGOS_BOULDER, - RHT_JABU_BOULDER, - RHT_SPIRIT_TEMPLE_BOULDER, // MAX RHT_MAX, } RandomizerHintTextKey; @@ -6782,7 +6453,6 @@ typedef enum { RSK_SHUFFLE_SWIM, RSK_SHUFFLE_GRAB, RSK_SHUFFLE_CLIMB, - RSK_SHUFFLE_ROLL, RSK_SHUFFLE_CRAWL, RSK_SHUFFLE_ROLL, RSK_SHUFFLE_OPEN_CHEST, @@ -6986,8 +6656,6 @@ typedef enum { RSK_SHUFFLE_SONG_FAIRIES, RSK_LOCK_OVERWORLD_DOORS, RSK_SHUFFLE_GRASS, - RSK_SHUFFLE_ROCKS, - RSK_SHUFFLE_BOULDERS, RSK_ROCS_FEATHER, RSK_MAX } RandomizerSettingKey; @@ -7361,14 +7029,6 @@ typedef enum { RO_SHUFFLE_CRATES_ALL, } RandoOptionShuffleCrates; -// Shuffle Boulder settings (off, dungeons, overworld, all) -typedef enum { - RO_SHUFFLE_BOULDERS_OFF, - RO_SHUFFLE_BOULDERS_DUNGEONS, - RO_SHUFFLE_BOULDERS_OVERWORLD, - RO_SHUFFLE_BOULDERS_ALL, -} RandoOptionShuffleBoulders; - // Link's Pocket Settings (dungeon reward, advancement, anything, nothing) typedef enum { RO_LINKS_POCKET_DUNGEON_REWARD, @@ -7452,11 +7112,6 @@ typedef struct ShopItemIdentity { int32_t itemPrice; } ShopItemIdentity; -typedef struct RockIdentity { - RandomizerInf randomizerInf; - RandomizerCheck randomizerCheck; -} RockIdentity; - typedef enum { TRACKER_WINDOW_FLOATING, TRACKER_WINDOW_WINDOW, diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index d0b7f83f317..9902ae32d63 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -83,9 +83,6 @@ bool showDungeonGrass; bool showOverworldCrates; bool showDungeonCrates; bool showTrees; -bool showRocks; -bool showOverworldBoulders; -bool showDungeonBoulders; bool showBushes; bool showFrogSongRupees; bool showFountainFairies; @@ -1492,28 +1489,7 @@ void LoadSettings() { showDungeonCrates = false; break; } - showTrees = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_TREES); - - showRocks = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_ROCKS); - switch (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_BOULDERS)) { - case RO_SHUFFLE_BOULDERS_ALL: - showOverworldBoulders = true; - showDungeonBoulders = true; - break; - case RO_SHUFFLE_BOULDERS_OVERWORLD: - showOverworldBoulders = true; - showDungeonBoulders = false; - break; - case RO_SHUFFLE_BOULDERS_DUNGEONS: - showOverworldBoulders = false; - showDungeonBoulders = true; - break; - default: - showOverworldBoulders = false; - showDungeonBoulders = false; - break; - } showBushes = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_BUSHES); } else { // Vanilla showOverworldTokens = true; @@ -1525,9 +1501,6 @@ void LoadSettings() { showOverworldCrates = false; showDungeonCrates = false; showTrees = false; - showRocks = false; - showOverworldBoulders = false; - showDungeonBoulders = false; showBushes = false; } @@ -1645,10 +1618,6 @@ bool IsCheckShuffled(RandomizerCheck rc) { (loc->GetRCType() != RCTYPE_NLTREE || (showTrees && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LOGIC_RULES) == RO_LOGIC_NO_LOGIC)) && - (loc->GetRCType() != RCTYPE_ROCK || showRocks) && - (loc->GetRCType() != RCTYPE_BOULDER || - (showOverworldBoulders && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) || - (showDungeonBoulders && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && (loc->GetRCType() != RCTYPE_BUSH || showBushes) && (loc->GetRCType() != RCTYPE_COW || showCows) && (loc->GetRCType() != RCTYPE_FISH || OTRGlobals::Instance->gRandoContext->GetFishsanity()->GetFishLocationIncluded(loc)) && diff --git a/soh/soh/Enhancements/randomizer/randomizer_inf.h b/soh/soh/Enhancements/randomizer/randomizer_inf.h index 2fb45277db7..96ccf07d0ca 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_inf.h +++ b/soh/soh/Enhancements/randomizer/randomizer_inf.h @@ -1140,7 +1140,6 @@ DEFINE_RAND_INF(RAND_INF_CAUGHT_LOACH) DEFINE_RAND_INF(RAND_INF_CAN_SWIM) DEFINE_RAND_INF(RAND_INF_CAN_CLIMB) -DEFINE_RAND_INF(RAND_INF_CAN_ROLL) DEFINE_RAND_INF(RAND_INF_CAN_CRAWL) DEFINE_RAND_INF(RAND_INF_CAN_ROLL) DEFINE_RAND_INF(RAND_INF_CAN_GRAB) @@ -2105,288 +2104,6 @@ DEFINE_RAND_INF(RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_6) DEFINE_RAND_INF(RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_7) DEFINE_RAND_INF(RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_8) // End Grass -DEFINE_RAND_INF(RAND_INF_KF_CIRCLE_ROCK_1) -DEFINE_RAND_INF(RAND_INF_KF_CIRCLE_ROCK_2) -DEFINE_RAND_INF(RAND_INF_KF_CIRCLE_ROCK_3) -DEFINE_RAND_INF(RAND_INF_KF_CIRCLE_ROCK_4) -DEFINE_RAND_INF(RAND_INF_KF_CIRCLE_ROCK_5) -DEFINE_RAND_INF(RAND_INF_KF_CIRCLE_ROCK_6) -DEFINE_RAND_INF(RAND_INF_KF_CIRCLE_ROCK_7) -DEFINE_RAND_INF(RAND_INF_KF_CIRCLE_ROCK_8) -DEFINE_RAND_INF(RAND_INF_KF_ROCK_BY_SARIAS_HOUSE) -DEFINE_RAND_INF(RAND_INF_KF_ROCK_BEHIND_SARIAS_HOUSE) -DEFINE_RAND_INF(RAND_INF_KF_ROCK_BY_MIDOS_HOUSE) -DEFINE_RAND_INF(RAND_INF_KF_ROCK_BY_KNOW_IT_ALLS_HOUSE) -DEFINE_RAND_INF(RAND_INF_LW_BOULDER_BY_GORON_CITY) -DEFINE_RAND_INF(RAND_INF_LW_BOULDER_BY_SACRED_FOREST_MEADOW) -DEFINE_RAND_INF(RAND_INF_LW_RUPEE_BOULDER) -DEFINE_RAND_INF(RAND_INF_HC_ROCK_1) -DEFINE_RAND_INF(RAND_INF_HC_ROCK_2) -DEFINE_RAND_INF(RAND_INF_HC_ROCK_3) -DEFINE_RAND_INF(RAND_INF_HC_BOULDER) -DEFINE_RAND_INF(RAND_INF_OGC_BRONZE_BOULDER_1) -DEFINE_RAND_INF(RAND_INF_OGC_BRONZE_BOULDER_2) -DEFINE_RAND_INF(RAND_INF_OGC_BRONZE_BOULDER_3) -DEFINE_RAND_INF(RAND_INF_OGC_SILVER_BOULDER_1) -DEFINE_RAND_INF(RAND_INF_OGC_SILVER_BOULDER_2) -DEFINE_RAND_INF(RAND_INF_OGC_SILVER_BOULDER_3) -DEFINE_RAND_INF(RAND_INF_OGC_SILVER_BOULDER_4) -DEFINE_RAND_INF(RAND_INF_DMC_CIRCLE_ROCK_1) -DEFINE_RAND_INF(RAND_INF_DMC_CIRCLE_ROCK_2) -DEFINE_RAND_INF(RAND_INF_DMC_CIRCLE_ROCK_3) -DEFINE_RAND_INF(RAND_INF_DMC_CIRCLE_ROCK_4) -DEFINE_RAND_INF(RAND_INF_DMC_CIRCLE_ROCK_5) -DEFINE_RAND_INF(RAND_INF_DMC_CIRCLE_ROCK_6) -DEFINE_RAND_INF(RAND_INF_DMC_CIRCLE_ROCK_7) -DEFINE_RAND_INF(RAND_INF_DMC_CIRCLE_ROCK_8) -DEFINE_RAND_INF(RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_1) -DEFINE_RAND_INF(RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_2) -DEFINE_RAND_INF(RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_3) -DEFINE_RAND_INF(RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_4) -DEFINE_RAND_INF(RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_5) -DEFINE_RAND_INF(RAND_INF_DMC_GOSSIP_ROCK_1) -DEFINE_RAND_INF(RAND_INF_DMC_GOSSIP_ROCK_2) -DEFINE_RAND_INF(RAND_INF_DMC_BOULDER_1) -DEFINE_RAND_INF(RAND_INF_DMC_BOULDER_2) -DEFINE_RAND_INF(RAND_INF_DMC_BOULDER_3) -DEFINE_RAND_INF(RAND_INF_DMC_BRONZE_BOULDER_1) -DEFINE_RAND_INF(RAND_INF_DMC_BRONZE_BOULDER_2) -DEFINE_RAND_INF(RAND_INF_DMC_BRONZE_BOULDER_3) -DEFINE_RAND_INF(RAND_INF_DMC_BRONZE_BOULDER_4) -DEFINE_RAND_INF(RAND_INF_GV_SILVER_BOULDER) -DEFINE_RAND_INF(RAND_INF_GV_ROCK_1) -DEFINE_RAND_INF(RAND_INF_GV_ROCK_2) -DEFINE_RAND_INF(RAND_INF_GV_ROCK_3) -DEFINE_RAND_INF(RAND_INF_GV_UNDERWATER_ROCK_1) -DEFINE_RAND_INF(RAND_INF_GV_UNDERWATER_ROCK_2) -DEFINE_RAND_INF(RAND_INF_GV_UNDERWATER_ROCK_3) -DEFINE_RAND_INF(RAND_INF_GV_ROCK_ACROSS_BRIDGE_1) -DEFINE_RAND_INF(RAND_INF_GV_ROCK_ACROSS_BRIDGE_2) -DEFINE_RAND_INF(RAND_INF_GV_ROCK_ACROSS_BRIDGE_3) -DEFINE_RAND_INF(RAND_INF_GV_ROCK_ACROSS_BRIDGE_4) -DEFINE_RAND_INF(RAND_INF_GV_BOULDER_1) -DEFINE_RAND_INF(RAND_INF_GV_BOULDER_2) -DEFINE_RAND_INF(RAND_INF_GV_BOULDER_ACROSS_BRIDGE) -DEFINE_RAND_INF(RAND_INF_GV_BRONZE_BOULDER_1) -DEFINE_RAND_INF(RAND_INF_GV_BRONZE_BOULDER_2) -DEFINE_RAND_INF(RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_1) -DEFINE_RAND_INF(RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_2) -DEFINE_RAND_INF(RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_3) -DEFINE_RAND_INF(RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_4) -DEFINE_RAND_INF(RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_5) -DEFINE_RAND_INF(RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_6) -DEFINE_RAND_INF(RAND_INF_HF_SILVER_BOULDER) -DEFINE_RAND_INF(RAND_INF_HF_ROCK_1) -DEFINE_RAND_INF(RAND_INF_HF_ROCK_2) -DEFINE_RAND_INF(RAND_INF_HF_ROCK_3) -DEFINE_RAND_INF(RAND_INF_HF_ROCK_4) -DEFINE_RAND_INF(RAND_INF_HF_ROCK_5) -DEFINE_RAND_INF(RAND_INF_HF_ROCK_6) -DEFINE_RAND_INF(RAND_INF_HF_ROCK_7) -DEFINE_RAND_INF(RAND_INF_HF_ROCK_8) -DEFINE_RAND_INF(RAND_INF_HF_BOULDER_NORTH) -DEFINE_RAND_INF(RAND_INF_HF_BOULDER_BY_MARKET) -DEFINE_RAND_INF(RAND_INF_HF_BOULDER_SOUTH) -DEFINE_RAND_INF(RAND_INF_HF_BRONZE_BOULDER_1) -DEFINE_RAND_INF(RAND_INF_HF_BRONZE_BOULDER_2) -DEFINE_RAND_INF(RAND_INF_HF_BRONZE_BOULDER_3) -DEFINE_RAND_INF(RAND_INF_HF_BRONZE_BOULDER_4) -DEFINE_RAND_INF(RAND_INF_KAK_SILVER_BOULDER) -DEFINE_RAND_INF(RAND_INF_KAK_ROCK_1) -DEFINE_RAND_INF(RAND_INF_KAK_ROCK_2) -DEFINE_RAND_INF(RAND_INF_GY_ROCK) -DEFINE_RAND_INF(RAND_INF_LA_ROCK) -DEFINE_RAND_INF(RAND_INF_ZD_CIRCLE_ROCK_1) -DEFINE_RAND_INF(RAND_INF_ZD_CIRCLE_ROCK_2) -DEFINE_RAND_INF(RAND_INF_ZD_CIRCLE_ROCK_3) -DEFINE_RAND_INF(RAND_INF_ZD_CIRCLE_ROCK_4) -DEFINE_RAND_INF(RAND_INF_ZD_CIRCLE_ROCK_5) -DEFINE_RAND_INF(RAND_INF_ZD_CIRCLE_ROCK_6) -DEFINE_RAND_INF(RAND_INF_ZD_CIRCLE_ROCK_7) -DEFINE_RAND_INF(RAND_INF_ZD_CIRCLE_ROCK_8) -DEFINE_RAND_INF(RAND_INF_ZF_BOULDER) -DEFINE_RAND_INF(RAND_INF_ZF_SILVER_BOULDER) -DEFINE_RAND_INF(RAND_INF_ZF_UNDERGROUND_BOULDER) -DEFINE_RAND_INF(RAND_INF_ZR_BOULDER_1) -DEFINE_RAND_INF(RAND_INF_ZR_BOULDER_2) -DEFINE_RAND_INF(RAND_INF_ZR_BOULDER_3) -DEFINE_RAND_INF(RAND_INF_ZR_BOULDER_4) -DEFINE_RAND_INF(RAND_INF_ZR_CIRCLE_ROCK_1) -DEFINE_RAND_INF(RAND_INF_ZR_CIRCLE_ROCK_2) -DEFINE_RAND_INF(RAND_INF_ZR_CIRCLE_ROCK_3) -DEFINE_RAND_INF(RAND_INF_ZR_CIRCLE_ROCK_4) -DEFINE_RAND_INF(RAND_INF_ZR_CIRCLE_ROCK_5) -DEFINE_RAND_INF(RAND_INF_ZR_CIRCLE_ROCK_6) -DEFINE_RAND_INF(RAND_INF_ZR_CIRCLE_ROCK_7) -DEFINE_RAND_INF(RAND_INF_ZR_CIRCLE_ROCK_8) -DEFINE_RAND_INF(RAND_INF_ZR_UPPER_CIRCLE_BOULDER) -DEFINE_RAND_INF(RAND_INF_ZR_UPPER_CIRCLE_ROCK_1) -DEFINE_RAND_INF(RAND_INF_ZR_UPPER_CIRCLE_ROCK_2) -DEFINE_RAND_INF(RAND_INF_ZR_UPPER_CIRCLE_ROCK_3) -DEFINE_RAND_INF(RAND_INF_ZR_UPPER_CIRCLE_ROCK_4) -DEFINE_RAND_INF(RAND_INF_ZR_UPPER_CIRCLE_ROCK_5) -DEFINE_RAND_INF(RAND_INF_ZR_UPPER_CIRCLE_ROCK_6) -DEFINE_RAND_INF(RAND_INF_ZR_UPPER_CIRCLE_ROCK_7) -DEFINE_RAND_INF(RAND_INF_ZR_UPPER_CIRCLE_ROCK_8) -DEFINE_RAND_INF(RAND_INF_ZR_ROCK) -DEFINE_RAND_INF(RAND_INF_ZR_UNDERWATER_ROCK_1) -DEFINE_RAND_INF(RAND_INF_ZR_UNDERWATER_ROCK_2) -DEFINE_RAND_INF(RAND_INF_ZR_UNDERWATER_ROCK_3) -DEFINE_RAND_INF(RAND_INF_ZR_UNDERWATER_ROCK_4) -DEFINE_RAND_INF(RAND_INF_DMT_ROCK_1) -DEFINE_RAND_INF(RAND_INF_DMT_ROCK_2) -DEFINE_RAND_INF(RAND_INF_DMT_ROCK_3) -DEFINE_RAND_INF(RAND_INF_DMT_ROCK_4) -DEFINE_RAND_INF(RAND_INF_DMT_ROCK_5) -DEFINE_RAND_INF(RAND_INF_DMT_SUMMIT_ROCK) -DEFINE_RAND_INF(RAND_INF_DMT_CIRCLE_ROCK_1) -DEFINE_RAND_INF(RAND_INF_DMT_CIRCLE_ROCK_2) -DEFINE_RAND_INF(RAND_INF_DMT_CIRCLE_ROCK_3) -DEFINE_RAND_INF(RAND_INF_DMT_CIRCLE_ROCK_4) -DEFINE_RAND_INF(RAND_INF_DMT_CIRCLE_ROCK_5) -DEFINE_RAND_INF(RAND_INF_DMT_CIRCLE_ROCK_6) -DEFINE_RAND_INF(RAND_INF_DMT_CIRCLE_ROCK_7) -DEFINE_RAND_INF(RAND_INF_DMT_CIRCLE_ROCK_8) -DEFINE_RAND_INF(RAND_INF_DMT_BOULDER_1) -DEFINE_RAND_INF(RAND_INF_DMT_BOULDER_2) -DEFINE_RAND_INF(RAND_INF_DMT_BOULDER_3) -DEFINE_RAND_INF(RAND_INF_DMT_COW_BOULDER) -DEFINE_RAND_INF(RAND_INF_DMT_BRONZE_BOULDER_1) -DEFINE_RAND_INF(RAND_INF_DMT_BRONZE_BOULDER_2) -DEFINE_RAND_INF(RAND_INF_DMT_BRONZE_BOULDER_3) -DEFINE_RAND_INF(RAND_INF_DMT_BRONZE_BOULDER_4) -DEFINE_RAND_INF(RAND_INF_DMT_BRONZE_BOULDER_5) -DEFINE_RAND_INF(RAND_INF_DMT_BRONZE_BOULDER_6) -DEFINE_RAND_INF(RAND_INF_DMT_BRONZE_BOULDER_7) -DEFINE_RAND_INF(RAND_INF_DMT_BRONZE_BOULDER_8) -DEFINE_RAND_INF(RAND_INF_DMT_BRONZE_BOULDER_9) -DEFINE_RAND_INF(RAND_INF_DMT_BRONZE_BOULDER_10) -DEFINE_RAND_INF(RAND_INF_DMT_BRONZE_BOULDER_11) -DEFINE_RAND_INF(RAND_INF_GC_LW_BOULDER_1) -DEFINE_RAND_INF(RAND_INF_GC_LW_BOULDER_2) -DEFINE_RAND_INF(RAND_INF_GC_LW_BOULDER_3) -DEFINE_RAND_INF(RAND_INF_GC_ENTRANCE_BOULDER_1) -DEFINE_RAND_INF(RAND_INF_GC_ENTRANCE_BOULDER_2) -DEFINE_RAND_INF(RAND_INF_GC_ENTRANCE_BOULDER_3) -DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_1) -DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_2) -DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_3) -DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_4) -DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_5) -DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_6) -DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_7) -DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_8) -DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_9) -DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_10) -DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_11) -DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_12) -DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_13) -DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_14) -DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_15) -DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_16) -DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_17) -DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_18) -DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_19) -DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_20) -DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_21) -DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_22) -DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_23) -DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_24) -DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_25) -DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_26) -DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_27) -DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_28) -DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_29) -DEFINE_RAND_INF(RAND_INF_GC_MAZE_BOULDER_1) -DEFINE_RAND_INF(RAND_INF_GC_MAZE_BOULDER_2) -DEFINE_RAND_INF(RAND_INF_GC_MAZE_BOULDER_3) -DEFINE_RAND_INF(RAND_INF_GC_MAZE_BOULDER_4) -DEFINE_RAND_INF(RAND_INF_GC_MAZE_BOULDER_5) -DEFINE_RAND_INF(RAND_INF_GC_MAZE_BOULDER_6) -DEFINE_RAND_INF(RAND_INF_GC_MAZE_BOULDER_7) -DEFINE_RAND_INF(RAND_INF_GC_MAZE_BOULDER_8) -DEFINE_RAND_INF(RAND_INF_GC_MAZE_BOULDER_9) -DEFINE_RAND_INF(RAND_INF_GC_MAZE_BOULDER_10) -DEFINE_RAND_INF(RAND_INF_GC_MAZE_BRONZE_BOULDER_1) -DEFINE_RAND_INF(RAND_INF_GC_MAZE_BRONZE_BOULDER_2) -DEFINE_RAND_INF(RAND_INF_GC_MAZE_BRONZE_BOULDER_3) -DEFINE_RAND_INF(RAND_INF_GC_MAZE_BRONZE_BOULDER_4) -DEFINE_RAND_INF(RAND_INF_GC_MAZE_BRONZE_BOULDER_5) -DEFINE_RAND_INF(RAND_INF_GC_MAZE_ROCK) -DEFINE_RAND_INF(RAND_INF_COLOSSUS_SILVER_BOULDER) -DEFINE_RAND_INF(RAND_INF_COLOSSUS_ROCK) -DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_1_ROCK_1) -DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_1_ROCK_2) -DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_1_ROCK_3) -DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_1_ROCK_4) -DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_1_ROCK_5) -DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_1_ROCK_6) -DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_1_ROCK_7) -DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_1_ROCK_8) -DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_2_ROCK_1) -DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_2_ROCK_2) -DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_2_ROCK_3) -DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_2_ROCK_4) -DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_2_ROCK_5) -DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_2_ROCK_6) -DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_2_ROCK_7) -DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_2_ROCK_8) -DEFINE_RAND_INF(RAND_INF_HC_STORMS_GROTTO_ROCK_1) -DEFINE_RAND_INF(RAND_INF_HC_STORMS_GROTTO_ROCK_2) -DEFINE_RAND_INF(RAND_INF_HC_STORMS_GROTTO_ROCK_3) -DEFINE_RAND_INF(RAND_INF_HC_STORMS_GROTTO_ROCK_4) -DEFINE_RAND_INF(RAND_INF_HC_STORMS_GROTTO_ROCK_5) -DEFINE_RAND_INF(RAND_INF_HC_STORMS_GROTTO_ROCK_6) -DEFINE_RAND_INF(RAND_INF_HC_STORMS_GROTTO_ROCK_7) -DEFINE_RAND_INF(RAND_INF_HC_STORMS_GROTTO_ROCK_8) -DEFINE_RAND_INF(RAND_INF_BOTW_BOULDER_1) -DEFINE_RAND_INF(RAND_INF_BOTW_BOULDER_2) -DEFINE_RAND_INF(RAND_INF_BOTW_BOULDER_3) -DEFINE_RAND_INF(RAND_INF_BOTW_BOULDER_4) -DEFINE_RAND_INF(RAND_INF_BOTW_BOULDER_5) -DEFINE_RAND_INF(RAND_INF_BOTW_BOULDER_6) -DEFINE_RAND_INF(RAND_INF_DEKU_TREE_MQ_BOULDER_1) -DEFINE_RAND_INF(RAND_INF_DEKU_TREE_MQ_BOULDER_2) -DEFINE_RAND_INF(RAND_INF_DEKU_TREE_MQ_BOULDER_3) -DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_1) -DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_2) -DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_1) -DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_2) -DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_3) -DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_1) -DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_2) -DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_1) -DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_2) -DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_3) -DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_4) -DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_5) -DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_6) -DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_7) -DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_8) -DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_9) -DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_10) -DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_11) -DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_12) -DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_TWO_FLAMES_BOULDER) -DEFINE_RAND_INF(RAND_INF_JABU_JABUS_BELLY_MQ_ENTRANCE_BOULDER) -DEFINE_RAND_INF(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_1) -DEFINE_RAND_INF(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_2) -DEFINE_RAND_INF(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_1) -DEFINE_RAND_INF(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_2) -DEFINE_RAND_INF(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_3) -DEFINE_RAND_INF(RAND_INF_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_1) -DEFINE_RAND_INF(RAND_INF_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_2) -DEFINE_RAND_INF(RAND_INF_JABU_JABUS_BELLY_MQ_TAILPASARAN_BOULDER) -DEFINE_RAND_INF(RAND_INF_JABU_JABUS_BELLY_MQ_TAILPASARAN_WALL_BOULDER) -DEFINE_RAND_INF(RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_1) -DEFINE_RAND_INF(RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_2) -DEFINE_RAND_INF(RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_3) -DEFINE_RAND_INF(RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_CEILING_BOULDER) -DEFINE_RAND_INF(RAND_INF_SPIRIT_TEMPLE_MQ_EARLY_ADULT_BOULDER) -DEFINE_RAND_INF(RAND_INF_BOTW_MQ_BOULDER_1) -DEFINE_RAND_INF(RAND_INF_BOTW_MQ_BOULDER_2) -DEFINE_RAND_INF(RAND_INF_BOTW_MQ_BOULDER_3) - DEFINE_RAND_INF(RAND_INF_OBTAINED_RUTOS_LETTER) DEFINE_RAND_INF(RAND_INF_OBTAINED_NAYRUS_LOVE) DEFINE_RAND_INF(RAND_INF_OBTAINED_ROCS_FEATHER) diff --git a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp index 45614f72ca8..061e904163c 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp @@ -2311,7 +2311,6 @@ void RegisterItemTrackerWidgets() { .ComboMap(extendedDisplayTypes)) .Callback([](WidgetInfo& info) { shouldUpdateVectors = true; }); ; - SohGui::mSohMenu->AddSearchWidget( { fishingPoleTracking, "Randomizer", "Item Tracker", "General Settings", "icon" }); diff --git a/soh/soh/Enhancements/randomizer/savefile.cpp b/soh/soh/Enhancements/randomizer/savefile.cpp index 31fd6b93553..b9fc298e6dd 100644 --- a/soh/soh/Enhancements/randomizer/savefile.cpp +++ b/soh/soh/Enhancements/randomizer/savefile.cpp @@ -324,183 +324,180 @@ extern "C" void Randomizer_InitSaveFile() { if (Randomizer_GetSettingValue(RSK_SHUFFLE_CRAWL) == RO_GENERIC_OFF) { Flags_SetRandomizerInf(RAND_INF_CAN_CRAWL); } - - if (Randomizer_GetSettingValue(RSK_SHUFFLE_ROLL) == RO_GENERIC_OFF) { - Flags_SetRandomizerInf(RAND_INF_CAN_ROLL); - } - if (Randomizer_GetSettingValue(RSK_SHUFFLE_OPEN_CHEST) == RO_GENERIC_OFF) { - Flags_SetRandomizerInf(RAND_INF_CAN_OPEN_CHEST); - } + if (Randomizer_GetSettingValue(RSK_SHUFFLE_ROLL) == RO_GENERIC_OFF) { + Flags_SetRandomizerInf(RAND_INF_CAN_ROLL); + } - if (Randomizer_GetSettingValue(RSK_SHUFFLE_CHILD_WALLET) == RO_GENERIC_OFF) { - Flags_SetRandomizerInf(RAND_INF_HAS_WALLET); - } + if (Randomizer_GetSettingValue(RSK_SHUFFLE_OPEN_CHEST) == RO_GENERIC_OFF) { + Flags_SetRandomizerInf(RAND_INF_CAN_OPEN_CHEST); + } - if (Randomizer_GetSettingValue(RSK_SHUFFLE_FISHING_POLE) == RO_GENERIC_OFF) { - Flags_SetRandomizerInf(RAND_INF_FISHING_POLE_FOUND); - } + if (Randomizer_GetSettingValue(RSK_SHUFFLE_CHILD_WALLET) == RO_GENERIC_OFF) { + Flags_SetRandomizerInf(RAND_INF_HAS_WALLET); + } - // Give Link's pocket item - GiveLinksPocketItem(); + if (Randomizer_GetSettingValue(RSK_SHUFFLE_FISHING_POLE) == RO_GENERIC_OFF) { + Flags_SetRandomizerInf(RAND_INF_FISHING_POLE_FOUND); + } - // Remove One Time Scrubs with Scrubsanity off - if (Randomizer_GetSettingValue(RSK_SHUFFLE_SCRUBS) == RO_SCRUBS_OFF) { - Flags_SetItemGetInf(ITEMGETINF_DEKU_SCRUB_HEART_PIECE); - Flags_SetInfTable(INFTABLE_BOUGHT_STICK_UPGRADE); - Flags_SetInfTable(INFTABLE_BOUGHT_NUT_UPGRADE); - } + // Give Link's pocket item + GiveLinksPocketItem(); - int startingAge = OTRGlobals::Instance->gRandoContext->GetOption(RSK_SELECTED_STARTING_AGE).Get(); - gSaveContext.savedSceneNum = -1; - switch (startingAge) { - case RO_AGE_ADULT: // Adult - gSaveContext.linkAge = LINK_AGE_ADULT; - gSaveContext.entranceIndex = ENTR_TEMPLE_OF_TIME_WARP_PAD; - gSaveContext.cutsceneIndex = 0; - break; - case RO_AGE_CHILD: // Child - gSaveContext.linkAge = LINK_AGE_CHILD; - break; - default: - break; - } + // Remove One Time Scrubs with Scrubsanity off + if (Randomizer_GetSettingValue(RSK_SHUFFLE_SCRUBS) == RO_SCRUBS_OFF) { + Flags_SetItemGetInf(ITEMGETINF_DEKU_SCRUB_HEART_PIECE); + Flags_SetInfTable(INFTABLE_BOUGHT_STICK_UPGRADE); + Flags_SetInfTable(INFTABLE_BOUGHT_NUT_UPGRADE); + } - if (Randomizer_GetSettingValue(RSK_SHUFFLE_OVERWORLD_SPAWNS)) { - // Override the spawn entrance so entrance rando can take control, - // and to prevent remember save location from breaking initial spawn. - gSaveContext.entranceIndex = -1; - } + int startingAge = OTRGlobals::Instance->gRandoContext->GetOption(RSK_SELECTED_STARTING_AGE).Get(); + gSaveContext.savedSceneNum = -1; + switch (startingAge) { + case RO_AGE_ADULT: // Adult + gSaveContext.linkAge = LINK_AGE_ADULT; + gSaveContext.entranceIndex = ENTR_TEMPLE_OF_TIME_WARP_PAD; + gSaveContext.cutsceneIndex = 0; + break; + case RO_AGE_CHILD: // Child + gSaveContext.linkAge = LINK_AGE_CHILD; + break; + default: + break; + } - for (auto trialFlag : { EVENTCHKINF_COMPLETED_LIGHT_TRIAL, EVENTCHKINF_COMPLETED_FOREST_TRIAL, - EVENTCHKINF_COMPLETED_FIRE_TRIAL, EVENTCHKINF_COMPLETED_WATER_TRIAL, - EVENTCHKINF_COMPLETED_SPIRIT_TRIAL, EVENTCHKINF_COMPLETED_SHADOW_TRIAL }) { - if (!OTRGlobals::Instance->gRandomizer->IsTrialRequired(trialFlag)) { - Flags_SetEventChkInf(trialFlag); - } - } + if (Randomizer_GetSettingValue(RSK_SHUFFLE_OVERWORLD_SPAWNS)) { + // Override the spawn entrance so entrance rando can take control, + // and to prevent remember save location from breaking initial spawn. + gSaveContext.entranceIndex = -1; + } - if (Randomizer_GetSettingValue(RSK_SKIP_CHILD_ZELDA)) { - GetItemEntry getItemEntry = - Randomizer_GetItemFromKnownCheck(RC_SONG_FROM_IMPA, (GetItemID)RG_ZELDAS_LULLABY); - StartingItemGive(getItemEntry, RC_SONG_FROM_IMPA); - getItemEntry = Randomizer_GetItemFromKnownCheck(RC_HC_MALON_EGG, (GetItemID)RG_WEIRD_EGG); - StartingItemGive(getItemEntry, RC_HC_ZELDAS_LETTER); - getItemEntry = Randomizer_GetItemFromKnownCheck(RC_HC_ZELDAS_LETTER, (GetItemID)RG_ZELDAS_LETTER); - StartingItemGive(getItemEntry, RC_HC_MALON_EGG); - - // Malon/Talon back at ranch. - Flags_SetEventChkInf(EVENTCHKINF_OBTAINED_POCKET_EGG); - Flags_SetRandomizerInf(RAND_INF_WEIRD_EGG); - Flags_SetEventChkInf(EVENTCHKINF_TALON_WOKEN_IN_CASTLE); - Flags_SetEventChkInf(EVENTCHKINF_TALON_RETURNED_FROM_CASTLE); - - // Set "Got Zelda's Letter" flag. Also ensures Saria is back at SFM. - Flags_SetEventChkInf(EVENTCHKINF_OBTAINED_ZELDAS_LETTER); - Flags_SetRandomizerInf(RAND_INF_ZELDAS_LETTER); - Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_LETTER_ZELDA); - - // Got item from Impa. - Flags_SetEventChkInf(EVENTCHKINF_LEARNED_ZELDAS_LULLABY); - - gSaveContext.sceneFlags[SCENE_HYRULE_CASTLE].swch |= - (1 << 0x4); // Move milk crates in Hyrule Castle to moat. - - // Set this at the end to ensure we always start with the letter. - // This is for the off chance, we got the Weird Egg from Impa (which should never happen). - INV_CONTENT(ITEM_LETTER_ZELDA) = ITEM_LETTER_ZELDA; + for (auto trialFlag : { EVENTCHKINF_COMPLETED_LIGHT_TRIAL, EVENTCHKINF_COMPLETED_FOREST_TRIAL, + EVENTCHKINF_COMPLETED_FIRE_TRIAL, EVENTCHKINF_COMPLETED_WATER_TRIAL, + EVENTCHKINF_COMPLETED_SPIRIT_TRIAL, EVENTCHKINF_COMPLETED_SHADOW_TRIAL }) { + if (!OTRGlobals::Instance->gRandomizer->IsTrialRequired(trialFlag)) { + Flags_SetEventChkInf(trialFlag); } + } - if (Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD) && startingAge == RO_AGE_ADULT) { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_TOT_MASTER_SWORD, GI_NONE); - StartingItemGive(getItemEntry, RC_TOT_MASTER_SWORD); - Flags_SetRandomizerInf(RAND_INF_TOT_MASTER_SWORD); - } + if (Randomizer_GetSettingValue(RSK_SKIP_CHILD_ZELDA)) { + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_SONG_FROM_IMPA, (GetItemID)RG_ZELDAS_LULLABY); + StartingItemGive(getItemEntry, RC_SONG_FROM_IMPA); + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_HC_MALON_EGG, (GetItemID)RG_WEIRD_EGG); + StartingItemGive(getItemEntry, RC_HC_ZELDAS_LETTER); + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_HC_ZELDAS_LETTER, (GetItemID)RG_ZELDAS_LETTER); + StartingItemGive(getItemEntry, RC_HC_MALON_EGG); + + // Malon/Talon back at ranch. + Flags_SetEventChkInf(EVENTCHKINF_OBTAINED_POCKET_EGG); + Flags_SetRandomizerInf(RAND_INF_WEIRD_EGG); + Flags_SetEventChkInf(EVENTCHKINF_TALON_WOKEN_IN_CASTLE); + Flags_SetEventChkInf(EVENTCHKINF_TALON_RETURNED_FROM_CASTLE); + + // Set "Got Zelda's Letter" flag. Also ensures Saria is back at SFM. + Flags_SetEventChkInf(EVENTCHKINF_OBTAINED_ZELDAS_LETTER); + Flags_SetRandomizerInf(RAND_INF_ZELDAS_LETTER); + Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_LETTER_ZELDA); + + // Got item from Impa. + Flags_SetEventChkInf(EVENTCHKINF_LEARNED_ZELDAS_LULLABY); + + gSaveContext.sceneFlags[SCENE_HYRULE_CASTLE].swch |= (1 << 0x4); // Move milk crates in Hyrule Castle to moat. + + // Set this at the end to ensure we always start with the letter. + // This is for the off chance, we got the Weird Egg from Impa (which should never happen). + INV_CONTENT(ITEM_LETTER_ZELDA) = ITEM_LETTER_ZELDA; + } - HIGH_SCORE(HS_POE_POINTS) = 1000 - (100 * Randomizer_GetSettingValue(RSK_BIG_POE_COUNT)); + if (Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD) && startingAge == RO_AGE_ADULT) { + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_TOT_MASTER_SWORD, GI_NONE); + StartingItemGive(getItemEntry, RC_TOT_MASTER_SWORD); + Flags_SetRandomizerInf(RAND_INF_TOT_MASTER_SWORD); + } - if (Randomizer_GetSettingValue(RSK_SKIP_EPONA_RACE)) { - Flags_SetEventChkInf(EVENTCHKINF_EPONA_OBTAINED); - } + HIGH_SCORE(HS_POE_POINTS) = 1000 - (100 * Randomizer_GetSettingValue(RSK_BIG_POE_COUNT)); - // Open lowest Vanilla Fire Temple locked door (to prevent key logic lockouts). - // Not done on Keysanity since this lockout is a non-issue when Fire Keys can be found outside the temple. - u8 keysanity = Randomizer_GetSettingValue(RSK_KEYSANITY) == RO_DUNGEON_ITEM_LOC_ANYWHERE || - Randomizer_GetSettingValue(RSK_KEYSANITY) == RO_DUNGEON_ITEM_LOC_OVERWORLD || - Randomizer_GetSettingValue(RSK_KEYSANITY) == RO_DUNGEON_ITEM_LOC_ANY_DUNGEON; - if (!ResourceMgr_IsSceneMasterQuest(SCENE_FIRE_TEMPLE) && !keysanity) { - gSaveContext.sceneFlags[SCENE_FIRE_TEMPLE].swch |= (1 << 0x17); - } + if (Randomizer_GetSettingValue(RSK_SKIP_EPONA_RACE)) { + Flags_SetEventChkInf(EVENTCHKINF_EPONA_OBTAINED); + } - // Opens locked Water Temple door in vanilla to prevent softlocks. - // West door on the middle level that leads to the water raising thing. - // Happens in 3DS rando and N64 rando as well. - if (!ResourceMgr_IsSceneMasterQuest(SCENE_WATER_TEMPLE)) { - gSaveContext.sceneFlags[SCENE_WATER_TEMPLE].swch |= (1 << 0x15); - } + // Open lowest Vanilla Fire Temple locked door (to prevent key logic lockouts). + // Not done on Keysanity since this lockout is a non-issue when Fire Keys can be found outside the temple. + u8 keysanity = Randomizer_GetSettingValue(RSK_KEYSANITY) == RO_DUNGEON_ITEM_LOC_ANYWHERE || + Randomizer_GetSettingValue(RSK_KEYSANITY) == RO_DUNGEON_ITEM_LOC_OVERWORLD || + Randomizer_GetSettingValue(RSK_KEYSANITY) == RO_DUNGEON_ITEM_LOC_ANY_DUNGEON; + if (!ResourceMgr_IsSceneMasterQuest(SCENE_FIRE_TEMPLE) && !keysanity) { + gSaveContext.sceneFlags[SCENE_FIRE_TEMPLE].swch |= (1 << 0x17); + } - int doorOfTime = Randomizer_GetSettingValue(RSK_DOOR_OF_TIME); - switch (doorOfTime) { - case RO_DOOROFTIME_OPEN: - Flags_SetEventChkInf(EVENTCHKINF_OPENED_THE_DOOR_OF_TIME); - break; - } + // Opens locked Water Temple door in vanilla to prevent softlocks. + // West door on the middle level that leads to the water raising thing. + // Happens in 3DS rando and N64 rando as well. + if (!ResourceMgr_IsSceneMasterQuest(SCENE_WATER_TEMPLE)) { + gSaveContext.sceneFlags[SCENE_WATER_TEMPLE].swch |= (1 << 0x15); + } - if (Randomizer_GetSettingValue(RSK_KAK_GATE) == RO_KAK_GATE_OPEN) { - Flags_SetInfTable(INFTABLE_SHOWED_ZELDAS_LETTER_TO_GATE_GUARD); - Flags_UnsetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_LETTER_ZELDA); - } + int doorOfTime = Randomizer_GetSettingValue(RSK_DOOR_OF_TIME); + switch (doorOfTime) { + case RO_DOOROFTIME_OPEN: + Flags_SetEventChkInf(EVENTCHKINF_OPENED_THE_DOOR_OF_TIME); + break; + } - if (Randomizer_GetSettingValue(RSK_GERUDO_FORTRESS) == RO_GF_CARPENTERS_FAST || - Randomizer_GetSettingValue(RSK_GERUDO_FORTRESS) == RO_GF_CARPENTERS_FREE) { - Flags_SetEventChkInf(EVENTCHKINF_CARPENTERS_FREE(1)); - Flags_SetEventChkInf(EVENTCHKINF_CARPENTERS_FREE(2)); - Flags_SetEventChkInf(EVENTCHKINF_CARPENTERS_FREE(3)); - gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x02); // heard yells and unlocked doors - gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x03); - gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x04); - gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x06); - gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x07); - gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x08); - gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x10); - gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x12); - gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x13); - gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].collect |= (1 << 0x0A); // picked up keys - gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].collect |= (1 << 0x0E); - gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].collect |= (1 << 0x0F); - } + if (Randomizer_GetSettingValue(RSK_KAK_GATE) == RO_KAK_GATE_OPEN) { + Flags_SetInfTable(INFTABLE_SHOWED_ZELDAS_LETTER_TO_GATE_GUARD); + Flags_UnsetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_LETTER_ZELDA); + } - if (Randomizer_GetSettingValue(RSK_GERUDO_FORTRESS) == RO_GF_CARPENTERS_FREE) { - Flags_SetEventChkInf(EVENTCHKINF_CARPENTERS_FREE(0)); - gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x01); // heard yell and unlocked door - gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x05); - gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x11); - gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].collect |= (1 << 0x0C); // picked up key + if (Randomizer_GetSettingValue(RSK_GERUDO_FORTRESS) == RO_GF_CARPENTERS_FAST || + Randomizer_GetSettingValue(RSK_GERUDO_FORTRESS) == RO_GF_CARPENTERS_FREE) { + Flags_SetEventChkInf(EVENTCHKINF_CARPENTERS_FREE(1)); + Flags_SetEventChkInf(EVENTCHKINF_CARPENTERS_FREE(2)); + Flags_SetEventChkInf(EVENTCHKINF_CARPENTERS_FREE(3)); + gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x02); // heard yells and unlocked doors + gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x03); + gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x04); + gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x06); + gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x07); + gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x08); + gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x10); + gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x12); + gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x13); + gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].collect |= (1 << 0x0A); // picked up keys + gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].collect |= (1 << 0x0E); + gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].collect |= (1 << 0x0F); + } - if (!Randomizer_GetSettingValue(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD)) { - Item_Give(NULL, ITEM_GERUDO_CARD); - } - } + if (Randomizer_GetSettingValue(RSK_GERUDO_FORTRESS) == RO_GF_CARPENTERS_FREE) { + Flags_SetEventChkInf(EVENTCHKINF_CARPENTERS_FREE(0)); + gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x01); // heard yell and unlocked door + gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x05); + gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x11); + gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].collect |= (1 << 0x0C); // picked up key - // complete mask quest - if (Randomizer_GetSettingValue(RSK_MASK_QUEST) == RO_MASK_QUEST_COMPLETED) { - Flags_SetInfTable(INFTABLE_GATE_GUARD_PUT_ON_KEATON_MASK); - Flags_SetEventChkInf(EVENTCHKINF_PAID_BACK_BUNNY_HOOD_FEE); - - Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_KEATON); - Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_SKULL); - Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_SPOOKY); - Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_BUNNY); - Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_GORON); - Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_ZORA); - Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_GERUDO); - Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_TRUTH); - - gSaveContext.itemGetInf[3] |= 0x100; // Sold Keaton Mask - gSaveContext.itemGetInf[3] |= 0x200; // Sold Skull Mask - gSaveContext.itemGetInf[3] |= 0x400; // Sold Spooky Mask - gSaveContext.itemGetInf[3] |= 0x800; // Bunny Hood related - gSaveContext.itemGetInf[3] |= 0x8000; // Obtained Mask of Truth + if (!Randomizer_GetSettingValue(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD)) { + Item_Give(NULL, ITEM_GERUDO_CARD); } } -} \ No newline at end of file + + // complete mask quest + if (Randomizer_GetSettingValue(RSK_MASK_QUEST) == RO_MASK_QUEST_COMPLETED) { + Flags_SetInfTable(INFTABLE_GATE_GUARD_PUT_ON_KEATON_MASK); + Flags_SetEventChkInf(EVENTCHKINF_PAID_BACK_BUNNY_HOOD_FEE); + + Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_KEATON); + Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_SKULL); + Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_SPOOKY); + Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_BUNNY); + Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_GORON); + Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_ZORA); + Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_GERUDO); + Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_TRUTH); + + gSaveContext.itemGetInf[3] |= 0x100; // Sold Keaton Mask + gSaveContext.itemGetInf[3] |= 0x200; // Sold Skull Mask + gSaveContext.itemGetInf[3] |= 0x400; // Sold Spooky Mask + gSaveContext.itemGetInf[3] |= 0x800; // Bunny Hood related + gSaveContext.itemGetInf[3] |= 0x8000; // Obtained Mask of Truth + } +} diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index dbfe6ff42a1..78ead12dd64 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -786,7 +786,6 @@ void Settings::CreateOptions() { OPT_BOOL(RSK_SHUFFLE_OCARINA_BUTTONS, "Shuffle Ocarina Buttons", CVAR_RANDOMIZER_SETTING("ShuffleOcarinaButtons"), mOptionDescriptions[RSK_SHUFFLE_OCARINA_BUTTONS]); OPT_BOOL(RSK_SHUFFLE_SWIM, "Shuffle Swim", CVAR_RANDOMIZER_SETTING("ShuffleSwim"), mOptionDescriptions[RSK_SHUFFLE_SWIM]); OPT_BOOL(RSK_SHUFFLE_CLIMB, "Shuffle Climb", CVAR_RANDOMIZER_SETTING("ShuffleClimb"), mOptionDescriptions[RSK_SHUFFLE_CLIMB]); - OPT_BOOL(RSK_SHUFFLE_ROLL, "Shuffle Roll", CVAR_RANDOMIZER_SETTING("ShuffleRoll"), mOptionDescriptions[RSK_SHUFFLE_ROLL]); OPT_BOOL(RSK_SHUFFLE_CRAWL, "Shuffle Crawl", CVAR_RANDOMIZER_SETTING("ShuffleCrawl"), mOptionDescriptions[RSK_SHUFFLE_CRAWL]); OPT_BOOL(RSK_SHUFFLE_ROLL, "Shuffle Roll", CVAR_RANDOMIZER_SETTING("ShuffleRoll"), mOptionDescriptions[RSK_SHUFFLE_ROLL]); OPT_BOOL(RSK_SHUFFLE_GRAB, "Shuffle Grab", CVAR_RANDOMIZER_SETTING("ShuffleGrab"), mOptionDescriptions[RSK_SHUFFLE_GRAB]); @@ -797,8 +796,6 @@ void Settings::CreateOptions() { OPT_U8(RSK_SHUFFLE_GRASS, "Shuffle Grass", {"Off", "Dungeons", "Overworld", "All Grass/Bushes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleGrass"), mOptionDescriptions[RSK_SHUFFLE_GRASS], WIDGET_CVAR_COMBOBOX, RO_SHUFFLE_GRASS_OFF); OPT_U8(RSK_SHUFFLE_CRATES, "Shuffle Crates", {"Off", "Dungeons", "Overworld", "All Crates"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleCrates"), mOptionDescriptions[RSK_SHUFFLE_CRATES], WIDGET_CVAR_COMBOBOX, RO_SHUFFLE_CRATES_OFF); OPT_BOOL(RSK_SHUFFLE_TREES, "Shuffle Trees", CVAR_RANDOMIZER_SETTING("ShuffleTrees"), mOptionDescriptions[RSK_SHUFFLE_TREES]); - OPT_BOOL(RSK_SHUFFLE_ROCKS, "Shuffle Rocks", CVAR_RANDOMIZER_SETTING("ShuffleRocks"), mOptionDescriptions[RSK_SHUFFLE_ROCKS]); - OPT_U8(RSK_SHUFFLE_BOULDERS, "Shuffle Boulders", {"Off", "Dungeons", "Overworld", "All Boulders"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleBoulders"), mOptionDescriptions[RSK_SHUFFLE_BOULDERS], WIDGET_CVAR_COMBOBOX, RO_SHUFFLE_BOULDERS_OFF); OPT_BOOL(RSK_SHUFFLE_BUSHES, "Shuffle Bushes", CVAR_RANDOMIZER_SETTING("ShuffleBushes"), mOptionDescriptions[RSK_SHUFFLE_BUSHES]); OPT_BOOL(RSK_SHUFFLE_FISHING_POLE, "Shuffle Fishing Pole", CVAR_RANDOMIZER_SETTING("ShuffleFishingPole"), mOptionDescriptions[RSK_SHUFFLE_FISHING_POLE]); OPT_CALLBACK(RSK_SHUFFLE_FISHING_POLE, { @@ -2334,8 +2331,6 @@ void Settings::CreateOptions() { &mOptions[RSK_FISHSANITY_AGE_SPLIT], &mOptions[RSK_SHUFFLE_FREESTANDING], &mOptions[RSK_SHUFFLE_BEEHIVES], - &mOptions[RSK_SHUFFLE_ROCKS], - &mOptions[RSK_SHUFFLE_BOULDERS], &mOptions[RSK_SHUFFLE_COWS], &mOptions[RSK_SHUFFLE_POTS], &mOptions[RSK_SHUFFLE_GRASS], @@ -2379,7 +2374,6 @@ void Settings::CreateOptions() { &mOptions[RSK_SCRUBS_PRICES_GIANT_WALLET_WEIGHT], &mOptions[RSK_SCRUBS_PRICES_TYCOON_WALLET_WEIGHT], &mOptions[RSK_SCRUBS_PRICES_AFFORDABLE], - &mOptions[RSK_SHUFFLE_MERCHANTS], &mOptions[RSK_MERCHANT_PRICES], &mOptions[RSK_MERCHANT_PRICES_FIXED_PRICE], @@ -2406,7 +2400,6 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_SWIM], &mOptions[RSK_SHUFFLE_GRAB], &mOptions[RSK_SHUFFLE_CLIMB], - &mOptions[RSK_SHUFFLE_ROLL], &mOptions[RSK_SHUFFLE_CRAWL], &mOptions[RSK_SHUFFLE_ROLL], &mOptions[RSK_SHUFFLE_OPEN_CHEST], @@ -2624,15 +2617,12 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_CRATES], &mOptions[RSK_SHUFFLE_TREES], &mOptions[RSK_SHUFFLE_BUSHES], - &mOptions[RSK_SHUFFLE_ROCKS], - &mOptions[RSK_SHUFFLE_BOULDERS], &mOptions[RSK_SHUFFLE_KOKIRI_SWORD], &mOptions[RSK_SHUFFLE_OCARINA], &mOptions[RSK_SHUFFLE_OCARINA_BUTTONS], &mOptions[RSK_SHUFFLE_SWIM], &mOptions[RSK_SHUFFLE_GRAB], &mOptions[RSK_SHUFFLE_CLIMB], - &mOptions[RSK_SHUFFLE_ROLL], &mOptions[RSK_SHUFFLE_CRAWL], &mOptions[RSK_SHUFFLE_ROLL], &mOptions[RSK_SHUFFLE_OPEN_CHEST], diff --git a/soh/soh/Enhancements/randomizer/static_data.h b/soh/soh/Enhancements/randomizer/static_data.h index a0b084e6caf..0b837179ba2 100644 --- a/soh/soh/Enhancements/randomizer/static_data.h +++ b/soh/soh/Enhancements/randomizer/static_data.h @@ -62,7 +62,6 @@ class StaticData { static void RegisterGrassLocations(); static void RegisterCrateLocations(); static void RegisterTreeLocations(); - static void RegisterRockLocations(); static void InitHashMaps(); static std::array, 17> randomizerFishingPondFish; static std::unordered_map randomizerGrottoFishMap; diff --git a/soh/soh/SohGui/SohMenuEnhancements.cpp b/soh/soh/SohGui/SohMenuEnhancements.cpp index bb603240da2..accd7a6649e 100644 --- a/soh/soh/SohGui/SohMenuEnhancements.cpp +++ b/soh/soh/SohGui/SohMenuEnhancements.cpp @@ -290,10 +290,6 @@ void SohMenu::AddMenuEnhancements() { .CVar(CVAR_ENHANCEMENT("BetterOwl")) .Options(CheckboxOptions().Tooltip( "The default response to Kaepora Gaebora is always that you understood what he said.")); - AddWidget(path, "Allow Dropping Throw-Only Objects", WIDGET_CVAR_CHECKBOX) - .CVar(CVAR_ENHANCEMENT("DropThrowOnlyObjects")) - .Options(CheckboxOptions().Tooltip("Allows normally throw-only objects (such as Cuccos, pots, grass, and small " - "rocks) to be dropped by pressing A while standing still.")); AddWidget(path, "Convenience", WIDGET_SEPARATOR_TEXT); AddWidget(path, "Quit Fishing at Door", WIDGET_CVAR_CHECKBOX) @@ -1773,9 +1769,6 @@ void SohMenu::AddMenuEnhancements() { .Options(CheckboxOptions().Tooltip( "Keese and Guay no longer target you and simply ignore you as if you were wearing the " "Skull Mask.")); - AddWidget(path, "Like Like don't Steal Items", WIDGET_CVAR_CHECKBOX) - .CVar(CVAR_CHEAT("NoLikeLikeItemSteal")) - .Options(CheckboxOptions().Tooltip("Prevents Like Likes from being able to steal your equipments.")); AddWidget(path, "Disable Haunted Wasteland Sandstorm", WIDGET_CVAR_CHECKBOX) .CVar(CVAR_CHEAT("DisableSandstorm")) .Options(CheckboxOptions().Tooltip("Disables sandstorm effect in Haunted Wasteland.")); diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index 3d46ae0c87d..049f0eaf574 100644 --- a/soh/src/code/z_parameter.c +++ b/soh/src/code/z_parameter.c @@ -2814,7 +2814,7 @@ void Interface_SetNaviCall(PlayState* play, u16 naviCallState) { if (((naviCallState == 0x1D) || (naviCallState == 0x1E)) && !interfaceCtx->naviCalling && (play->csCtx.state == CS_STATE_IDLE)) { - if (GameInteractor_Should(VB_PLAY_NAVI_CALL_SOUND, true, naviCallState)) { + if (!CVarGetInteger(CVAR_AUDIO("DisableNaviCallAudio"), 0)) { // clang-format off if (naviCallState == 0x1E) { Audio_PlaySoundGeneral(NA_SE_VO_NAVY_CALL, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } diff --git a/soh/src/overlays/actors/ovl_En_Elf/z_en_elf.c b/soh/src/overlays/actors/ovl_En_Elf/z_en_elf.c index 94f3d75a411..96a9297b969 100644 --- a/soh/src/overlays/actors/ovl_En_Elf/z_en_elf.c +++ b/soh/src/overlays/actors/ovl_En_Elf/z_en_elf.c @@ -817,30 +817,28 @@ void EnElf_UpdateLights(EnElf* this, PlayState* play) { s16 glowLightRadius; Player* player; - if (GameInteractor_Should(VB_FAIRY_UPDATE_LIGHTS, true, this)) { - glowLightRadius = 100; + glowLightRadius = 100; - if (this->unk_2A8 == 8) { - glowLightRadius = 0; - } + if (this->unk_2A8 == 8) { + glowLightRadius = 0; + } - if (this->fairyFlags & 0x20) { - player = GET_PLAYER(play); - Lights_PointNoGlowSetInfo(&this->lightInfoNoGlow, player->actor.world.pos.x, - (s16)(player->actor.world.pos.y) + 60.0f, player->actor.world.pos.z, 255, 255, - 255, 200); - } else { - Lights_PointNoGlowSetInfo(&this->lightInfoNoGlow, this->actor.world.pos.x, this->actor.world.pos.y, - this->actor.world.pos.z, 255, 255, 255, -1); - } + if (this->fairyFlags & 0x20) { + player = GET_PLAYER(play); + Lights_PointNoGlowSetInfo(&this->lightInfoNoGlow, player->actor.world.pos.x, + (s16)(player->actor.world.pos.y) + 60.0f, player->actor.world.pos.z, 255, 255, 255, + 200); + } else { + Lights_PointNoGlowSetInfo(&this->lightInfoNoGlow, this->actor.world.pos.x, this->actor.world.pos.y, + this->actor.world.pos.z, 255, 255, 255, -1); + } - Lights_PointGlowSetInfo(&this->lightInfoGlow, this->actor.world.pos.x, this->actor.world.pos.y, - this->actor.world.pos.z, 255, 255, 255, glowLightRadius); + Lights_PointGlowSetInfo(&this->lightInfoGlow, this->actor.world.pos.x, this->actor.world.pos.y, + this->actor.world.pos.z, 255, 255, 255, glowLightRadius); - this->unk_2BC = Math_Atan2S(this->actor.velocity.z, this->actor.velocity.x); + this->unk_2BC = Math_Atan2S(this->actor.velocity.z, this->actor.velocity.x); - Actor_SetScale(&this->actor, this->actor.scale.x); - } + Actor_SetScale(&this->actor, this->actor.scale.x); } void func_80A03CF8(EnElf* this, PlayState* play) { @@ -874,9 +872,7 @@ void func_80A03CF8(EnElf* this, PlayState* play) { if ((play->sceneNum == SCENE_LINKS_HOUSE) && (gSaveContext.sceneSetupIndex == 4)) { // play dash sound as Navi enters Links house in the intro if (play->csCtx.frames == 55) { - if (GameInteractor_Should(VB_FAIRY_PLAY_DASH_SOUND, true, this)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_FAIRY_DASH); - } + Audio_PlayActorSound2(&this->actor, NA_SE_EV_FAIRY_DASH); } // play dash sound in intervals as Navi is waking up Link in the intro @@ -888,9 +884,7 @@ void func_80A03CF8(EnElf* this, PlayState* play) { } else { if (this->actor.world.pos.y < prevPos.y) { this->fairyFlags |= 0x40; - if (GameInteractor_Should(VB_FAIRY_PLAY_DASH_SOUND, true, this)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_FAIRY_DASH); - } + Audio_PlayActorSound2(&this->actor, NA_SE_EV_FAIRY_DASH); } } } @@ -973,9 +967,7 @@ void func_80A03CF8(EnElf* this, PlayState* play) { this->fairyFlags |= 2; if (this->unk_2C7 == 0) { - if (GameInteractor_Should(VB_FAIRY_PLAY_DASH_SOUND, true, this)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_FAIRY_DASH); - } + Audio_PlayActorSound2(&this->actor, NA_SE_EV_FAIRY_DASH); } this->unk_2C0 = 0x64; @@ -1023,9 +1015,7 @@ void func_80A04414(EnElf* this, PlayState* play) { this->unk_29C = 1.0f; if (this->unk_2C7 == 0) { - if (GameInteractor_Should(VB_FAIRY_PLAY_DASH_SOUND, true, this)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_FAIRY_DASH); - } + Audio_PlayActorSound2(&this->actor, NA_SE_EV_FAIRY_DASH); } } else { @@ -1115,9 +1105,7 @@ void func_80A0461C(EnElf* this, PlayState* play) { temp = 0; } else { if (this->unk_2C7 == 0) { - if (GameInteractor_Should(VB_FAIRY_PLAY_VANISH_SOUND, true, this)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_NAVY_VANISH); - } + Audio_PlayActorSound2(&this->actor, NA_SE_EV_NAVY_VANISH); } temp = 7; } @@ -1161,9 +1149,7 @@ void func_80A0461C(EnElf* this, PlayState* play) { if (!(player->stateFlags2 & PLAYER_STATE2_NAVI_ACTIVE)) { temp = 7; if (this->unk_2C7 == 0) { - if (GameInteractor_Should(VB_FAIRY_PLAY_VANISH_SOUND, true, this)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_NAVY_VANISH); - } + Audio_PlayActorSound2(&this->actor, NA_SE_EV_NAVY_VANISH); } } break; @@ -1173,9 +1159,7 @@ void func_80A0461C(EnElf* this, PlayState* play) { this->unk_2C0 = 42; temp = 11; if (this->unk_2C7 == 0) { - if (GameInteractor_Should(VB_FAIRY_PLAY_DASH_SOUND, true, this)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_FAIRY_DASH); - } + Audio_PlayActorSound2(&this->actor, NA_SE_EV_FAIRY_DASH); } } break; @@ -1206,22 +1190,20 @@ void EnElf_SpawnSparkles(EnElf* this, PlayState* play, s32 sparkleLife) { Color_RGBA8 primColor; Color_RGBA8 envColor; - if (GameInteractor_Should(VB_FAIRY_SPAWN_SPARKLES, true, this, sparkleLife)) { - sparklePos.x = Rand_CenteredFloat(6.0f) + this->actor.world.pos.x; - sparklePos.y = (Rand_ZeroOne() * 6.0f) + this->actor.world.pos.y; - sparklePos.z = Rand_CenteredFloat(6.0f) + this->actor.world.pos.z; + sparklePos.x = Rand_CenteredFloat(6.0f) + this->actor.world.pos.x; + sparklePos.y = (Rand_ZeroOne() * 6.0f) + this->actor.world.pos.y; + sparklePos.z = Rand_CenteredFloat(6.0f) + this->actor.world.pos.z; - primColor.r = this->innerColor.r; - primColor.g = this->innerColor.g; - primColor.b = this->innerColor.b; + primColor.r = this->innerColor.r; + primColor.g = this->innerColor.g; + primColor.b = this->innerColor.b; - envColor.r = this->outerColor.r; - envColor.g = this->outerColor.g; - envColor.b = this->outerColor.b; + envColor.r = this->outerColor.r; + envColor.g = this->outerColor.g; + envColor.b = this->outerColor.b; - EffectSsKiraKira_SpawnDispersed(play, &sparklePos, &sparkleVelocity, &sparkleAccel, &primColor, &envColor, 1000, - sparkleLife); - } + EffectSsKiraKira_SpawnDispersed(play, &sparklePos, &sparkleVelocity, &sparkleAccel, &primColor, &envColor, 1000, + sparkleLife); } void func_80A04D90(EnElf* this, PlayState* play) { @@ -1410,9 +1392,7 @@ void func_80A053F0(Actor* thisx, PlayState* play) { } if (Actor_ProcessTalkRequest(thisx, play)) { - if (GameInteractor_Should(VB_FAIRY_PLAY_C_UP_TALK_SOUND, true, this)) { - func_800F4524(&gSfxDefaultPos, NA_SE_VO_SK_LAUGH, 0x20); - } + func_800F4524(&gSfxDefaultPos, NA_SE_VO_SK_LAUGH, 0x20); thisx->focus.pos = thisx->world.pos; if (thisx->textId == ElfMessage_GetCUpText(play)) { @@ -1526,7 +1506,7 @@ void EnElf_Draw(Actor* thisx, PlayState* play) { Gfx* dListHead; Player* player = GET_PLAYER(play); - if (GameInteractor_Should(VB_FAIRY_DRAW, ((this->unk_2A8 != 8) && !(this->fairyFlags & 8)), this)) { + if ((this->unk_2A8 != 8) && !(this->fairyFlags & 8)) { if (!(player->stateFlags1 & PLAYER_STATE1_FIRST_PERSON) || (kREG(90) < this->actor.projectedPos.z)) { dListHead = Graph_Alloc(play->state.gfxCtx, sizeof(Gfx) * 4); diff --git a/soh/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c b/soh/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c index fccc1a0d222..37dc1fa9db7 100644 --- a/soh/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c +++ b/soh/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c @@ -8,7 +8,6 @@ #include "overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.h" #include "objects/gameplay_field_keep/gameplay_field_keep.h" #include "soh/OTRGlobals.h" -#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include "vt.h" @@ -252,10 +251,6 @@ void EnIshi_SpawnDustLarge(EnIshi* this, PlayState* play) { void EnIshi_DropCollectible(EnIshi* this, PlayState* play) { s16 dropParams; - if (!GameInteractor_Should(VB_ROCK_DROP_ITEM, true, this)) { - return; - } - if ((this->actor.params & 1) == ROCK_SMALL) { dropParams = (this->actor.params >> 8) & 0xF; diff --git a/soh/src/overlays/actors/ovl_En_Rr/z_en_rr.c b/soh/src/overlays/actors/ovl_En_Rr/z_en_rr.c index d94e6dd220b..831e11b8c38 100644 --- a/soh/src/overlays/actors/ovl_En_Rr/z_en_rr.c +++ b/soh/src/overlays/actors/ovl_En_Rr/z_en_rr.c @@ -300,35 +300,32 @@ void EnRr_SetupReleasePlayer(EnRr* this, PlayState* play) { this->wobbleSizeTarget = 2048.0f; tunic = 0; shield = 0; - if (GameInteractor_Should(VB_LIKE_LIKE_STEAL_EQUIPMENT, true, this)) { - if (CUR_EQUIP_VALUE(EQUIP_TYPE_SHIELD) != EQUIP_VALUE_SHIELD_MIRROR) { - shield = Inventory_DeleteEquipment(play, EQUIP_TYPE_SHIELD); - if (shield != 0) { - this->eatenShield = shield; - this->retreat = true; - } - } - if (CUR_EQUIP_VALUE(EQUIP_TYPE_TUNIC) != EQUIP_VALUE_TUNIC_KOKIRI && !IS_RANDO /* Randomizer Save File */) { - tunic = Inventory_DeleteEquipment(play, EQUIP_TYPE_TUNIC); - if (tunic != 0) { - this->eatenTunic = tunic; - this->retreat = true; - } + if (CUR_EQUIP_VALUE(EQUIP_TYPE_SHIELD) != EQUIP_VALUE_SHIELD_MIRROR) { + shield = Inventory_DeleteEquipment(play, EQUIP_TYPE_SHIELD); + if (shield != 0) { + this->eatenShield = shield; + this->retreat = true; } - - switch (EnRr_GetMessage(shield, tunic)) { - case RR_MESSAGE_SHIELD: - Message_StartTextbox(play, 0x305F, NULL); - break; - case RR_MESSAGE_TUNIC: - Message_StartTextbox(play, 0x3060, NULL); - break; - case RR_MESSAGE_TUNIC | RR_MESSAGE_SHIELD: - Message_StartTextbox(play, 0x3061, NULL); - break; + } + if (CUR_EQUIP_VALUE(EQUIP_TYPE_TUNIC) != EQUIP_VALUE_TUNIC_KOKIRI && !IS_RANDO /* Randomizer Save File */) { + tunic = Inventory_DeleteEquipment(play, EQUIP_TYPE_TUNIC); + if (tunic != 0) { + this->eatenTunic = tunic; + this->retreat = true; } } player->actor.parent = NULL; + switch (EnRr_GetMessage(shield, tunic)) { + case RR_MESSAGE_SHIELD: + Message_StartTextbox(play, 0x305F, NULL); + break; + case RR_MESSAGE_TUNIC: + Message_StartTextbox(play, 0x3060, NULL); + break; + case RR_MESSAGE_TUNIC | RR_MESSAGE_SHIELD: + Message_StartTextbox(play, 0x3061, NULL); + break; + } osSyncPrintf(VT_FGCOL(YELLOW) "%s[%d] : Rr_Catch_Cancel" VT_RST "\n", __FILE__, __LINE__); func_8002F6D4(play, &this->actor, 4.0f, this->actor.shape.rot.y, 12.0f, 8); if (this->actor.colorFilterTimer == 0) { @@ -669,53 +666,50 @@ void EnRr_Death(EnRr* this, PlayState* play) { (SQ(4 - i) * (f32)this->frameCount * 0.003f) + 1.0f; } } else if (this->frameCount >= 95) { - if (GameInteractor_Should(VB_LIKE_LIKE_DROP_COLLECTIBLE, true, this)) { - Vec3f dropPos; - - dropPos.x = this->actor.world.pos.x; - dropPos.y = this->actor.world.pos.y; - dropPos.z = this->actor.world.pos.z; - switch (this->eatenShield) { - case 1: - Item_DropCollectible(play, &dropPos, ITEM00_SHIELD_DEKU); - break; - case 2: - Item_DropCollectible(play, &dropPos, ITEM00_SHIELD_HYLIAN); - break; - } - switch (this->eatenTunic) { - case 2: - Item_DropCollectible(play, &dropPos, ITEM00_TUNIC_GORON); - break; - case 3: - Item_DropCollectible(play, &dropPos, ITEM00_TUNIC_ZORA); - break; - } - // "dropped" - osSyncPrintf(VT_FGCOL(GREEN) "「%s」が出た!!" VT_RST "\n", sDropNames[this->dropType]); - switch (this->dropType) { - case RR_DROP_MAGIC: - Item_DropCollectible(play, &dropPos, ITEM00_MAGIC_SMALL); - break; - case RR_DROP_ARROW: - Item_DropCollectible(play, &dropPos, ITEM00_ARROWS_SINGLE); - break; - case RR_DROP_FLEXIBLE: - Item_DropCollectible(play, &dropPos, ITEM00_FLEXIBLE); - break; - case RR_DROP_RUPEE_PURPLE: - Item_DropCollectible(play, &dropPos, ITEM00_RUPEE_PURPLE); - break; - case RR_DROP_RUPEE_RED: - Item_DropCollectible(play, &dropPos, ITEM00_RUPEE_RED); - break; - case RR_DROP_RANDOM_RUPEE: - default: - Item_DropCollectibleRandom(play, &this->actor, &dropPos, 12 << 4); - break; - } + Vec3f dropPos; + + dropPos.x = this->actor.world.pos.x; + dropPos.y = this->actor.world.pos.y; + dropPos.z = this->actor.world.pos.z; + switch (this->eatenShield) { + case 1: + Item_DropCollectible(play, &dropPos, ITEM00_SHIELD_DEKU); + break; + case 2: + Item_DropCollectible(play, &dropPos, ITEM00_SHIELD_HYLIAN); + break; + } + switch (this->eatenTunic) { + case 2: + Item_DropCollectible(play, &dropPos, ITEM00_TUNIC_GORON); + break; + case 3: + Item_DropCollectible(play, &dropPos, ITEM00_TUNIC_ZORA); + break; + } + // "dropped" + osSyncPrintf(VT_FGCOL(GREEN) "「%s」が出た!!" VT_RST "\n", sDropNames[this->dropType]); + switch (this->dropType) { + case RR_DROP_MAGIC: + Item_DropCollectible(play, &dropPos, ITEM00_MAGIC_SMALL); + break; + case RR_DROP_ARROW: + Item_DropCollectible(play, &dropPos, ITEM00_ARROWS_SINGLE); + break; + case RR_DROP_FLEXIBLE: + Item_DropCollectible(play, &dropPos, ITEM00_FLEXIBLE); + break; + case RR_DROP_RUPEE_PURPLE: + Item_DropCollectible(play, &dropPos, ITEM00_RUPEE_PURPLE); + break; + case RR_DROP_RUPEE_RED: + Item_DropCollectible(play, &dropPos, ITEM00_RUPEE_RED); + break; + case RR_DROP_RANDOM_RUPEE: + default: + Item_DropCollectibleRandom(play, &this->actor, &dropPos, 12 << 4); + break; } - Actor_Kill(&this->actor); } else if (this->frameCount == 88) { Vec3f pos; diff --git a/soh/src/overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.c b/soh/src/overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.c index 019a09320c1..602236816e0 100644 --- a/soh/src/overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.c +++ b/soh/src/overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.c @@ -7,7 +7,6 @@ #include "z_obj_bombiwa.h" #include "overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.h" #include "objects/object_bombiwa/object_bombiwa.h" -#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS 0 @@ -76,7 +75,7 @@ void ObjBombiwa_InitCollision(Actor* thisx, PlayState* play) { void ObjBombiwa_Init(Actor* thisx, PlayState* play) { Actor_ProcessInitChain(thisx, sInitChain); ObjBombiwa_InitCollision(thisx, play); - if (GameInteractor_Should(VB_BOULDER_BREAK_FLAG, Flags_GetSwitch(play, thisx->params & 0x3F), thisx)) { + if ((Flags_GetSwitch(play, thisx->params & 0x3F) != 0)) { Actor_Kill(thisx); } else { CollisionCheck_SetInfo(&thisx->colChkInfo, NULL, &sColChkInfoInit); diff --git a/soh/src/overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.c b/soh/src/overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.c index c609992d72b..d4d952cc0bc 100644 --- a/soh/src/overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.c +++ b/soh/src/overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.c @@ -6,7 +6,6 @@ #include "z_obj_hamishi.h" #include "objects/gameplay_field_keep/gameplay_field_keep.h" -#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS 0 @@ -151,7 +150,7 @@ void ObjHamishi_Init(Actor* thisx, PlayState* play) { ObjHamishi_InitCollision(&this->actor, play); CollisionCheck_SetInfo(&this->actor.colChkInfo, NULL, &sColChkInfoInit); - if (GameInteractor_Should(VB_BOULDER_BREAK_FLAG, Flags_GetSwitch(play, this->actor.params & 0x3F), this)) { + if (Flags_GetSwitch(play, this->actor.params & 0x3F)) { Actor_Kill(&this->actor); return; } diff --git a/soh/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c b/soh/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c index 8582f2e3ea3..2b8cfcb7a10 100644 --- a/soh/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c +++ b/soh/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c @@ -8,7 +8,6 @@ #include "objects/object_demo_kekkai/object_demo_kekkai.h" #include "objects/gameplay_keep/gameplay_keep.h" #include "objects/object_spot02_objects/object_spot02_objects.h" -#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include "soh/frame_interpolation.h" #include @@ -206,25 +205,23 @@ void ObjectKankyo_Fairies(ObjectKankyo* this, PlayState* play) { dist = 1.0f; } - if (GameInteractor_Should(VB_PLAY_INTRO_NAVI_SOUNDS, true, this)) { - func_800F436C(&sSoundPos, NA_SE_EV_NAVY_FLY - SFX_FLAG, (0.4f * dist) + 0.6f); - switch (play->csCtx.frames) { - case 473: - Sfx_PlaySfxCentered2(NA_SE_VO_NA_HELLO_3); - break; + func_800F436C(&sSoundPos, NA_SE_EV_NAVY_FLY - SFX_FLAG, (0.4f * dist) + 0.6f); + switch (play->csCtx.frames) { + case 473: + Sfx_PlaySfxCentered2(NA_SE_VO_NA_HELLO_3); + break; - case 583: - func_800F4524(&gSfxDefaultPos, NA_SE_VO_NA_HELLO_2, 32); - break; + case 583: + func_800F4524(&gSfxDefaultPos, NA_SE_VO_NA_HELLO_2, 32); + break; - case 763: - Sfx_PlaySfxCentered(NA_SE_EV_NAVY_CRASH - SFX_FLAG); - break; + case 763: + Sfx_PlaySfxCentered(NA_SE_EV_NAVY_CRASH - SFX_FLAG); + break; - case 771: - Sfx_PlaySfxCentered(NA_SE_VO_RT_THROW); - break; - } + case 771: + Sfx_PlaySfxCentered(NA_SE_VO_RT_THROW); + break; } } From 447272879a099437a18424e359f0c673cb88d15d Mon Sep 17 00:00:00 2001 From: TheLynk <44308308+TheLynk@users.noreply.github.com> Date: Tue, 27 Jan 2026 12:52:45 +0100 Subject: [PATCH 45/45] Add Missing Line --- soh/soh/Enhancements/randomizer/randomizer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index affc1c4978f..acfad5aff10 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -127,6 +127,7 @@ std::map randomizerGetToRandInf = { { RG_CLIMB, RAND_INF_CAN_CLIMB }, { RG_CRAWL, RAND_INF_CAN_CRAWL }, { RG_OPEN_CHEST, RAND_INF_CAN_OPEN_CHEST }, + { RG_ROLL, RAND_INF_CAN_ROLL }, { RG_QUIVER_INF, RAND_INF_HAS_INFINITE_QUIVER }, { RG_BOMB_BAG_INF, RAND_INF_HAS_INFINITE_BOMB_BAG }, { RG_BULLET_BAG_INF, RAND_INF_HAS_INFINITE_BULLET_BAG },