From 55b52a26a5163fba6a4fa705ea834b5c9f2f7908 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= <159546+serprex@users.noreply.github.com> Date: Mon, 10 Aug 2026 01:21:41 +0000 Subject: [PATCH] replace specialized bean logic with events (#5842) --- .../Enhancements/randomizer/bean_patches.h | 56 +++++++ .../Enhancements/randomizer/hook_handlers.cpp | 150 +++--------------- .../randomizer/location_access.cpp | 100 +----------- .../Enhancements/randomizer/location_access.h | 10 +- .../overworld/death_mountain_crater.cpp | 93 +++++------ .../overworld/death_mountain_trail.cpp | 15 +- .../overworld/desert_colossus.cpp | 13 +- .../overworld/gerudo_valley.cpp | 15 +- .../location_access/overworld/graveyard.cpp | 17 +- .../overworld/kokiri_forest.cpp | 29 ++-- .../location_access/overworld/lake_hylia.cpp | 17 +- .../location_access/overworld/lost_woods.cpp | 26 +-- .../location_access/overworld/zoras_river.cpp | 11 +- soh/soh/Enhancements/randomizer/logic.cpp | 39 +++-- soh/soh/Enhancements/randomizer/logic.h | 1 + .../randomizer/randomizerEnums/LogicVal.h | 10 ++ soh/soh/Enhancements/randomizer/savefile.cpp | 26 +-- 17 files changed, 256 insertions(+), 372 deletions(-) create mode 100644 soh/soh/Enhancements/randomizer/bean_patches.h diff --git a/soh/soh/Enhancements/randomizer/bean_patches.h b/soh/soh/Enhancements/randomizer/bean_patches.h new file mode 100644 index 0000000000..ee15b2523c --- /dev/null +++ b/soh/soh/Enhancements/randomizer/bean_patches.h @@ -0,0 +1,56 @@ +#pragma once + +#include + +#include "randomizerTypes.h" +#include "z64scene.h" + +// One row per bean patch, shared by logic, savefile setup and the actor hooks. +// swchFlag is the switch flag set once the bean is planted, +// found using the Actor Viewer to get the Obj_Bean parameters & 0x3F. +struct BeanPatch { + LogicVal plantEvent; + RandomizerGet soul; + RandomizerInf soulRandInf; + SceneID scene; + uint8_t swchFlag; +}; + +inline constexpr std::array beanPatches = { { + { LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL, + RAND_INF_DEATH_MOUNTAIN_CRATER_BEAN_SOUL, SCENE_DEATH_MOUNTAIN_CRATER, 3 }, + { LOGIC_PLANT_DEATH_MOUNTAIN_TRAIL_BEAN, RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL, RAND_INF_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL, + SCENE_DEATH_MOUNTAIN_TRAIL, 6 }, + { LOGIC_PLANT_DESERT_COLOSSUS_BEAN, RG_DESERT_COLOSSUS_BEAN_SOUL, RAND_INF_DESERT_COLOSSUS_BEAN_SOUL, + SCENE_DESERT_COLOSSUS, 24 }, + { LOGIC_PLANT_GERUDO_VALLEY_BEAN, RG_GERUDO_VALLEY_BEAN_SOUL, RAND_INF_GERUDO_VALLEY_BEAN_SOUL, SCENE_GERUDO_VALLEY, + 3 }, + { LOGIC_PLANT_GRAVEYARD_BEAN, RG_GRAVEYARD_BEAN_SOUL, RAND_INF_GRAVEYARD_BEAN_SOUL, SCENE_GRAVEYARD, 3 }, + { LOGIC_PLANT_KOKIRI_FOREST_BEAN, RG_KOKIRI_FOREST_BEAN_SOUL, RAND_INF_KOKIRI_FOREST_BEAN_SOUL, SCENE_KOKIRI_FOREST, + 9 }, + { LOGIC_PLANT_LAKE_HYLIA_BEAN, RG_LAKE_HYLIA_BEAN_SOUL, RAND_INF_LAKE_HYLIA_BEAN_SOUL, SCENE_LAKE_HYLIA, 1 }, + { LOGIC_PLANT_LOST_WOODS_BRIDGE_BEAN, RG_LOST_WOODS_BRIDGE_BEAN_SOUL, RAND_INF_LOST_WOODS_BRIDGE_BEAN_SOUL, + SCENE_LOST_WOODS, 4 }, + { LOGIC_PLANT_LOST_WOODS_THEATER_BEAN, RG_LOST_WOODS_BEAN_SOUL, RAND_INF_LOST_WOODS_BEAN_SOUL, SCENE_LOST_WOODS, + 18 }, + { LOGIC_PLANT_ZORAS_RIVER_BEAN, RG_ZORAS_RIVER_BEAN_SOUL, RAND_INF_ZORAS_RIVER_BEAN_SOUL, SCENE_ZORAS_RIVER, 3 }, +} }; + +inline const BeanPatch* FindBeanPatch(LogicVal plantEvent) { + for (const BeanPatch& patch : beanPatches) { + if (patch.plantEvent == plantEvent) { + return &patch; + } + } + return nullptr; +} + +// Lost Woods is the only scene with two patches, so swchFlag only has to tell those apart +inline const BeanPatch* FindBeanPatch(int32_t sceneNum, uint8_t swchFlag) { + for (const BeanPatch& patch : beanPatches) { + if (patch.scene == sceneNum && (sceneNum != SCENE_LOST_WOODS || patch.swchFlag == swchFlag)) { + return &patch; + } + } + return nullptr; +} diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 5eddf8827d..8004475e2f 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -3,6 +3,7 @@ #include "soh/Enhancements/enhancementTypes.h" #include "soh/Enhancements/custom-message/CustomMessageTypes.h" #include "soh/Enhancements/randomizer/randomizerTypes.h" +#include "soh/Enhancements/randomizer/bean_patches.h" #include "soh/Enhancements/randomizer/dungeon.h" #include "soh/Enhancements/randomizer/static_data.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" @@ -469,6 +470,21 @@ void RandomizerOnPlayerUpdateForItemQueueHandler() { } } +// plants every bean patch at once for skip planting beans, growing the one in the current scene if it's loaded +static void PlantAllBeans() { + for (const BeanPatch& patch : beanPatches) { + gSaveContext.sceneFlags[patch.scene].swch |= 1 << patch.swchFlag; + if (gPlayState->sceneNum == patch.scene) { + Flags_SetSwitch(gPlayState, patch.swchFlag); + } + } + ObjBean* bean = (ObjBean*)Actor_Find(&gPlayState->actorCtx, ACTOR_OBJ_BEAN, ACTORCAT_BG); + if (bean != nullptr) { + func_80B8FE00(bean); + } + AMMO(ITEM_BEAN) = 0; +} + void RandomizerOnItemReceiveHandler(GetItemEntry receivedItemEntry) { if (randomizerQueuedCheck == RC_UNKNOWN_CHECK) return; @@ -506,49 +522,7 @@ void RandomizerOnItemReceiveHandler(GetItemEntry receivedItemEntry) { if (receivedItemEntry.modIndex == MOD_RANDOMIZER && receivedItemEntry.getItemId == RG_MAGIC_BEAN_PACK) { if (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SKIP_PLANTING_BEANS)) { - gSaveContext.sceneFlags[SCENE_DEATH_MOUNTAIN_CRATER].swch |= (1 << 3); - if (gPlayState->sceneNum == SCENE_DEATH_MOUNTAIN_CRATER) { - Flags_SetSwitch(gPlayState, 3); - } - gSaveContext.sceneFlags[SCENE_DEATH_MOUNTAIN_TRAIL].swch |= (1 << 6); - if (gPlayState->sceneNum == SCENE_DEATH_MOUNTAIN_TRAIL) { - Flags_SetSwitch(gPlayState, 6); - } - gSaveContext.sceneFlags[SCENE_DESERT_COLOSSUS].swch |= (1 << 24); - if (gPlayState->sceneNum == SCENE_DESERT_COLOSSUS) { - Flags_SetSwitch(gPlayState, 24); - } - gSaveContext.sceneFlags[SCENE_GERUDO_VALLEY].swch |= (1 << 3); - if (gPlayState->sceneNum == SCENE_GERUDO_VALLEY) { - Flags_SetSwitch(gPlayState, 3); - } - gSaveContext.sceneFlags[SCENE_GRAVEYARD].swch |= (1 << 3); - if (gPlayState->sceneNum == SCENE_GRAVEYARD) { - Flags_SetSwitch(gPlayState, 3); - } - gSaveContext.sceneFlags[SCENE_KOKIRI_FOREST].swch |= (1 << 9); - if (gPlayState->sceneNum == SCENE_KOKIRI_FOREST) { - Flags_SetSwitch(gPlayState, 9); - } - gSaveContext.sceneFlags[SCENE_LAKE_HYLIA].swch |= (1 << 1); - if (gPlayState->sceneNum == SCENE_LAKE_HYLIA) { - Flags_SetSwitch(gPlayState, 1); - } - gSaveContext.sceneFlags[SCENE_LOST_WOODS].swch |= (1 << 4) | (1 << 18); - if (gPlayState->sceneNum == SCENE_LOST_WOODS) { - Flags_SetSwitch(gPlayState, 4); - Flags_SetSwitch(gPlayState, 18); - } - gSaveContext.sceneFlags[SCENE_ZORAS_RIVER].swch |= (1 << 3); - if (gPlayState->sceneNum == SCENE_ZORAS_RIVER) { - Flags_SetSwitch(gPlayState, 3); - } - ObjBean* bean = (ObjBean*)Actor_Find(&gPlayState->actorCtx, ACTOR_OBJ_BEAN, ACTORCAT_BG); - if (bean != nullptr) { - Flags_SetSwitch(gPlayState, bean->dyna.actor.params & 0x3F); - func_80B8FE00(bean); - } - AMMO(ITEM_BEAN) = 0; + PlantAllBeans(); } } @@ -1516,21 +1490,7 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l Rupees_ChangeBy(-60); Item_Give(NULL, ITEM_BEAN); BEANS_BOUGHT = 10; - AMMO(ITEM_BEAN) = 0; - 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); - ObjBean* bean = (ObjBean*)Actor_Find(&gPlayState->actorCtx, ACTOR_OBJ_BEAN, ACTORCAT_BG); - if (bean != nullptr) { - Flags_SetSwitch(gPlayState, bean->dyna.actor.params & 0x3F); - func_80B8FE00(bean); - } + PlantAllBeans(); enMs->actionFunc = (EnMsActionFunc)EnMs_Wait; *should = false; } @@ -2533,77 +2493,15 @@ void RandomizerOnActorInitHandler(void* actorRef) { } if (RAND_GET_OPTION(RSK_SHUFFLE_BEAN_SOULS)) { - RandomizerInf currentBeanSoulRandInf = RAND_INF_MAX; + const BeanPatch* patch = nullptr; if (actor->id == ACTOR_OBJ_BEAN) { - 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; - } + // bean params hold the switch flag + patch = FindBeanPatch(gPlayState->sceneNum, actor->params & 0x3F); } else if (actor->id == ACTOR_OBJ_MAKEKINSUTA) { - 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 == 0x4e01) { - 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; - } + // soft soil params don't, so map the Lost Woods pair onto their flags + patch = FindBeanPatch(gPlayState->sceneNum, actor->params == 0x4e01 ? 4 : 18); } - if (currentBeanSoulRandInf != RAND_INF_MAX && !Flags_GetRandomizerInf(currentBeanSoulRandInf)) { + if (patch != nullptr && !Flags_GetRandomizerInf(patch->soulRandInf)) { Actor_Kill(actor); return; } diff --git a/soh/soh/Enhancements/randomizer/location_access.cpp b/soh/soh/Enhancements/randomizer/location_access.cpp index bb84bbc817..6242c6404c 100644 --- a/soh/soh/Enhancements/randomizer/location_access.cpp +++ b/soh/soh/Enhancements/randomizer/location_access.cpp @@ -504,13 +504,6 @@ Rando::Entrance* Region::GetExit(RandomizerRegion exitToReturn) { return nullptr; } -bool Region::CanPlantBeanCheck(RandomizerGet bean) const { - auto ctx = Rando::Context::GetInstance(); - auto logic = ctx->GetLogic(); - return logic->HasItem(bean) && logic->GetAmmo(ITEM_BEAN) > 0 && - (ctx->GetOption(RSK_SKIP_PLANTING_BEANS) || BothAgesCheck()); -} - bool Region::AllAccountedFor() const { for (const EventAccess& event : events) { if (!event.GetEvent()) { @@ -865,94 +858,11 @@ bool AnyAgeTime(ConditionFn condition) { return areaTable[logic->CurrentRegionKey].AnyAgeTime(condition); } -bool BeanPlanted(const RandomizerGet bean) { - auto logic = Rando::Context::GetInstance()->GetLogic(); - // flag irrelevant if plant won't spawn - if (!logic->HasItem(bean)) { - return false; - } else if (ctx->GetOption(RSK_SKIP_PLANTING_BEANS) && ctx->GetOption(RSK_STARTING_BEANS)) { - return true; - } - - // swchFlag found using the Actor Viewer to get the Obj_Bean parameters & 0x3F - // not tested with multiple OTRs, but can be automated similarly to GetUsedSmallKeys - SceneID sceneID; - uint8_t swchFlag; - switch (bean) { - case RG_ZORAS_RIVER_BEAN_SOUL: - sceneID = SceneID::SCENE_ZORAS_RIVER; - swchFlag = 3; - break; - case RG_GRAVEYARD_BEAN_SOUL: - sceneID = SceneID::SCENE_GRAVEYARD; - swchFlag = 3; - break; - case RG_KOKIRI_FOREST_BEAN_SOUL: - sceneID = SceneID::SCENE_KOKIRI_FOREST; - swchFlag = 9; - break; - case RG_LOST_WOODS_BRIDGE_BEAN_SOUL: - sceneID = SceneID::SCENE_LOST_WOODS; - swchFlag = 4; - break; - case RG_LOST_WOODS_BEAN_SOUL: - sceneID = SceneID::SCENE_LOST_WOODS; - swchFlag = 18; - break; - case RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL: - sceneID = SceneID::SCENE_DEATH_MOUNTAIN_TRAIL; - swchFlag = 6; - break; - case RG_LAKE_HYLIA_BEAN_SOUL: - sceneID = SceneID::SCENE_LAKE_HYLIA; - swchFlag = 1; - break; - case RG_GERUDO_VALLEY_BEAN_SOUL: - sceneID = SceneID::SCENE_GERUDO_VALLEY; - swchFlag = 3; - break; - case RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL: - sceneID = SceneID::SCENE_DEATH_MOUNTAIN_CRATER; - swchFlag = 3; - break; - case RG_DESERT_COLOSSUS_BEAN_SOUL: - sceneID = SceneID::SCENE_DESERT_COLOSSUS; - swchFlag = 24; - break; - default: - sceneID = SCENE_ID_MAX; - swchFlag = 0; - assert(false); - break; - } - - // Get the swch value for the scene - uint32_t swch; - if (gPlayState != nullptr && gPlayState->sceneNum == sceneID) { - swch = gPlayState->actorCtx.flags.swch; - } else if (sceneID != SCENE_ID_MAX) { - swch = logic->GetSaveContext()->sceneFlags[sceneID].swch; - } else { - swch = 0; - } - - return swch >> swchFlag & 1; -} - -bool CanPlantBean(const RandomizerRegion region, const RandomizerGet bean) { - return areaTable[region].CanPlantBeanCheck(bean) || BeanPlanted(bean); -} - -bool BothAges(const RandomizerRegion region) { - return areaTable[region].BothAgesCheck(); -} - -bool ChildCanAccess(const RandomizerRegion region) { - return areaTable[region].Child(); -} - -bool AdultCanAccess(const RandomizerRegion region) { - return areaTable[region].Adult(); +bool CanPlantBean(const RandomizerGet bean) { + auto ctx = Rando::Context::GetInstance(); + auto logic = ctx->GetLogic(); + return logic->HasItem(bean) && logic->GetAmmo(ITEM_BEAN) > 0 && + (logic->IsChild || ctx->GetOption(RSK_SKIP_PLANTING_BEANS)); } Rando::Context* ctx; diff --git a/soh/soh/Enhancements/randomizer/location_access.h b/soh/soh/Enhancements/randomizer/location_access.h index d80a10ebe8..b20ebda152 100644 --- a/soh/soh/Enhancements/randomizer/location_access.h +++ b/soh/soh/Enhancements/randomizer/location_access.h @@ -192,10 +192,6 @@ class Region { return adultDay || adultNight; } - bool BothAgesCheck() const { - return Child() && Adult(); - } - bool HasAccess() const { return Child() || Adult(); } @@ -247,7 +243,6 @@ class Region { return hereVal; } - bool CanPlantBeanCheck(RandomizerGet bean) const; bool AllAccountedFor() const; void ResetVariables(); @@ -266,10 +261,7 @@ bool SpiritShared( ConditionFn thirdCondition = [] { return false; }); bool SpiritCertainAccess(RandomizerRegion region); bool DMCPadToPots(); -bool CanPlantBean(const RandomizerRegion region, RandomizerGet bean); -bool BothAges(const RandomizerRegion region); -bool ChildCanAccess(const RandomizerRegion region); -bool AdultCanAccess(const RandomizerRegion region); +bool CanPlantBean(RandomizerGet bean); namespace Regions { extern void AccessReset(); 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 86d92ca32f..b9588df7f1 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 @@ -23,11 +23,11 @@ void RegionTable_Init_DeathMountainCrater() { //Locations //You can also walk off the edge at a shallow angle to not grab the wall, then drift to land in the alcove. LOCATION(RC_DMC_WALL_FREESTANDING_POH, ((logic->FireTimer() >= 16 || logic->Health() >= 3 * 16) && (logic->HasItem(RG_CLIMB) || (ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS) && logic->CanJumpslash()))) || - (logic->IsAdult && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL) && + (logic->IsAdult && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN) && (((logic->FireTimer() >= 72 || logic->Health() >= 14 * 16) && logic->DMCUpperToPots() && logic->DMCPotsToPad()) || ((logic->FireTimer() >= 48 || logic->Health() >= 9 * 16) && logic->DMCUpperToPad())))), LOCATION(RC_DMC_VOLCANO_FREESTANDING_POH, ((logic->FireTimer() >= 24 || logic->Health() >= 5 * 16) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS)) || - (logic->IsAdult && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL) && + (logic->IsAdult && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN) && (((logic->FireTimer() >= 56 || logic->Health() >= 11 * 16) && logic->DMCUpperToPots() && logic->DMCPotsToPad()) || ((logic->FireTimer() >= 40 || logic->Health() >= 8 * 16) && logic->DMCUpperToPad())))), }, { @@ -56,11 +56,11 @@ void RegionTable_Init_DeathMountainCrater() { }, { //Locations LOCATION(RC_DMC_WALL_FREESTANDING_POH, ((logic->FireTimer() >= 8 || logic->Health() >= 2 * 16) && (logic->HasItem(RG_CLIMB) || (ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS) && logic->CanJumpslash()))) || - (logic->IsAdult && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL) && + (logic->IsAdult && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN) && (((logic->FireTimer() >= 72 || logic->Health() >= 14 * 16) && logic->DMCUpperToPots() && logic->DMCPotsToPad()) || ((logic->FireTimer() >= 40 || logic->Health() >= 8 * 16) && logic->DMCUpperToPad())))), LOCATION(RC_DMC_VOLCANO_FREESTANDING_POH, ((logic->FireTimer() >= 24 || logic->Health() >= 5 * 16) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS)) || - (logic->IsAdult && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL) && + (logic->IsAdult && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN) && (((logic->FireTimer() >= 64 || logic->Health() >= 12 * 16) && logic->DMCUpperToPots() && logic->DMCPotsToPad()) || ((logic->FireTimer() >= 40 || logic->Health() >= 8 * 16) && logic->DMCUpperToPad())))), }, { @@ -88,20 +88,20 @@ void RegionTable_Init_DeathMountainCrater() { areaTable[RR_DMC_BLOCKED_ENTRY] = Region("DMC Blocked Entry", SCENE_DEATH_MOUNTAIN_CRATER, {}, { //Locations LOCATION(RC_DMC_WALL_FREESTANDING_POH, ((logic->FireTimer() >= 24 || logic->Health() >= 5 * 16) && logic->CanClimbLadder() && (logic->HasItem(RG_CLIMB) || (ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS) && logic->CanJumpslash()))) || - (logic->IsAdult && (logic->FireTimer() >= 40 || logic->Health() >= 8 * 16) && logic->DMCPotsToPad() && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)) || + (logic->IsAdult && (logic->FireTimer() >= 40 || logic->Health() >= 8 * 16) && logic->DMCPotsToPad() && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN)) || ((logic->FireTimer() >= 24 || logic->Health() >= 5 * 16) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_LONGSHOT))), LOCATION(RC_DMC_VOLCANO_FREESTANDING_POH, ((logic->FireTimer() >= 16 || logic->Health() >= 3 * 16) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS)) || - (logic->IsAdult && (logic->FireTimer() >= 40 || logic->Health() >= 8 * 16) && logic->DMCPotsToPad() && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL))), + (logic->IsAdult && (logic->FireTimer() >= 40 || logic->Health() >= 8 * 16) && logic->DMCPotsToPad() && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN))), }, { //Exits ENTRANCE(RR_DMC_CRATE, ((logic->FireTimer() >= 24 || logic->Health() >= 5 * 16) && logic->CanClimbLadder()) || - (logic->IsAdult && (logic->FireTimer() >= 56 || logic->Health() >= 11 * 16) && logic->DMCPotsToPad() && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)) || + (logic->IsAdult && (logic->FireTimer() >= 56 || logic->Health() >= 11 * 16) && logic->DMCPotsToPad() && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN)) || ((logic->FireTimer() >= 24 || logic->Health() >= 5 * 16) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_LONGSHOT))), ENTRANCE(RR_DMC_ROCK_GROTTO, ((logic->FireTimer() >= 24 || logic->Health() >= 5 * 16) && logic->CanClimbLadder()) || - (logic->IsAdult && (logic->FireTimer() >= 48 || logic->Health() >= 9 * 16) && logic->DMCPotsToPad() && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)) || + (logic->IsAdult && (logic->FireTimer() >= 48 || logic->Health() >= 9 * 16) && logic->DMCPotsToPad() && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN)) || ((logic->FireTimer() >= 24 || logic->Health() >= 5 * 16) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_LONGSHOT))), ENTRANCE(RR_DMC_CRACKED_WALL, (logic->FireTimer() >= 32 || logic->Health() >= 6 * 16) && logic->CanClimbLadder() || - (logic->IsAdult && (logic->FireTimer() >= 48 || logic->Health() >= 9 * 16) && logic->DMCPotsToPad() && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)) || + (logic->IsAdult && (logic->FireTimer() >= 48 || logic->Health() >= 9 * 16) && logic->DMCPotsToPad() && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN)) || ((logic->FireTimer() >= 32 || logic->Health() >= 6 * 16) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_LONGSHOT))), ENTRANCE(RR_DMC_SCRUB, logic->FireTimer() >= 8 || logic->Health() >= 2 * 16), ENTRANCE(RR_DMC_BLOCKED_EXIT, true), @@ -111,7 +111,7 @@ void RegionTable_Init_DeathMountainCrater() { (logic->IsAdult && (logic->FireTimer() >= 48 || logic->Health() >= 9 * 16) && logic->DMCUpperToPad())), ENTRANCE(RR_DMC_FAR_PLATFORM, (logic->IsAdult && (logic->FireTimer() >= 48 || logic->Health() >= 9 * 16) && logic->DMCPotsToPad() && logic->ReachDistantScarecrow()) || ((logic->FireTimer() >= 32 || logic->Health() >= 6 * 16) && logic->TakeDamage() && ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS) && logic->CanClimbLadder()) || - (logic->IsAdult && (logic->FireTimer() >= 48 || logic->Health() >= 9 * 16) && logic->DMCPotsToPad() && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)) || + (logic->IsAdult && (logic->FireTimer() >= 48 || logic->Health() >= 9 * 16) && logic->DMCPotsToPad() && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN)) || ((logic->FireTimer() >= 32 || logic->Health() >= 6 * 16) && logic->TakeDamage() && ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS))), ENTRANCE(RR_DMC_TEMPLE_EXIT, (logic->IsAdult || (ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && (((logic->FireTimer() >= 48 || logic->Health() >= 9 * 16) && logic->DMCPotsToPad()) || @@ -121,20 +121,20 @@ void RegionTable_Init_DeathMountainCrater() { areaTable[RR_DMC_POTS_ENTRY] = Region("DMC Pots Entry", SCENE_DEATH_MOUNTAIN_CRATER, {}, { //Locations LOCATION(RC_DMC_WALL_FREESTANDING_POH, ((logic->FireTimer() >= 40 || logic->Health() >= 8 * 16) && logic->CanClimbLadder() && (logic->HasItem(RG_CLIMB) || (ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS) && logic->CanJumpslash()))) || - (logic->IsAdult && (logic->FireTimer() >= 40 || logic->Health() >= 8 * 16) && logic->DMCPotsToPad() && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)) || + (logic->IsAdult && (logic->FireTimer() >= 40 || logic->Health() >= 8 * 16) && logic->DMCPotsToPad() && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN)) || ((logic->FireTimer() >= 24 || logic->Health() >= 5 * 16) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_LONGSHOT))), LOCATION(RC_DMC_VOLCANO_FREESTANDING_POH, ((logic->FireTimer() >= 8 || logic->Health() >= 2 * 16) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS)) || - (logic->IsAdult && (logic->FireTimer() >= 32 || logic->Health() >= 6 * 16) && logic->DMCPotsToPad() && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL))), + (logic->IsAdult && (logic->FireTimer() >= 32 || logic->Health() >= 6 * 16) && logic->DMCPotsToPad() && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN))), }, { //Exits ENTRANCE(RR_DMC_CRATE, (logic->FireTimer() >= 32 || logic->Health() >= 6 * 16) && logic->CanClimbLadder() || - (logic->IsAdult && (logic->FireTimer() >= 48 || logic->Health() >= 9 * 16) && logic->DMCPotsToPad() && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)) || + (logic->IsAdult && (logic->FireTimer() >= 48 || logic->Health() >= 9 * 16) && logic->DMCPotsToPad() && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN)) || ((logic->FireTimer() >= 24 || logic->Health() >= 5 * 16) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_LONGSHOT))), ENTRANCE(RR_DMC_ROCK_GROTTO, (logic->FireTimer() >= 32 || logic->Health() >= 6 * 16) && logic->CanClimbLadder() || - (logic->IsAdult && (logic->FireTimer() >= 48 || logic->Health() >= 9 * 16) && logic->DMCPotsToPad() && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)) || + (logic->IsAdult && (logic->FireTimer() >= 48 || logic->Health() >= 9 * 16) && logic->DMCPotsToPad() && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN)) || ((logic->FireTimer() >= 24 || logic->Health() >= 5 * 16) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_LONGSHOT))), ENTRANCE(RR_DMC_CRACKED_WALL, (logic->FireTimer() >= 32 || logic->Health() >= 6 * 16) && logic->CanClimbLadder() || - (logic->IsAdult && (logic->FireTimer() >= 40 || logic->Health() >= 8 * 16) && logic->DMCPotsToPad() && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)) || + (logic->IsAdult && (logic->FireTimer() >= 40 || logic->Health() >= 8 * 16) && logic->DMCPotsToPad() && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN)) || ((logic->FireTimer() >= 24 || logic->Health() >= 5 * 16) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_LONGSHOT))), ENTRANCE(RR_DMC_SCRUB, logic->FireTimer() >= 16 || logic->Health() >= 3 * 16), ENTRANCE(RR_DMC_BLOCKED_EXIT, logic->FireTimer() >= 8 || logic->Health() >= 2 * 16), @@ -144,7 +144,7 @@ void RegionTable_Init_DeathMountainCrater() { ((logic->FireTimer() >= 56 || logic->Health() >= 11 * 16) && logic->DMCUpperToPad() && logic->CanClimbLadder())), ENTRANCE(RR_DMC_FAR_PLATFORM, (logic->IsAdult && (logic->FireTimer() >= 40 || logic->Health() >= 8 * 16) && logic->DMCPotsToPad() && logic->ReachDistantScarecrow()) || ((logic->FireTimer() >= 32 || logic->Health() >= 6 * 16) && logic->TakeDamage() && ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS) && logic->CanClimbLadder()) || - (logic->IsAdult && (logic->FireTimer() >= 40 || logic->Health() >= 8 * 16) && logic->DMCPotsToPad() && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)) || + (logic->IsAdult && (logic->FireTimer() >= 40 || logic->Health() >= 8 * 16) && logic->DMCPotsToPad() && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN)) || ((logic->FireTimer() >= 32 || logic->Health() >= 6 * 16) && logic->TakeDamage() && ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS))), ENTRANCE(RR_DMC_TEMPLE_EXIT, (logic->IsAdult || (ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && (((logic->FireTimer() >= 40 || logic->Health() >= 8 * 16) && logic->DMCPotsToPad()) || @@ -154,20 +154,20 @@ void RegionTable_Init_DeathMountainCrater() { areaTable[RR_DMC_POT_GROTTO_ENTRY] = Region("DMC Pot Grotto Entry", SCENE_DEATH_MOUNTAIN_CRATER, {}, { //Locations LOCATION(RC_DMC_WALL_FREESTANDING_POH, ((logic->FireTimer() >= 40 || logic->Health() >= 8 * 16) && logic->CanClimbLadder() && (logic->HasItem(RG_CLIMB) || (ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS) && logic->CanJumpslash()))) || - (logic->IsAdult && (logic->FireTimer() >= 40 || logic->Health() >= 8 * 16) && logic->DMCPotsToPad() && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)) || + (logic->IsAdult && (logic->FireTimer() >= 40 || logic->Health() >= 8 * 16) && logic->DMCPotsToPad() && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN)) || ((logic->FireTimer() >= 24 || logic->Health() >= 5 * 16) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_LONGSHOT) && (logic->HasItem(RG_CLIMB) || (ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS) && logic->CanJumpslash())))), LOCATION(RC_DMC_VOLCANO_FREESTANDING_POH, (logic->FireTimer() >= 16 || logic->Health() >= 3 * 16) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS) || - (logic->IsAdult && (logic->FireTimer() >= 32 || logic->Health() >= 6 * 16) && logic->DMCPotsToPad() && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL))), + (logic->IsAdult && (logic->FireTimer() >= 32 || logic->Health() >= 6 * 16) && logic->DMCPotsToPad() && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN))), }, { //Exits ENTRANCE(RR_DMC_CRATE, (logic->FireTimer() >= 32 || logic->Health() >= 6 * 16) && logic->CanClimbLadder() || - (logic->IsAdult && (logic->FireTimer() >= 48 || logic->Health() >= 9 * 16) && logic->DMCPotsToPad() && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)) || + (logic->IsAdult && (logic->FireTimer() >= 48 || logic->Health() >= 9 * 16) && logic->DMCPotsToPad() && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN)) || ((logic->FireTimer() >= 24 || logic->Health() >= 5 * 16) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_LONGSHOT))), ENTRANCE(RR_DMC_ROCK_GROTTO, (logic->FireTimer() >= 32 || logic->Health() >= 6 * 16) && logic->CanClimbLadder() || - (logic->IsAdult && (logic->FireTimer() >= 40 || logic->Health() >= 8 * 16) && logic->DMCPotsToPad() && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)) || + (logic->IsAdult && (logic->FireTimer() >= 40 || logic->Health() >= 8 * 16) && logic->DMCPotsToPad() && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN)) || ((logic->FireTimer() >= 24 || logic->Health() >= 5 * 16) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_LONGSHOT))), ENTRANCE(RR_DMC_CRACKED_WALL, (logic->FireTimer() >= 40 || logic->Health() >= 8 * 16) && logic->CanClimbLadder() || - (logic->IsAdult && (logic->FireTimer() >= 48 || logic->Health() >= 9 * 16) && logic->DMCPotsToPad() && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)) || + (logic->IsAdult && (logic->FireTimer() >= 48 || logic->Health() >= 9 * 16) && logic->DMCPotsToPad() && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN)) || ((logic->FireTimer() >= 32 || logic->Health() >= 6 * 16) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_LONGSHOT))), ENTRANCE(RR_DMC_SCRUB, logic->FireTimer() >= 24 || logic->Health() >= 5 * 16), ENTRANCE(RR_DMC_BLOCKED_EXIT, logic->FireTimer() >= 16 || logic->Health() >= 3 * 16), @@ -177,7 +177,7 @@ void RegionTable_Init_DeathMountainCrater() { ((logic->FireTimer() >= 56 || logic->Health() >= 11 * 16) && logic->DMCUpperToPad() && logic->CanClimbLadder())), ENTRANCE(RR_DMC_FAR_PLATFORM, (logic->IsAdult && (logic->FireTimer() >= 40 || logic->Health() >= 8 * 16) && logic->DMCPotsToPad() && logic->ReachDistantScarecrow()) || ((logic->FireTimer() >= 40 || logic->Health() >= 8 * 16) && logic->TakeDamage() && ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS) && logic->CanClimbLadder()) || - (logic->IsAdult && (logic->FireTimer() >= 40 || logic->Health() >= 8 * 16) && logic->DMCPotsToPad() && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)) || + (logic->IsAdult && (logic->FireTimer() >= 40 || logic->Health() >= 8 * 16) && logic->DMCPotsToPad() && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN)) || ((logic->FireTimer() >= 32 || logic->Health() >= 6 * 16) && logic->TakeDamage() && ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS))), ENTRANCE(RR_DMC_TEMPLE_EXIT, (logic->IsAdult || (ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && (((logic->FireTimer() >= 40 || logic->Health() >= 8 * 16) && logic->DMCPotsToPad()) || @@ -188,32 +188,32 @@ void RegionTable_Init_DeathMountainCrater() { //Locations LOCATION(RC_DMC_WALL_FREESTANDING_POH, ((logic->FireTimer() >= 40 || logic->Health() >= 8 * 16) && logic->CanClimbLadder() && logic->DMCPadToPots() && (logic->HasItem(RG_CLIMB) || (ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS) && logic->CanJumpslash()))) || ((logic->FireTimer() >= 32 || logic->Health() >= 6 * 16) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_LONGSHOT) && (logic->HasItem(RG_CLIMB) || (ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS) && logic->CanJumpslash()))) || - (logic->IsAdult && (logic->FireTimer() >= 16 || logic->Health() >= 3 * 16) && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL))), + (logic->IsAdult && (logic->FireTimer() >= 16 || logic->Health() >= 3 * 16) && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN))), LOCATION(RC_DMC_VOLCANO_FREESTANDING_POH, (logic->FireTimer() >= 24 || logic->Health() >= 5 * 16) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS) && logic->DMCPadToPots() || - (logic->IsAdult && (logic->FireTimer() >= 8 || logic->Health() >= 2 * 16) && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL))), + (logic->IsAdult && (logic->FireTimer() >= 8 || logic->Health() >= 2 * 16) && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN))), }, { //Exits ENTRANCE(RR_DMC_CRATE, ((logic->FireTimer() >= 40 || logic->Health() >= 8 * 16) && logic->CanClimbLadder() && logic->DMCPadToPots()) || ((logic->FireTimer() >= 40 || logic->Health() >= 8 * 16) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_LONGSHOT)) || - (logic->IsAdult && (logic->FireTimer() >= 24 || logic->Health() >= 5 * 16) && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL))), + (logic->IsAdult && (logic->FireTimer() >= 24 || logic->Health() >= 5 * 16) && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN))), ENTRANCE(RR_DMC_ROCK_GROTTO, ((logic->FireTimer() >= 40 || logic->Health() >= 8 * 16) && logic->CanClimbLadder() && logic->DMCPadToPots()) || ((logic->FireTimer() >= 32 || logic->Health() >= 6 * 16) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_LONGSHOT)) || - (logic->IsAdult && (logic->FireTimer() >= 16 || logic->Health() >= 3 * 16) && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL))), + (logic->IsAdult && (logic->FireTimer() >= 16 || logic->Health() >= 3 * 16) && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN))), ENTRANCE(RR_DMC_CRACKED_WALL, (logic->FireTimer() >= 48 || logic->Health() >= 9 * 16) && logic->CanClimbLadder() && logic->DMCPadToPots() || ((logic->FireTimer() >= 40 || logic->Health() >= 8 * 16) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_LONGSHOT)) || - (logic->IsAdult && (logic->FireTimer() >= 24 || logic->Health() >= 5 * 16) && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL))), + (logic->IsAdult && (logic->FireTimer() >= 24 || logic->Health() >= 5 * 16) && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN))), ENTRANCE(RR_DMC_SCRUB, (logic->FireTimer() >= 24 || logic->Health() >= 5 * 16) && logic->DMCPadToPots() || - (logic->IsAdult && (logic->FireTimer() >= 16 || logic->Health() >= 3 * 16) && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL))), + (logic->IsAdult && (logic->FireTimer() >= 16 || logic->Health() >= 3 * 16) && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN))), ENTRANCE(RR_DMC_BLOCKED_EXIT, (logic->FireTimer() >= 24 || logic->Health() >= 5 * 16) && logic->DMCPadToPots() || - (logic->IsAdult && (logic->FireTimer() >= 16 || logic->Health() >= 3 * 16) && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL))), + (logic->IsAdult && (logic->FireTimer() >= 16 || logic->Health() >= 3 * 16) && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN))), ENTRANCE(RR_DMC_POTS, (logic->FireTimer() >= 16 || logic->Health() >= 3 * 16) && logic->DMCPadToPots() || - (logic->IsAdult && (logic->FireTimer() >= 16 || logic->Health() >= 3 * 16) && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL))), + (logic->IsAdult && (logic->FireTimer() >= 16 || logic->Health() >= 3 * 16) && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN))), ENTRANCE(RR_DMC_POT_GROTTO_EXIT, (logic->FireTimer() >= 16 || logic->Health() >= 3 * 16) && logic->DMCPadToPots() || - ((logic->IsAdult && logic->FireTimer() >= 24 || logic->Health() >= 5 * 16) && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL))), + ((logic->IsAdult && logic->FireTimer() >= 24 || logic->Health() >= 5 * 16) && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN))), ENTRANCE(RR_DMC_CENTRAL, (logic->FireTimer() >= 16 || logic->Health() >= 3 * 16)), ENTRANCE(RR_DMC_FAR_PLATFORM, ((logic->FireTimer() >= 56 || logic->Health() >= 11 * 16) && logic->TakeDamage() && ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS) && logic->CanClimbLadder() && logic->DMCPadToPots()) || ((logic->FireTimer() >= 40 || logic->Health() >= 8 * 16) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_LONGSHOT)) || - (logic->IsAdult && (logic->FireTimer() >= 24 || logic->Health() >= 5 * 16) && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL))|| + (logic->IsAdult && (logic->FireTimer() >= 24 || logic->Health() >= 5 * 16) && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN))|| (logic->IsAdult && (logic->FireTimer() >= 16 || logic->Health() >= 3 * 16) && logic->ReachDistantScarecrow())), ENTRANCE(RR_DMC_TEMPLE_EXIT, (logic->IsAdult || (ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && (logic->FireTimer() >= 16 || logic->Health() >= 3 * 16)), @@ -224,42 +224,42 @@ void RegionTable_Init_DeathMountainCrater() { LOCATION(RC_DMC_WALL_FREESTANDING_POH, logic->HasItem(RG_CLIMB) && (((logic->FireTimer() >= 72 || logic->Health() >= 14 * 16) && logic->DMCPadToPots()) || ((logic->FireTimer() >= 64 || logic->Health() >= 12 * 16) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_LONGSHOT)) || - (logic->IsAdult && (logic->FireTimer() >= 48 || logic->Health() >= 9 * 16) && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)))), + (logic->IsAdult && (logic->FireTimer() >= 48 || logic->Health() >= 9 * 16) && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN)))), LOCATION(RC_DMC_VOLCANO_FREESTANDING_POH, logic->HasItem(RG_CLIMB) && ((logic->FireTimer() >= 56 || logic->Health() >= 11 * 16) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS) && logic->DMCPadToPots() || - (logic->IsAdult && (logic->FireTimer() >= 40 || logic->Health() >= 8 * 16) && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)))), + (logic->IsAdult && (logic->FireTimer() >= 40 || logic->Health() >= 8 * 16) && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN)))), }, { //Exits ENTRANCE(RR_DMC_CRATE, logic->HasItem(RG_CLIMB) && (logic->IsAdult || (ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && (((logic->FireTimer() >= 72 || logic->Health() >= 14 * 16) && logic->DMCPadToPots()) || ((logic->FireTimer() >= 72 || logic->Health() >= 14 * 16) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_LONGSHOT)) || - (logic->IsAdult && (logic->FireTimer() >= 56 || logic->Health() >= 11 * 16) && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)))), + (logic->IsAdult && (logic->FireTimer() >= 56 || logic->Health() >= 11 * 16) && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN)))), ENTRANCE(RR_DMC_ROCK_GROTTO, logic->HasItem(RG_CLIMB) && (logic->IsAdult || (ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && (((logic->FireTimer() >= 72 || logic->Health() >= 14 * 16) && logic->DMCPadToPots()) || ((logic->FireTimer() >= 64 || logic->Health() >= 12 * 16) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_LONGSHOT)) || - (logic->IsAdult && (logic->FireTimer() >= 48 || logic->Health() >= 9 * 16) && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)))), + (logic->IsAdult && (logic->FireTimer() >= 48 || logic->Health() >= 9 * 16) && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN)))), ENTRANCE(RR_DMC_CRACKED_WALL, logic->HasItem(RG_CLIMB) && (logic->IsAdult || (ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && (((logic->FireTimer() >= 80 || logic->Health() >= 15 * 16) && logic->DMCPadToPots()) || ((logic->FireTimer() >= 72 || logic->Health() >= 14 * 16) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_LONGSHOT)) || - (logic->IsAdult && (logic->FireTimer() >= 56 || logic->Health() >= 11 * 16) && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)))), + (logic->IsAdult && (logic->FireTimer() >= 56 || logic->Health() >= 11 * 16) && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN)))), ENTRANCE(RR_DMC_SCRUB, logic->HasItem(RG_CLIMB) && (logic->IsAdult || (ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && (((logic->FireTimer() >= 56 || logic->Health() >= 11 * 16) && logic->DMCPadToPots()) || - (logic->IsAdult && (logic->FireTimer() >= 48 || logic->Health() >= 9 * 16) && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)))), + (logic->IsAdult && (logic->FireTimer() >= 48 || logic->Health() >= 9 * 16) && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN)))), ENTRANCE(RR_DMC_BLOCKED_EXIT, logic->HasItem(RG_CLIMB) && (logic->IsAdult || (ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && (((logic->FireTimer() >= 56 || logic->Health() >= 11 * 16) && logic->DMCPadToPots()) || - (logic->IsAdult && (logic->FireTimer() >= 48 || logic->Health() >= 9 * 16) && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)))), + (logic->IsAdult && (logic->FireTimer() >= 48 || logic->Health() >= 9 * 16) && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN)))), ENTRANCE(RR_DMC_POTS, logic->HasItem(RG_CLIMB) && (logic->IsAdult || (ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && (((logic->FireTimer() >= 48 || logic->Health() >= 9 * 16) && logic->DMCPadToPots()) || - (logic->IsAdult && (logic->FireTimer() >= 48 || logic->Health() >= 9 * 16) && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)))), + (logic->IsAdult && (logic->FireTimer() >= 48 || logic->Health() >= 9 * 16) && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN)))), ENTRANCE(RR_DMC_POT_GROTTO_EXIT, logic->HasItem(RG_CLIMB) && (logic->IsAdult || (ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && (((logic->FireTimer() >= 48 || logic->Health() >= 9 * 16) && logic->DMCPadToPots()) || - (logic->IsAdult && (logic->FireTimer() >= 56 || logic->Health() >= 11 * 16) && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)))), + (logic->IsAdult && (logic->FireTimer() >= 56 || logic->Health() >= 11 * 16) && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN)))), ENTRANCE(RR_DMC_CENTRAL, logic->HasItem(RG_CLIMB) && (logic->IsAdult || (ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && (logic->FireTimer() >= 48 || logic->Health() >= 9 * 16)), ENTRANCE(RR_DMC_FAR_PLATFORM, logic->HasItem(RG_CLIMB) && (logic->IsAdult || (ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && (((logic->FireTimer() >= 88 || logic->Health() >= 16 * 16) && logic->TakeDamage() && ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS) && logic->CanClimbLadder() && logic->DMCPadToPots()) || ((logic->FireTimer() >= 72 || logic->Health() >= 14 * 16) && ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_LONGSHOT)) || - (logic->IsAdult && (logic->FireTimer() >= 56 || logic->Health() >= 11 * 16) && CanPlantBean(RR_DMC_CENTRAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL))|| + (logic->IsAdult && (logic->FireTimer() >= 56 || logic->Health() >= 11 * 16) && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN))|| (logic->IsAdult && (logic->FireTimer() >= 48 || logic->Health() >= 9 * 16) && logic->ReachDistantScarecrow()))), ENTRANCE(RR_DMC_TEMPLE_EXIT, true), }); @@ -346,7 +346,8 @@ void RegionTable_Init_DeathMountainCrater() { areaTable[RR_DMC_CENTRAL] = Region("DMC Central", SCENE_DEATH_MOUNTAIN_CRATER, { //Events - EVENT_ACCESS(LOGIC_FAIRY_ACCESS, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), + EVENT_ACCESS(LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN, CanPlantBean(RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)), + EVENT_ACCESS(LOGIC_FAIRY_ACCESS, logic->IsChild && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), }, { //Locations LOCATION(RC_SHEIK_IN_CRATER, logic->IsAdult), @@ -359,9 +360,9 @@ void RegionTable_Init_DeathMountainCrater() { LOCATION(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_4, logic->IsChild), LOCATION(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_5, logic->IsChild), LOCATION(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_6, logic->IsChild), - 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)), - 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)), - 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)), + LOCATION(RC_DMC_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_DMC_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_DMC_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), 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), 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 22ac7b4939..160990cc6e 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,22 +7,23 @@ void RegionTable_Init_DeathMountainTrail() { // clang-format off areaTable[RR_DEATH_MOUNTAIN_TRAIL] = Region("Death Mountain Trail", SCENE_DEATH_MOUNTAIN_TRAIL, { //Events - EVENT_ACCESS(LOGIC_FAIRY_ACCESS, 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))), + EVENT_ACCESS(LOGIC_PLANT_DEATH_MOUNTAIN_TRAIL_BEAN, CanPlantBean(RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET))), + EVENT_ACCESS(LOGIC_FAIRY_ACCESS, logic->IsChild && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_TRAIL_BEAN) && 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))) && 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_FREESTANDING_POH, logic->TakeDamage() || logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_TRAIL_BEAN) && (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() && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_BOOMERANG))), LOCATION(RC_DMT_GS_ABOVE_DODONGOS_CAVERN, logic->IsAdult && logic->CanGetNightTimeGS() && ((logic->CanUse(RG_MEGATON_HAMMER) || (ctx->GetTrickOption(RT_ITEM_EXTENSION) && logic->CanUse(RG_HOOKSHOT)) || (ctx->GetTrickOption(RT_BOULDER_COLLISION) && logic->CanUse(RG_LONGSHOT)) || (ctx->GetTrickOption(RT_DMT_JS_LOWER_GS) && logic->CanJumpslash())) || - ((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_BEAN_LOWER_GS) && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_TRAIL_BEAN)) || (ctx->GetTrickOption(RT_DMT_HOVERS_LOWER_GS) && logic->CanUse(RG_HOVER_BOOTS)) && (logic->HasExplosives() || logic->CanUse(RG_DINS_FIRE) || ((ctx->GetTrickOption(RT_BOULDER_COLLISION) || ctx->GetTrickOption(RT_ITEM_EXTENSION)) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT))) || logic->CanJumpslash())))), 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->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_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_TRAIL_BEAN) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET))), + LOCATION(RC_DMT_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_TRAIL_BEAN) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET))), + LOCATION(RC_DMT_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_TRAIL_BEAN) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET))), LOCATION(RC_DMT_FLAG_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)), LOCATION(RC_DMT_ROCK_1, logic->CanBreakRocks()), LOCATION(RC_DMT_ROCK_2, logic->CanBreakRocks()), @@ -60,7 +61,7 @@ void RegionTable_Init_DeathMountainTrail() { //Exits ENTRANCE(RR_KAK_BEHIND_GATE, true), ENTRANCE(RR_GORON_CITY, true), - ENTRANCE(RR_DEATH_MOUNTAIN_ROCKFALL, AnyAgeTime([]{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_DEATH_MOUNTAIN_ROCKFALL, AnyAgeTime([]{return logic->BlastOrSmash();}) || (logic->IsAdult && ((logic->BeanPlanted(LOGIC_PLANT_DEATH_MOUNTAIN_TRAIL_BEAN) && logic->HasItem(RG_GORONS_BRACELET)) || (logic->CanUse(RG_HOVER_BOOTS) && ctx->GetTrickOption(RT_DMT_CLIMB_HOVERS))))), ENTRANCE(RR_DODONGOS_CAVERN_ENTRYWAY, logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET) || logic->IsAdult), ENTRANCE(RR_DMT_STORMS_GROTTO, logic->CanOpenStormsGrotto()), }); 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 0085a27a25..f2c6343156 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/desert_colossus.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/desert_colossus.cpp @@ -7,16 +7,17 @@ void RegionTable_Init_DesertColossus() { // clang-format off areaTable[RR_DESERT_COLOSSUS] = Region("Desert Colossus", SCENE_DESERT_COLOSSUS, { //Events - EVENT_ACCESS(LOGIC_BUG_ACCESS, logic->HasItem(RG_POWER_BRACELET)), + EVENT_ACCESS(LOGIC_PLANT_DESERT_COLOSSUS_BEAN, CanPlantBean(RG_DESERT_COLOSSUS_BEAN_SOUL)), + EVENT_ACCESS(LOGIC_BUG_ACCESS, logic->HasItem(RG_POWER_BRACELET)), }, { //Locations - LOCATION(RC_COLOSSUS_FREESTANDING_POH, logic->IsAdult && CanPlantBean(RR_DESERT_COLOSSUS, RG_DESERT_COLOSSUS_BEAN_SOUL)), + LOCATION(RC_COLOSSUS_FREESTANDING_POH, logic->IsAdult && logic->BeanPlanted(LOGIC_PLANT_DESERT_COLOSSUS_BEAN)), 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, 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_GS_HILL, logic->IsAdult && ((logic->BeanPlanted(LOGIC_PLANT_DESERT_COLOSSUS_BEAN) && 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->BeanPlanted(LOGIC_PLANT_DESERT_COLOSSUS_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_COLOSSUS_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->BeanPlanted(LOGIC_PLANT_DESERT_COLOSSUS_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_COLOSSUS_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->BeanPlanted(LOGIC_PLANT_DESERT_COLOSSUS_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_COLOSSUS_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), LOCATION(RC_COLOSSUS_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_COLOSSUS_SILVER_BOULDER, logic->CanUse(RG_SILVER_GAUNTLETS)), 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 61a31d6926..e051ef839b 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp @@ -42,24 +42,25 @@ void RegionTable_Init_GerudoValley() { areaTable[RR_GV_UPPER_STREAM] = Region("GV Upper Stream", SCENE_GERUDO_VALLEY, { //Events - EVENT_ACCESS(LOGIC_FAIRY_ACCESS, logic->CallGossipFairy() || (logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_GERUDO_VALLEY_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS))), + EVENT_ACCESS(LOGIC_PLANT_GERUDO_VALLEY_BEAN, CanPlantBean(RG_GERUDO_VALLEY_BEAN_SOUL)), + EVENT_ACCESS(LOGIC_FAIRY_ACCESS, logic->CallGossipFairy() || (logic->IsChild && logic->BeanPlanted(LOGIC_PLANT_GERUDO_VALLEY_BEAN) && logic->CanUse(RG_SONG_OF_STORMS))), }, { //Locations 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->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_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->BeanPlanted(LOGIC_PLANT_GERUDO_VALLEY_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_GV_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->BeanPlanted(LOGIC_PLANT_GERUDO_VALLEY_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_GV_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->BeanPlanted(LOGIC_PLANT_GERUDO_VALLEY_BEAN) && 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), LOCATION(RC_GV_NEAR_COW_CRATE, logic->IsChild && logic->CanBreakCrates()), - LOCATION(RC_GV_WONDER_LOWER_WATERFALL, logic->IsAdult && (CanPlantBean(RR_GV_UPPER_STREAM, RG_GERUDO_VALLEY_BEAN_SOUL) || logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || (ctx->GetTrickOption(RT_VOIDOUT_COLLECTION) && logic->CanVoid()))), - LOCATION(RC_GV_WONDER_UPPER_WATERFALL, logic->IsAdult && CanPlantBean(RR_GV_UPPER_STREAM, RG_GERUDO_VALLEY_BEAN_SOUL)), + LOCATION(RC_GV_WONDER_LOWER_WATERFALL, logic->IsAdult && (logic->BeanPlanted(LOGIC_PLANT_GERUDO_VALLEY_BEAN) || logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || (ctx->GetTrickOption(RT_VOIDOUT_COLLECTION) && logic->CanVoid()))), + LOCATION(RC_GV_WONDER_UPPER_WATERFALL, logic->IsAdult && logic->BeanPlanted(LOGIC_PLANT_GERUDO_VALLEY_BEAN)), }, { //Exits ENTRANCE(RR_GV_UPPER_STREAM_WATER, true), - ENTRANCE(RR_GV_WATERFALL_ALCOVE, (logic->CanUse(RG_LONGSHOT) && (logic->HasItem(RG_CLIMB) || ctx->GetTrickOption(RT_HOOKSHOT_LADDERS))) || CanPlantBean(RR_GV_UPPER_STREAM, RG_GERUDO_VALLEY_BEAN_SOUL)), + ENTRANCE(RR_GV_WATERFALL_ALCOVE, (logic->CanUse(RG_LONGSHOT) && (logic->HasItem(RG_CLIMB) || ctx->GetTrickOption(RT_HOOKSHOT_LADDERS))) || logic->BeanPlanted(LOGIC_PLANT_GERUDO_VALLEY_BEAN)), }); areaTable[RR_GV_UPPER_STREAM_WATER] = Region("GV Upper Stream Water", SCENE_GERUDO_VALLEY, {}, {}, { diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp index f1b56d4ec4..30bb9c47f1 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp @@ -7,18 +7,19 @@ void RegionTable_Init_Graveyard() { // clang-format off areaTable[RR_THE_GRAVEYARD] = Region("The Graveyard", SCENE_GRAVEYARD, { //Events - EVENT_ACCESS(LOGIC_FAIRY_ACCESS, (logic->AtDay && logic->CanUse(RG_STICKS)) || (logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS))), - EVENT_ACCESS(LOGIC_BUG_ACCESS, logic->HasItem(RG_POWER_BRACELET)), - EVENT_ACCESS(LOGIC_BORROW_BUNNY_HOOD, logic->IsChild && logic->AtDay && logic->Get(LOGIC_BORROW_SPOOKY_MASK) && logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_SPEAK_HYLIAN)), + EVENT_ACCESS(LOGIC_PLANT_GRAVEYARD_BEAN, CanPlantBean(RG_GRAVEYARD_BEAN_SOUL)), + EVENT_ACCESS(LOGIC_FAIRY_ACCESS, (logic->AtDay && logic->CanUse(RG_STICKS)) || (logic->IsChild && logic->BeanPlanted(LOGIC_PLANT_GRAVEYARD_BEAN) && logic->CanUse(RG_SONG_OF_STORMS))), + EVENT_ACCESS(LOGIC_BUG_ACCESS, logic->HasItem(RG_POWER_BRACELET)), + EVENT_ACCESS(LOGIC_BORROW_BUNNY_HOOD, logic->IsChild && logic->AtDay && logic->Get(LOGIC_BORROW_SPOOKY_MASK) && logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_SPEAK_HYLIAN)), }, { //Locations - 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_FREESTANDING_POH, (((logic->IsAdult && logic->BeanPlanted(LOGIC_PLANT_GRAVEYARD_BEAN)) || 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->HasItem(RG_SPEAK_HYLIAN) && 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(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_GRAVEYARD_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->BeanPlanted(LOGIC_PLANT_GRAVEYARD_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_GRAVEYARD_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->BeanPlanted(LOGIC_PLANT_GRAVEYARD_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_GRAVEYARD_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->BeanPlanted(LOGIC_PLANT_GRAVEYARD_BEAN) && 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()), @@ -31,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, RG_GRAVEYARD_BEAN_SOUL)) || logic->CanUse(RG_LONGSHOT)) && logic->CanBreakCrates()), + LOCATION(RC_GRAVEYARD_CRATE, ((logic->IsAdult && logic->BeanPlanted(LOGIC_PLANT_GRAVEYARD_BEAN)) || logic->CanUse(RG_LONGSHOT)) && logic->CanBreakCrates()), LOCATION(RC_GY_ROCK, logic->CanBreakRocks()), LOCATION(RC_GY_NEAR_HUT_GRAVE_BUTTERFLY_FAIRY, logic->IsChild && logic->AtDay && logic->CanUse(RG_STICKS)), LOCATION(RC_GY_ENTRANCE_RECTANGLE_SIGN, logic->CanRead()), 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 3ba6b45676..1cc32caaf3 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp @@ -7,7 +7,8 @@ void RegionTable_Init_KokiriForest() { // clang-format off areaTable[RR_KOKIRI_FOREST] = Region("Kokiri Forest", SCENE_KOKIRI_FOREST, { //Events - EVENT_ACCESS(LOGIC_FAIRY_ACCESS, logic->CallGossipFairyExceptSuns() || (logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_KOKIRI_FOREST_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS))), + EVENT_ACCESS(LOGIC_PLANT_KOKIRI_FOREST_BEAN, CanPlantBean(RG_KOKIRI_FOREST_BEAN_SOUL)), + EVENT_ACCESS(LOGIC_FAIRY_ACCESS, logic->CallGossipFairyExceptSuns() || (logic->IsChild && logic->BeanPlanted(LOGIC_PLANT_KOKIRI_FOREST_BEAN) && logic->CanUse(RG_SONG_OF_STORMS))), EVENT_ACCESS(LOGIC_SHOWED_MIDO_SWORD_AND_SHIELD, logic->IsChild && logic->HasItem(RG_SPEAK_KOKIRI) && logic->CanUse(RG_KOKIRI_SWORD) && logic->CanUse(RG_DEKU_SHIELD)), }, { //Locations @@ -16,22 +17,22 @@ void RegionTable_Init_KokiriForest() { LOCATION(RC_KF_GS_HOUSE_OF_TWINS, logic->IsAdult && logic->CanGetNightTimeGS() && (logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG) || (ctx->GetTrickOption(RT_KF_ADULT_GS) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_SHORT_JUMPSLASH)))), - 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_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->BeanPlanted(LOGIC_PLANT_KOKIRI_FOREST_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_KF_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->BeanPlanted(LOGIC_PLANT_KOKIRI_FOREST_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_KF_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->BeanPlanted(LOGIC_PLANT_KOKIRI_FOREST_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_KF_BRIDGE_RUPEE, logic->IsChild), LOCATION(RC_KF_BEHIND_MIDOS_RUPEE, logic->IsChild), LOCATION(RC_KF_SOUTH_GRASS_WEST_RUPEE, logic->IsChild), LOCATION(RC_KF_SOUTH_GRASS_EAST_RUPEE, logic->IsChild), LOCATION(RC_KF_NORTH_GRASS_WEST_RUPEE, logic->IsChild), LOCATION(RC_KF_NORTH_GRASS_EAST_RUPEE, logic->IsChild), - LOCATION(RC_KF_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 && (logic->BeanPlanted(LOGIC_PLANT_KOKIRI_FOREST_BEAN) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_2, logic->IsAdult && (logic->BeanPlanted(LOGIC_PLANT_KOKIRI_FOREST_BEAN) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_3, logic->IsAdult && (logic->BeanPlanted(LOGIC_PLANT_KOKIRI_FOREST_BEAN) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_4, logic->IsAdult && (logic->BeanPlanted(LOGIC_PLANT_KOKIRI_FOREST_BEAN) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_5, logic->IsAdult && (logic->BeanPlanted(LOGIC_PLANT_KOKIRI_FOREST_BEAN) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_6, logic->IsAdult && (logic->BeanPlanted(LOGIC_PLANT_KOKIRI_FOREST_BEAN) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RED_RUPEE, logic->IsAdult && (logic->BeanPlanted(LOGIC_PLANT_KOKIRI_FOREST_BEAN) || 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), @@ -113,8 +114,8 @@ void RegionTable_Init_KokiriForest() { ENTRANCE(RR_KF_KNOW_IT_ALL_HOUSE, true), ENTRANCE(RR_KF_KOKIRI_SHOP, true), ENTRANCE(RR_KF_OUTSIDE_DEKU_TREE, (logic->IsAdult && (logic->CanPassEnemy(RE_BIG_SKULLTULA) || logic->Get(LOGIC_FOREST_TEMPLE_CLEAR))) || logic->Get(LOGIC_SHOWED_MIDO_SWORD_AND_SHIELD)), - ENTRANCE(RR_KF_OUTSIDE_LOST_WOODS, logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS)))), - ENTRANCE(RR_KF_RUPEE_ALCOVE, logic->IsAdult && CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL)), + ENTRANCE(RR_KF_OUTSIDE_LOST_WOODS, logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && (logic->BeanPlanted(LOGIC_PLANT_KOKIRI_FOREST_BEAN) || ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS)))), + ENTRANCE(RR_KF_RUPEE_ALCOVE, logic->IsAdult && logic->BeanPlanted(LOGIC_PLANT_KOKIRI_FOREST_BEAN)), ENTRANCE(RR_LW_BRIDGE_FROM_FOREST, logic->IsAdult || ctx->GetOption(RSK_FOREST).IsNot(RO_CLOSED_FOREST_ON) || logic->Get(LOGIC_DEKU_TREE_CLEAR)), }); @@ -135,7 +136,7 @@ void RegionTable_Init_KokiriForest() { //Exits ENTRANCE(RR_KOKIRI_FOREST, true), ENTRANCE(RR_THE_LOST_WOODS, true), - ENTRANCE(RR_KF_RUPEE_ALCOVE, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || logic->CanUse(RG_HOVER_BOOTS))), + ENTRANCE(RR_KF_RUPEE_ALCOVE, logic->IsAdult && (logic->BeanPlanted(LOGIC_PLANT_KOKIRI_FOREST_BEAN) || logic->CanUse(RG_HOVER_BOOTS))), ENTRANCE(RR_KF_STORMS_GROTTO, logic->CanOpenStormsGrotto()), }); 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 2ca455e4ed..d80a2004bc 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp @@ -7,15 +7,16 @@ void RegionTable_Init_LakeHylia() { // clang-format off areaTable[RR_LAKE_HYLIA] = Region("Lake Hylia", SCENE_LAKE_HYLIA, { //Events - EVENT_ACCESS(LOGIC_FAIRY_ACCESS, logic->CallGossipFairy() || logic->CanUse(RG_STICKS) || (logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_LAKE_HYLIA_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS))), - EVENT_ACCESS(LOGIC_BUG_ACCESS, logic->IsChild && logic->CanCutShrubs()), - EVENT_ACCESS(LOGIC_CHILD_SCARECROW, logic->IsChild && logic->HasItem(RG_FAIRY_OCARINA) && logic->OcarinaButtons() >= 2), + EVENT_ACCESS(LOGIC_PLANT_LAKE_HYLIA_BEAN, CanPlantBean(RG_LAKE_HYLIA_BEAN_SOUL)), + EVENT_ACCESS(LOGIC_FAIRY_ACCESS, logic->CallGossipFairy() || logic->CanUse(RG_STICKS) || (logic->IsChild && logic->BeanPlanted(LOGIC_PLANT_LAKE_HYLIA_BEAN) && logic->CanUse(RG_SONG_OF_STORMS))), + EVENT_ACCESS(LOGIC_BUG_ACCESS, logic->IsChild && logic->CanCutShrubs()), + EVENT_ACCESS(LOGIC_CHILD_SCARECROW, logic->IsChild && logic->HasItem(RG_FAIRY_OCARINA) && logic->OcarinaButtons() >= 2), EVENT_ACCESS(LOGIC_ADULT_SCARECROW, logic->IsAdult && logic->HasItem(RG_FAIRY_OCARINA) && logic->OcarinaButtons() >= 2), }, { //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->ReachDistantScarecrow()) && logic->CanUse(RG_FAIRY_BOW)), - LOCATION(RC_LH_FREESTANDING_POH, logic->IsAdult && (logic->ReachScarecrow() || CanPlantBean(RR_LAKE_HYLIA, RG_LAKE_HYLIA_BEAN_SOUL)) && logic->CanAvoidEnemy(RE_GUAY, false) && logic->HasItem(RG_CLIMB)), + LOCATION(RC_LH_FREESTANDING_POH, logic->IsAdult && (logic->ReachScarecrow() || logic->BeanPlanted(LOGIC_PLANT_LAKE_HYLIA_BEAN)) && logic->CanAvoidEnemy(RE_GUAY, false) && logic->HasItem(RG_CLIMB)), 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)), @@ -23,9 +24,9 @@ void RegionTable_Init_LakeHylia() { 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->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_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->BeanPlanted(LOGIC_PLANT_LAKE_HYLIA_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_LH_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->BeanPlanted(LOGIC_PLANT_LAKE_HYLIA_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_LH_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->BeanPlanted(LOGIC_PLANT_LAKE_HYLIA_BEAN) && 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 @@ -89,7 +90,7 @@ void RegionTable_Init_LakeHylia() { ENTRANCE(RR_HF_TO_LAKE_HYLIA, true), ENTRANCE(RR_LH_FROM_SHORTCUT, true), ENTRANCE(RR_LH_OWL_FLIGHT, logic->IsChild && (logic->HasItem(RG_SPEAK_DEKU) || logic->HasItem(RG_SPEAK_GERUDO) || logic->HasItem(RG_SPEAK_GORON) || logic->HasItem(RG_SPEAK_KOKIRI) || logic->HasItem(RG_SPEAK_HYLIAN) || logic->HasItem(RG_SPEAK_ZORA))), - ENTRANCE(RR_LH_FISHING_ISLAND, ((logic->IsChild || logic->Get(LOGIC_WATER_TEMPLE_CLEAR)) && logic->HasItem(RG_BRONZE_SCALE)) || (logic->IsAdult && (logic->ReachScarecrow() || CanPlantBean(RR_LAKE_HYLIA, RG_LAKE_HYLIA_BEAN_SOUL)))), + ENTRANCE(RR_LH_FISHING_ISLAND, ((logic->IsChild || logic->Get(LOGIC_WATER_TEMPLE_CLEAR)) && logic->HasItem(RG_BRONZE_SCALE)) || (logic->IsAdult && (logic->ReachScarecrow() || logic->BeanPlanted(LOGIC_PLANT_LAKE_HYLIA_BEAN)))), ENTRANCE(RR_LH_LAB, logic->HasItem(RG_HYLIA_LAB_KEY)), ENTRANCE(RR_LH_FROM_WATER_TEMPLE, true), ENTRANCE(RR_LH_GROTTO, logic->HasItem(RG_POWER_BRACELET) && (logic->IsAdult || logic->HasItem(RG_SPEAK_DEKU) || logic->HasItem(RG_SPEAK_GERUDO) || logic->HasItem(RG_SPEAK_GORON) || logic->HasItem(RG_SPEAK_KOKIRI) || logic->HasItem(RG_SPEAK_HYLIAN) || logic->HasItem(RG_SPEAK_ZORA))), 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 67c122f851..f6c8c7c6ff 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/lost_woods.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/lost_woods.cpp @@ -12,9 +12,10 @@ void RegionTable_Init_LostWoods() { areaTable[RR_THE_LOST_WOODS] = Region("Lost Woods", SCENE_LOST_WOODS, { //Events - EVENT_ACCESS(LOGIC_FAIRY_ACCESS, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_LOST_WOODS_BRIDGE_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), - EVENT_ACCESS(LOGIC_BUG_ACCESS, logic->IsChild && logic->CanCutShrubs()), - EVENT_ACCESS(LOGIC_BORROW_SPOOKY_MASK, logic->IsChild && logic->Get(LOGIC_BORROW_SKULL_MASK) && logic->CanUse(RG_SARIAS_SONG) && logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_SPEAK_KOKIRI) && logic->HasItem(RG_SPEAK_HYLIAN)), + EVENT_ACCESS(LOGIC_PLANT_LOST_WOODS_BRIDGE_BEAN, CanPlantBean(RG_LOST_WOODS_BRIDGE_BEAN_SOUL)), + EVENT_ACCESS(LOGIC_FAIRY_ACCESS, logic->IsChild && logic->BeanPlanted(LOGIC_PLANT_LOST_WOODS_BRIDGE_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + EVENT_ACCESS(LOGIC_BUG_ACCESS, logic->IsChild && logic->CanCutShrubs()), + EVENT_ACCESS(LOGIC_BORROW_SPOOKY_MASK, logic->IsChild && logic->Get(LOGIC_BORROW_SKULL_MASK) && logic->CanUse(RG_SARIAS_SONG) && logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_SPEAK_KOKIRI) && logic->HasItem(RG_SPEAK_HYLIAN)), }, { //Locations LOCATION(RC_LW_SKULL_KID, logic->IsChild && logic->CanUse(RG_SARIAS_SONG)), @@ -41,9 +42,9 @@ void RegionTable_Init_LostWoods() { LOCATION(RC_LW_SHORTCUT_RUPEE_6, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG))), LOCATION(RC_LW_SHORTCUT_RUPEE_7, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG))), LOCATION(RC_LW_SHORTCUT_RUPEE_8, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG))), - 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_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_1, logic->IsChild && logic->BeanPlanted(LOGIC_PLANT_LOST_WOODS_BRIDGE_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_2, logic->IsChild && logic->BeanPlanted(LOGIC_PLANT_LOST_WOODS_BRIDGE_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_3, logic->IsChild && logic->BeanPlanted(LOGIC_PLANT_LOST_WOODS_BRIDGE_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_LW_SHORTCUT_STORMS_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_LW_GRASS_1, logic->CanCutShrubs()), LOCATION(RC_LW_GRASS_2, logic->CanCutShrubs()), @@ -57,7 +58,7 @@ void RegionTable_Init_LostWoods() { ENTRANCE(RR_LW_FOREST_EXIT, true), ENTRANCE(RR_LW_UNDER_BRIDGE, true), ENTRANCE(RR_GC_WOODS_WARP, true), - ENTRANCE(RR_LW_BRIDGE, (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_LW_BRIDGE, (logic->IsAdult && (logic->BeanPlanted(LOGIC_PLANT_LOST_WOODS_BRIDGE_BEAN) || ctx->GetTrickOption(RT_LW_BRIDGE))) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_LONGSHOT)), ENTRANCE(RR_ZR_FROM_SHORTCUT, 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, logic->IsChild || logic->CanUse(RG_SARIAS_SONG) || ctx->GetTrickOption(RT_LW_MIDO_BACKFLIP)), ENTRANCE(RR_LW_NEAR_SHORTCUTS_GROTTO, AnyAgeTime([]{return logic->BlastOrSmash();})), @@ -80,17 +81,18 @@ void RegionTable_Init_LostWoods() { areaTable[RR_LW_BEYOND_MIDO] = Region("LW Beyond Mido", SCENE_LOST_WOODS, { //Events - EVENT_ACCESS(LOGIC_FAIRY_ACCESS, logic->CanUse(RG_STICKS) || (logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_LOST_WOODS_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS))), + EVENT_ACCESS(LOGIC_PLANT_LOST_WOODS_THEATER_BEAN, CanPlantBean(RG_LOST_WOODS_BEAN_SOUL)), + EVENT_ACCESS(LOGIC_FAIRY_ACCESS, logic->CanUse(RG_STICKS) || (logic->IsChild && logic->BeanPlanted(LOGIC_PLANT_LOST_WOODS_THEATER_BEAN) && logic->CanUse(RG_SONG_OF_STORMS))), }, { //Locations LOCATION(RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, logic->IsChild && logic->CanStunDeku() && logic->HasItem(RG_SPEAK_DEKU) && GetCheckPrice() <= GetWalletCapacity()), LOCATION(RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, logic->IsChild && logic->CanStunDeku() && logic->HasItem(RG_SPEAK_DEKU) && GetCheckPrice() <= GetWalletCapacity()), - LOCATION(RC_LW_GS_ABOVE_THEATER, logic->IsAdult && ((CanPlantBean(RR_LW_BEYOND_MIDO, RG_LOST_WOODS_BEAN_SOUL) && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)) || (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_ABOVE_THEATER, logic->IsAdult && ((logic->BeanPlanted(LOGIC_PLANT_LOST_WOODS_THEATER_BEAN) && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)) || (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->CanGetEnemyDrop(RE_GOLD_SKULLTULA) || (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->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_BEAN_SPROUT_NEAR_THEATER_FAIRY_1, logic->IsChild && logic->BeanPlanted(LOGIC_PLANT_LOST_WOODS_THEATER_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_2, logic->IsChild && logic->BeanPlanted(LOGIC_PLANT_LOST_WOODS_THEATER_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_3, logic->IsChild && logic->BeanPlanted(LOGIC_PLANT_LOST_WOODS_THEATER_BEAN) && 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()), 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 3a137ea60d..5301b7f08f 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp @@ -38,7 +38,8 @@ void RegionTable_Init_ZoraRiver() { areaTable[RR_ZORAS_RIVER] = Region("Zora River", SCENE_ZORAS_RIVER, { //Events - EVENT_ACCESS(LOGIC_FAIRY_ACCESS, logic->CallGossipFairy() || (logic->IsChild && logic->CanUse(RG_STICKS)) || (logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_ZORAS_RIVER_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS))), + EVENT_ACCESS(LOGIC_PLANT_ZORAS_RIVER_BEAN, CanPlantBean(RG_ZORAS_RIVER_BEAN_SOUL)), + EVENT_ACCESS(LOGIC_FAIRY_ACCESS, logic->CallGossipFairy() || (logic->IsChild && logic->CanUse(RG_STICKS)) || (logic->IsChild && logic->BeanPlanted(LOGIC_PLANT_ZORAS_RIVER_BEAN) && logic->CanUse(RG_SONG_OF_STORMS))), }, { //Locations LOCATION(RC_ZR_MAGIC_BEAN_SALESMAN, logic->IsChild && logic->HasItem(RG_SPEAK_HYLIAN) && GetCheckPrice() <= GetWalletCapacity()), @@ -54,9 +55,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->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_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->BeanPlanted(LOGIC_PLANT_ZORAS_RIVER_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_ZR_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->BeanPlanted(LOGIC_PLANT_ZORAS_RIVER_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_ZR_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->BeanPlanted(LOGIC_PLANT_ZORAS_RIVER_BEAN) && 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) || (ctx->GetTrickOption(RT_VOIDOUT_COLLECTION) && logic->CanVoid()))), @@ -115,7 +116,7 @@ void RegionTable_Init_ZoraRiver() { }, { //Exits ENTRANCE(RR_ZR_FRONT, logic->IsAdult || logic->HasItem(RG_BRONZE_SCALE) || logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash() || logic->HasItem(RG_HOVER_BOOTS)), - ENTRANCE(RR_ZR_ATOP_LADDER, ((logic->IsAdult || logic->HasItem(RG_POWER_BRACELET)) && logic->CanClimbLadder()) || (logic->IsAdult && CanPlantBean(RR_ZORAS_RIVER, RG_ZORAS_RIVER_BEAN_SOUL))), + ENTRANCE(RR_ZR_ATOP_LADDER, ((logic->IsAdult || logic->HasItem(RG_POWER_BRACELET)) && logic->CanClimbLadder()) || (logic->IsAdult && logic->BeanPlanted(LOGIC_PLANT_ZORAS_RIVER_BEAN))), ENTRANCE(RR_ZR_PILLAR, (logic->IsChild && logic->HasItem(RG_POWER_BRACELET)) || logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && ctx->GetTrickOption(RT_ZR_LOWER))), ENTRANCE(RR_ZR_FROM_SHORTCUT, logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS)), ENTRANCE(RR_ZR_STORMS_GROTTO, logic->CanOpenStormsGrotto()), diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index 58253e005a..341a7475eb 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -1,4 +1,5 @@ #include "logic.h" +#include "bean_patches.h" #include "../debugger/performanceTimer.h" #include @@ -14,6 +15,8 @@ #include #include "location_access.h" +extern "C" PlayState* gPlayState; + namespace Rando { bool Logic::HasItem(RandomizerGet itemName) { @@ -1307,6 +1310,29 @@ bool Logic::CanDetonateUprightBombFlower() { (EffectiveHealth() > 8 || CanUse(RG_NAYRUS_LOVE))); } +bool Logic::BeanPlanted(LogicVal beanEvent) { + // rely on Get, rest is to track bean being planted out of logic + if (Get(beanEvent)) { + return true; + } + + const BeanPatch* patch = FindBeanPatch(beanEvent); + if (patch == nullptr) { + assert(false); + return false; + } + + // Get the swch value for the scene + uint32_t swch; + if (gPlayState != nullptr && gPlayState->sceneNum == patch->scene) { + swch = gPlayState->actorCtx.flags.swch; + } else { + swch = GetSaveContext()->sceneFlags[patch->scene].swch; + } + + return swch >> patch->swchFlag & 1; +} + bool Logic::CanHammerRecoilHover(bool needShield) { return CanUse(RG_HOVER_BOOTS) && ctx->GetTrickOption(RT_HOVER_BOOST_SIMPLE) && CanUse(RG_MEGATON_HAMMER) && (!needShield || CanStandingShield()); @@ -3060,16 +3086,9 @@ void Logic::Reset(bool resetSaveContext /*= 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); + for (const BeanPatch& patch : beanPatches) { + SetRandoInf(patch.soulRandInf, true); + } } // If not keysanity, start with 1 logical key to account for automatically unlocking the basement door in diff --git a/soh/soh/Enhancements/randomizer/logic.h b/soh/soh/Enhancements/randomizer/logic.h index 6452d757b6..87ddef994a 100644 --- a/soh/soh/Enhancements/randomizer/logic.h +++ b/soh/soh/Enhancements/randomizer/logic.h @@ -60,6 +60,7 @@ class Logic { bool CanHitEyeTargets(); bool CanDetonateBombFlowers(); bool CanDetonateUprightBombFlower(); + bool BeanPlanted(LogicVal beanEvent); bool CanHammerRecoilHover(bool needShield = false); bool Water3FCentralToHighEmblem(); bool WaterRisingTargetTo3FCentral(); diff --git a/soh/soh/Enhancements/randomizer/randomizerEnums/LogicVal.h b/soh/soh/Enhancements/randomizer/randomizerEnums/LogicVal.h index fae4cea67d..8adc2dc685 100644 --- a/soh/soh/Enhancements/randomizer/randomizerEnums/LogicVal.h +++ b/soh/soh/Enhancements/randomizer/randomizerEnums/LogicVal.h @@ -237,6 +237,16 @@ RANDO_ENUM_ITEM(LOGIC_TH_COULD_FREE_SLOPE_CARPENTER) RANDO_ENUM_ITEM(LOGIC_TH_RESCUED_ALL_CARPENTERS) RANDO_ENUM_ITEM(LOGIC_GF_GATE_OPEN) RANDO_ENUM_ITEM(LOGIC_GTG_GATE_OPEN) +RANDO_ENUM_ITEM(LOGIC_PLANT_DEATH_MOUNTAIN_CRATER_BEAN) +RANDO_ENUM_ITEM(LOGIC_PLANT_DEATH_MOUNTAIN_TRAIL_BEAN) +RANDO_ENUM_ITEM(LOGIC_PLANT_DESERT_COLOSSUS_BEAN) +RANDO_ENUM_ITEM(LOGIC_PLANT_GERUDO_VALLEY_BEAN) +RANDO_ENUM_ITEM(LOGIC_PLANT_GRAVEYARD_BEAN) +RANDO_ENUM_ITEM(LOGIC_PLANT_KOKIRI_FOREST_BEAN) +RANDO_ENUM_ITEM(LOGIC_PLANT_LAKE_HYLIA_BEAN) +RANDO_ENUM_ITEM(LOGIC_PLANT_LOST_WOODS_BRIDGE_BEAN) +RANDO_ENUM_ITEM(LOGIC_PLANT_LOST_WOODS_THEATER_BEAN) +RANDO_ENUM_ITEM(LOGIC_PLANT_ZORAS_RIVER_BEAN) RANDO_ENUM_ITEM(LOGIC_DRAIN_WELL) RANDO_ENUM_ITEM(LOGIC_GORON_CITY_CHILD_FIRE) RANDO_ENUM_ITEM(LOGIC_GORON_CITY_WOODS_WARP_OPEN) diff --git a/soh/soh/Enhancements/randomizer/savefile.cpp b/soh/soh/Enhancements/randomizer/savefile.cpp index 926cd5c215..52469e2ef6 100644 --- a/soh/soh/Enhancements/randomizer/savefile.cpp +++ b/soh/soh/Enhancements/randomizer/savefile.cpp @@ -2,6 +2,7 @@ #include "soh/OTRGlobals.h" #include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/Enhancements/randomizer/bean_patches.h" #include "soh/Enhancements/randomizer/logic.h" #include "soh/Enhancements/randomizer/randomizer.h" @@ -466,31 +467,18 @@ extern "C" void Randomizer_InitSaveFile() { } if (Randomizer_GetSettingValue(RSK_SKIP_PLANTING_BEANS)) { AMMO(ITEM_BEAN) = 0; - 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); + for (const BeanPatch& patch : beanPatches) { + gSaveContext.sceneFlags[patch.scene].swch |= 1 << patch.swchFlag; + } } else { AMMO(ITEM_BEAN) = 10; } } 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); + for (const BeanPatch& patch : beanPatches) { + Flags_SetRandomizerInf(patch.soulRandInf); + } } if (Randomizer_GetSettingValue(RSK_SHUFFLE_OCARINA_BUTTONS) == RO_GENERIC_OFF) {