From 080038c39e6de25a4cc3b157b7f94d7435427db3 Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Sun, 14 Jan 2024 19:16:32 +0100 Subject: [PATCH] Rando: Shuffle Beehives (Rando V3) (#3763) * Shuffle Beehives * Address review * Fix build --- soh/include/functions.h | 2 +- soh/include/z64actor.h | 3 + soh/include/z64save.h | 2 +- .../Enhancements/debugger/debugSaveEditor.h | 41 +++++++++++- .../randomizer/3drando/category.hpp | 1 + .../hint_list/hint_list_exclude_overworld.cpp | 37 +++++++++- .../randomizer/3drando/item_pool.cpp | 45 +++++++++++++ .../location_access/locacc_death_mountain.cpp | 21 ++++-- .../location_access/locacc_gerudo_valley.cpp | 6 +- .../location_access/locacc_hyrule_field.cpp | 29 +++++--- .../location_access/locacc_kakariko.cpp | 8 ++- .../location_access/locacc_lost_woods.cpp | 22 +++--- .../location_access/locacc_zoras_domain.cpp | 38 ++++++----- .../randomizer/3drando/spoiler_log.cpp | 6 +- .../Enhancements/randomizer/location_list.cpp | 67 +++++++++++++++++++ soh/soh/Enhancements/randomizer/logic.cpp | 20 +++--- soh/soh/Enhancements/randomizer/logic.h | 2 + .../randomizer/option_descriptions.cpp | 2 + .../Enhancements/randomizer/randomizer.cpp | 54 +++++++++++++++ soh/soh/Enhancements/randomizer/randomizer.h | 1 + .../Enhancements/randomizer/randomizerTypes.h | 48 +++++++++++++ .../randomizer/randomizer_check_objects.cpp | 1 + .../randomizer/randomizer_check_tracker.cpp | 5 ++ .../Enhancements/randomizer/randomizer_inf.h | 33 +++++++++ soh/soh/Enhancements/randomizer/settings.cpp | 7 ++ soh/soh/OTRGlobals.cpp | 4 ++ soh/soh/OTRGlobals.h | 1 + soh/src/code/z_actor.c | 4 +- soh/src/code/z_en_item00.c | 40 ++++++----- .../overlays/actors/ovl_Obj_Comb/z_obj_comb.c | 37 +++++++++- .../overlays/actors/ovl_Obj_Comb/z_obj_comb.h | 1 + 31 files changed, 505 insertions(+), 83 deletions(-) diff --git a/soh/include/functions.h b/soh/include/functions.h index 6f188a842..d8b4b934b 100644 --- a/soh/include/functions.h +++ b/soh/include/functions.h @@ -457,7 +457,7 @@ u32 Actor_HasParent(Actor* actor, PlayState* play); // TODO: Rename the follwing 3 functions using whatever scheme we use when we rename func_8002F434 and func_8002F554. s32 GiveItemEntryWithoutActor(PlayState* play, GetItemEntry getItemEntry); s32 GiveItemEntryFromActor(Actor* actor, PlayState* play, GetItemEntry getItemEntry, f32 xzRange, f32 yRange); -void GiveItemEntryFromActorWithFixedRange(Actor* actor, PlayState* play, GetItemEntry getItemEntry); +s32 GiveItemEntryFromActorWithFixedRange(Actor* actor, PlayState* play, GetItemEntry getItemEntry); s32 func_8002F434(Actor* actor, PlayState* play, s32 getItemId, f32 xzRange, f32 yRange); void func_8002F554(Actor* actor, PlayState* play, s32 getItemId); void func_8002F580(Actor* actor, PlayState* play); diff --git a/soh/include/z64actor.h b/soh/include/z64actor.h index 7d4e313e7..0a8ac9297 100644 --- a/soh/include/z64actor.h +++ b/soh/include/z64actor.h @@ -8,6 +8,7 @@ #include "z64bgcheck.h" #include "soh/Enhancements/item-tables/ItemTableTypes.h" #include "z64actor_enum.h" +#include "soh/Enhancements/randomizer/randomizerTypes.h" #define ACTOR_NUMBER_MAX 2000 #define INVISIBLE_ACTOR_MAX 20 @@ -285,6 +286,8 @@ typedef struct EnItem00 { /* 0x160 */ ColliderCylinder collider; s16 ogParams; GetItemEntry randoGiEntry; + RandomizerCheck randoCheck; + RandomizerInf randoInf; } EnItem00; // size = 0x1AC // Only A_OBJ_SIGNPOST_OBLONG and A_OBJ_SIGNPOST_ARROW are used in room files. diff --git a/soh/include/z64save.h b/soh/include/z64save.h index b0839b1d3..0f527925d 100644 --- a/soh/include/z64save.h +++ b/soh/include/z64save.h @@ -283,7 +283,7 @@ typedef struct { // #endregion // #region SOH [Randomizer] // Upstream TODO: Move these to their own struct or name to more obviously specific to Randomizer - /* */ u16 randomizerInf[14]; + /* */ u16 randomizerInf[16]; /* */ u8 mqDungeonCount; /* */ u16 adultTradeItems; /* */ u8 triforcePiecesCollected; diff --git a/soh/soh/Enhancements/debugger/debugSaveEditor.h b/soh/soh/Enhancements/debugger/debugSaveEditor.h index 481d6c75d..310d3ebe5 100644 --- a/soh/soh/Enhancements/debugger/debugSaveEditor.h +++ b/soh/soh/Enhancements/debugger/debugSaveEditor.h @@ -348,7 +348,7 @@ const std::vector flagTables = { { 0x24, "Market Crowd Text Randomizer" }, { 0x30, "Entered the Market" }, } }, - { "Randomizer Inf Flags", RANDOMIZER_INF, 13, { + { "Randomizer Inf Flags", RANDOMIZER_INF, 16, { { RAND_INF_DUNGEONS_DONE_DEKU_TREE, "DUNGEONS_DONE_DEKU_TREE" }, { RAND_INF_DUNGEONS_DONE_DODONGOS_CAVERN, "DUNGEONS_DONE_DODONGOS_CAVERN" }, { RAND_INF_DUNGEONS_DONE_JABU_JABUS_BELLY, "DUNGEONS_DONE_JABU_JABUS_BELLY" }, @@ -517,6 +517,45 @@ const std::vector flagTables = { { RAND_INF_GANON_SOUL, "RAND_INF_GANON_SOUL" }, { RAND_INF_GRANT_GANONS_BOSSKEY, "RAND_INF_GRANT_GANONS_BOSSKEY" }, + { RAND_INF_HAS_OCARINA_A, "RAND_INF_HAS_OCARINA_A"}, + { RAND_INF_HAS_OCARINA_C_UP, "RAND_INF_HAS_OCARINA_C_UP" }, + { RAND_INF_HAS_OCARINA_C_DOWN, "RAND_INF_HAS_OCARINA_C_DOWN" }, + { RAND_INF_HAS_OCARINA_C_LEFT, "RAND_INF_HAS_OCARINA_C_LEFT"}, + { RAND_INF_HAS_OCARINA_C_RIGHT, "RAND_INF_HAS_OCARINA_C_RIGHT"}, + + { RAND_INF_BEEHIVE_KF_STORMS_GROTTO_LEFT, "RAND_INF_BEEHIVE_KF_STORMS_GROTTO_LEFT" }, + { RAND_INF_BEEHIVE_KF_STORMS_GROTTO_RIGHT, "RAND_INF_BEEHIVE_KF_STORMS_GROTTO_RIGHT" }, + { RAND_INF_BEEHIVE_LW_NEAR_SHORTCUTS_GROTTO_LEFT, "RAND_INF_BEEHIVE_LW_NEAR_SHORTCUTS_GROTTO_LEFT" }, + { RAND_INF_BEEHIVE_LW_NEAR_SHORTCUTS_GROTTO_RIGHT, "RAND_INF_BEEHIVE_LW_NEAR_SHORTCUTS_GROTTO_RIGHT" }, + { RAND_INF_BEEHIVE_LW_DEKU_SCRUB_GROTTO, "RAND_INF_BEEHIVE_LW_DEKU_SCRUB_GROTTO" }, + { RAND_INF_BEEHIVE_SFM_STORMS_GROTTO, "RAND_INF_BEEHIVE_SFM_STORMS_GROTTO" }, + { RAND_INF_BEEHIVE_HF_NEAR_MARKET_GROTTO_LEFT, "RAND_INF_BEEHIVE_HF_NEAR_MARKET_GROTTO_LEFT" }, + { RAND_INF_BEEHIVE_HF_NEAR_MARKET_GROTTO_RIGHT, "RAND_INF_BEEHIVE_HF_NEAR_MARKET_GROTTO_RIGHT" }, + { RAND_INF_BEEHIVE_HF_OPEN_GROTTO_LEFT, "RAND_INF_BEEHIVE_HF_OPEN_GROTTO_LEFT" }, + { RAND_INF_BEEHIVE_HF_OPEN_GROTTO_RIGHT, "RAND_INF_BEEHIVE_HF_OPEN_GROTTO_RIGHT" }, + { RAND_INF_BEEHIVE_HF_SOUTHEAST_GROTTO_LEFT, "RAND_INF_BEEHIVE_HF_SOUTHEAST_GROTTO_LEFT" }, + { RAND_INF_BEEHIVE_HF_SOUTHEAST_GROTTO_RIGHT, "RAND_INF_BEEHIVE_HF_SOUTHEAST_GROTTO_RIGHT" }, + { RAND_INF_BEEHIVE_HF_INSIDE_FENCE_GROTTO, "RAND_INF_BEEHIVE_HF_INSIDE_FENCE_GROTTO" }, + { RAND_INF_BEEHIVE_LLR_GROTTO, "RAND_INF_BEEHIVE_LLR_GROTTO" }, + { RAND_INF_BEEHIVE_KAK_OPEN_GROTTO_LEFT, "RAND_INF_BEEHIVE_KAK_OPEN_GROTTO_LEFT" }, + { RAND_INF_BEEHIVE_KAK_OPEN_GROTTO_RIGHT, "RAND_INF_BEEHIVE_KAK_OPEN_GROTTO_RIGHT" }, + { RAND_INF_BEEHIVE_DMT_COW_GROTTO, "RAND_INF_BEEHIVE_DMT_COW_GROTTO" }, + { RAND_INF_BEEHIVE_DMT_STORMS_GROTTO_LEFT, "RAND_INF_BEEHIVE_DMT_STORMS_GROTTO_LEFT" }, + { RAND_INF_BEEHIVE_DMT_STORMS_GROTTO_RIGHT, "RAND_INF_BEEHIVE_DMT_STORMS_GROTTO_RIGHT" }, + { RAND_INF_BEEHIVE_GC_GROTTO, "RAND_INF_BEEHIVE_GC_GROTTO" }, + { RAND_INF_BEEHIVE_DMC_UPPER_GROTTO_LEFT, "RAND_INF_BEEHIVE_DMC_UPPER_GROTTO_LEFT" }, + { RAND_INF_BEEHIVE_DMC_UPPER_GROTTO_RIGHT, "RAND_INF_BEEHIVE_DMC_UPPER_GROTTO_RIGHT" }, + { RAND_INF_BEEHIVE_DMC_HAMMER_GROTTO, "RAND_INF_BEEHIVE_DMC_HAMMER_GROTTO" }, + { RAND_INF_BEEHIVE_ZR_OPEN_GROTTO_LEFT, "RAND_INF_BEEHIVE_ZR_OPEN_GROTTO_LEFT" }, + { RAND_INF_BEEHIVE_ZR_OPEN_GROTTO_RIGHT, "RAND_INF_BEEHIVE_ZR_OPEN_GROTTO_RIGHT" }, + { RAND_INF_BEEHIVE_ZR_STORMS_GROTTO, "RAND_INF_BEEHIVE_ZR_STORMS_GROTTO" }, + { RAND_INF_BEEHIVE_ZD_IN_FRONT_OF_KING_ZORA_LEFT, "RAND_INF_BEEHIVE_ZD_IN_FRONT_OF_KING_ZORA_LEFT" }, + { RAND_INF_BEEHIVE_ZD_IN_FRONT_OF_KING_ZORA_RIGHT, "RAND_INF_BEEHIVE_ZD_IN_FRONT_OF_KING_ZORA_RIGHT" }, + { RAND_INF_BEEHIVE_ZD_BEHIND_KING_ZORA, "RAND_INF_BEEHIVE_ZD_BEHIND_KING_ZORA" }, + { RAND_INF_BEEHIVE_LH_GROTTO, "RAND_INF_BEEHIVE_LH_GROTTO" }, + { RAND_INF_BEEHIVE_GV_DEKU_SCRUB_GROTTO, "RAND_INF_BEEHIVE_GV_DEKU_SCRUB_GROTTO" }, + { RAND_INF_BEEHIVE_COLOSSUS_GROTTO, "RAND_INF_BEEHIVE_COLOSSUS_GROTTO" }, + { RAND_INF_CHILD_FISH_1, "RAND_INF_CHILD_FISH_1" }, { RAND_INF_CHILD_FISH_2, "RAND_INF_CHILD_FISH_2" }, { RAND_INF_CHILD_FISH_3, "RAND_INF_CHILD_FISH_3" }, diff --git a/soh/soh/Enhancements/randomizer/3drando/category.hpp b/soh/soh/Enhancements/randomizer/3drando/category.hpp index 8916f53df..22522789c 100644 --- a/soh/soh/Enhancements/randomizer/3drando/category.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/category.hpp @@ -18,6 +18,7 @@ enum class Category { cVanillaMap, cVanillaCompass, cAdultTrade, + cBeehive, }; enum class OptionCategory { 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 026514441..c705bb2b6 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 @@ -1429,4 +1429,39 @@ void HintTable_Init_Exclude_Overworld() { //obscure text Text{"a #cow in a luxurious hole# offers", /*french*/"la #vache dans une grotte luxueuse# donne", /*spanish*/"una #vaca de un lujoso hoyo# brinda"}, }); -} + + hintTable[RHT_BEEHIVE_CHEST_GROTTO] = HintText::Exclude({ + //obscure text + Text{"a #beehive above a chest# hides", /*french*/"", /*spanish*/"una #colmena sobre un cofre# esconde"}, + }); + + hintTable[RHT_BEEHIVE_LONELY_SCRUB_GROTTO] = HintText::Exclude({ + //obscure text + Text{"a #beehive above a lonely scrub# hides", /*french*/"", /*spanish*/"una #colmena sobre un deku solitario# esconde"}, + }); + + hintTable[RHT_BEEHIVE_SCRUB_PAIR_GROTTO] = HintText::Exclude({ + //obscure text + Text{"a #beehive above a pair of scrubs# hides", /*french*/"", /*spanish*/"una #colmena sobre un par de dekus# esconde"}, + }); + + hintTable[RHT_BEEHIVE_SCRUB_TRIO_GROTTO] = HintText::Exclude({ + //obscure text + Text{"a #beehive above a trio of scrubs# hides", /*french*/"", /*spanish*/"una #colmena sobre un trío de dekus# esconde"}, + }); + + hintTable[RHT_BEEHIVE_COW_GROTTO] = HintText::Exclude({ + //obscure text + Text{"a #beehive above a cow# hides", /*french*/"", /*spanish*/"una #colmena sobre una vaca# esconde"}, + }); + + hintTable[RHT_BEEHIVE_IN_FRONT_OF_KING_ZORA] = HintText::Exclude({ + //obscure text + Text{"a #beehive in front of the king of the zoras# hides", /*french*/"", /*spanish*/"una #colmena delante del rey de los zoras# esconde"}, + }); + + hintTable[RHT_BEEHIVE_BEHIND_KING_ZORA] = HintText::Exclude({ + //obscure text + Text{"a #beehive behind the king of the zoras# hides", /*french*/"", /*spanish*/"una #colmena detrás del rey de los zoras# esconde"}, + }); +} \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index 7acb68949..6ec66b5a8 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -557,6 +557,43 @@ static void PlaceVanillaBossKeys() { // TODO: This feels like it could be moved to Dungeons class and probably shorten // a few function call chains. Needs investigation. +static void PlaceVanillaBeehiveRupees() { + auto ctx = Rando::Context::GetInstance(); + ctx->PlaceItemInLocation(RC_KF_STORMS_GROTTO_BEEHIVE_LEFT, RG_BLUE_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_LEFT, RG_BLUE_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_LEFT, RG_BLUE_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_HF_OPEN_GROTTO_BEEHIVE_LEFT, RG_BLUE_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_HF_SOUTHEAST_GROTTO_BEEHIVE_LEFT, RG_BLUE_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_KAK_OPEN_GROTTO_BEEHIVE_LEFT, RG_BLUE_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_DMT_STORMS_GROTTO_BEEHIVE_LEFT, RG_BLUE_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_DMC_UPPER_GROTTO_BEEHIVE_LEFT, RG_BLUE_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_ZR_OPEN_GROTTO_BEEHIVE_LEFT, RG_BLUE_RUPEE, false, true); + + ctx->PlaceItemInLocation(RC_KF_STORMS_GROTTO_BEEHIVE_RIGHT, RG_RED_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_RIGHT, RG_RED_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_LW_DEKU_SCRUB_GROTTO_BEEHIVE, RG_RED_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_SFM_STORMS_GROTTO_BEEHIVE, RG_RED_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_RIGHT, RG_RED_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_HF_OPEN_GROTTO_BEEHIVE_RIGHT, RG_RED_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_HF_SOUTHEAST_GROTTO_BEEHIVE_RIGHT, RG_RED_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_HF_INSIDE_FENCE_GROTTO_BEEHIVE, RG_RED_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_LLR_GROTTO_BEEHIVE, RG_RED_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_KAK_OPEN_GROTTO_BEEHIVE_RIGHT, RG_RED_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_DMT_COW_GROTTO_BEEHIVE, RG_RED_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_DMT_STORMS_GROTTO_BEEHIVE_RIGHT, RG_RED_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_GC_GROTTO_BEEHIVE, RG_RED_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_DMC_UPPER_GROTTO_BEEHIVE_RIGHT, RG_RED_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_DMC_HAMMER_GROTTO_BEEHIVE, RG_RED_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_ZR_OPEN_GROTTO_BEEHIVE_RIGHT, RG_RED_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_ZR_STORMS_GROTTO_BEEHIVE, RG_RED_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_LEFT, RG_RED_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_RIGHT, RG_RED_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_ZD_BEHIND_KING_ZORA_BEEHIVE, RG_RED_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_LH_GROTTO_BEEHIVE, RG_RED_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_GV_DEKU_SCRUB_GROTTO_BEEHIVE, RG_RED_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_COLOSSUS_GROTTO_BEEHIVE, RG_RED_RUPEE, false, true); +} + static void PlaceVanillaCowMilk() { auto ctx = Rando::Context::GetInstance(); ctx->PlaceItemInLocation(RC_KF_LINKS_HOUSE_COW, RG_MILK, false, true); @@ -745,6 +782,14 @@ void GenerateItemPool() { ctx->possibleIceTrapModels.push_back(RG_OCARINA_C_RIGHT_BUTTON); } + if (ctx->GetOption(RSK_SHUFFLE_BEEHIVES)) { + //32 total beehive locations + AddItemToMainPool(RG_RED_RUPEE, 23); + AddItemToMainPool(RG_BLUE_RUPEE, 9); + } else { + PlaceVanillaBeehiveRupees(); + } + if (ctx->GetOption(RSK_SHUFFLE_COWS)) { //9 total cow locations for (uint8_t i = 0; i < 9; i++) { diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_death_mountain.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_death_mountain.cpp index af1400eb9..e4a8fbb63 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_death_mountain.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_death_mountain.cpp @@ -52,7 +52,8 @@ void AreaTable_Init_DeathMountain() { areaTable[RR_DMT_COW_GROTTO] = Area("DMT Cow Grotto", "DMT Cow Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(RC_DMT_COW_GROTTO_COW, {[]{return logic->CanUse(RG_EPONAS_SONG);}}), + LocationAccess(RC_DMT_COW_GROTTO_COW, {[]{return logic->CanUse(RG_EPONAS_SONG);}}), + LocationAccess(RC_DMT_COW_GROTTO_BEEHIVE, {[]{return logic->CanBreakLowerBeehives;}}), }, { //Exits Entrance(RR_DEATH_MOUNTAIN_SUMMIT, {[]{return true;}}), @@ -61,9 +62,11 @@ void AreaTable_Init_DeathMountain() { areaTable[RR_DMT_STORMS_GROTTO] = Area("DMT Storms Grotto", "DMT Storms Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, grottoEvents, { //Locations - LocationAccess(RC_DMT_STORMS_GROTTO_CHEST, {[]{return true;}}), - LocationAccess(RC_DMT_STORMS_GROTTO_FISH, {[]{return logic->HasBottle;}}), - LocationAccess(RC_DMT_STORMS_GROTTO_GOSSIP_STONE, {[]{return true;}}), + LocationAccess(RC_DMT_STORMS_GROTTO_CHEST, {[]{return true;}}), + LocationAccess(RC_DMT_STORMS_GROTTO_FISH, {[]{return logic->HasBottle;}}), + LocationAccess(RC_DMT_STORMS_GROTTO_GOSSIP_STONE, {[]{return true;}}), + LocationAccess(RC_DMT_STORMS_GROTTO_BEEHIVE_LEFT, {[]{return logic->CanBreakLowerBeehives;}}), + LocationAccess(RC_DMT_STORMS_GROTTO_BEEHIVE_RIGHT, {[]{return logic->CanBreakLowerBeehives;}}), }, { //Exits Entrance(RR_DEATH_MOUNTAIN_TRAIL, {[]{return true;}}), @@ -155,6 +158,7 @@ void AreaTable_Init_DeathMountain() { LocationAccess(RC_GC_DEKU_SCRUB_GROTTO_LEFT, {[]{return logic->CanStunDeku;}}), LocationAccess(RC_GC_DEKU_SCRUB_GROTTO_RIGHT, {[]{return logic->CanStunDeku;}}), LocationAccess(RC_GC_DEKU_SCRUB_GROTTO_CENTER, {[]{return logic->CanStunDeku;}}), + LocationAccess(RC_GC_GROTTO_BEEHIVE, {[]{return logic->CanBreakUpperBeehives;}}), }, { //Exits Entrance(RR_GC_GROTTO_PLATFORM, {[]{return true;}}), @@ -241,9 +245,11 @@ void AreaTable_Init_DeathMountain() { areaTable[RR_DMC_UPPER_GROTTO] = Area("DMC Upper Grotto", "DMC Upper Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, grottoEvents, { //Locations - LocationAccess(RC_DMC_UPPER_GROTTO_CHEST, {[]{return true;}}), - LocationAccess(RC_DMC_UPPER_GROTTO_FISH, {[]{return logic->HasBottle;}}), - LocationAccess(RC_DMC_UPPER_GROTTO_GOSSIP_STONE, {[]{return true;}}), + LocationAccess(RC_DMC_UPPER_GROTTO_CHEST, {[]{return true;}}), + LocationAccess(RC_DMC_UPPER_GROTTO_FISH, {[]{return logic->HasBottle;}}), + LocationAccess(RC_DMC_UPPER_GROTTO_GOSSIP_STONE, {[]{return true;}}), + LocationAccess(RC_DMC_UPPER_GROTTO_BEEHIVE_LEFT, {[]{return logic->CanBreakLowerBeehives;}}), + LocationAccess(RC_DMC_UPPER_GROTTO_BEEHIVE_RIGHT, {[]{return logic->CanBreakLowerBeehives;}}), }, { //Exits Entrance(RR_DMC_UPPER_LOCAL, {[]{return true;}}), @@ -254,6 +260,7 @@ void AreaTable_Init_DeathMountain() { LocationAccess(RC_DMC_DEKU_SCRUB_GROTTO_LEFT, {[]{return logic->CanStunDeku;}}), LocationAccess(RC_DMC_DEKU_SCRUB_GROTTO_RIGHT, {[]{return logic->CanStunDeku;}}), LocationAccess(RC_DMC_DEKU_SCRUB_GROTTO_CENTER, {[]{return logic->CanStunDeku;}}), + LocationAccess(RC_DMC_HAMMER_GROTTO_BEEHIVE, {[]{return logic->CanBreakUpperBeehives;}}), }, { //Exits Entrance(RR_DMC_LOWER_LOCAL, {[]{return true;}}), diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_gerudo_valley.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_gerudo_valley.cpp index 2fd86634a..1a3c84305 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_gerudo_valley.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_gerudo_valley.cpp @@ -85,8 +85,9 @@ void AreaTable_Init_GerudoValley() { areaTable[RR_GV_STORMS_GROTTO] = Area("GV Storms Grotto", "GV Storms Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(RC_GV_DEKU_SCRUB_GROTTO_REAR, {[]{return logic->CanStunDeku;}}), - LocationAccess(RC_GV_DEKU_SCRUB_GROTTO_FRONT, {[]{return logic->CanStunDeku;}}), + LocationAccess(RC_GV_DEKU_SCRUB_GROTTO_REAR, {[]{return logic->CanStunDeku;}}), + LocationAccess(RC_GV_DEKU_SCRUB_GROTTO_FRONT, {[]{return logic->CanStunDeku;}}), + LocationAccess(RC_GV_DEKU_SCRUB_GROTTO_BEEHIVE, {[]{return logic->CanBreakUpperBeehives;}}), }, { //Exits Entrance(RR_GV_FORTRESS_SIDE, {[]{return true;}}), @@ -200,6 +201,7 @@ void AreaTable_Init_GerudoValley() { //Locations LocationAccess(RC_COLOSSUS_DEKU_SCRUB_GROTTO_REAR, {[]{return logic->CanStunDeku;}}), LocationAccess(RC_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT, {[]{return logic->CanStunDeku;}}), + LocationAccess(RC_COLOSSUS_GROTTO_BEEHIVE, {[]{return logic->CanBreakUpperBeehives;}}), }, { //Exits Entrance(RR_DESERT_COLOSSUS, {[]{return true;}}), diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_hyrule_field.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_hyrule_field.cpp index 258ffd8d6..1d75415d3 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_hyrule_field.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_hyrule_field.cpp @@ -32,9 +32,11 @@ void AreaTable_Init_HyruleField() { areaTable[RR_HF_SOUTHEAST_GROTTO] = Area("HF Southeast Grotto", "HF Southeast Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, grottoEvents, { //Locations - LocationAccess(RC_HF_SOUTHEAST_GROTTO_CHEST, {[]{return true;}}), - LocationAccess(RC_HF_SOUTHEAST_GROTTO_FISH, {[]{return logic->HasBottle;}}), - LocationAccess(RC_HF_SOUTHEAST_GOSSIP_STONE, {[]{return true;}}), + LocationAccess(RC_HF_SOUTHEAST_GROTTO_CHEST, {[]{return true;}}), + LocationAccess(RC_HF_SOUTHEAST_GROTTO_FISH, {[]{return logic->HasBottle;}}), + LocationAccess(RC_HF_SOUTHEAST_GOSSIP_STONE, {[]{return true;}}), + LocationAccess(RC_HF_SOUTHEAST_GROTTO_BEEHIVE_LEFT, {[]{return logic->CanBreakLowerBeehives;}}), + LocationAccess(RC_HF_SOUTHEAST_GROTTO_BEEHIVE_RIGHT, {[]{return logic->CanBreakLowerBeehives;}}), }, { //Exits Entrance(RR_HYRULE_FIELD, {[]{return true;}}), @@ -42,9 +44,11 @@ void AreaTable_Init_HyruleField() { areaTable[RR_HF_OPEN_GROTTO] = Area("HF Open Grotto", "HF Open Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, grottoEvents, { //Locations - LocationAccess(RC_HF_OPEN_GROTTO_CHEST, {[]{return true;}}), - LocationAccess(RC_HF_OPEN_GROTTO_FISH, {[]{return logic->HasBottle;}}), - LocationAccess(RC_HF_OPEN_GROTTO_GOSSIP_STONE, {[]{return true;}}), + LocationAccess(RC_HF_OPEN_GROTTO_CHEST, {[]{return true;}}), + LocationAccess(RC_HF_OPEN_GROTTO_FISH, {[]{return logic->HasBottle;}}), + LocationAccess(RC_HF_OPEN_GROTTO_GOSSIP_STONE, {[]{return true;}}), + LocationAccess(RC_HF_OPEN_GROTTO_BEEHIVE_LEFT, {[]{return logic->CanBreakLowerBeehives;}}), + LocationAccess(RC_HF_OPEN_GROTTO_BEEHIVE_RIGHT, {[]{return logic->CanBreakLowerBeehives;}}), }, { //Exits Entrance(RR_HYRULE_FIELD, {[]{return true;}}), @@ -52,7 +56,8 @@ void AreaTable_Init_HyruleField() { areaTable[RR_HF_INSIDE_FENCE_GROTTO] = Area("HF Inside Fence Grotto", "HF Inside Fence Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(RC_HF_DEKU_SCRUB_GROTTO, {[]{return logic->CanStunDeku;}}), + LocationAccess(RC_HF_DEKU_SCRUB_GROTTO, {[]{return logic->CanStunDeku;}}), + LocationAccess(RC_HF_INSIDE_FENCE_GROTTO_BEEHIVE, {[]{return logic->CanBreakLowerBeehives;}}), }, { //Exits Entrance(RR_HYRULE_FIELD, {[]{return true;}}), @@ -70,9 +75,11 @@ void AreaTable_Init_HyruleField() { areaTable[RR_HF_NEAR_MARKET_GROTTO] = Area("HF Near Market Grotto", "HF Near Market Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, grottoEvents, { //Locations - LocationAccess(RC_HF_NEAR_MARKET_GROTTO_CHEST, {[]{return true;}}), - LocationAccess(RC_HF_NEAR_MARKET_GROTTO_FISH, {[]{return logic->HasBottle;}}), - LocationAccess(RC_HF_NEAR_MARKET_GOSSIP_STONE, {[]{return true;}}), + LocationAccess(RC_HF_NEAR_MARKET_GROTTO_CHEST, {[]{return true;}}), + LocationAccess(RC_HF_NEAR_MARKET_GROTTO_FISH, {[]{return logic->HasBottle;}}), + LocationAccess(RC_HF_NEAR_MARKET_GOSSIP_STONE, {[]{return true;}}), + LocationAccess(RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_LEFT, {[]{return logic->CanBreakLowerBeehives;}}), + LocationAccess(RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_RIGHT, {[]{return logic->CanBreakLowerBeehives;}}), }, { //Exits Entrance(RR_HYRULE_FIELD, {[]{return true;}}), @@ -206,6 +213,7 @@ void AreaTable_Init_HyruleField() { LocationAccess(RC_LH_DEKU_SCRUB_GROTTO_LEFT, {[]{return logic->CanStunDeku;}}), LocationAccess(RC_LH_DEKU_SCRUB_GROTTO_RIGHT, {[]{return logic->CanStunDeku;}}), LocationAccess(RC_LH_DEKU_SCRUB_GROTTO_CENTER, {[]{return logic->CanStunDeku;}}), + LocationAccess(RC_LH_GROTTO_BEEHIVE, {[]{return logic->CanBreakUpperBeehives;}}), }, { //Exits Entrance(RR_LAKE_HYLIA, {[]{return true;}}), @@ -263,6 +271,7 @@ void AreaTable_Init_HyruleField() { LocationAccess(RC_LLR_DEKU_SCRUB_GROTTO_LEFT, {[]{return logic->CanStunDeku;}}), LocationAccess(RC_LLR_DEKU_SCRUB_GROTTO_RIGHT, {[]{return logic->CanStunDeku;}}), LocationAccess(RC_LLR_DEKU_SCRUB_GROTTO_CENTER, {[]{return logic->CanStunDeku;}}), + LocationAccess(RC_LLR_GROTTO_BEEHIVE, {[]{return logic->CanBreakUpperBeehives;}}), }, { //Exits Entrance(RR_LON_LON_RANCH, {[]{return true;}}), diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_kakariko.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_kakariko.cpp index 750767323..5eb7263d3 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_kakariko.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_kakariko.cpp @@ -196,9 +196,11 @@ void AreaTable_Init_Kakariko() { areaTable[RR_KAK_OPEN_GROTTO] = Area("Kak Open Grotto", "Kak Open Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, grottoEvents, { //Locations - LocationAccess(RC_KAK_OPEN_GROTTO_CHEST, {[]{return true;}}), - LocationAccess(RC_KAK_OPEN_GROTTO_FISH, {[]{return logic->HasBottle;}}), - LocationAccess(RC_KAK_OPEN_GROTTO_GOSSIP_STONE, {[]{return true;}}), + LocationAccess(RC_KAK_OPEN_GROTTO_CHEST, {[]{return true;}}), + LocationAccess(RC_KAK_OPEN_GROTTO_FISH, {[]{return logic->HasBottle;}}), + LocationAccess(RC_KAK_OPEN_GROTTO_GOSSIP_STONE, {[]{return true;}}), + LocationAccess(RC_KAK_OPEN_GROTTO_BEEHIVE_LEFT, {[]{return logic->CanBreakLowerBeehives;}}), + LocationAccess(RC_KAK_OPEN_GROTTO_BEEHIVE_RIGHT, {[]{return logic->CanBreakLowerBeehives;}}), }, { //Exits Entrance(RR_KAK_BACKYARD, {[]{return true;}}), diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_lost_woods.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_lost_woods.cpp index 5ad1e6d5c..69911b049 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_lost_woods.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_lost_woods.cpp @@ -96,9 +96,11 @@ void AreaTable_Init_LostWoods() { areaTable[RR_KF_STORMS_GROTTO] = Area("KF Storms Grotto", "KF Storms Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, grottoEvents, { //Locations - LocationAccess(RC_KF_STORMS_GROTTO_CHEST, {[]{return true;}}), - LocationAccess(RC_KF_STORMS_GROTTO_FISH, {[]{return logic->HasBottle;}}), - LocationAccess(RC_KF_STORMS_GOSSIP_STONE, {[]{return true;}}), + LocationAccess(RC_KF_STORMS_GROTTO_CHEST, {[]{return true;}}), + LocationAccess(RC_KF_STORMS_GROTTO_FISH, {[]{return logic->HasBottle;}}), + LocationAccess(RC_KF_STORMS_GOSSIP_STONE, {[]{return true;}}), + LocationAccess(RC_KF_STORMS_GROTTO_BEEHIVE_LEFT, {[]{return logic->CanBreakLowerBeehives;}}), + LocationAccess(RC_KF_STORMS_GROTTO_BEEHIVE_RIGHT, {[]{return logic->CanBreakLowerBeehives;}}), }, { //Exits Entrance(RR_KOKIRI_FOREST, {[]{return true;}}) @@ -164,9 +166,11 @@ void AreaTable_Init_LostWoods() { areaTable[RR_LW_NEAR_SHORTCUTS_GROTTO] = Area("LW Near Shortcuts Grotto", "LW Near Shortcuts Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, grottoEvents, { //Locations - LocationAccess(RC_LW_NEAR_SHORTCUTS_GROTTO_CHEST, {[]{return true;}}), - LocationAccess(RC_LW_NEAR_SHORTCUTS_GROTTO_FISH, {[]{return logic->HasBottle;}}), - LocationAccess(RC_LW_NEAR_SHORTCUTS_GOSSIP_STONE, {[]{return true;}}), + LocationAccess(RC_LW_NEAR_SHORTCUTS_GROTTO_CHEST, {[]{return true;}}), + LocationAccess(RC_LW_NEAR_SHORTCUTS_GROTTO_FISH, {[]{return logic->HasBottle;}}), + LocationAccess(RC_LW_NEAR_SHORTCUTS_GOSSIP_STONE, {[]{return true;}}), + LocationAccess(RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_LEFT, {[]{return logic->CanBreakLowerBeehives;}}), + LocationAccess(RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_RIGHT, {[]{return logic->CanBreakLowerBeehives;}}), }, { //Exits Entrance(RR_THE_LOST_WOODS, {[]{return true;}}), @@ -183,8 +187,9 @@ void AreaTable_Init_LostWoods() { areaTable[RR_LW_SCRUBS_GROTTO] = Area("LW Scrubs Grotto", "LW Scrubs Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(RC_LW_DEKU_SCRUB_GROTTO_REAR, {[]{return logic->CanStunDeku;}}), - LocationAccess(RC_LW_DEKU_SCRUB_GROTTO_FRONT, {[]{return logic->CanStunDeku;}}), + LocationAccess(RC_LW_DEKU_SCRUB_GROTTO_REAR, {[]{return logic->CanStunDeku;}}), + LocationAccess(RC_LW_DEKU_SCRUB_GROTTO_FRONT, {[]{return logic->CanStunDeku;}}), + LocationAccess(RC_LW_DEKU_SCRUB_GROTTO_BEEHIVE, {[]{return logic->CanBreakUpperBeehives;}}), }, { //Exits Entrance(RR_LW_BEYOND_MIDO, {[]{return true;}}), @@ -236,6 +241,7 @@ void AreaTable_Init_LostWoods() { //Locations LocationAccess(RC_SFM_DEKU_SCRUB_GROTTO_REAR, {[]{return logic->CanStunDeku;}}), LocationAccess(RC_SFM_DEKU_SCRUB_GROTTO_FRONT, {[]{return logic->CanStunDeku;}}), + LocationAccess(RC_SFM_STORMS_GROTTO_BEEHIVE, {[]{return logic->CanBreakUpperBeehives;}}), }, { //Exits Entrance(RR_SACRED_FOREST_MEADOW, {[]{return true;}}), diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_zoras_domain.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_zoras_domain.cpp index 5dade599a..d0cd7358d 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_zoras_domain.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_zoras_domain.cpp @@ -54,9 +54,11 @@ void AreaTable_Init_ZorasDomain() { areaTable[RR_ZR_OPEN_GROTTO] = Area("ZR Open Grotto", "ZR Open Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, grottoEvents, { //Locations - LocationAccess(RC_ZR_OPEN_GROTTO_CHEST, {[]{return true;}}), - LocationAccess(RC_ZR_OPEN_GROTTO_FISH, {[]{return logic->HasBottle;}}), - LocationAccess(RC_ZR_OPEN_GROTTO_GOSSIP_STONE, {[]{return true;}}), + LocationAccess(RC_ZR_OPEN_GROTTO_CHEST, {[]{return true;}}), + LocationAccess(RC_ZR_OPEN_GROTTO_FISH, {[]{return logic->HasBottle;}}), + LocationAccess(RC_ZR_OPEN_GROTTO_GOSSIP_STONE, {[]{return true;}}), + LocationAccess(RC_ZR_OPEN_GROTTO_BEEHIVE_LEFT, {[]{return logic->CanBreakLowerBeehives;}}), + LocationAccess(RC_ZR_OPEN_GROTTO_BEEHIVE_RIGHT, {[]{return logic->CanBreakLowerBeehives;}}), }, { //Exits Entrance(RR_ZORAS_RIVER, {[]{return true;}}), @@ -74,6 +76,7 @@ void AreaTable_Init_ZorasDomain() { //Locations LocationAccess(RC_ZR_DEKU_SCRUB_GROTTO_REAR, {[]{return logic->CanStunDeku;}}), LocationAccess(RC_ZR_DEKU_SCRUB_GROTTO_FRONT, {[]{return logic->CanStunDeku;}}), + LocationAccess(RC_ZR_STORMS_GROTTO_BEEHIVE, {[]{return logic->CanBreakUpperBeehives;}}), }, { //Exits Entrance(RR_ZORAS_RIVER, {[]{return true;}}), @@ -90,17 +93,19 @@ void AreaTable_Init_ZorasDomain() { EventAccess(&logic->DeliverLetter, {[]{return logic->DeliverLetter || (logic->RutosLetter && logic->IsChild && randoCtx->GetOption(RSK_ZORAS_FOUNTAIN).IsNot(RO_ZF_OPEN));}}), }, { //Locations - LocationAccess(RC_ZD_DIVING_MINIGAME, {[]{return logic->IsChild;}}), - LocationAccess(RC_ZD_CHEST, {[]{return logic->IsChild && logic->CanUse(RG_STICKS);}}), - LocationAccess(RC_ZD_KING_ZORA_THAWED, {[]{return logic->KingZoraThawed;}}), - LocationAccess(RC_ZD_TRADE_PRESCRIPTION, {[]{return logic->KingZoraThawed && logic->Prescription;}}), - LocationAccess(RC_ZD_GS_FROZEN_WATERFALL, {[]{return logic->IsAdult && logic->AtNight && (logic->HookshotOrBoomerang || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->Bow || (logic->MagicMeter && (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_BIGGORON_SWORD))) || (randoCtx->GetTrickOption(RT_ZD_GS) && logic->CanJumpslash)) && logic->CanGetNightTimeGS;}}), - LocationAccess(RC_ZD_FISH_1, {[]{return logic->IsChild && logic->HasBottle;}}), - LocationAccess(RC_ZD_FISH_2, {[]{return logic->IsChild && logic->HasBottle;}}), - LocationAccess(RC_ZD_FISH_3, {[]{return logic->IsChild && logic->HasBottle;}}), - LocationAccess(RC_ZD_FISH_4, {[]{return logic->IsChild && logic->HasBottle;}}), - LocationAccess(RC_ZD_FISH_5, {[]{return logic->IsChild && logic->HasBottle;}}), - LocationAccess(RC_ZD_GOSSIP_STONE, {[]{return true;}}), + LocationAccess(RC_ZD_DIVING_MINIGAME, {[]{return logic->IsChild;}}), + LocationAccess(RC_ZD_CHEST, {[]{return logic->IsChild && logic->CanUse(RG_STICKS);}}), + LocationAccess(RC_ZD_KING_ZORA_THAWED, {[]{return logic->KingZoraThawed;}}), + LocationAccess(RC_ZD_TRADE_PRESCRIPTION, {[]{return logic->KingZoraThawed && logic->Prescription;}}), + LocationAccess(RC_ZD_GS_FROZEN_WATERFALL, {[]{return logic->IsAdult && logic->AtNight && (logic->HookshotOrBoomerang || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->Bow || (logic->MagicMeter && (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_BIGGORON_SWORD))) || (randoCtx->GetTrickOption(RT_ZD_GS) && logic->CanJumpslash)) && logic->CanGetNightTimeGS;}}), + LocationAccess(RC_ZD_FISH_1, {[]{return logic->IsChild && logic->HasBottle;}}), + LocationAccess(RC_ZD_FISH_2, {[]{return logic->IsChild && logic->HasBottle;}}), + LocationAccess(RC_ZD_FISH_3, {[]{return logic->IsChild && logic->HasBottle;}}), + LocationAccess(RC_ZD_FISH_4, {[]{return logic->IsChild && logic->HasBottle;}}), + LocationAccess(RC_ZD_FISH_5, {[]{return logic->IsChild && logic->HasBottle;}}), + LocationAccess(RC_ZD_GOSSIP_STONE, {[]{return true;}}), + LocationAccess(RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_LEFT, {[]{return logic->CanBreakUpperBeehives;}}), + LocationAccess(RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_RIGHT, {[]{return logic->CanBreakUpperBeehives;}}), }, { //Exits Entrance(RR_ZR_BEHIND_WATERFALL, {[]{return true;}}), @@ -110,7 +115,10 @@ void AreaTable_Init_ZorasDomain() { Entrance(RR_ZD_STORMS_GROTTO, {[]{return logic->CanOpenStormGrotto;}}), }); - areaTable[RR_ZD_BEHIND_KING_ZORA] = Area("ZD Behind King Zora", "Zoras Domain", RA_ZORAS_DOMAIN, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_ZD_BEHIND_KING_ZORA] = Area("ZD Behind King Zora", "Zoras Domain", RA_ZORAS_DOMAIN, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LocationAccess(RC_ZD_BEHIND_KING_ZORA_BEEHIVE, {[]{return logic->CanBreakUpperBeehives;}}), + }, { //Exits Entrance(RR_ZORAS_DOMAIN, {[]{return logic->DeliverLetter || randoCtx->GetOption(RSK_ZORAS_FOUNTAIN).Is(RO_ZF_OPEN) || (randoCtx->GetOption(RSK_ZORAS_FOUNTAIN).Is(RO_ZF_CLOSED_CHILD) && logic->IsAdult);}}), Entrance(RR_ZORAS_FOUNTAIN, {[]{return true;}}), diff --git a/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp b/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp index 8e0dee301..6dd1802a6 100644 --- a/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp @@ -115,8 +115,12 @@ void WriteIngameSpoilerLog() { // if (loc->IsExcluded()) { // continue; // } + // Beehives + if (!ctx->GetOption(RSK_SHUFFLE_BEEHIVES) && loc->IsCategory(Category::cBeehive)) { + continue; + } // Cows - if (!ctx->GetOption(RSK_SHUFFLE_COWS) && loc->IsCategory(Category::cCow)) { + else if (!ctx->GetOption(RSK_SHUFFLE_COWS) && loc->IsCategory(Category::cCow)) { continue; } // Merchants diff --git a/soh/soh/Enhancements/randomizer/location_list.cpp b/soh/soh/Enhancements/randomizer/location_list.cpp index 56861e484..ea4775d46 100644 --- a/soh/soh/Enhancements/randomizer/location_list.cpp +++ b/soh/soh/Enhancements/randomizer/location_list.cpp @@ -463,6 +463,39 @@ std::vector Rando::StaticData::overworldLocations = { RC_LLR_GS_RAIN_SHED, RC_LLR_GS_HOUSE_WINDOW, RC_LLR_GS_TREE, + + RC_KF_STORMS_GROTTO_BEEHIVE_LEFT, + RC_KF_STORMS_GROTTO_BEEHIVE_RIGHT, + RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_LEFT, + RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_RIGHT, + RC_LW_DEKU_SCRUB_GROTTO_BEEHIVE, + RC_SFM_STORMS_GROTTO_BEEHIVE, + RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_LEFT, + RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_RIGHT, + RC_HF_OPEN_GROTTO_BEEHIVE_LEFT, + RC_HF_OPEN_GROTTO_BEEHIVE_RIGHT, + RC_HF_SOUTHEAST_GROTTO_BEEHIVE_LEFT, + RC_HF_SOUTHEAST_GROTTO_BEEHIVE_RIGHT, + RC_HF_INSIDE_FENCE_GROTTO_BEEHIVE, + RC_LLR_GROTTO_BEEHIVE, + RC_KAK_OPEN_GROTTO_BEEHIVE_LEFT, + RC_KAK_OPEN_GROTTO_BEEHIVE_RIGHT, + RC_DMT_COW_GROTTO_BEEHIVE, + RC_DMT_STORMS_GROTTO_BEEHIVE_LEFT, + RC_DMT_STORMS_GROTTO_BEEHIVE_RIGHT, + RC_GC_GROTTO_BEEHIVE, + RC_DMC_UPPER_GROTTO_BEEHIVE_LEFT, + RC_DMC_UPPER_GROTTO_BEEHIVE_RIGHT, + RC_DMC_HAMMER_GROTTO_BEEHIVE, + RC_ZR_OPEN_GROTTO_BEEHIVE_LEFT, + RC_ZR_OPEN_GROTTO_BEEHIVE_RIGHT, + RC_ZR_STORMS_GROTTO_BEEHIVE, + RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_LEFT, + RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_RIGHT, + RC_ZD_BEHIND_KING_ZORA_BEEHIVE, + RC_LH_GROTTO_BEEHIVE, + RC_GV_DEKU_SCRUB_GROTTO_BEEHIVE, + RC_COLOSSUS_GROTTO_BEEHIVE, }; std::vector Rando::StaticData::gossipStoneLocations = { @@ -1297,6 +1330,40 @@ void Rando::StaticData::InitLocationTable() { locationTable[RC_SONG_FROM_OCARINA_OF_TIME] = Location::Delayed(RC_SONG_FROM_OCARINA_OF_TIME, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_HYRULE_FIELD, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x2A, "Song from Ocarina of Time", "Song from Ocarina of Time", RHT_SONG_FROM_OCARINA_OF_TIME, RG_SONG_OF_TIME, { Category::cSong }, SpoilerCollectionCheck::Chest(0x51, 0x1F), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD, true); locationTable[RC_SONG_FROM_WINDMILL] = Location::Delayed(RC_SONG_FROM_WINDMILL, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, 0x2B, "Song from Windmill", "Song from Windmill", RHT_SONG_FROM_WINDMILL, RG_SONG_OF_STORMS, { Category::cSong }, SpoilerCollectionCheck::EventChkInf(0x5B), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, true); + //Beehives Randomizer Check Randomizer Check Quest Type Area Actor ID Scene ID Params Flags Short Name Spoiler Name Hint Text Key Vanilla Item Categories Spoiler Collection Check Collection Check Group Vanilla Progression + locationTable[RC_KF_STORMS_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_KF_STORMS_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_KOKIRI_FOREST, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x2C), 0x00, "Storms Grotto Beehive Left", "KF Storms Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST, false); + locationTable[RC_KF_STORMS_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_KF_STORMS_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_KOKIRI_FOREST, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x2C), 0x00, "Storms Grotto Beehive Right", "KF Storms Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST, false); + locationTable[RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_LOST_WOODS, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x14), 0x00, "Near Shortcuts Grotto Beehive Left", "LW Near Shortcuts Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, false); + locationTable[RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_LOST_WOODS, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x14), 0x00, "Near Shortcuts Grotto Beehive Right", "LW Near Shortcuts Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, false); + locationTable[RC_LW_DEKU_SCRUB_GROTTO_BEEHIVE] = Location::Base(RC_LW_DEKU_SCRUB_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_LOST_WOODS, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(747, 0xF5), 0x00, "Deku Scrub Grotto Beehive", "LW Deku Scrub Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, false); + locationTable[RC_SFM_STORMS_GROTTO_BEEHIVE] = Location::Base(RC_SFM_STORMS_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_SACRED_FOREST_MEADOW, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2262, 0xEE), 0x00, "Storms Grotto Beehive", "SFM Storms Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS, false); + locationTable[RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x00), 0x00, "Near Market Grotto Beehive Left", "HF Near Market Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD, false); + locationTable[RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x00), 0x00, "Near Market Grotto Beehive Right", "HF Near Market Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD, false); + locationTable[RC_HF_OPEN_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_HF_OPEN_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x03), 0x00, "Open Grotto Beehive Left", "HF Open Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD, false); + locationTable[RC_HF_OPEN_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_HF_OPEN_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x03), 0x00, "Open Grotto Beehive Right", "HF Open Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD, false); + locationTable[RC_HF_SOUTHEAST_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_HF_SOUTHEAST_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x22), 0x00, "Southeast Grotto Beehive Left", "HF Southeast Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD, false); + locationTable[RC_HF_SOUTHEAST_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_HF_SOUTHEAST_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x22), 0x00, "Southeast Grotto Beehive Right", "HF Southeast Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD, false); + locationTable[RC_HF_INSIDE_FENCE_GROTTO_BEEHIVE] = Location::Base(RC_HF_INSIDE_FENCE_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(1410, 0xE6), 0x00, "Inside Fence Grotto Beehive", "HF Inside Fence Grotto Beehive", RHT_BEEHIVE_LONELY_SCRUB_GROTTO, RG_RED_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD, false); + locationTable[RC_LLR_GROTTO_BEEHIVE] = Location::Base(RC_LLR_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_LON_LON_RANCH, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(5144, 0xFC), 0x00, "Grotto Beehive", "LLR Grotto Beehive", RHT_BEEHIVE_SCRUB_TRIO_GROTTO, RG_RED_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH, false); + locationTable[RC_KAK_OPEN_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_KAK_OPEN_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_KAKARIKO_VILLAGE, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x28), 0x00, "Open Grotto Beehive Left", "Kak Open Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, false); + locationTable[RC_KAK_OPEN_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_KAK_OPEN_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_KAKARIKO_VILLAGE, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x28), 0x00, "Open Grotto Beehive Right", "Kak Open Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_KAKARIKO, false); + locationTable[RC_DMT_COW_GROTTO_BEEHIVE] = Location::Base(RC_DMT_COW_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2617, 0xF8), 0x00, "Cow Grotto Beehive", "DMT Cow Grotto Beehive", RHT_BEEHIVE_COW_GROTTO, RG_RED_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN, false); + locationTable[RC_DMT_STORMS_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_DMT_STORMS_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x57), 0x00, "Storms Grotto Beehive Left", "DMT Storms Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN, false); + locationTable[RC_DMT_STORMS_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_DMT_STORMS_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x57), 0x00, "Storms Grotto Beehive Right", "DMT Storms Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN, false); + locationTable[RC_GC_GROTTO_BEEHIVE] = Location::Base(RC_GC_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_GORON_CITY, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(5144, 0xFB), 0x00, "Grotto Beehive", "GC Grotto Beehive", RHT_BEEHIVE_SCRUB_TRIO_GROTTO, RG_RED_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_GORON_CITY, false); + locationTable[RC_DMC_UPPER_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_DMC_UPPER_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x7A), 0x00, "Upper Grotto Beehive Left", "DMC Upper Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN, false); + locationTable[RC_DMC_UPPER_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_DMC_UPPER_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x7A), 0x00, "Upper Grotto Beehive Right", "DMC Upper Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN, false); + locationTable[RC_DMC_HAMMER_GROTTO_BEEHIVE] = Location::Base(RC_DMC_HAMMER_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(5144, 0xF9), 0x00, "Hammer Grotto Beehive", "DMC Hammer Grotto Beehive", RHT_BEEHIVE_SCRUB_TRIO_GROTTO, RG_RED_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN, false); + locationTable[RC_ZR_OPEN_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_ZR_OPEN_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_ZORAS_RIVER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x29), 0x00, "Open Grotto Beehive Left", "ZR Open Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER, false); + locationTable[RC_ZR_OPEN_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_ZR_OPEN_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_ZORAS_RIVER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x29), 0x00, "Open Grotto Beehive Right", "ZR Open Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER, false); + locationTable[RC_ZR_STORMS_GROTTO_BEEHIVE] = Location::Base(RC_ZR_STORMS_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_ZORAS_RIVER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2262, 0xEB), 0x00, "Storms Grotto Beehive", "ZR Storms Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER, false); + locationTable[RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_LEFT] = Location::Base(RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_ZORAS_DOMAIN, ACTOR_OBJ_COMB, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(382, 0x00), 0x00, "In Front of King Zora Beehive Left", "ZD In Front of King Zora Beehive Left", RHT_BEEHIVE_IN_FRONT_OF_KING_ZORA, RG_BLUE_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN, false); + locationTable[RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_RIGHT] = Location::Base(RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_ZORAS_DOMAIN, ACTOR_OBJ_COMB, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(948, 0x00), 0x00, "In Front of King Zora Beehive Right", "ZD In Front of King Zora Beehive Right", RHT_BEEHIVE_IN_FRONT_OF_KING_ZORA, RG_RED_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN, false); + locationTable[RC_ZD_BEHIND_KING_ZORA_BEEHIVE] = Location::Base(RC_ZD_BEHIND_KING_ZORA_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_ZORAS_DOMAIN, ACTOR_OBJ_COMB, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(701, 0x00), 0x00, "Behind King Zora Beehive", "ZD Behind King Zora Beehive", RHT_BEEHIVE_BEHIND_KING_ZORA, RG_RED_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN, false); + locationTable[RC_LH_GROTTO_BEEHIVE] = Location::Base(RC_LH_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_LAKE_HYLIA, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(5144, 0xEF), 0x00, "Grotto Beehive", "LH Grotto Beehive", RHT_BEEHIVE_SCRUB_TRIO_GROTTO, RG_RED_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA, false); + locationTable[RC_GV_DEKU_SCRUB_GROTTO_BEEHIVE] = Location::Base(RC_GV_DEKU_SCRUB_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_GERUDO_VALLEY, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2262, 0xF0), 0x00, "Deku Scrub Grotto Beehive", "GV Deku Scrub Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, false); + locationTable[RC_COLOSSUS_GROTTO_BEEHIVE] = Location::Base(RC_COLOSSUS_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DESERT_COLOSSUS, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2262, 0xFD), 0x00, "Grotto Beehive", "Colossus Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, {Category::cBeehive}, SpoilerCollectionCheck::RandomizerInf(0, 0), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY, false); + // Cows Randomizer Check Randomizer Check Quest Type Area Actor ID Scene ID Params Flags Short Name Spoiler Name Hint Text Key Vanilla Item Categories Spoiler Collection Check Collection Check Group locationTable[RC_KF_LINKS_HOUSE_COW] = Location::Base(RC_KF_LINKS_HOUSE_COW, RCQUEST_BOTH, RCTYPE_COW, RCAREA_KOKIRI_FOREST, ACTOR_EN_COW, SCENE_LINKS_HOUSE, 0x00, 0x15, "Links House Cow", "KF Links House Cow", RHT_KF_LINKS_HOUSE_COW, RG_MILK, { Category::cCow }, SpoilerCollectionCheck::Cow(0x34, 0x15), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); locationTable[RC_HF_COW_GROTTO_COW] = Location::Base(RC_HF_COW_GROTTO_COW, RCQUEST_BOTH, RCTYPE_COW, RCAREA_HYRULE_FIELD, ACTOR_EN_COW, SCENE_GROTTOS, TWO_ACTOR_PARAMS(3485, -291), 0x16, "Cow Grotto Cow", "HF Cow Grotto Cow", RHT_HF_COW_GROTTO_COW, RG_MILK, { Category::cCow }, SpoilerCollectionCheck::Cow(0x3E, 0x16), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index 90e956b0b..293295e92 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -331,6 +331,8 @@ namespace Rando { CanOpenStormGrotto = CanUse(RG_SONG_OF_STORMS) && (ShardOfAgony || ctx->GetTrickOption(RT_GROTTOS_WITHOUT_AGONY)); HookshotOrBoomerang = CanUse(RG_HOOKSHOT) || CanUse(RG_BOOMERANG); CanGetNightTimeGS = (CanUse(RG_SUNS_SONG) || !ctx->GetOption(RSK_SKULLS_SUNS_SONG)); + CanBreakUpperBeehives = HookshotOrBoomerang || (ctx->GetTrickOption(RT_BOMBCHU_BEEHIVES) && HasBombchus); + CanBreakLowerBeehives = CanBreakUpperBeehives || Bombs; CanFish = CanUse(RG_FISHING_POLE) || !ctx->GetOption(RSK_SHUFFLE_FISHING_POLE); CanGetChildFish = CanFish && (IsChild || (IsAdult && !ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))); CanGetAdultFish = CanFish && IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT); @@ -748,14 +750,16 @@ namespace Rando { CanSummonGossipFairy = false; CanSummonGossipFairyWithoutSuns = false; //CanPlantBean = false; - CanOpenBombGrotto = false; - CanOpenStormGrotto = false; - BigPoeKill = false; - HookshotOrBoomerang = false; - CanGetChildFish = false; - CanGetAdultFish = false; - FishingPole = false; - CanFish = false; + CanOpenBombGrotto = false; + CanOpenStormGrotto = false; + BigPoeKill = false; + HookshotOrBoomerang = false; + CanBreakUpperBeehives = false; + CanBreakLowerBeehives = false; + CanGetChildFish = false; + CanGetAdultFish = false; + FishingPole = false; + CanFish = false; BaseHearts = ctx->GetOption(RSK_STARTING_HEARTS).Value() + 1; Hearts = 0; diff --git a/soh/soh/Enhancements/randomizer/logic.h b/soh/soh/Enhancements/randomizer/logic.h index dfad1077e..425aba55e 100644 --- a/soh/soh/Enhancements/randomizer/logic.h +++ b/soh/soh/Enhancements/randomizer/logic.h @@ -295,6 +295,8 @@ class Logic { bool BigPoeKill = false; bool HookshotOrBoomerang = false; bool CanGetNightTimeGS = false; + bool CanBreakLowerBeehives = false; + bool CanBreakUpperBeehives = false; bool FishingPole = false; bool CanGetChildFish = false; bool CanGetAdultFish = false; diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp index 0fd5c2572..62d1526d1 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -273,6 +273,8 @@ void Settings::CreateOptionDescriptions() { "Expensive - Scrubs will be shuffled and their item will cost the vanilla price.\n" "\n" "Random - Scrubs will be shuffled and their item will cost will be between 0-95 rupees.\n"; + mOptionDescriptions[RSK_SHUFFLE_BEEHIVES] = + "Beehives give a randomized item from the pool when broken."; mOptionDescriptions[RSK_SHUFFLE_COWS] = "Cows give a randomized item from the pool upon performing Epona's Song in front of them."; mOptionDescriptions[RSK_SHUFFLE_MAGIC_BEANS] = diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 41f937828..3dc49988c 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -1540,6 +1540,38 @@ std::map rcToRandomizerInf = { { RC_LH_ADULT_FISHING, RAND_INF_ADULT_FISHING }, { RC_MARKET_10_BIG_POES, RAND_INF_10_BIG_POES }, { RC_KAK_100_GOLD_SKULLTULA_REWARD, RAND_INF_KAK_100_GOLD_SKULLTULA_REWARD }, + { RC_KF_STORMS_GROTTO_BEEHIVE_LEFT, RAND_INF_BEEHIVE_KF_STORMS_GROTTO_LEFT }, + { RC_KF_STORMS_GROTTO_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_KF_STORMS_GROTTO_RIGHT }, + { RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_LEFT, RAND_INF_BEEHIVE_LW_NEAR_SHORTCUTS_GROTTO_LEFT }, + { RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_LW_NEAR_SHORTCUTS_GROTTO_RIGHT }, + { RC_LW_DEKU_SCRUB_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_LW_DEKU_SCRUB_GROTTO }, + { RC_SFM_STORMS_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_SFM_STORMS_GROTTO }, + { RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_LEFT, RAND_INF_BEEHIVE_HF_NEAR_MARKET_GROTTO_LEFT }, + { RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_HF_NEAR_MARKET_GROTTO_RIGHT }, + { RC_HF_OPEN_GROTTO_BEEHIVE_LEFT, RAND_INF_BEEHIVE_HF_OPEN_GROTTO_LEFT }, + { RC_HF_OPEN_GROTTO_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_HF_OPEN_GROTTO_RIGHT }, + { RC_HF_SOUTHEAST_GROTTO_BEEHIVE_LEFT, RAND_INF_BEEHIVE_HF_SOUTHEAST_GROTTO_LEFT }, + { RC_HF_SOUTHEAST_GROTTO_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_HF_SOUTHEAST_GROTTO_RIGHT }, + { RC_HF_INSIDE_FENCE_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_HF_INSIDE_FENCE_GROTTO }, + { RC_LLR_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_LLR_GROTTO }, + { RC_KAK_OPEN_GROTTO_BEEHIVE_LEFT, RAND_INF_BEEHIVE_KAK_OPEN_GROTTO_LEFT }, + { RC_KAK_OPEN_GROTTO_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_KAK_OPEN_GROTTO_RIGHT }, + { RC_DMT_COW_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_DMT_COW_GROTTO }, + { RC_DMT_STORMS_GROTTO_BEEHIVE_LEFT, RAND_INF_BEEHIVE_DMT_STORMS_GROTTO_LEFT }, + { RC_DMT_STORMS_GROTTO_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_DMT_STORMS_GROTTO_RIGHT }, + { RC_GC_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_GC_GROTTO }, + { RC_DMC_UPPER_GROTTO_BEEHIVE_LEFT, RAND_INF_BEEHIVE_DMC_UPPER_GROTTO_LEFT }, + { RC_DMC_UPPER_GROTTO_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_DMC_UPPER_GROTTO_RIGHT }, + { RC_DMC_HAMMER_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_DMC_HAMMER_GROTTO }, + { RC_ZR_OPEN_GROTTO_BEEHIVE_LEFT, RAND_INF_BEEHIVE_ZR_OPEN_GROTTO_LEFT }, + { RC_ZR_OPEN_GROTTO_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_ZR_OPEN_GROTTO_RIGHT }, + { RC_ZR_STORMS_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_ZR_STORMS_GROTTO }, + { RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_LEFT, RAND_INF_BEEHIVE_ZD_IN_FRONT_OF_KING_ZORA_LEFT }, + { RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_ZD_IN_FRONT_OF_KING_ZORA_RIGHT }, + { RC_ZD_BEHIND_KING_ZORA_BEEHIVE, RAND_INF_BEEHIVE_ZD_BEHIND_KING_ZORA }, + { RC_LH_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_LH_GROTTO }, + { RC_GV_DEKU_SCRUB_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_GV_DEKU_SCRUB_GROTTO }, + { RC_COLOSSUS_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_COLOSSUS_GROTTO }, { RC_LH_CHILD_FISH_1, RAND_INF_CHILD_FISH_1 }, { RC_LH_CHILD_FISH_2, RAND_INF_CHILD_FISH_2 }, { RC_LH_CHILD_FISH_3, RAND_INF_CHILD_FISH_3 }, @@ -1589,6 +1621,28 @@ std::map rcToRandomizerInf = { { RC_ZD_FISH_5, RAND_INF_ZD_FISH_5 }, }; +BeehiveIdentity Randomizer::IdentifyBeehive(s32 sceneNum, s16 xPosition, s32 respawnData) { + struct BeehiveIdentity beehiveIdentity; + + beehiveIdentity.randomizerInf = RAND_INF_MAX; + beehiveIdentity.randomizerCheck = RC_UNKNOWN_CHECK; + + if (sceneNum == SCENE_GROTTOS) { + respawnData = TWO_ACTOR_PARAMS(xPosition, respawnData); + } else { + respawnData = TWO_ACTOR_PARAMS(xPosition, 0); + } + + Rando::Location* location = GetCheckObjectFromActor(ACTOR_OBJ_COMB, sceneNum, respawnData); + + if (location->GetRandomizerCheck() != RC_UNKNOWN_CHECK) { + beehiveIdentity.randomizerInf = rcToRandomizerInf[location->GetRandomizerCheck()]; + beehiveIdentity.randomizerCheck = location->GetRandomizerCheck(); + } + + return beehiveIdentity; +} + Rando::Location* Randomizer::GetCheckObjectFromActor(s16 actorId, s16 sceneNum, s32 actorParams = 0x00) { auto fs = OTRGlobals::Instance->gRandoContext->GetFishsanity(); RandomizerCheck specialRc = RC_UNKNOWN_CHECK; diff --git a/soh/soh/Enhancements/randomizer/randomizer.h b/soh/soh/Enhancements/randomizer/randomizer.h index 23a63a074..4d5a2ff30 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.h +++ b/soh/soh/Enhancements/randomizer/randomizer.h @@ -52,6 +52,7 @@ class Randomizer { RandomizerInf GetRandomizerInfFromCheck(RandomizerCheck rc); Rando::Location* GetCheckObjectFromActor(s16 actorId, s16 sceneNum, s32 actorParams); ScrubIdentity IdentifyScrub(s32 sceneNum, s32 actorParams, s32 respawnData); + BeehiveIdentity IdentifyBeehive(s32 sceneNum, s16 xPosition, s32 respawnData); ShopItemIdentity IdentifyShopItem(s32 sceneNum, u8 slotIndex); CowIdentity IdentifyCow(s32 sceneNum, s32 posX, s32 posZ); FishIdentity IdentifyFish(s32 sceneNum, s32 actorParams); diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 2ab5bd745..6822bc650 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -112,6 +112,7 @@ typedef enum { RCTYPE_BOSS_HEART_OR_OTHER_REWARD, // Boss heart container or lesser dungeon rewards (lens, ice arrow) RCTYPE_DUNGEON_REWARD, // Dungeon rewards (blue warps) RCTYPE_OCARINA, // Ocarina locations + RCTYPE_BEEHIVE, // Beehives RCTYPE_FISH, } RandomizerCheckType; @@ -1426,6 +1427,38 @@ typedef enum { RC_ZR_NEAR_DOMAIN_GOSSIP_STONE, RC_ZR_NEAR_GROTTOS_GOSSIP_STONE, RC_ZR_OPEN_GROTTO_GOSSIP_STONE, + RC_KF_STORMS_GROTTO_BEEHIVE_LEFT, + RC_KF_STORMS_GROTTO_BEEHIVE_RIGHT, + RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_LEFT, + RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_RIGHT, + RC_LW_DEKU_SCRUB_GROTTO_BEEHIVE, + RC_SFM_STORMS_GROTTO_BEEHIVE, + RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_LEFT, + RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_RIGHT, + RC_HF_OPEN_GROTTO_BEEHIVE_LEFT, + RC_HF_OPEN_GROTTO_BEEHIVE_RIGHT, + RC_HF_SOUTHEAST_GROTTO_BEEHIVE_LEFT, + RC_HF_SOUTHEAST_GROTTO_BEEHIVE_RIGHT, + RC_HF_INSIDE_FENCE_GROTTO_BEEHIVE, + RC_LLR_GROTTO_BEEHIVE, + RC_KAK_OPEN_GROTTO_BEEHIVE_LEFT, + RC_KAK_OPEN_GROTTO_BEEHIVE_RIGHT, + RC_DMT_COW_GROTTO_BEEHIVE, + RC_DMT_STORMS_GROTTO_BEEHIVE_LEFT, + RC_DMT_STORMS_GROTTO_BEEHIVE_RIGHT, + RC_GC_GROTTO_BEEHIVE, + RC_DMC_UPPER_GROTTO_BEEHIVE_LEFT, + RC_DMC_UPPER_GROTTO_BEEHIVE_RIGHT, + RC_DMC_HAMMER_GROTTO_BEEHIVE, + RC_ZR_OPEN_GROTTO_BEEHIVE_LEFT, + RC_ZR_OPEN_GROTTO_BEEHIVE_RIGHT, + RC_ZR_STORMS_GROTTO_BEEHIVE, + RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_LEFT, + RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_RIGHT, + RC_ZD_BEHIND_KING_ZORA_BEEHIVE, + RC_LH_GROTTO_BEEHIVE, + RC_GV_DEKU_SCRUB_GROTTO_BEEHIVE, + RC_COLOSSUS_GROTTO_BEEHIVE, RC_GANONDORF_HINT, RC_SHEIK_HINT_GC, RC_SHEIK_HINT_MQ_GC, @@ -1466,6 +1499,7 @@ typedef enum { RT_BUNNY_HOOD_JUMPS, RT_DAMAGE_BOOST_SIMPLE, RT_HOVER_BOOST_SIMPLE, + RT_BOMBCHU_BEEHIVES, RT_KF_ADULT_GS, // -- location tricks RT_LW_BRIDGE, RT_LW_MIDO_BACKFLIP, @@ -2922,6 +2956,14 @@ typedef enum { RHT_GANONS_TOWER_BOSS_KEY_CHEST, RHT_DELIVER_RUTOS_LETTER, RHT_MASTER_SWORD_PEDESTAL, + // Beehives + RHT_BEEHIVE_CHEST_GROTTO, + RHT_BEEHIVE_COW_GROTTO, + RHT_BEEHIVE_LONELY_SCRUB_GROTTO, + RHT_BEEHIVE_SCRUB_PAIR_GROTTO, + RHT_BEEHIVE_SCRUB_TRIO_GROTTO, + RHT_BEEHIVE_IN_FRONT_OF_KING_ZORA, + RHT_BEEHIVE_BEHIND_KING_ZORA, // Items RHT_KOKIRI_SWORD, RHT_MASTER_SWORD, @@ -3494,6 +3536,7 @@ typedef enum { RSK_SHOPSANITY_PRICES, RSK_SHOPSANITY_PRICES_AFFORDABLE, RSK_SHUFFLE_SCRUBS, + RSK_SHUFFLE_BEEHIVES, RSK_SHUFFLE_COWS, RSK_SHUFFLE_WEIRD_EGG, RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD, @@ -3977,6 +4020,11 @@ typedef enum { CANT_OBTAIN_NEED_EMPTY_BOTTLE, } ItemObtainability; +typedef struct BeehiveIdentity { + RandomizerInf randomizerInf; + RandomizerCheck randomizerCheck; +} BeehiveIdentity; + typedef struct ScrubIdentity { RandomizerInf randomizerInf; RandomizerCheck randomizerCheck; diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp index 3fa6b82d6..bbd4682ce 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp @@ -153,6 +153,7 @@ void RandomizerCheckObjects::UpdateImGuiVisibility() { RandomizerCheckObjects::AreaIsOverworld(location.GetArea())) || ((CVarGetInteger("gRandomizeShuffleTokens", RO_TOKENSANITY_OFF) == RO_TOKENSANITY_DUNGEONS) && RandomizerCheckObjects::AreaIsDungeon(location.GetArea()))) && + (location.GetRCType() != RCTYPE_BEEHIVE || CVarGetInteger("gRandomizeShuffleBeehives", RO_GENERIC_NO)) && (location.GetRCType() != RCTYPE_COW || CVarGetInteger("gRandomizeShuffleCows", RO_GENERIC_NO)) && (location.GetRCType() != RCTYPE_FISH || ctx->GetFishsanity()->GetFishLocationIncluded(&location, FSO_SOURCE_CVARS)) && (location.GetRCType() != RCTYPE_ADULT_TRADE || diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index 82c2f98fd..2dc6d2271 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -59,6 +59,7 @@ bool showDungeonTokens; bool showBeans; bool showScrubs; bool showMerchants; +bool showBeehives; bool showCows; bool showAdultTrade; bool showKokiriSword; @@ -1091,6 +1092,9 @@ void LoadSettings() { showMerchants = IS_RANDO ? OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF : true; + showBeehives = IS_RANDO ? + OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_BEEHIVES) == RO_GENERIC_YES + : false; showCows = IS_RANDO ? OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_COWS) == RO_GENERIC_YES : false; @@ -1208,6 +1212,7 @@ bool IsVisibleInCheckTracker(RandomizerCheck rc) { rc == RC_LW_DEKU_SCRUB_GROTTO_FRONT ) && (loc->GetRCType() != RCTYPE_MERCHANT || showMerchants) && + (loc->GetRCType() != RCTYPE_BEEHIVE || showBeehives) && (loc->GetRCType() != RCTYPE_OCARINA || showOcarinas) && (loc->GetRCType() != RCTYPE_SKULL_TOKEN || alwaysShowGS || (showOverworldTokens && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) || diff --git a/soh/soh/Enhancements/randomizer/randomizer_inf.h b/soh/soh/Enhancements/randomizer/randomizer_inf.h index 8cc8e7fb3..4c90aee18 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_inf.h +++ b/soh/soh/Enhancements/randomizer/randomizer_inf.h @@ -212,6 +212,39 @@ typedef enum { RAND_INF_HAS_OCARINA_C_LEFT, RAND_INF_HAS_OCARINA_C_RIGHT, + RAND_INF_BEEHIVE_KF_STORMS_GROTTO_LEFT, + RAND_INF_BEEHIVE_KF_STORMS_GROTTO_RIGHT, + RAND_INF_BEEHIVE_LW_NEAR_SHORTCUTS_GROTTO_LEFT, + RAND_INF_BEEHIVE_LW_NEAR_SHORTCUTS_GROTTO_RIGHT, + RAND_INF_BEEHIVE_LW_DEKU_SCRUB_GROTTO, + RAND_INF_BEEHIVE_SFM_STORMS_GROTTO, + RAND_INF_BEEHIVE_HF_NEAR_MARKET_GROTTO_LEFT, + RAND_INF_BEEHIVE_HF_NEAR_MARKET_GROTTO_RIGHT, + RAND_INF_BEEHIVE_HF_OPEN_GROTTO_LEFT, + RAND_INF_BEEHIVE_HF_OPEN_GROTTO_RIGHT, + RAND_INF_BEEHIVE_HF_SOUTHEAST_GROTTO_LEFT, + RAND_INF_BEEHIVE_HF_SOUTHEAST_GROTTO_RIGHT, + RAND_INF_BEEHIVE_HF_INSIDE_FENCE_GROTTO, + RAND_INF_BEEHIVE_LLR_GROTTO, + RAND_INF_BEEHIVE_KAK_OPEN_GROTTO_LEFT, + RAND_INF_BEEHIVE_KAK_OPEN_GROTTO_RIGHT, + RAND_INF_BEEHIVE_DMT_COW_GROTTO, + RAND_INF_BEEHIVE_DMT_STORMS_GROTTO_LEFT, + RAND_INF_BEEHIVE_DMT_STORMS_GROTTO_RIGHT, + RAND_INF_BEEHIVE_GC_GROTTO, + RAND_INF_BEEHIVE_DMC_UPPER_GROTTO_LEFT, + RAND_INF_BEEHIVE_DMC_UPPER_GROTTO_RIGHT, + RAND_INF_BEEHIVE_DMC_HAMMER_GROTTO, + RAND_INF_BEEHIVE_ZR_OPEN_GROTTO_LEFT, + RAND_INF_BEEHIVE_ZR_OPEN_GROTTO_RIGHT, + RAND_INF_BEEHIVE_ZR_STORMS_GROTTO, + RAND_INF_BEEHIVE_ZD_IN_FRONT_OF_KING_ZORA_LEFT, + RAND_INF_BEEHIVE_ZD_IN_FRONT_OF_KING_ZORA_RIGHT, + RAND_INF_BEEHIVE_ZD_BEHIND_KING_ZORA, + RAND_INF_BEEHIVE_LH_GROTTO, + RAND_INF_BEEHIVE_GV_DEKU_SCRUB_GROTTO, + RAND_INF_BEEHIVE_COLOSSUS_GROTTO, + RAND_INF_GROTTO_FISH_ZR_OPEN_GROTTO, RAND_INF_GROTTO_FISH_DMC_UPPER_GROTTO, RAND_INF_GROTTO_FISH_DMT_STORMS_GROTTO, diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index df886e92a..9adfd85b8 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -101,6 +101,7 @@ void Settings::CreateOptions() { mOptions[RSK_SHOPSANITY_PRICES_AFFORDABLE] = Option::Bool("Affordable Prices", "gRandomizeShopsanityPricesAffordable", mOptionDescriptions[RSK_SHOPSANITY_PRICES_AFFORDABLE]); mOptions[RSK_SHUFFLE_TOKENS] = Option::U8("Tokensanity", {"Off", "Dungeons", "Overworld", "All Tokens"}, OptionCategory::Setting, "gRandomizeShuffleTokens", mOptionDescriptions[RSK_SHUFFLE_TOKENS], WidgetType::Combobox, RO_TOKENSANITY_OFF); mOptions[RSK_SHUFFLE_SCRUBS] = Option::U8("Scrub Shuffle", {"Off", "Affordable", "Expensive", "Random Prices"}, OptionCategory::Setting, "gRandomizeShuffleScrubs", mOptionDescriptions[RSK_SHUFFLE_SCRUBS], WidgetType::Combobox, RO_SCRUBS_OFF); + mOptions[RSK_SHUFFLE_BEEHIVES] = Option::Bool("Shuffle Beehives", "gRandomizeShuffleBeehives", mOptionDescriptions[RSK_SHUFFLE_BEEHIVES]); mOptions[RSK_SHUFFLE_COWS] = Option::Bool("Shuffle Cows", "gRandomizeShuffleCows", mOptionDescriptions[RSK_SHUFFLE_COWS]); mOptions[RSK_SHUFFLE_KOKIRI_SWORD] = Option::Bool("Shuffle Kokiri Sword", "gRandomizeShuffleKokiriSword", mOptionDescriptions[RSK_SHUFFLE_KOKIRI_SWORD]); mOptions[RSK_SHUFFLE_MASTER_SWORD] = Option::Bool("Shuffle Master Sword", "gRandomizeShuffleMasterSword", mOptionDescriptions[RSK_SHUFFLE_MASTER_SWORD]); @@ -232,6 +233,7 @@ void Settings::CreateOptions() { // mTrickOptions[RT_BUNNY_HOOD_JUMPS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED}, false, "Bunny Hood Jumps", "Allows reaching locations using Bunny Hood's extended jumps."); // mTrickOptions[RT_DAMAGE_BOOST_SIMPLE] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED}, false, "Simple damage boosts", "Allows damage boosts to reach Hyrule Castle guards, the bomb bag area in DC and the Gerudo Valley crate Piece of Heart. Can be combined with \"Simple hover boosts\" for reaching far distances."); // mTrickOptions[RT_HOVER_BOOST_SIMPLE] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED}, false, "Simple hover boosts", "Allows equipping of hover boots when link is moving at high speeds to extend distance covered. Can be combined with \"Simple damage boosts\" for greater uses."); + mTrickOptions[RT_BOMBCHU_BEEHIVES] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::NOVICE}, false, "Bombchu Beehives", "Allows exploding beehives with bombchus"), mTrickOptions[RT_KF_ADULT_GS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_KOKIRI_FOREST, {Tricks::Tag::NOVICE}, false, "Adult Kokiri Forest GS with Hover Boots", "Can be obtained without Hookshot by using the Hover Boots off of one of the roots."); mTrickOptions[RT_LW_BRIDGE] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_THE_LOST_WOODS, {Tricks::Tag::EXPERT}, false, "Jump onto the Lost Woods Bridge as Adult with Nothing", "With very precise movement it's possible for adult to jump onto the bridge without needing Longshot, Hover Boots, or Bean."); mTrickOptions[RT_LW_MIDO_BACKFLIP] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_THE_LOST_WOODS, {Tricks::Tag::NOVICE}, false, "Backflip over Mido as Adult", "With a specific position and angle, you can backflip over Mido."); @@ -661,6 +663,7 @@ void Settings::CreateOptions() { &mOptions[RSK_FISHSANITY_POND_COUNT], &mOptions[RSK_FISHSANITY_AGE_SPLIT], &mOptions[RSK_SHUFFLE_SCRUBS], + &mOptions[RSK_SHUFFLE_BEEHIVES], &mOptions[RSK_SHUFFLE_COWS], &mOptions[RSK_SHUFFLE_MAGIC_BEANS], &mOptions[RSK_SHUFFLE_MERCHANTS], @@ -859,6 +862,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_FISHING_POLE], &mOptions[RSK_SHUFFLE_TOKENS], &mOptions[RSK_SHUFFLE_SCRUBS], + &mOptions[RSK_SHUFFLE_BEEHIVES], &mOptions[RSK_SHUFFLE_COWS], &mOptions[RSK_SHUFFLE_KOKIRI_SWORD], &mOptions[RSK_SHUFFLE_OCARINA], @@ -1038,6 +1042,7 @@ void Settings::CreateOptions() { &mOptions[RSK_FISHSANITY_POND_COUNT], &mOptions[RSK_FISHSANITY_AGE_SPLIT], &mOptions[RSK_SHUFFLE_SCRUBS], + &mOptions[RSK_SHUFFLE_BEEHIVES], &mOptions[RSK_SHUFFLE_COWS], &mOptions[RSK_SHUFFLE_MAGIC_BEANS], &mOptions[RSK_SHUFFLE_MERCHANTS], @@ -1079,6 +1084,7 @@ void Settings::CreateOptions() { { "Shuffle Settings:Split Pond Fish", RSK_FISHSANITY_AGE_SPLIT }, { "Shuffle Settings:Shuffle Fishing Pole", RSK_SHUFFLE_FISHING_POLE }, { "Shuffle Settings:Scrub Shuffle", RSK_SHUFFLE_SCRUBS }, + { "Shuffle Settings:Beehive Shuffle", RSK_SHUFFLE_BEEHIVES }, { "Shuffle Settings:Shuffle Cows", RSK_SHUFFLE_COWS }, { "Shuffle Settings:Tokensanity", RSK_SHUFFLE_TOKENS }, { "Shuffle Settings:Shuffle Ocarinas", RSK_SHUFFLE_OCARINA }, @@ -2225,6 +2231,7 @@ void Settings::ParseJson(nlohmann::json spoilerFileJson) { case RSK_FISHSANITY_AGE_SPLIT: case RSK_FISHING_POLE_HINT: case RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD: + case RSK_SHUFFLE_BEEHIVES: case RSK_SHUFFLE_COWS: case RSK_SHUFFLE_ADULT_TRADE: case RSK_SHUFFLE_MAGIC_BEANS: diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index feae99c47..7603cb398 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -2379,6 +2379,10 @@ extern "C" ScrubIdentity Randomizer_IdentifyScrub(s32 sceneNum, s32 actorParams, return OTRGlobals::Instance->gRandomizer->IdentifyScrub(sceneNum, actorParams, respawnData); } +extern "C" BeehiveIdentity Randomizer_IdentifyBeehive(s32 sceneNum, s16 xPosition, s32 respawnData) { + return OTRGlobals::Instance->gRandomizer->IdentifyBeehive(sceneNum, xPosition, respawnData); +} + extern "C" ShopItemIdentity Randomizer_IdentifyShopItem(s32 sceneNum, u8 slotIndex) { return OTRGlobals::Instance->gRandomizer->IdentifyShopItem(sceneNum, slotIndex); } diff --git a/soh/soh/OTRGlobals.h b/soh/soh/OTRGlobals.h index 143ec9ef2..d397a96a1 100644 --- a/soh/soh/OTRGlobals.h +++ b/soh/soh/OTRGlobals.h @@ -154,6 +154,7 @@ uint8_t GetSeedIconIndex(uint8_t index); u8 Randomizer_GetSettingValue(RandomizerSettingKey randoSettingKey); RandomizerCheck Randomizer_GetCheckFromActor(s16 actorId, s16 sceneNum, s16 actorParams); ScrubIdentity Randomizer_IdentifyScrub(s32 sceneNum, s32 actorParams, s32 respawnData); +BeehiveIdentity Randomizer_IdentifyBeehive(s32 sceneNum, s16 xPosition, s32 respawnData); ShopItemIdentity Randomizer_IdentifyShopItem(s32 sceneNum, u8 slotIndex); CowIdentity Randomizer_IdentifyCow(s32 sceneNum, s32 posX, s32 posZ); FishIdentity Randomizer_IdentifyFish(s32 sceneNum, s32 actorParams); diff --git a/soh/src/code/z_actor.c b/soh/src/code/z_actor.c index cd17e1756..a24e7e43c 100644 --- a/soh/src/code/z_actor.c +++ b/soh/src/code/z_actor.c @@ -2075,8 +2075,8 @@ s32 GiveItemEntryFromActor(Actor* actor, PlayState* play, GetItemEntry getItemEn * \param play the Global Context * \param getItemEntry the GetItemEntry for the item you want the player to receive. */ -void GiveItemEntryFromActorWithFixedRange(Actor* actor, PlayState* play, GetItemEntry getItemEntry) { - GiveItemEntryFromActor(actor, play, getItemEntry, 50.0f, 10.0f); +s32 GiveItemEntryFromActorWithFixedRange(Actor* actor, PlayState* play, GetItemEntry getItemEntry) { + return GiveItemEntryFromActor(actor, play, getItemEntry, 50.0f, 10.0f); } // TODO: Rename to GiveItemIdFromActor or similar diff --git a/soh/src/code/z_en_item00.c b/soh/src/code/z_en_item00.c index 42ea78f90..77f42aebd 100644 --- a/soh/src/code/z_en_item00.c +++ b/soh/src/code/z_en_item00.c @@ -348,6 +348,7 @@ void EnItem00_Init(Actor* thisx, PlayState* play) { f32 shadowScale = 6.0f; s32 getItemId = GI_NONE; this->randoGiEntry = (GetItemEntry)GET_ITEM_NONE; + this->randoCheck = (RandomizerCheck)RC_UNKNOWN_CHECK; s16 spawnParam8000 = this->actor.params & 0x8000; s32 pad1; @@ -485,12 +486,11 @@ void EnItem00_Init(Actor* thisx, PlayState* play) { this->actor.shape.shadowAlpha = 180; this->actor.focus.pos = this->actor.world.pos; this->getItemId = GI_NONE; - RandomizerCheck randoCheck = - Randomizer_GetCheckFromActor(this->actor.id, play->sceneNum, this->ogParams); + this->randoCheck = Randomizer_GetCheckFromActor(this->actor.id, play->sceneNum, this->ogParams); + this->randoInf = RAND_INF_MAX; - if (IS_RANDO && randoCheck != RC_UNKNOWN_CHECK) { - this->randoGiEntry = - Randomizer_GetItemFromKnownCheck(randoCheck, getItemId); + if (IS_RANDO && this->randoCheck != RC_UNKNOWN_CHECK) { + this->randoGiEntry = Randomizer_GetItemFromKnownCheck(this->randoCheck, getItemId); this->randoGiEntry.getItemFrom = ITEM_FROM_FREESTANDING; } @@ -581,7 +581,9 @@ void EnItem00_Init(Actor* thisx, PlayState* play) { if (!IS_RANDO || this->randoGiEntry.getItemId == GI_NONE) { func_8002F554(&this->actor, play, getItemId); } else { - GiveItemEntryFromActorWithFixedRange(&this->actor, play, this->randoGiEntry); + if (GiveItemEntryFromActorWithFixedRange(&this->actor, play, this->randoGiEntry) && this->randoInf != RAND_INF_MAX) { + Flags_SetRandomizerInf(this->randoInf); + } } } } @@ -734,7 +736,9 @@ void func_8001E5C8(EnItem00* this, PlayState* play) { if (!IS_RANDO) { func_8002F434(&this->actor, play, this->getItemId, 50.0f, 80.0f); } else { - GiveItemEntryFromActor(&this->actor, play, this->randoGiEntry, 50.0f, 80.0f); + if (GiveItemEntryFromActor(&this->actor, play, this->randoGiEntry, 50.0f, 80.0f) && this->randoInf != RAND_INF_MAX) { + Flags_SetRandomizerInf(this->randoInf); + } } this->unk_15A++; } else { @@ -955,7 +959,9 @@ void EnItem00_Update(Actor* thisx, PlayState* play) { func_8002F554(&this->actor, play, getItemId); } else { getItemId = this->randoGiEntry.getItemId; - GiveItemEntryFromActorWithFixedRange(&this->actor, play, this->randoGiEntry); + if (GiveItemEntryFromActorWithFixedRange(&this->actor, play, this->randoGiEntry) && this->randoInf != RAND_INF_MAX) { + Flags_SetRandomizerInf(this->randoInf); + } } } @@ -1363,15 +1369,11 @@ static const Vtx customDropVtx[] = { */ void EnItem00_DrawCollectible(EnItem00* this, PlayState* play) { if (IS_RANDO && (this->getItemId != GI_NONE || this->actor.params == ITEM00_SMALL_KEY)) { - RandomizerCheck randoCheck = - Randomizer_GetCheckFromActor(this->actor.id, play->sceneNum, this->ogParams); - - if (randoCheck != RC_UNKNOWN_CHECK) { - this->randoGiEntry = - Randomizer_GetItemFromKnownCheck(randoCheck, GI_NONE); + if (this->randoCheck != RC_UNKNOWN_CHECK) { + this->randoGiEntry = Randomizer_GetItemFromKnownCheck(this->randoCheck, GI_NONE); this->randoGiEntry.getItemFrom = ITEM_FROM_FREESTANDING; } - + f32 mtxScale = 10.67f; Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY); EnItem00_CustomItemsParticles(&this->actor, play, this->randoGiEntry); @@ -1457,12 +1459,8 @@ void EnItem00_DrawHeartContainer(EnItem00* this, PlayState* play) { */ void EnItem00_DrawHeartPiece(EnItem00* this, PlayState* play) { if (IS_RANDO) { - RandomizerCheck randoCheck = - Randomizer_GetCheckFromActor(this->actor.id, play->sceneNum, this->ogParams); - - if (randoCheck != RC_UNKNOWN_CHECK) { - this->randoGiEntry = - Randomizer_GetItemFromKnownCheck(randoCheck, GI_NONE); + if (this->randoCheck != RC_UNKNOWN_CHECK) { + this->randoGiEntry = Randomizer_GetItemFromKnownCheck(this->randoCheck, GI_NONE); this->randoGiEntry.getItemFrom = ITEM_FROM_FREESTANDING; } diff --git a/soh/src/overlays/actors/ovl_Obj_Comb/z_obj_comb.c b/soh/src/overlays/actors/ovl_Obj_Comb/z_obj_comb.c index a9e5ca2a7..0dde415e0 100644 --- a/soh/src/overlays/actors/ovl_Obj_Comb/z_obj_comb.c +++ b/soh/src/overlays/actors/ovl_Obj_Comb/z_obj_comb.c @@ -7,6 +7,7 @@ #include "z_obj_comb.h" #include "overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.h" #include "objects/gameplay_field_keep/gameplay_field_keep.h" +#include "include/z64actor.h" #define FLAGS 0 @@ -131,6 +132,21 @@ void ObjComb_Break(ObjComb* this, PlayState* play) { void ObjComb_ChooseItemDrop(ObjComb* this, PlayState* play) { s16 params = this->actor.params & 0x1F; + if ( + IS_RANDO && + Randomizer_GetSettingValue(RSK_SHUFFLE_BEEHIVES) && + !Flags_GetRandomizerInf(this->beehiveIdentity.randomizerInf) + ) { + GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(this->beehiveIdentity.randomizerCheck, GI_NONE); + + EnItem00* actor = (EnItem00*)Item_DropCollectible2(play, &this->actor.world.pos, ITEM00_SMALL_KEY); + actor->randoCheck = this->beehiveIdentity.randomizerCheck; + actor->randoGiEntry = getItemEntry; + actor->randoGiEntry.getItemFrom = ITEM_FROM_FREESTANDING; + actor->randoInf = this->beehiveIdentity.randomizerInf; + return; + } + if ((params > 0) || (params < 0x1A)) { if (params == 6) { if (Flags_GetCollectible(play, (this->actor.params >> 8) & 0x3F)) { @@ -154,6 +170,10 @@ void ObjComb_Init(Actor* thisx, PlayState* play) { Collider_InitJntSph(play, &this->collider); Collider_SetJntSph(play, &this->collider, &this->actor, &sJntSphInit, this->colliderItems); ObjComb_SetupWait(this); + if (IS_RANDO) { + s16 respawnData = gSaveContext.respawn[RESPAWN_MODE_RETURN].data & ((1 << 8) - 1); + this->beehiveIdentity = Randomizer_IdentifyBeehive(play->sceneNum, (s16)this->actor.world.pos.x, respawnData); + } } void ObjComb_Destroy(Actor* thisx, PlayState* play2) { @@ -171,7 +191,15 @@ void ObjComb_Wait(ObjComb* this, PlayState* play) { s32 dmgFlags; this->unk_1B0 -= 50; - if (this->unk_1B0 < 0) { + if ( + IS_RANDO && + Randomizer_GetSettingValue(RSK_SHUFFLE_BEEHIVES) && + !Flags_GetRandomizerInf(this->beehiveIdentity.randomizerInf) + ) { + if (this->unk_1B0 <= -5000) { + this->unk_1B0 = 1500; + } + } else if (this->unk_1B0 < 0) { this->unk_1B0 = 0; } @@ -199,7 +227,12 @@ void ObjComb_Update(Actor* thisx, PlayState* play) { this->unk_1B2 += 0x2EE0; this->actionFunc(this, play); - this->actor.shape.rot.x = Math_SinS(this->unk_1B2) * this->unk_1B0 + this->actor.home.rot.x; + s16 wiggleOffset = this->unk_1B0; + + if (IS_RANDO && this->unk_1B0 < 0) { + wiggleOffset = 0; + } + this->actor.shape.rot.x = Math_SinS(this->unk_1B2) * wiggleOffset + this->actor.home.rot.x; } void ObjComb_Draw(Actor* thisx, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_Obj_Comb/z_obj_comb.h b/soh/src/overlays/actors/ovl_Obj_Comb/z_obj_comb.h index 68640544f..f7713a961 100644 --- a/soh/src/overlays/actors/ovl_Obj_Comb/z_obj_comb.h +++ b/soh/src/overlays/actors/ovl_Obj_Comb/z_obj_comb.h @@ -15,6 +15,7 @@ typedef struct ObjComb { /* 0x0170 */ ColliderJntSphElement colliderItems[1]; /* 0x01B0 */ s16 unk_1B0; /* 0x01B2 */ s16 unk_1B2; + /* */ BeehiveIdentity beehiveIdentity; } ObjComb; // size = 0x01B4 #endif