replace specialized bean logic with events (#5842)

This commit is contained in:
Philip Dubé
2026-08-10 01:21:41 +00:00
committed by GitHub
parent 7e9cf1eb1c
commit 55b52a26a5
17 changed files with 256 additions and 372 deletions
@@ -0,0 +1,56 @@
#pragma once
#include <array>
#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<BeanPatch, 10> 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;
}
+24 -126
View File
@@ -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;
}
@@ -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;
@@ -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();
@@ -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),
@@ -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()),
});
@@ -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)),
@@ -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, {}, {}, {
@@ -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()),
@@ -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()),
});
@@ -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))),
@@ -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()),
@@ -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()),
+29 -10
View File
@@ -1,4 +1,5 @@
#include "logic.h"
#include "bean_patches.h"
#include "../debugger/performanceTimer.h"
#include <vector>
@@ -14,6 +15,8 @@
#include <ship/utils/StringHelper.h>
#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
+1
View File
@@ -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();
@@ -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)
+7 -19
View File
@@ -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) {