Rando: Shuffle Climb (#5182)

Co-authored-by: Pepper0ni <93387759+Pepper0ni@users.noreply.github.com>
This commit is contained in:
Philip Dubé
2026-01-19 19:47:56 +00:00
committed by GitHub
parent f52b653cfb
commit 596b714fa4
41 changed files with 753 additions and 365 deletions
@@ -294,6 +294,14 @@ typedef enum {
// - `*EnGm`
VB_CHECK_RANDO_PRICE_OF_MEDIGORON,
// #### `result`
// ```c
// true
// ```
// #### `args`
// - None
VB_CLIMB,
// #### `result`
// ```c
// CHECK_BTN_ALL(input->press.button, BTN_START)
@@ -2117,10 +2117,11 @@ void StaticData::HintTable_Init_Item() {
{ CustomMessage("a master unlocker", /*german*/ "ein Meisterentsperrer", /*french*/ "un Kit de Déverrouillage") });
// /*spanish*/un desbloqueador maestro
//RANDOTODO if these are ever used for anything other than name, they want obscure and ambiguous hints
hintTextTable[RHT_CLIMB] = HintText(CustomMessage("the ability to climb", /*german*/TODO_TRANSLATE, /*french*/"la capacité de grimper"));
hintTextTable[RHT_CRAWL] = HintText(CustomMessage("the ability to crawl", /*german*/TODO_TRANSLATE, /*french*/"la capacité de ramper"));
hintTextTable[RHT_OPEN_CHEST] = HintText(CustomMessage("the ability to open chests", /*german*/TODO_TRANSLATE, /*french*/TODO_TRANSLATE));
//RANDOTODO if these are ever used for anything other than name, they want abscure and ambiguous hints
hintTextTable[RHT_QUIVER_INF] = HintText(CustomMessage("an infinite Quiver", /*german*/"der unendliche Köcher", /*french*/"un Carquois Infini"));
hintTextTable[RHT_BOMB_BAG_INF] = HintText(CustomMessage("an infinite Bomb Bag", /*german*/"die unendliche Bombentasche", /*french*/"un Sac de Bombe sans fond"));
@@ -401,7 +401,12 @@ void GenerateItemPool() {
int bronzeScale = ctx->GetOption(RSK_SHUFFLE_SWIM) ? 1 : 0;
AddItemToPool(RG_PROGRESSIVE_SCALE, 3 + bronzeScale, 2 + bronzeScale, 2 + bronzeScale, 2 + bronzeScale);
int powerBracelet = ctx->GetOption(RSK_SHUFFLE_GRAB) ? 1 : 0;
AddItemToPool(RG_PROGRESSIVE_STRENGTH, 4 + powerBracelet, 3 + powerBracelet, 3 + powerBracelet, 3 + powerBracelet);
if (ctx->GetOption(RSK_SHUFFLE_CLIMB)) {
AddItemToPool(RG_CLIMB, 2, 1, 1, 1);
}
if (ctx->GetOption(RSK_SHUFFLE_CRAWL)) {
AddItemToPool(RG_CRAWL, 2, 1, 1, 1);
}
@@ -409,9 +414,6 @@ void GenerateItemPool() {
AddItemToPool(RG_OPEN_CHEST, 2, 1, 1, 1);
}
int powerBracelet = ctx->GetOption(RSK_SHUFFLE_GRAB) ? 1 : 0;
AddItemToPool(RG_PROGRESSIVE_STRENGTH, 4 + powerBracelet, 3 + powerBracelet, 3 + powerBracelet, 3 + powerBracelet);
if (ctx->GetOption(RSK_SHUFFLE_BEEHIVES)) {
PlaceItemsForType(RCTYPE_BEEHIVE, true, true);
}
@@ -997,6 +997,10 @@ void InitTrickNames() {
Text{ "Stalfos Key" }, Text{ "Nightmare Key" }, Text{ "Graveyard Key" },
Text{ "King's Key" }, Text{ "Hero's Key" },
};
trickNameTable[RG_CLIMB] = {
// TODO_TRANSLATE
Text{ "Cling" },
};
trickNameTable[RG_CRAWL] = {
// TODO_TRANSLATE
Text{ "Crouch" },
+35 -18
View File
@@ -24,7 +24,6 @@ extern "C" {
#include "objects/object_fish/object_fish.h"
#include "objects/object_toki_objects/object_toki_objects.h"
#include "objects/object_gi_bomb_2/object_gi_bomb_2.h"
#include "objects/gameplay_field_keep/gameplay_field_keep.h"
#include "objects/object_goma/object_goma.h"
#include "objects/object_kingdodongo/object_kingdodongo.h"
#include "objects/object_bv/object_bv.h"
@@ -32,9 +31,9 @@ extern "C" {
#include "objects/object_fd/object_fd.h"
#include "objects/object_mamenoki/object_mamenoki.h"
#include "objects/object_mo/object_mo.h"
#include "objects/object_mori_objects/object_mori_objects.h"
#include "objects/object_sst/object_sst.h"
#include "overlays/actors/ovl_Boss_Goma/z_boss_goma.h"
#include "overlays/ovl_Boss_Sst/ovl_Boss_Sst.h"
#include "objects/object_tw/object_tw.h"
#include "objects/object_ganon2/object_ganon2.h"
#include "objects/object_gi_shield_1/object_gi_shield_1.h"
@@ -1139,6 +1138,40 @@ extern "C" void Randomizer_DrawBronzeScale(PlayState* play, GetItemEntry* getIte
CLOSE_DISPS(play->state.gfxCtx);
}
extern "C" void Randomizer_DrawPowerBracelet(PlayState* play, GetItemEntry* getItemEntry) {
OPEN_DISPS(play->state.gfxCtx);
Gfx_SetupDL_25Opa(play->state.gfxCtx);
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPGrayscale(POLY_OPA_DISP++, true);
gDPSetGrayscaleColor(POLY_OPA_DISP++, 80, 80, 80, 255);
gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gGiGoronBraceletDL);
gSPGrayscale(POLY_OPA_DISP++, false);
CLOSE_DISPS(play->state.gfxCtx);
}
extern "C" void Randomizer_DrawLadder(PlayState* play, GetItemEntry* getItemEntry) {
OPEN_DISPS(play->state.gfxCtx);
Gfx_SetupDL_25Opa(play->state.gfxCtx);
gSPSegment(POLY_OPA_DISP++, 0x08, (uintptr_t)gMoriHashiraTex);
Matrix_Translate(0, -30, 0, MTXMODE_APPLY);
Matrix_Scale(1.0f, 0.25f, 1.0f, MTXMODE_APPLY);
gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gMoriHashigoLadderDL);
Matrix_RotateY(M_PIf, MTXMODE_APPLY);
gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gMoriHashigoLadderDL);
CLOSE_DISPS(play->state.gfxCtx);
}
extern "C" void Randomizer_DrawKneePads(PlayState* play, GetItemEntry* getItemEntry) {
OPEN_DISPS(play->state.gfxCtx);
@@ -1156,22 +1189,6 @@ extern "C" void Randomizer_DrawKneePads(PlayState* play, GetItemEntry* getItemEn
CLOSE_DISPS(play->state.gfxCtx);
}
extern "C" void Randomizer_DrawPowerBracelet(PlayState* play, GetItemEntry* getItemEntry) {
OPEN_DISPS(play->state.gfxCtx);
Gfx_SetupDL_25Opa(play->state.gfxCtx);
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPGrayscale(POLY_OPA_DISP++, true);
gDPSetGrayscaleColor(POLY_OPA_DISP++, 80, 80, 80, 255);
gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gGiGoronBraceletDL);
gSPGrayscale(POLY_OPA_DISP++, false);
CLOSE_DISPS(play->state.gfxCtx);
}
static Gfx* boxLidDL;
static Gfx* boxBodyDL;
extern "C" void EnBox_PostLimbDrawOverride(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, void* thisx) {
+1
View File
@@ -23,6 +23,7 @@ void Randomizer_DrawTriforcePieceGI(PlayState* play, GetItemEntry getItemEntry);
void Randomizer_DrawOcarinaButton(PlayState* play, GetItemEntry* getItemEntry);
void Randomizer_DrawBronzeScale(PlayState* play, GetItemEntry* getItemEntry);
void Randomizer_DrawPowerBracelet(PlayState* play, GetItemEntry* getItemEntry);
void Randomizer_DrawLadder(PlayState* play, GetItemEntry* getItemEntry);
void Randomizer_DrawKneePads(PlayState* play, GetItemEntry* getItemEntry);
void Randomizer_DrawOpenChest(PlayState* play, GetItemEntry* getItemEntry);
void Randomizer_DrawFishingPoleGI(PlayState* play, GetItemEntry* getItemEntry);
+20 -20
View File
@@ -261,8 +261,8 @@ void SetAllEntrancesData() {
{ EntranceType::Dungeon, RR_JABU_JABUS_BELLY_ENTRYWAY, RR_ZORAS_FOUNTAIN, ENTR_ZORAS_FOUNTAIN_OUTSIDE_JABU_JABU } },
{ { EntranceType::Dungeon, RR_SACRED_FOREST_MEADOW, RR_FOREST_TEMPLE_ENTRYWAY, ENTR_FOREST_TEMPLE_ENTRANCE },
{ EntranceType::Dungeon, RR_FOREST_TEMPLE_ENTRYWAY, RR_SACRED_FOREST_MEADOW, ENTR_SACRED_FOREST_MEADOW_OUTSIDE_TEMPLE } },
{ { EntranceType::Dungeon, RR_DMC_CENTRAL_LOCAL, RR_FIRE_TEMPLE_ENTRYWAY, ENTR_FIRE_TEMPLE_ENTRANCE },
{ EntranceType::Dungeon, RR_FIRE_TEMPLE_ENTRYWAY, RR_DMC_CENTRAL_LOCAL, ENTR_DEATH_MOUNTAIN_CRATER_OUTSIDE_TEMPLE } },
{ { EntranceType::Dungeon, RR_DMC_OUTSIDE_FIRE_TEMPLE, RR_FIRE_TEMPLE_ENTRYWAY, ENTR_FIRE_TEMPLE_ENTRANCE },
{ EntranceType::Dungeon, RR_FIRE_TEMPLE_ENTRYWAY, RR_DMC_OUTSIDE_FIRE_TEMPLE, ENTR_DEATH_MOUNTAIN_CRATER_OUTSIDE_TEMPLE } },
{ { EntranceType::Dungeon, RR_LH_FROM_WATER_TEMPLE, RR_WATER_TEMPLE_ENTRYWAY, ENTR_WATER_TEMPLE_ENTRANCE },
{ EntranceType::Dungeon, RR_WATER_TEMPLE_ENTRYWAY, RR_LH_FROM_WATER_TEMPLE, ENTR_LAKE_HYLIA_OUTSIDE_TEMPLE } },
{ { EntranceType::Dungeon, RR_DESERT_COLOSSUS, RR_SPIRIT_TEMPLE_ENTRYWAY, ENTR_SPIRIT_TEMPLE_ENTRANCE },
@@ -340,8 +340,8 @@ void SetAllEntrancesData() {
{ EntranceType::Interior, RR_KAK_SHOOTING_GALLERY, RR_KAKARIKO_VILLAGE, ENTR_KAKARIKO_VILLAGE_OUTSIDE_SHOOTING_GALLERY } },
{ { EntranceType::Interior, RR_DESERT_COLOSSUS, RR_COLOSSUS_GREAT_FAIRY_FOUNTAIN, ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_NAYRUS_COLOSSUS },
{ EntranceType::Interior, RR_COLOSSUS_GREAT_FAIRY_FOUNTAIN, RR_DESERT_COLOSSUS, ENTR_DESERT_COLOSSUS_GREAT_FAIRY_EXIT } },
{ { EntranceType::Interior, RR_HYRULE_CASTLE_GROUNDS, RR_HC_GREAT_FAIRY_FOUNTAIN, ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_DINS_HC },
{ EntranceType::Interior, RR_HC_GREAT_FAIRY_FOUNTAIN, RR_CASTLE_GROUNDS, ENTR_CASTLE_GROUNDS_GREAT_FAIRY_EXIT } },
{ { EntranceType::Interior, RR_HC_PAST_GATE, RR_HC_GREAT_FAIRY_FOUNTAIN, ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_DINS_HC },
{ EntranceType::Interior, RR_HC_GREAT_FAIRY_FOUNTAIN, RR_HC_PAST_GATE, ENTR_CASTLE_GROUNDS_GREAT_FAIRY_EXIT } },
{ { EntranceType::Interior, RR_GANONS_CASTLE_GROUNDS, RR_OGC_GREAT_FAIRY_FOUNTAIN, ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_OGC_DD },
// 0x3E8 is an unused entrance index repurposed to differentiate between the HC and OGC fairy
// fountain exits (normally they both use 0x340)
@@ -353,8 +353,8 @@ void SetAllEntrancesData() {
{ { EntranceType::Interior, RR_ZORAS_FOUNTAIN, RR_ZF_GREAT_FAIRY_FOUNTAIN, ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_FARORES_ZF },
{ EntranceType::Interior, RR_ZF_GREAT_FAIRY_FOUNTAIN, RR_ZORAS_FOUNTAIN, ENTR_ZORAS_FOUNTAIN_OUTSIDE_GREAT_FAIRY } },
{ { EntranceType::SpecialInterior, RR_KOKIRI_FOREST, RR_KF_LINKS_HOUSE, ENTR_LINKS_HOUSE_1 },
{ EntranceType::SpecialInterior, RR_KF_LINKS_HOUSE, RR_KOKIRI_FOREST, ENTR_KOKIRI_FOREST_OUTSIDE_LINKS_HOUSE } },
{ { EntranceType::SpecialInterior, RR_KF_LINKS_PORCH, RR_KF_LINKS_HOUSE, ENTR_LINKS_HOUSE_1 },
{ EntranceType::SpecialInterior, RR_KF_LINKS_HOUSE, RR_KF_LINKS_PORCH, ENTR_KOKIRI_FOREST_OUTSIDE_LINKS_HOUSE } },
{ { EntranceType::SpecialInterior, RR_TOT_ENTRANCE, RR_TEMPLE_OF_TIME, ENTR_TEMPLE_OF_TIME_ENTRANCE },
{ EntranceType::SpecialInterior, RR_TEMPLE_OF_TIME, RR_TOT_ENTRANCE, ENTR_TEMPLE_OF_TIME_EXTERIOR_DAY_OUTSIDE_TEMPLE } },
{ { EntranceType::SpecialInterior, RR_KAKARIKO_VILLAGE, RR_KAK_WINDMILL_LOWER, ENTR_WINDMILL_AND_DAMPES_GRAVE_WINDMILL },
@@ -413,14 +413,14 @@ void SetAllEntrancesData() {
{ EntranceType::GrottoGrave, RR_GC_GROTTO, RR_GC_GROTTO_PLATFORM, ENTRANCE_GROTTO_EXIT(GROTTO_GORON_CITY_OFFSET) } },
{ { EntranceType::GrottoGrave, RR_DEATH_MOUNTAIN_TRAIL, RR_DMT_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_DMT_STORMS_OFFSET) },
{ EntranceType::GrottoGrave, RR_DMT_STORMS_GROTTO, RR_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROTTO_EXIT(GROTTO_DMT_STORMS_OFFSET) } },
{ { EntranceType::GrottoGrave, RR_DEATH_MOUNTAIN_SUMMIT, RR_DMT_COW_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_DMT_COW_OFFSET) },
{ EntranceType::GrottoGrave, RR_DMT_COW_GROTTO, RR_DEATH_MOUNTAIN_SUMMIT, ENTRANCE_GROTTO_EXIT(GROTTO_DMT_COW_OFFSET) } },
{ { EntranceType::GrottoGrave, RR_DEATH_MOUNTAIN_ROCKFALL, RR_DMT_COW_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_DMT_COW_OFFSET) },
{ EntranceType::GrottoGrave, RR_DMT_COW_GROTTO, RR_DEATH_MOUNTAIN_ROCKFALL, ENTRANCE_GROTTO_EXIT(GROTTO_DMT_COW_OFFSET) } },
{ { EntranceType::GrottoGrave, RR_KAK_BACKYARD, RR_KAK_OPEN_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_KAK_OPEN_OFFSET) },
{ EntranceType::GrottoGrave, RR_KAK_OPEN_GROTTO, RR_KAK_BACKYARD, ENTRANCE_GROTTO_EXIT(GROTTO_KAK_OPEN_OFFSET) } },
{ { EntranceType::GrottoGrave, RR_KAKARIKO_VILLAGE, RR_KAK_REDEAD_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_KAK_REDEAD_OFFSET) },
{ EntranceType::GrottoGrave, RR_KAK_REDEAD_GROTTO, RR_KAKARIKO_VILLAGE, ENTRANCE_GROTTO_EXIT(GROTTO_KAK_REDEAD_OFFSET) } },
{ { EntranceType::GrottoGrave, RR_HYRULE_CASTLE_GROUNDS, RR_HC_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_HC_STORMS_OFFSET) },
{ EntranceType::GrottoGrave, RR_HC_STORMS_GROTTO, RR_CASTLE_GROUNDS, ENTRANCE_GROTTO_EXIT(GROTTO_HC_STORMS_OFFSET) } },
{ { EntranceType::GrottoGrave, RR_HC_MOAT, RR_HC_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_HC_STORMS_OFFSET) },
{ EntranceType::GrottoGrave, RR_HC_STORMS_GROTTO, RR_HC_MOAT, ENTRANCE_GROTTO_EXIT(GROTTO_HC_STORMS_OFFSET) } },
{ { EntranceType::GrottoGrave, RR_HYRULE_FIELD, RR_HF_TEKTITE_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_HF_TEKTITE_OFFSET) },
{ EntranceType::GrottoGrave, RR_HF_TEKTITE_GROTTO, RR_HYRULE_FIELD, ENTRANCE_GROTTO_EXIT(GROTTO_HF_TEKTITE_OFFSET) } },
{ { EntranceType::GrottoGrave, RR_HYRULE_FIELD, RR_HF_NEAR_KAK_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_HF_NEAR_KAK_OFFSET) },
@@ -443,14 +443,14 @@ void SetAllEntrancesData() {
{ EntranceType::GrottoGrave, RR_SFM_WOLFOS_GROTTO, RR_SFM_ENTRYWAY, ENTRANCE_GROTTO_EXIT(GROTTO_SFM_WOLFOS_OFFSET) } },
{ { EntranceType::GrottoGrave, RR_SACRED_FOREST_MEADOW, RR_SFM_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_SFM_STORMS_OFFSET) },
{ EntranceType::GrottoGrave, RR_SFM_STORMS_GROTTO, RR_SACRED_FOREST_MEADOW, ENTRANCE_GROTTO_EXIT(GROTTO_SFM_STORMS_OFFSET) } },
{ { EntranceType::GrottoGrave, RR_SACRED_FOREST_MEADOW, RR_SFM_FAIRY_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_SFM_FAIRY_OFFSET) },
{ EntranceType::GrottoGrave, RR_SFM_FAIRY_GROTTO, RR_SACRED_FOREST_MEADOW, ENTRANCE_GROTTO_EXIT(GROTTO_SFM_FAIRY_OFFSET) } },
{ { EntranceType::GrottoGrave, RR_SFM_OUTSIDE_FAIRY_GROTTO, RR_SFM_FAIRY_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_SFM_FAIRY_OFFSET) },
{ EntranceType::GrottoGrave, RR_SFM_FAIRY_GROTTO, RR_SFM_OUTSIDE_FAIRY_GROTTO, ENTRANCE_GROTTO_EXIT(GROTTO_SFM_FAIRY_OFFSET) } },
{ { EntranceType::GrottoGrave, RR_LW_BEYOND_MIDO, RR_LW_SCRUBS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_LW_SCRUBS_OFFSET) },
{ EntranceType::GrottoGrave, RR_LW_SCRUBS_GROTTO, RR_LW_BEYOND_MIDO, ENTRANCE_GROTTO_EXIT(GROTTO_LW_SCRUBS_OFFSET) } },
{ { EntranceType::GrottoGrave, RR_THE_LOST_WOODS, RR_LW_NEAR_SHORTCUTS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_LW_NEAR_SHORTCUTS_OFFSET) },
{ EntranceType::GrottoGrave, RR_LW_NEAR_SHORTCUTS_GROTTO, RR_THE_LOST_WOODS, ENTRANCE_GROTTO_EXIT(GROTTO_LW_NEAR_SHORTCUTS_OFFSET) } },
{ { EntranceType::GrottoGrave, RR_KOKIRI_FOREST, RR_KF_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_KF_STORMS_OFFSET) },
{ EntranceType::GrottoGrave, RR_KF_STORMS_GROTTO, RR_KOKIRI_FOREST, ENTRANCE_GROTTO_EXIT(GROTTO_KF_STORMS_OFFSET) } },
{ { EntranceType::GrottoGrave, RR_KF_OUTSIDE_LOST_WOODS, RR_KF_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_KF_STORMS_OFFSET) },
{ EntranceType::GrottoGrave, RR_KF_STORMS_GROTTO, RR_KF_OUTSIDE_LOST_WOODS, ENTRANCE_GROTTO_EXIT(GROTTO_KF_STORMS_OFFSET) } },
{ { EntranceType::GrottoGrave, RR_ZORAS_DOMAIN_ISLAND, RR_ZD_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_ZD_STORMS_OFFSET) },
{ EntranceType::GrottoGrave, RR_ZD_STORMS_GROTTO, RR_ZORAS_DOMAIN_ISLAND, ENTRANCE_GROTTO_EXIT(GROTTO_ZD_STORMS_OFFSET) } },
{ { EntranceType::GrottoGrave, RR_GF_NEAR_GROTTO, RR_GF_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_GF_STORMS_OFFSET) },
@@ -474,8 +474,8 @@ void SetAllEntrancesData() {
{ { EntranceType::Overworld, RR_KOKIRI_FOREST, RR_LW_BRIDGE_FROM_FOREST, ENTR_LOST_WOODS_BRIDGE_EAST_EXIT },
{ EntranceType::Overworld, RR_LW_BRIDGE, RR_KOKIRI_FOREST, ENTR_KOKIRI_FOREST_LOWER_EXIT } },
{ { EntranceType::Overworld, RR_KOKIRI_FOREST, RR_THE_LOST_WOODS, ENTR_LOST_WOODS_SOUTH_EXIT },
{ EntranceType::Overworld, RR_LW_FOREST_EXIT, RR_KOKIRI_FOREST, ENTR_KOKIRI_FOREST_UPPER_EXIT } },
{ { EntranceType::Overworld, RR_KF_OUTSIDE_LOST_WOODS, RR_THE_LOST_WOODS, ENTR_LOST_WOODS_SOUTH_EXIT },
{ EntranceType::Overworld, RR_LW_FOREST_EXIT, RR_KF_OUTSIDE_LOST_WOODS, ENTR_KOKIRI_FOREST_UPPER_EXIT } },
{ { EntranceType::Overworld, RR_THE_LOST_WOODS, RR_GC_WOODS_WARP, ENTR_GORON_CITY_TUNNEL_SHORTCUT },
{ EntranceType::Overworld, RR_GC_WOODS_WARP, RR_THE_LOST_WOODS, ENTR_LOST_WOODS_TUNNEL_SHORTCUT } },
{ { EntranceType::Overworld, RR_THE_LOST_WOODS, RR_ZR_FROM_SHORTCUT, ENTR_ZORAS_RIVER_UNDERWATER_SHORTCUT },
@@ -484,8 +484,8 @@ void SetAllEntrancesData() {
{ EntranceType::Overworld, RR_SFM_ENTRYWAY, RR_LW_BEYOND_MIDO, ENTR_LOST_WOODS_NORTH_EXIT } },
{ { EntranceType::Overworld, RR_LW_BRIDGE, RR_HYRULE_FIELD, ENTR_HYRULE_FIELD_WOODED_EXIT },
{ EntranceType::Overworld, RR_HYRULE_FIELD, RR_LW_BRIDGE, ENTR_LOST_WOODS_BRIDGE_WEST_EXIT } },
{ { EntranceType::Overworld, RR_HYRULE_FIELD, RR_LAKE_HYLIA, ENTR_LAKE_HYLIA_NORTH_EXIT },
{ EntranceType::Overworld, RR_LAKE_HYLIA, RR_HYRULE_FIELD, ENTR_HYRULE_FIELD_FENCE_EXIT } },
{ { EntranceType::Overworld, RR_HF_TO_LAKE_HYLIA, RR_LAKE_HYLIA, ENTR_LAKE_HYLIA_NORTH_EXIT },
{ EntranceType::Overworld, RR_LAKE_HYLIA, RR_HF_TO_LAKE_HYLIA, ENTR_HYRULE_FIELD_FENCE_EXIT } },
{ { EntranceType::Overworld, RR_HYRULE_FIELD, RR_GERUDO_VALLEY, ENTR_GERUDO_VALLEY_EAST_EXIT },
{ EntranceType::Overworld, RR_GERUDO_VALLEY, RR_HYRULE_FIELD, ENTR_HYRULE_FIELD_ROCKY_PATH } },
{ { EntranceType::Overworld, RR_HYRULE_FIELD, RR_MARKET_ENTRANCE, ENTR_MARKET_ENTRANCE_NEAR_GUARD_EXIT },
@@ -1544,7 +1544,7 @@ int EntranceShuffler::ShuffleAllEntrances() {
{ EntranceNameByRegions(RR_FOREST_TEMPLE_BOSS_ROOM, RR_FOREST_TEMPLE_BOSS_ENTRYWAY),
GetEntrance(RR_FOREST_TEMPLE_ENTRYWAY, RR_SACRED_FOREST_MEADOW) },
{ EntranceNameByRegions(RR_FIRE_TEMPLE_BOSS_ROOM, RR_FIRE_TEMPLE_BOSS_ENTRYWAY),
GetEntrance(RR_FIRE_TEMPLE_ENTRYWAY, RR_DMC_CENTRAL_LOCAL) },
GetEntrance(RR_FIRE_TEMPLE_ENTRYWAY, RR_DMC_OUTSIDE_FIRE_TEMPLE) },
{ EntranceNameByRegions(RR_WATER_TEMPLE_BOSS_ROOM, RR_WATER_TEMPLE_BOSS_ENTRYWAY),
GetEntrance(RR_WATER_TEMPLE_ENTRYWAY, RR_LH_FROM_WATER_TEMPLE) },
{ EntranceNameByRegions(RR_SPIRIT_TEMPLE_BOSS_ROOM, RR_SPIRIT_TEMPLE_BOSS_ENTRYWAY),
@@ -1566,7 +1566,7 @@ int EntranceShuffler::ShuffleAllEntrances() {
GetEntrance(RR_JABU_JABUS_BELLY_BOSS_ROOM, RR_ZORAS_FOUNTAIN) },
{ EntranceNameByRegions(RR_FOREST_TEMPLE_ENTRYWAY, RR_SACRED_FOREST_MEADOW),
GetEntrance(RR_FOREST_TEMPLE_BOSS_ROOM, RR_SACRED_FOREST_MEADOW) },
{ EntranceNameByRegions(RR_FIRE_TEMPLE_ENTRYWAY, RR_DMC_CENTRAL_LOCAL),
{ EntranceNameByRegions(RR_FIRE_TEMPLE_ENTRYWAY, RR_DMC_OUTSIDE_FIRE_TEMPLE),
GetEntrance(RR_FIRE_TEMPLE_BOSS_ROOM, RR_DMC_CENTRAL_LOCAL) },
{ EntranceNameByRegions(RR_WATER_TEMPLE_ENTRYWAY, RR_LH_FROM_WATER_TEMPLE),
GetEntrance(RR_WATER_TEMPLE_BOSS_ROOM, RR_LAKE_HYLIA) },
@@ -850,6 +850,17 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l
va_copy(args, originalArgs);
switch (id) {
case VB_CLIMB:
if (RAND_GET_OPTION(RSK_SHUFFLE_CLIMB) && !Flags_GetRandomizerInf(RAND_INF_CAN_CLIMB)) {
s32* x = va_arg(args, s32*);
s32* y = va_arg(args, s32*);
*x = 0;
if (*y > 0) {
*y = 0;
}
}
break;
case VB_CRAWL:
*should = *should && Flags_GetRandomizerInf(RAND_INF_CAN_CRAWL);
break;
@@ -366,17 +366,18 @@ void Rando::StaticData::InitItemTable() {
itemTable[RG_GERUDO_MASK] = Item(RG_GERUDO_MASK, Text{ "Gerudo Mask", "Masque de Gerudo", TODO_TRANSLATE }, ITEMTYPE_ITEM, RG_GERUDO_MASK, true, LOGIC_NONE, RHT_MASK_GERUDO, RG_GERUDO_MASK, OBJECT_GI_GERUDOMASK, GID_MASK_GERUDO, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_MASK_OF_TRUTH] = Item(RG_MASK_OF_TRUTH, Text{ "Mask of Truth", "Masque de Vérité", TODO_TRANSLATE }, ITEMTYPE_ITEM, RG_MASK_OF_TRUTH, true, LOGIC_NONE, RHT_MASK_TRUTH, RG_MASK_OF_TRUTH, OBJECT_GI_TRUTH_MASK, GID_MASK_TRUTH, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_BRONZE_SCALE] = Item(RG_BRONZE_SCALE, Text{ "Bronze Scale", "Écaille de Bronze", "Bronzene Schuppe" }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, LOGIC_PROGRESSIVE_SCALE, RHT_NONE, RG_BRONZE_SCALE, OBJECT_GI_SCALE, GID_SCALE_SILVER, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"the ", "die ", "le "});
itemTable[RG_BRONZE_SCALE] = Item(RG_BRONZE_SCALE, Text{ "Bronze Scale", "Écaille de Bronze", "Bronzene Schuppe" }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, LOGIC_PROGRESSIVE_SCALE, RHT_NONE, RG_BRONZE_SCALE, OBJECT_GI_SCALE, GID_SCALE_SILVER, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"the ", "die ", "le "});
itemTable[RG_BRONZE_SCALE].SetCustomDrawFunc(Randomizer_DrawBronzeScale);
itemTable[RG_CRAWL] = Item(RG_CRAWL, Text{ "Crawl", "Ramper", "Kriechen" }, ITEMTYPE_ITEM, GI_SHIELD_DEKU, true, LOGIC_NONE, RHT_CRAWL, RG_CRAWL, OBJECT_GI_SHIELD_1, GID_SHIELD_DEKU, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_CRAWL].SetCustomDrawFunc(Randomizer_DrawKneePads);
itemTable[RG_POWER_BRACELET] = Item(RG_POWER_BRACELET, Text{ "Power Bracelet", TODO_TRANSLATE, TODO_TRANSLATE }, ITEMTYPE_ITEM, GI_BRACELET, true, LOGIC_NONE, RHT_NONE, RG_POWER_BRACELET, OBJECT_GI_BRACELET, GID_BRACELET, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_POWER_BRACELET].SetCustomDrawFunc(Randomizer_DrawPowerBracelet);
itemTable[RG_CLIMB] = Item(RG_CLIMB, Text{ "Climb", TODO_TRANSLATE, "Grimper" }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, LOGIC_NONE, RHT_CLIMB, RG_CLIMB, OBJECT_GI_SCALE, GID_SCALE_SILVER, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_CLIMB].SetCustomDrawFunc(Randomizer_DrawLadder);
itemTable[RG_CRAWL] = Item(RG_CRAWL, Text{ "Crawl", "Ramper", "Kriechen" }, ITEMTYPE_ITEM, GI_SHIELD_DEKU, true, LOGIC_NONE, RHT_CRAWL, RG_CRAWL, OBJECT_GI_SHIELD_1, GID_SHIELD_DEKU, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_CRAWL].SetCustomDrawFunc(Randomizer_DrawKneePads);
itemTable[RG_OPEN_CHEST] = Item(RG_OPEN_CHEST, Text{ "Open Chests", TODO_TRANSLATE, TODO_TRANSLATE }, ITEMTYPE_ITEM, GI_KEY_SMALL, true, LOGIC_NONE, RHT_OPEN_CHEST, RG_OPEN_CHEST, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_OPEN_CHEST].SetCustomDrawFunc(Randomizer_DrawOpenChest);
itemTable[RG_PROGRESSIVE_BOMBCHU_BAG] = Item(RG_PROGRESSIVE_BOMBCHU_BAG, Text{ "Bombchu Bag", "Sac de Missiles Teigneux", "Krabbelminentasche" }, ITEMTYPE_ITEM, RG_PROGRESSIVE_BOMBCHU_BAG, true, LOGIC_BOMBCHUS, RHT_BOMBCHU_BAG, RG_PROGRESSIVE_BOMBCHU_BAG, OBJECT_GI_BOMB_2, GID_BOMBCHU, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"a ", "eine ", "un "});
itemTable[RG_PROGRESSIVE_BOMBCHU_BAG] = Item(RG_PROGRESSIVE_BOMBCHU_BAG, Text{ "Bombchu Bag", "Sac de Missiles Teigneux", "Krabbelminentasche" }, ITEMTYPE_ITEM, RG_PROGRESSIVE_BOMBCHU_BAG, true, LOGIC_BOMBCHUS, RHT_BOMBCHU_BAG, RG_PROGRESSIVE_BOMBCHU_BAG, OBJECT_GI_BOMB_2, GID_BOMBCHU, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"a ", "eine ", "un "});
itemTable[RG_PROGRESSIVE_BOMBCHU_BAG].SetCustomDrawFunc(Randomizer_DrawBombchuBag);
itemTable[RG_QUIVER_INF] = Item(RG_QUIVER_INF, Text{ "Infinite Quiver", "Carquois Infini", "Unendlicher Köcher" }, ITEMTYPE_ITEM, RG_QUIVER_INF, true, LOGIC_PROGRESSIVE_BOW, RHT_QUIVER_INF, RG_QUIVER_INF, OBJECT_GI_ARROWCASE, GID_QUIVER_50, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "den ", "le "});
@@ -1,11 +1,7 @@
#include "location_access.h"
#include "soh/Enhancements/randomizer/dungeon.h"
#include "soh/Enhancements/randomizer/static_data.h"
#include "soh/Enhancements/randomizer/SeedContext.h"
#include "soh/Enhancements/randomizer/3drando/item_pool.hpp"
#include "soh/Enhancements/randomizer/3drando/spoiler_log.hpp"
#include "soh/Enhancements/randomizer/trial.h"
#include "soh/Enhancements/randomizer/entrance.h"
#include "soh/Enhancements/debugger/performanceTimer.h"
@@ -626,31 +622,116 @@ std::array<Region, RR_MAX> areaTable;
// clang-format off
std::map<RandomizerRegion, SpiritLogicData> Region::spiritLogicData = {
//Vanilla Child uses ExplosiveKeyLogic here because they need to exist for shared adult checks
{RR_SPIRIT_TEMPLE_SUN_ON_FLOOR_1F, {5, 0, 3, 0, []{return true;}, []{return logic->SpiritExplosiveKeyLogic() && logic->HasItem(RG_POWER_BRACELET)/* && logic->CanClimbHigh() */;}, []{return true/*logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS)*/;}}},
{RR_SPIRIT_TEMPLE_SUN_ON_FLOOR_2F, {5, 0, 3, 0, []{return true/*logic->CanClimbHigh()*/;}, []{return logic->SpiritExplosiveKeyLogic() && logic->HasItem(RG_POWER_BRACELET)/* && logic->CanClimbHigh() */;}, []{return true/*logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS)*/;}}},
{RR_SPIRIT_TEMPLE_2F_MIRROR_ROOM, {5, 0, 3, 0, []{return logic->CanUse(RG_HOOKSHOT) && logic->SpiritSunOnFloorToStatue();}, []{return true/*logic->CanClimbHigh()*/;}, []{return logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS);}}},
{RR_SPIRIT_TEMPLE_STATUE_ROOM_CHILD, {5, 0, 3, 0, []{return logic->SpiritExplosiveKeyLogic()/* && logic->CanClimbHigh()*/;}, []{return logic->SpiritExplosiveKeyLogic() && logic->HasItem(RG_POWER_BRACELET)/* && logic->CanClimbHigh()*/;}, []{return true/*logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS)*/;}}},
{RR_SPIRIT_TEMPLE_INNER_WEST_HAND, {5, 0, 3, 0, []{return logic->SpiritExplosiveKeyLogic()/* && logic->CanClimbHigh()*/;}, []{return logic->SpiritExplosiveKeyLogic() && logic->HasItem(RG_POWER_BRACELET)/* && logic->CanClimbHigh()*/;}, []{return true/*logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS)*/;}}},
{RR_SPIRIT_TEMPLE_GS_LEDGE, {5, 0, 3, 0, []{return logic->SpiritExplosiveKeyLogic() && logic->SpiritWestToSkull()/* && logic->CanClimbHigh()*/;}, []{return logic->SpiritExplosiveKeyLogic() && logic->HasItem(RG_POWER_BRACELET) && logic->SpiritWestToSkull()/* && logic->CanClimbHigh()*/;}, []{return logic->SpiritWestToSkull()/* && (logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS))*/;}}},
{RR_SPIRIT_TEMPLE_STATUE_ROOM, {5, 0, 3, 0, []{return logic->SpiritExplosiveKeyLogic();}, []{return logic->SpiritExplosiveKeyLogic() && logic->HasItem(RG_POWER_BRACELET)/* && logic->CanClimbHigh()*/;}, []{return true;}}},
//Assumes SpiritSunBlockSouthLedge() for all access
{RR_SPIRIT_TEMPLE_SUN_BLOCK_CHEST_LEDGE, {5, 0, 3, 0, []{return logic->SpiritExplosiveKeyLogic() && logic->HasItem(RG_POWER_BRACELET)/* && logic->CanClimbHigh()*/;}, []{return logic->SpiritExplosiveKeyLogic() && logic->HasItem(RG_POWER_BRACELET)/* && logic->CanClimbHigh()*/;}, []{return logic->HasItem(RG_POWER_BRACELET)/*((logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS)) && logic->HasItem(RG_POWER_BRACELET)) || (logic->CanKillEnemy(RE_BEAMOS) && logic->CanUse(RG_LONGSHOT))*/;}}},
{RR_SPIRIT_TEMPLE_SKULLTULA_STAIRS, {5, 0, 3, 0, []{return logic->SpiritExplosiveKeyLogic() && logic->HasItem(RG_POWER_BRACELET)/* && logic->CanClimbHigh()*/;}, []{return logic->SpiritExplosiveKeyLogic() && logic->HasItem(RG_POWER_BRACELET)/* && logic->CanClimbHigh()*/;}, []{return logic->HasItem(RG_POWER_BRACELET)/*((logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS)) && logic->HasItem(RG_POWER_BRACELET)) || (logic->CanKillEnemy(RE_BEAMOS) && logic->CanUse(RG_LONGSHOT))*/;}}},
{RR_SPIRIT_TEMPLE_OUTER_RIGHT_HAND, {5, 5, 3, 3, []{return logic->OuterWestHandLogic();}, []{return logic->OuterWestHandLogic();}, []{return logic->OuterWestHandLogic();}}},
{RR_SPIRIT_TEMPLE_STATUE_ROOM_ADULT, {5, 0, 3, 0, []{return logic->SpiritExplosiveKeyLogic() && logic->CanUse(RG_HOOKSHOT)/* && logic->CanClimbHigh()*/;}, []{return logic->HasItem(RG_POWER_BRACELET)/* && logic->CanClimbHigh()*/;}, []{return logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS);}}},
{RR_SPIRIT_TEMPLE_INNER_LEFT_HAND, {5, 0, 3, 0, []{return logic->SpiritExplosiveKeyLogic() && logic->CanUse(RG_HOOKSHOT)/* && logic->CanClimbHigh()*/;}, []{return logic->HasItem(RG_POWER_BRACELET)/* && logic->CanClimbHigh()*/;}, []{return logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS);}}},
{RR_SPIRIT_TEMPLE_SHORTCUT_SWITCH, {5, 0, 3, 0, []{return logic->SpiritExplosiveKeyLogic() && logic->CanUse(RG_HOOKSHOT) && logic->SpiritEastToSwitch();}, []{return logic->SpiritEastToSwitch() && logic->HasItem(RG_POWER_BRACELET)/* && logic->CanClimbHigh()*/;}, []{return logic->SpiritEastToSwitch() && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS));}}},
//MQ /*&& logic->CanClimbHigh()*/
{RR_SPIRIT_TEMPLE_MQ_UNDER_LIKE_LIKE, {7, 6, 7, 7, []{return logic->StatueRoomMQKeyLogic();}, []{return logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 6) && logic->CanHitSwitch()/* && logic->Climb*/;}, []{return logic->StatueRoomMQKeyLogic() && logic->CanHitSwitch()/* && (logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS))*/;}}},
{RR_SPIRIT_TEMPLE_MQ_SUN_ON_FLOOR, {7, 6, 7, 7, []{return logic->StatueRoomMQKeyLogic() && logic->CanHitSwitch()/* && logic->CanClimbHigh()*/;}, []{return logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 6)/* && logic->Climb*/;}, []{return logic->StatueRoomMQKeyLogic()/* && (logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS))*/;}}},
{RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM_CHILD, {7, 0, 0, 0, []{return logic->CanHitSwitch()/* && logic->CanClimbHigh()*/;}, []{return true/*logic->Climb*/;}, []{return true/*logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS)*/;}}},
{RR_SPIRIT_TEMPLE_MQ_POT_LEDGE, {7, 0, 0, 0, []{return logic->CanHitSwitch() && logic->MQSpiritWestToPots()/* && logic->CanClimbHigh()*/;}, []{return logic->MQSpiritWestToPots()/* && logic->Climb*/;}, []{return /*logic->CanUse(RG_HOVER_BOOTS) || (logic->CanClimb() && */logic->MQSpiritWestToPots()/*)*/;}}},
{RR_SPIRIT_TEMPLE_MQ_INNER_RIGHT_HAND, {7, 0, 0, 0, []{return logic->CanHitSwitch() && logic->MQSpiritWestToPots()/* && logic->CanClimbHigh()*/;}, []{return logic->MQSpiritWestToPots()/* && logic->Climb*/;}, []{return /*logic->CanUse(RG_HOVER_BOOTS) || (logic->CanClimb() && */logic->MQSpiritWestToPots()/*)*/;}}},
{RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, {7, 0, 0, 0, []{return logic->CanHitSwitch()/* && logic->CanClimbHigh()*/;}, []{return true;}, []{return true;}}},
{RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM, {7, 0, 0, 0, []{return logic->CanHitSwitch() && logic->MQSpiritStatueToSunBlock()/* && logic->CanClimbHigh()*/;}, []{return logic->MQSpiritStatueToSunBlock()/* && logic->Climb*/;}, []{return logic->MQSpiritStatueToSunBlock()/* && (logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS))*/;}}},
{RR_SPIRIT_TEMPLE_MQ_OUTER_RIGHT_HAND, {7, 7, 4, 4, []{return logic->CanHitSwitch() && logic->OuterWestHandMQLogic() && logic->HasItem(RG_POWER_BRACELET)/* && logic->CanClimbHigh()*/;}, []{return logic->OuterWestHandMQLogic();}, []{return logic->OuterWestHandMQLogic();}}},
{RR_SPIRIT_TEMPLE_MQ_BIG_BLOCKS_DOOR, {7, 0, 0, 0, []{return logic->CanHitSwitch() && /* logic->CanClimbHigh() &&*/
areaTable[RR_SPIRIT_TEMPLE_MQ_BIG_BLOCKS_DOOR].AnyAgeTime([]{return logic->MQSpiritStatueSouthDoor();});}, []{return true;}, []{return areaTable[RR_SPIRIT_TEMPLE_MQ_BIG_BLOCKS_DOOR].AnyAgeTime([]{return logic->MQSpiritStatueSouthDoor();});}}},
{RR_SPIRIT_TEMPLE_SUN_ON_FLOOR_1F, {5, 0, 3, 0,
[]{return true;},
[]{return logic->SpiritExplosiveKeyLogic() && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT)) && logic->HasItem(RG_POWER_BRACELET);},
[]{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS);},
}},
{RR_SPIRIT_TEMPLE_SUN_ON_FLOOR_2F, {5, 0, 3, 0,
[]{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT);},
[]{return logic->SpiritExplosiveKeyLogic() && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT)) && logic->HasItem(RG_POWER_BRACELET);},
[]{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS);},
}},
{RR_SPIRIT_TEMPLE_2F_MIRROR_ROOM, {5, 0, 3, 0,
[]{return false;},
[]{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT);},
[]{return logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS);},
}},
{RR_SPIRIT_TEMPLE_STATUE_ROOM_CHILD, {5, 0, 3, 0,
[]{return logic->SpiritExplosiveKeyLogic() && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT));},
[]{return logic->SpiritExplosiveKeyLogic() && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT)) && logic->HasItem(RG_POWER_BRACELET);},
[]{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS);},
}},
{RR_SPIRIT_TEMPLE_INNER_WEST_HAND, {5, 0, 3, 0,
[]{return logic->SpiritExplosiveKeyLogic() && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT));},
[]{return logic->SpiritExplosiveKeyLogic() && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT)) && logic->HasItem(RG_POWER_BRACELET);},
[]{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS);},
}},
{RR_SPIRIT_TEMPLE_GS_LEDGE, {5, 0, 3, 0,
[]{return logic->SpiritExplosiveKeyLogic() && logic->SpiritWestToSkull() && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT));},
[]{return logic->SpiritExplosiveKeyLogic() && logic->SpiritWestToSkull() && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT)) && logic->HasItem(RG_POWER_BRACELET);},
[]{return logic->SpiritWestToSkull() && ((logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT)) || logic->CanUse(RG_HOVER_BOOTS));},
}},
{RR_SPIRIT_TEMPLE_STATUE_ROOM, {5, 0, 3, 0,
[]{return logic->SpiritExplosiveKeyLogic();},
[]{return logic->SpiritExplosiveKeyLogic() && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT)) && logic->HasItem(RG_POWER_BRACELET);},
[]{return true;},
}},
{RR_SPIRIT_TEMPLE_SUN_BLOCK_CHEST_LEDGE, {5, 0, 3, 0,
[]{return logic->SpiritExplosiveKeyLogic() && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT)) && logic->HasItem(RG_POWER_BRACELET);},
[]{return logic->SpiritExplosiveKeyLogic() && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT)) && logic->HasItem(RG_POWER_BRACELET);},
[]{return (((logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT)) || logic->CanUse(RG_HOVER_BOOTS)) && logic->HasItem(RG_POWER_BRACELET)) || (logic->CanKillEnemy(RE_BEAMOS) && logic->CanUse(RG_LONGSHOT));},
}},
{RR_SPIRIT_TEMPLE_SKULLTULA_STAIRS, {5, 0, 3, 0,
[]{return logic->SpiritExplosiveKeyLogic() && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT)) && logic->HasItem(RG_POWER_BRACELET);},
[]{return logic->SpiritExplosiveKeyLogic() && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT)) && logic->HasItem(RG_POWER_BRACELET);},
[]{return (((logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT)) || logic->CanUse(RG_HOVER_BOOTS)) && logic->HasItem(RG_POWER_BRACELET)) || (logic->CanKillEnemy(RE_BEAMOS) && logic->CanUse(RG_LONGSHOT));},
}},
{RR_SPIRIT_TEMPLE_OUTER_RIGHT_HAND, {5, 5, 3, 3,
[]{return logic->OuterWestHandLogic();},
[]{return logic->OuterWestHandLogic();},
[]{return logic->OuterWestHandLogic();},
}},
{RR_SPIRIT_TEMPLE_STATUE_ROOM_ADULT, {5, 0, 3, 0,
[]{return logic->SpiritExplosiveKeyLogic() && logic->CanUse(RG_HOOKSHOT) && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT));},
[]{return (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT)) && logic->HasItem(RG_POWER_BRACELET);},
[]{return logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS);},
}},
{RR_SPIRIT_TEMPLE_INNER_LEFT_HAND, {5, 0, 3, 0,
[]{return logic->SpiritExplosiveKeyLogic() && logic->CanUse(RG_HOOKSHOT) && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT));},
[]{return (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT)) && logic->HasItem(RG_POWER_BRACELET);},
[]{return logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS);},
}},
{RR_SPIRIT_TEMPLE_SHORTCUT_SWITCH, {5, 0, 3, 0,
[]{return logic->SpiritExplosiveKeyLogic() && logic->CanUse(RG_HOOKSHOT) && logic->SpiritEastToSwitch();},
[]{return logic->SpiritEastToSwitch() && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT)) && logic->HasItem(RG_POWER_BRACELET);},
[]{return logic->SpiritEastToSwitch() && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS));}}},
//MQ
{RR_SPIRIT_TEMPLE_MQ_UNDER_LIKE_LIKE, {7, 6, 7, 7,
[]{return logic->StatueRoomMQKeyLogic();},
[]{return logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 6) && logic->CanHitSwitch() && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT));},
[]{return logic->StatueRoomMQKeyLogic() && logic->CanHitSwitch() && ((logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT)) || logic->CanUse(RG_HOVER_BOOTS));},
}},
{RR_SPIRIT_TEMPLE_MQ_SUN_ON_FLOOR, {7, 6, 7, 7,
[]{return logic->StatueRoomMQKeyLogic() && logic->CanHitSwitch() && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT));},
[]{return logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 6) && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT));},
[]{return logic->StatueRoomMQKeyLogic() && ((logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT)) || logic->CanUse(RG_HOVER_BOOTS));},
}},
{RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM_CHILD, {7, 0, 0, 0,
[]{return logic->CanHitSwitch() && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT));},
[]{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT);},
[]{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS);},
}},
{RR_SPIRIT_TEMPLE_MQ_POT_LEDGE, {7, 0, 0, 0,
[]{return logic->CanHitSwitch() && logic->MQSpiritWestToPots() && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT));},
[]{return logic->MQSpiritWestToPots() && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT));},
[]{return logic->CanUse(RG_HOVER_BOOTS) || ((logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT)) && logic->MQSpiritWestToPots());},
}},
{RR_SPIRIT_TEMPLE_MQ_INNER_RIGHT_HAND, {7, 0, 0, 0,
[]{return logic->CanHitSwitch() && logic->MQSpiritWestToPots() && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT));},
[]{return logic->MQSpiritWestToPots() && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT));},
[]{return logic->CanUse(RG_HOVER_BOOTS) || ((logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT)) && logic->MQSpiritWestToPots());},
}},
{RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, {7, 0, 0, 0,
[]{return logic->CanHitSwitch() && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT));},
[]{return true;},
[]{return true;},
}},
{RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM, {7, 0, 0, 0,
[]{return logic->CanHitSwitch() && logic->MQSpiritStatueToSunBlock() && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT));},
[]{return logic->MQSpiritStatueToSunBlock() && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT));},
[]{return logic->MQSpiritStatueToSunBlock() && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS));},
}},
{RR_SPIRIT_TEMPLE_MQ_OUTER_RIGHT_HAND, {7, 7, 4, 4,
[]{return logic->CanHitSwitch() && logic->OuterWestHandMQLogic() && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT)) && logic->HasItem(RG_POWER_BRACELET);},
[]{return logic->OuterWestHandMQLogic();},
[]{return logic->OuterWestHandMQLogic();},
}},
{RR_SPIRIT_TEMPLE_MQ_BIG_BLOCKS_DOOR, {7, 0, 0, 0,
[]{return logic->CanHitSwitch() && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT)) && areaTable[RR_SPIRIT_TEMPLE_MQ_BIG_BLOCKS_DOOR].AnyAgeTime([]{return logic->MQSpiritStatueSouthDoor();});},
[]{return true;},
[]{return areaTable[RR_SPIRIT_TEMPLE_MQ_BIG_BLOCKS_DOOR].AnyAgeTime([]{return logic->MQSpiritStatueSouthDoor();});},
}},
};
// clang-format on
@@ -20,7 +20,7 @@ void RegionTable_Init_BottomOfTheWell() {
areaTable[RR_BOTW_CORRIDOR] = Region("Bottom of the Well Corridor", SCENE_BOTTOM_OF_THE_WELL, {}, {}, {
//Exits
Entrance(RR_BOTW_ENTRYWAY, []{return logic->CanUse(RG_CRAWL) /* && CanClimb*/;}),
Entrance(RR_BOTW_ENTRYWAY, []{return logic->CanUse(RG_CRAWL) && logic->HasItem(RG_CLIMB);}),
Entrance(RR_BOTW_PERIMETER, []{return logic->CanPassEnemy(RE_BIG_SKULLTULA);}),
});
@@ -48,8 +48,8 @@ void RegionTable_Init_BottomOfTheWell() {
Entrance(RR_BOTW_HIDDEN_POTS, []{return ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH);}),
Entrance(RR_BOTW_CORNER_CRAWLSPACE, []{return logic->CanUse(RG_CRAWL);}),
//Climb always needed in case water is lowered out of logic
Entrance(RR_BOTW_BEHIND_MOAT, []{return (logic->Get(LOGIC_BOTW_LOWERED_WATER) || logic->HasItem(RG_BRONZE_SCALE) ||
(logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT))/*CanClimb*/);}),
Entrance(RR_BOTW_BEHIND_MOAT, []{return ((logic->Get(LOGIC_BOTW_LOWERED_WATER) && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT))) || logic->HasItem(RG_BRONZE_SCALE) ||
(logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT)));}),
Entrance(RR_BOTW_NEAR_BOSS_LOWER, []{return logic->Get(LOGIC_BOTW_LOWERED_WATER) && logic->CanUse(RG_CRAWL);}),
//Falling down into basement requires nothing, but falling down somewhere specific requires lens or lens trick
//kinda questionable given several drops are blocked by rocks, but that's how it was handled before and on N64
@@ -148,7 +148,7 @@ void RegionTable_Init_BottomOfTheWell() {
//Exits
//Climb always needed in case water is lowered out of logic
Entrance(RR_BOTW_PERIMETER, []{return (logic->Get(LOGIC_BOTW_LOWERED_WATER) || logic->HasItem(RG_BRONZE_SCALE) ||
(logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT))/* && CanClimb()*/);}),
(logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT))) && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT));}),
Entrance(RR_BOTW_CRYPT, []{return true;}),
});
@@ -166,8 +166,8 @@ void RegionTable_Init_BottomOfTheWell() {
//Exits
//Climb always needed in case the water is lowered out of logic
//Adult can ground jump out of the pit without climb but needs a way through the crawlspace
Entrance(RR_BOTW_PERIMETER, []{return logic->CanUse(RG_CRAWL) && (logic->Get(LOGIC_BOTW_LOWERED_WATER) || logic->HasItem(RG_BRONZE_SCALE))/*&& CanClimb*/;}),
Entrance(RR_BOTW_NEAR_BOSS_UPPER, []{return true/*CanClimb or (isAdult && CanGroundJump)*/;}),
Entrance(RR_BOTW_PERIMETER, []{return logic->CanUse(RG_CRAWL) && (logic->Get(LOGIC_BOTW_LOWERED_WATER) || logic->HasItem(RG_BRONZE_SCALE)) && logic->HasItem(RG_CLIMB);}),
Entrance(RR_BOTW_NEAR_BOSS_UPPER, []{return logic->HasItem(RG_CLIMB) || (logic->IsAdult && logic->CanGroundJump());}),
});
areaTable[RR_BOTW_NEAR_BOSS_UPPER] = Region("Bottom of the Well Near Boss Upper", SCENE_BOTTOM_OF_THE_WELL, {}, {}, {
@@ -205,7 +205,7 @@ void RegionTable_Init_BottomOfTheWell() {
LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_GRASS_3, logic->CanCutShrubs()),
}, {
//Exits
Entrance(RR_BOTW_HIDDEN_POTS, []{return true/*CanClimbHigh()*/;}),
Entrance(RR_BOTW_HIDDEN_POTS, []{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT);}),
//It's possible to abuse boulder's limited range of collision detection to detonate the flowers through the boulder with bow, but this is a glitch
//the exact range is just past the furthest away plank in the green goo section
Entrance(RR_BOTW_B3_BOMB_FLOWERS, []{return AnyAgeTime([]{return logic->BlastOrSmash() || logic->CanUse(RG_DINS_FIRE) || (ctx->GetTrickOption(RT_BOTW_BASEMENT) && logic->CanUse(RG_STICKS)) || (ctx->GetTrickOption(RT_DISTANT_BOULDER_COLLISION) && logic->CanUse(RG_FAIRY_BOW));});}),
@@ -280,12 +280,12 @@ void RegionTable_Init_BottomOfTheWell() {
LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_BOMB_RIGHT_HEART, logic->HasExplosives()),
}, {
//Exits
Entrance(RR_BOTW_ENTRYWAY, []{return logic->CanUse(RG_CRAWL) /* && CanClimb()*/;}),
Entrance(RR_BOTW_ENTRYWAY, []{return logic->CanUse(RG_CRAWL) && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT));}),
Entrance(RR_BOTW_MQ_MIDDLE, []{return logic->Get(LOGIC_BOTW_MQ_OPENED_GATES);}),
Entrance(RR_BOTW_MQ_PIT_CAGE, []{return AnyAgeTime([]{return logic->BlastOrSmash();}) && logic->CanPassEnemy(RE_BIG_SKULLTULA);}),
//Climb always needed in case water is lowered out of logic
Entrance(RR_BOTW_MQ_BEHIND_MOAT, []{return (logic->Get(LOGIC_BOTW_LOWERED_WATER) || logic->HasItem(RG_BRONZE_SCALE) ||
(logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT))/*&& CanClimb()*/);}),
Entrance(RR_BOTW_MQ_BEHIND_MOAT, []{return (logic->Get(LOGIC_BOTW_LOWERED_WATER) && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT))) || logic->HasItem(RG_BRONZE_SCALE) ||
(logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT));}),
Entrance(RR_BOTW_MQ_CORNER_CRAWLSPACE, []{return logic->CanUse(RG_CRAWL);}),
Entrance(RR_BOTW_MQ_NEAR_BOSS_LOWER, []{return logic->CanUse(RG_CRAWL) && logic->Get(LOGIC_BOTW_LOWERED_WATER);}),
Entrance(RR_BOTW_MQ_B3, []{return true;}),
@@ -354,8 +354,8 @@ void RegionTable_Init_BottomOfTheWell() {
areaTable[RR_BOTW_MQ_BEHIND_MOAT] = Region("Bottom of the Well MQ Behind Moat", SCENE_BOTTOM_OF_THE_WELL, {}, {}, {
//Exits
//Climb always needed in case water is lowered out of logic
Entrance(RR_BOTW_MQ_PERIMETER, []{return (logic->Get(LOGIC_BOTW_LOWERED_WATER)|| logic->HasItem(RG_BRONZE_SCALE) ||
(logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT))/* && CanClimb*/);}),
Entrance(RR_BOTW_MQ_PERIMETER, []{return ((logic->Get(LOGIC_BOTW_LOWERED_WATER) || logic->HasItem(RG_BRONZE_SCALE)) && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT))) ||
(logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT));}),
Entrance(RR_BOTW_MQ_CRYPT, []{return logic->SmallKeys(SCENE_BOTTOM_OF_THE_WELL, 2);}),
});
@@ -391,8 +391,8 @@ void RegionTable_Init_BottomOfTheWell() {
//Exits
//Climb always needed in case the water is lowered out of logic
//Adult can ground jump out of the pit without climb but needs a way through the crawlspace
Entrance(RR_BOTW_MQ_PERIMETER, []{return logic->CanUse(RG_CRAWL) && (logic->Get(LOGIC_BOTW_LOWERED_WATER) || logic->HasItem(RG_BRONZE_SCALE))/*&& CanClimb*/;}),
Entrance(RR_BOTW_MQ_NEAR_BOSS_UPPER, []{return true/*CanClimb*/;}),
Entrance(RR_BOTW_MQ_PERIMETER, []{return logic->CanUse(RG_CRAWL) && (logic->Get(LOGIC_BOTW_LOWERED_WATER) || logic->HasItem(RG_BRONZE_SCALE)) && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT));}),
Entrance(RR_BOTW_MQ_NEAR_BOSS_UPPER, []{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT);}),
});
areaTable[RR_BOTW_MQ_NEAR_BOSS_UPPER] = Region("Bottom of the Well MQ Near Boss Upper", SCENE_BOTTOM_OF_THE_WELL, {}, {}, {
@@ -424,7 +424,7 @@ void RegionTable_Init_BottomOfTheWell() {
LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)),
}, {
//Exits
Entrance(RR_BOTW_MQ_PERIMETER, []{return true/*CanClimbHigh()*/;}),
Entrance(RR_BOTW_MQ_PERIMETER, []{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT);}),
});
areaTable[RR_BOTW_MQ_B3_PLATFORM] = Region("Bottom of the Well MQ B3 Platform", SCENE_BOTTOM_OF_THE_WELL, {}, {
@@ -18,13 +18,13 @@ void RegionTable_Init_DekuTree() {
areaTable[RR_DEKU_TREE_LOBBY] = Region("Deku Tree Lobby", SCENE_DEKU_TREE, {
//Events
EventAccess(LOGIC_STICK_ACCESS, []{return logic->CanGetDekuBabaSticks();}),
EventAccess(LOGIC_NUT_ACCESS, []{return logic->CanGetDekuBabaNuts();}),
EventAccess(LOGIC_STICK_ACCESS, []{return logic->CanGetDekuBabaSticks();}),
EventAccess(LOGIC_NUT_ACCESS, []{return logic->CanGetDekuBabaNuts();}),
EventAccess(LOGIC_DEKU_TREE_1F_BROKE_WEB, []{return logic->HasFireSource();}),
}, {
//Locations
LOCATION(RC_DEKU_TREE_MAP_CHEST, logic->HasItem(RG_OPEN_CHEST)),
LOCATION(RC_DEKU_TREE_LOBBY_LOWER_HEART, true),
LOCATION(RC_DEKU_TREE_LOBBY_UPPER_HEART, logic->CanPassEnemy(RE_BIG_SKULLTULA)),
LOCATION(RC_DEKU_TREE_LOBBY_LOWER_HEART, logic->CanUse(RG_BOOMERANG)),
LOCATION(RC_DEKU_TREE_LOBBY_GRASS_1, logic->CanCutShrubs()),
LOCATION(RC_DEKU_TREE_LOBBY_GRASS_2, logic->CanCutShrubs()),
LOCATION(RC_DEKU_TREE_LOBBY_GRASS_3, logic->CanCutShrubs()),
@@ -33,13 +33,35 @@ void RegionTable_Init_DekuTree() {
}, {
//Exits
Entrance(RR_DEKU_TREE_ENTRYWAY, []{return true;}),
Entrance(RR_DEKU_TREE_2F_MIDDLE_ROOM, []{return true;}),
Entrance(RR_DEKU_TREE_COMPASS_ROOM, []{return true;}),
Entrance(RR_DEKU_TREE_BASEMENT_LOWER, []{return AnyAgeTime([]{return logic->CanAttack() || logic->CanUse(RG_NUTS);});}),
Entrance(RR_DEKU_TREE_LOBBY_2F, []{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT);}),
Entrance(RR_DEKU_TREE_BASEMENT_LOWER, []{return logic->Get(LOGIC_DEKU_TREE_1F_BROKE_WEB);}),
Entrance(RR_DEKU_TREE_OUTSIDE_BOSS_ROOM, []{return false;}),
Entrance(RR_DEKU_TREE_BOSS_ENTRYWAY, []{return false;}),
});
areaTable[RR_DEKU_TREE_LOBBY_2F] = Region("Deku Tree Lobby 2F", SCENE_DEKU_TREE, {}, {
//Locations
LOCATION(RC_DEKU_TREE_MAP_CHEST, true),
LOCATION(RC_DEKU_TREE_LOBBY_LOWER_HEART, true),
}, {
//Exits
Entrance(RR_DEKU_TREE_LOBBY, []{return true;}),
Entrance(RR_DEKU_TREE_LOBBY_3F, []{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT);}), // precise hookshot atop chest can make it as adult
Entrance(RR_DEKU_TREE_2F_MIDDLE_ROOM, []{return true;}),
});
areaTable[RR_DEKU_TREE_LOBBY_3F] = Region("Deku Tree Lobby 3F", SCENE_DEKU_TREE, {
//Events
EventAccess(LOGIC_DEKU_TREE_1F_BROKE_WEB, []{return logic->CanPassEnemy(RE_BIG_SKULLTULA);}),
}, {
//Locations
LOCATION(RC_DEKU_TREE_LOBBY_UPPER_HEART, logic->CanPassEnemy(RE_BIG_SKULLTULA)),
}, {
//Exits
Entrance(RR_DEKU_TREE_LOBBY_2F, []{return true;}),
Entrance(RR_DEKU_TREE_COMPASS_ROOM, []{return true;}),
});
areaTable[RR_DEKU_TREE_2F_MIDDLE_ROOM] = Region("Deku Tree 2F Middle Room", SCENE_DEKU_TREE, {}, {}, {
//Exits
Entrance(RR_DEKU_TREE_LOBBY, []{return AnyAgeTime([]{return logic->CanReflectNuts() || logic->CanUse(RG_MEGATON_HAMMER);});}),
@@ -49,14 +71,14 @@ void RegionTable_Init_DekuTree() {
areaTable[RR_DEKU_TREE_SLINGSHOT_ROOM] = Region("Deku Tree Slingshot Room", SCENE_DEKU_TREE, {}, {
//Locations
LOCATION(RC_DEKU_TREE_SLINGSHOT_CHEST, logic->HasItem(RG_OPEN_CHEST)),
LOCATION(RC_DEKU_TREE_SLINGSHOT_ROOM_SIDE_CHEST, logic->HasItem(RG_OPEN_CHEST)),
LOCATION(RC_DEKU_TREE_SLINGSHOT_GRASS_1, logic->CanCutShrubs() && logic->CanReflectNuts()),
LOCATION(RC_DEKU_TREE_SLINGSHOT_GRASS_2, logic->CanCutShrubs() && logic->CanReflectNuts()),
LOCATION(RC_DEKU_TREE_SLINGSHOT_GRASS_3, logic->CanCutShrubs() && logic->CanReflectNuts()),
LOCATION(RC_DEKU_TREE_SLINGSHOT_GRASS_4, logic->CanCutShrubs() && logic->CanReflectNuts()),
LOCATION(RC_DEKU_TREE_SLINGSHOT_ROOM_SIDE_CHEST, (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT)) && logic->HasItem(RG_OPEN_CHEST)),
LOCATION(RC_DEKU_TREE_SLINGSHOT_GRASS_1, logic->CanCutShrubs()),
LOCATION(RC_DEKU_TREE_SLINGSHOT_GRASS_2, logic->CanCutShrubs()),
LOCATION(RC_DEKU_TREE_SLINGSHOT_GRASS_3, logic->CanCutShrubs()),
LOCATION(RC_DEKU_TREE_SLINGSHOT_GRASS_4, logic->CanCutShrubs()),
}, {
//Exits
Entrance(RR_DEKU_TREE_2F_MIDDLE_ROOM, []{return logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_HOVER_BOOTS);}),
Entrance(RR_DEKU_TREE_2F_MIDDLE_ROOM, []{return true;}),
});
areaTable[RR_DEKU_TREE_COMPASS_ROOM] = Region("Deku Tree Compass Room", SCENE_DEKU_TREE, {
@@ -86,12 +108,12 @@ void RegionTable_Init_DekuTree() {
//Locations
LOCATION(RC_DEKU_TREE_BASEMENT_CHEST, logic->HasItem(RG_OPEN_CHEST)),
LOCATION(RC_DEKU_TREE_GS_BASEMENT_GATE, logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_SHORT_JUMPSLASH)),
LOCATION(RC_DEKU_TREE_GS_BASEMENT_VINES, logic->CanKillEnemy(RE_GOLD_SKULLTULA, ctx->GetTrickOption(RT_DEKU_MQ_COMPASS_GS) ? ED_SHORT_JUMPSLASH : ED_BOMB_THROW)),
LOCATION(RC_DEKU_TREE_GS_BASEMENT_VINES, logic->CanKillEnemy(RE_GOLD_SKULLTULA, ctx->GetTrickOption(RT_DEKU_MQ_COMPASS_GS) ? ED_SHORT_JUMPSLASH : ED_BOMB_THROW) && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_BOOMERANG))),
LOCATION(RC_DEKU_TREE_BASEMENT_GRASS_1, logic->CanCutShrubs()),
LOCATION(RC_DEKU_TREE_BASEMENT_GRASS_2, logic->CanCutShrubs()),
}, {
//Exits
Entrance(RR_DEKU_TREE_LOBBY, []{return true;}),
Entrance(RR_DEKU_TREE_LOBBY, []{return logic->HasItem(RG_CLIMB) || (logic->IsAdult && logic->CanUse(RG_LONGSHOT));}),
Entrance(RR_DEKU_TREE_BASEMENT_SCRUB_ROOM, []{return AnyAgeTime([]{return logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW);});}),
Entrance(RR_DEKU_TREE_BASEMENT_UPPER, []{return logic->IsAdult || ctx->GetTrickOption(RT_DEKU_B1_SKIP) || logic->CanGroundJump() || logic->Get(LOGIC_DEKU_TREE_PUSHED_BASEMENT_BLOCK);}),
Entrance(RR_DEKU_TREE_OUTSIDE_BOSS_ROOM, []{return false;}),
@@ -187,7 +209,7 @@ void RegionTable_Init_DekuTree() {
LOCATION(RC_DEKU_TREE_BEFORE_BOSS_GRASS_3, logic->CanCutShrubs() && logic->HasFireSourceWithTorch()),
}, {
//Exits
Entrance(RR_DEKU_TREE_BASEMENT_UPPER, []{return logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_HOOKSHOT);}),
Entrance(RR_DEKU_TREE_BASEMENT_UPPER, []{return logic->HasItem(RG_CLIMB) && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_HOOKSHOT));}),
Entrance(RR_DEKU_TREE_BOSS_ENTRYWAY, []{return AnyAgeTime([]{return logic->CanReflectNuts();});}),
});
@@ -201,6 +223,7 @@ void RegionTable_Init_DekuTree() {
EventAccess(LOGIC_NUT_ACCESS, []{return logic->HasFireSource();}),
}, {
//Locations
LOCATION(RC_DEKU_TREE_MQ_LOBBY_HEART, logic->CanUse(RG_BOOMERANG)),
LOCATION(RC_DEKU_TREE_MQ_LOBBY_GRASS_1, logic->CanCutShrubs()),
LOCATION(RC_DEKU_TREE_MQ_LOBBY_GRASS_2, logic->CanCutShrubs()),
LOCATION(RC_DEKU_TREE_MQ_LOBBY_GRASS_3, logic->CanCutShrubs()),
@@ -210,10 +233,8 @@ void RegionTable_Init_DekuTree() {
//Exits
Entrance(RR_DEKU_TREE_ENTRYWAY, []{return true;}),
//may need canAvoid logic with enemy shuffle
Entrance(RR_DEKU_TREE_MQ_2F, []{return true;}),
//Swim is not required because you can jump with enough momentum to hit land.
//You even avoid fall damage if you hit the shallow water, though it's obscure knowledge so may be a trick
//if it is, then we need a landing room with (IsAdult || HasItem(RG_BRONZE_SCALE) || TakeDamage() || that trick) to reach basement
Entrance(RR_DEKU_TREE_MQ_2F, []{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT);}),
//Swim is not required because you can jump with enough momentum to hit land. You even avoid fall damage if you hit the shallow water.
Entrance(RR_DEKU_TREE_MQ_BASEMENT, []{return logic->Get(LOGIC_DEKU_TREE_1F_BROKE_WEB);}),
//is it possible to recoil from here to the ledge with a trick?
});
@@ -233,7 +254,7 @@ void RegionTable_Init_DekuTree() {
//Exits
Entrance(RR_DEKU_TREE_MQ_1F, []{return true;}),
//Will need canAvoid logic with enemy shuffle
Entrance(RR_DEKU_TREE_MQ_3F, []{return true;}),
Entrance(RR_DEKU_TREE_MQ_3F, []{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT);}), // precise hookshot atop chest can make it as adult
Entrance(RR_DEKU_TREE_MQ_EYE_TARGET_ROOM, []{return logic->Get(LOGIC_DEKU_TREE_MQ_2F_BURNED_WEB);}),
});
@@ -296,8 +317,8 @@ void RegionTable_Init_DekuTree() {
LOCATION(RC_DEKU_TREE_MQ_COMPASS_GRASS_4, logic->CanCutShrubs()),
}, {
//Exits
Entrance(RR_DEKU_TREE_MQ_EYE_TARGET_ROOM, []{return logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_HOVER_BOOTS);}),
Entrance(RR_DEKU_TREE_MQ_PAST_BOULDER_VINES, []{return AnyAgeTime([]{return logic->CanUse(RG_BOMBCHU_5) || (logic->CanUse(RG_BOMB_BAG) && (logic->CanUse(RG_SONG_OF_TIME) || logic->IsAdult || logic->CanUse(RG_HOVER_BOOTS))) || (logic->CanUse(RG_MEGATON_HAMMER) && (logic->CanUse(RG_SONG_OF_TIME) || ctx->GetTrickOption(RT_DEKU_MQ_COMPASS_GS)));});}),
Entrance(RR_DEKU_TREE_MQ_EYE_TARGET_ROOM, []{return true;}),
Entrance(RR_DEKU_TREE_MQ_PAST_BOULDER_VINES, []{return (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanUse(RG_SONG_OF_TIME))) && AnyAgeTime([]{return logic->CanUse(RG_BOMBCHU_5) || (logic->CanUse(RG_BOMB_BAG) && (logic->CanUse(RG_SONG_OF_TIME) || logic->IsAdult || logic->CanUse(RG_HOVER_BOOTS))) || (logic->CanUse(RG_MEGATON_HAMMER) && ((logic->IsAdult && logic->CanUse(RG_SONG_OF_TIME)) || (ctx->GetTrickOption(RT_DEKU_MQ_COMPASS_GS) && logic->HasItem(RG_CLIMB))));});}),
});
areaTable[RR_DEKU_TREE_MQ_PAST_BOULDER_VINES] = Region("Deku Tree MQ Past Boulder Vines", SCENE_DEKU_TREE, {}, {
@@ -323,7 +344,7 @@ void RegionTable_Init_DekuTree() {
LOCATION(RC_DEKU_TREE_MQ_BASEMENT_LOWER_GRASS_4, logic->CanCutShrubs()),
}, {
//Exits
Entrance(RR_DEKU_TREE_MQ_1F, []{return true;}),
Entrance(RR_DEKU_TREE_MQ_1F, []{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT);}),
Entrance(RR_DEKU_TREE_MQ_BASEMENT_SOUTHEAST_ROOM, []{return AnyAgeTime([]{return logic->CanHitEyeTargets();});}),
//includes RR_DEKU_TREE_MQ_BASEMENT_SOUTHEAST_ROOM Access, other fire sources clear directly from there
Entrance(RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_FRONT, []{return AnyAgeTime([]{return logic->CanHitEyeTargets();}) && logic->Get(LOGIC_DEKU_TREE_MQ_CLEARED_SE_ROOM) && AnyAgeTime([]{return logic->CanUse(RG_STICKS);});}),
@@ -382,7 +403,7 @@ void RegionTable_Init_DekuTree() {
//Locations
LOCATION(RC_DEKU_TREE_MQ_BASEMENT_LARVAE_GRASS_1, logic->CanCutShrubs()),
LOCATION(RC_DEKU_TREE_MQ_BASEMENT_LARVAE_GRASS_2, logic->CanCutShrubs()),
}, {
}, {
//Exits
//both imply CanKillEnemy(RE_GOHMA_LARVA)
Entrance(RR_DEKU_TREE_MQ_BASEMENT_GRAVE_ROOM, []{return AnyAgeTime([]{return logic->CanKillEnemy(RE_MAD_SCRUB) && logic->CanKillEnemy(RE_KEESE);});}),
@@ -449,7 +470,7 @@ void RegionTable_Init_DekuTree() {
LOCATION(RC_DEKU_TREE_MQ_BEFORE_BOSS_GRASS_3, logic->CanCutShrubs()),
}, {
//Exits
Entrance(RR_DEKU_TREE_MQ_BASEMENT_LEDGE, []{return logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_HOOKSHOT);}),
Entrance(RR_DEKU_TREE_MQ_BASEMENT_LEDGE, []{return logic->HasItem(RG_CLIMB) && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_HOOKSHOT));}),
Entrance(RR_DEKU_TREE_BOSS_ENTRYWAY, []{return AnyAgeTime([]{return logic->CanReflectNuts();});}),
});
@@ -134,7 +134,7 @@ void RegionTable_Init_DodongosCavern() {
areaTable[RR_DODONGOS_CAVERN_STAIRS_UPPER] = Region("Dodongos Cavern Stairs Upper", SCENE_DODONGOS_CAVERN, {}, {
//Locations
LOCATION(RC_DODONGOS_CAVERN_GS_ALCOVE_ABOVE_STAIRS, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, logic->Get(LOGIC_DC_LIFT_PLATFORM) ? ED_BOOMERANG : ED_LONGSHOT)),
LOCATION(RC_DODONGOS_CAVERN_GS_VINES_ABOVE_STAIRS, logic->HasItem(RG_POWER_BRACELET) || logic->CanKillEnemy(RE_GOLD_SKULLTULA, logic->IsAdult ? ED_LONG_JUMPSLASH : ED_BOMB_THROW)),
LOCATION(RC_DODONGOS_CAVERN_GS_VINES_ABOVE_STAIRS, (logic->HasItem(RG_CLIMB) && logic->HasItem(RG_POWER_BRACELET)) || logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)),
LOCATION(RC_DODONGOS_CAVERN_STAIRCASE_POT_1, logic->CanBreakPots()),
LOCATION(RC_DODONGOS_CAVERN_STAIRCASE_POT_2, logic->CanBreakPots()),
LOCATION(RC_DODONGOS_CAVERN_STAIRCASE_POT_3, logic->CanBreakPots()),
@@ -167,7 +167,7 @@ void RegionTable_Init_DodongosCavern() {
LOCATION(RC_DODONGOS_CAVERN_BLADE_GRASS, logic->CanCutShrubs()),
}, {
//Exits
Entrance(RR_DODONGOS_CAVERN_ARMOS_ROOM, []{return true;}),
Entrance(RR_DODONGOS_CAVERN_ARMOS_ROOM, []{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT);}),
Entrance(RR_DODONGOS_CAVERN_2F_SIDE_ROOM, []{return AnyAgeTime([]{return logic->CanBreakMudWalls() || (ctx->GetTrickOption(RT_DC_SCRUB_ROOM) && logic->HasItem(RG_GORONS_BRACELET));});}),
Entrance(RR_DODONGOS_CAVERN_FIRST_SLINGSHOT_ROOM, []{return AnyAgeTime([]{return logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET);});}),
Entrance(RR_DODONGOS_CAVERN_BOMB_ROOM_UPPER, []{return (logic->IsAdult && (ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS) || logic->CanGroundJump())) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives() && logic->CanJumpslash());}),
@@ -367,7 +367,7 @@ void RegionTable_Init_DodongosCavern() {
areaTable[RR_DODONGOS_CAVERN_MQ_STAIRS_UPPER] = Region("Dodongos Cavern MQ Stairs Upper", SCENE_DODONGOS_CAVERN, {
//Events
EventAccess(LOGIC_DC_MQ_STAIRS_SILVER_RUPEES, []{return true;}),
EventAccess(LOGIC_DC_MQ_STAIRS_SILVER_RUPEES, []{return logic->HasItem(RG_CLIMB);}),
}, {
//Locations
LOCATION(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE, logic->CanStunDeku() && GetCheckPrice() <= GetWalletCapacity()),
@@ -533,7 +533,7 @@ void RegionTable_Init_DodongosCavern() {
LOCATION(RC_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_6, logic->HasItem(RG_GORONS_BRACELET) || logic->CanBreakCrates()),
LOCATION(RC_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_7, logic->HasItem(RG_GORONS_BRACELET) || logic->CanBreakCrates()),
LOCATION(RC_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_8, logic->HasItem(RG_GORONS_BRACELET) || logic->CanBreakCrates()),
}, {
}, {
//Exits
Entrance(RR_DODONGOS_CAVERN_MQ_OUTSIDE_POES_ROOM, []{return AnyAgeTime([]{return logic->CanDetonateBombFlowers() || logic->HasItem(RG_GORONS_BRACELET);});}),
Entrance(RR_DODONGOS_CAVERN_MQ_LOWER_LIZALFOS, []{return true;}),
@@ -11,7 +11,7 @@ void RegionTable_Init_FireTemple() {
//Exits
Entrance(RR_FIRE_TEMPLE_FOYER, []{return ctx->GetDungeon(FIRE_TEMPLE)->IsVanilla();}),
Entrance(RR_FIRE_TEMPLE_MQ_FOYER_LOWER, []{return ctx->GetDungeon(FIRE_TEMPLE)->IsMQ();}),
Entrance(RR_DMC_CENTRAL_LOCAL, []{return true;}),
Entrance(RR_DMC_OUTSIDE_FIRE_TEMPLE, []{return true;}),
});
#pragma region Vanilla
@@ -143,7 +143,7 @@ void RegionTable_Init_FireTemple() {
areaTable[RR_FIRE_TEMPLE_LAVA_GEYSER_1F] = Region("Fire Temple Lava Geyser 1F", SCENE_FIRE_TEMPLE, {}, {}, {
//Exits
Entrance(RR_FIRE_TEMPLE_BIG_LAVA_ROOM, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 3);}),
Entrance(RR_FIRE_TEMPLE_LAVA_GEYSER_GRATE, []{return logic->FireTimer() >= 40/* && CanClimbHigh()*/;}),
Entrance(RR_FIRE_TEMPLE_LAVA_GEYSER_GRATE, []{return logic->FireTimer() >= 40 && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT));}),
Entrance(RR_FIRE_TEMPLE_LAVA_GEYSER_TORCH, []{return logic->CanUse(RG_LONGSHOT) && logic->FireTimer() >= 40;}),
});
@@ -176,7 +176,7 @@ void RegionTable_Init_FireTemple() {
//Exits
Entrance(RR_FIRE_TEMPLE_LAVA_GEYSER_1F, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 4);}),
Entrance(RR_FIRE_TEMPLE_SHORTCUT_CLIMB, []{return logic->Get(LOGIC_FIRE_OPENED_UPPER_SHORTCUT);}),
Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_LOWER, []{return logic->IsAdult && (((logic->HasItem(RG_GORONS_BRACELET) || ctx->GetTrickOption(RT_FIRE_STRENGTH))/*CanUse(RG_CLIMB)*/) || logic->CanGroundJump()) && logic->CanHitSwitch(ED_BOMB_THROW);}),
Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_LOWER, []{return logic->IsAdult && logic->HasItem(RG_CLIMB) && ((logic->HasItem(RG_GORONS_BRACELET) || ctx->GetTrickOption(RT_FIRE_STRENGTH)) || logic->CanGroundJump()) && logic->CanHitSwitch(ED_BOMB_THROW);}),
});
areaTable[RR_FIRE_TEMPLE_SHORTCUT_CLIMB] = Region("Fire Temple Shortcut Climb", SCENE_FIRE_TEMPLE, {
@@ -188,7 +188,7 @@ void RegionTable_Init_FireTemple() {
}, {
//Exits
Entrance(RR_FIRE_TEMPLE_SHORTCUT_ROOM, []{return true;}),
Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_UPPER, []{return true/*CanUse(RG_CLIMB)*/;}),
Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_UPPER, []{return logic->HasItem(RG_CLIMB);}),
});
areaTable[RR_FIRE_TEMPLE_BOULDER_MAZE_LOWER] = Region("Fire Temple Boulder Maze Lower", SCENE_FIRE_TEMPLE, {}, {
@@ -258,15 +258,18 @@ void RegionTable_Init_FireTemple() {
Entrance(RR_FIRE_TEMPLE_GS_CLIMB_4F, []{return logic->ReachScarecrow() || (ctx->GetTrickOption(RT_FIRE_SCARECROW) && logic->IsAdult && logic->CanUse(RG_LONGSHOT));}),
});
areaTable[RR_FIRE_TEMPLE_GS_CLIMB_4F] = Region("Fire Temple GS Climb 4F", SCENE_FIRE_TEMPLE, {}, {}, {
areaTable[RR_FIRE_TEMPLE_GS_CLIMB_4F] = Region("Fire Temple GS Climb 4F", SCENE_FIRE_TEMPLE, {}, {
//Locations
LOCATION(RC_FIRE_TEMPLE_GS_SCARECROW_CLIMB, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_LONGSHOT)),
}, {
//Exits
Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_UPPER, []{return true;}),
Entrance(RR_FIRE_TEMPLE_GS_CLIMB_5F, []{return true/*CanUse(RG_CLIMB)*/;}),
Entrance(RR_FIRE_TEMPLE_GS_CLIMB_5F, []{return logic->HasItem(RG_CLIMB);}),
});
areaTable[RR_FIRE_TEMPLE_GS_CLIMB_5F] = Region("Fire Temple GS Climb 5F", SCENE_FIRE_TEMPLE, {}, {
//Locations
LOCATION(RC_FIRE_TEMPLE_GS_SCARECROW_CLIMB, logic->CanKillEnemy(RE_GOLD_SKULLTULA, /*CanUse(RG_CLIMB) ?*/ED_SHORT_JUMPSLASH/*: ED_BOMB_THROW*/)),
LOCATION(RC_FIRE_TEMPLE_GS_SCARECROW_CLIMB, logic->CanKillEnemy(RE_GOLD_SKULLTULA, logic->HasItem(RG_CLIMB) ? ED_SHORT_JUMPSLASH : ED_BOMB_THROW)),
}, {
//Exits
Entrance(RR_FIRE_TEMPLE_GS_CLIMB_4F, []{return true;}),
@@ -384,7 +387,7 @@ void RegionTable_Init_FireTemple() {
areaTable[RR_FIRE_TEMPLE_SWITCH_CLIMB] = Region("Fire Temple Switch Climb", SCENE_FIRE_TEMPLE, {}, {}, {
//Exits
Entrance(RR_FIRE_TEMPLE_ABOVE_3F_FLARE_DANCER, []{return true;}),
Entrance(RR_FIRE_TEMPLE_NARROW_STAIRS, []{return logic->CanHitSwitch(ED_BOMB_THROW)/* && CanUse(RG_CLIMB)*/;}),
Entrance(RR_FIRE_TEMPLE_NARROW_STAIRS, []{return logic->CanHitSwitch(ED_BOMB_THROW) && logic->HasItem(RG_CLIMB);}),
});
areaTable[RR_FIRE_TEMPLE_NARROW_STAIRS] = Region("Fire Temple Narrow Stairs", SCENE_FIRE_TEMPLE, {}, {
@@ -630,15 +633,10 @@ void RegionTable_Init_FireTemple() {
Entrance(RR_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM, []{return true;}),
});
areaTable[RR_FIRE_TEMPLE_MQ_LAVA_GEYSER_1F] = Region("Fire Temple MQ Lava Geyser 1F", SCENE_FIRE_TEMPLE, {}, {
//Locations
LOCATION(RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_LEFT_HEART, true),
LOCATION(RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_RIGHT_HEART, true),
LOCATION(RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_LOWER_HEART, true),
}, {
areaTable[RR_FIRE_TEMPLE_MQ_LAVA_GEYSER_1F] = Region("Fire Temple MQ Lava Geyser 1F", SCENE_FIRE_TEMPLE, {}, {}, {
//Exits
Entrance(RR_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM, []{return true;}),
Entrance(RR_FIRE_TEMPLE_MQ_LAVA_GEYSER_GRATE, []{return logic->FireTimer() >= 40/* && CanClimbHigh()*/;}),
Entrance(RR_FIRE_TEMPLE_MQ_LAVA_GEYSER_GRATE, []{return logic->FireTimer() >= 40 && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT));}),
//this technically only reaches torch pillar, but the heart pillar can be reached from there with longshot
Entrance(RR_FIRE_TEMPLE_MQ_LAVA_GEYSER_PILLARS, []{return logic->FireTimer() >= 40 && logic->CanUse(RG_LONGSHOT);}),
});
@@ -658,6 +656,7 @@ void RegionTable_Init_FireTemple() {
areaTable[RR_FIRE_TEMPLE_MQ_LAVA_GEYSER_PILLARS] = Region("Fire Temple MQ Lava Geyser Pillars", SCENE_FIRE_TEMPLE, {}, {
//Locations
//rang can get the other 2 hearts from here but it's an awkward shot so a trick
//similarly rang from 1f can get this lower heart
LOCATION(RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_LOWER_HEART, true),
}, {
//Exits
@@ -678,8 +677,8 @@ void RegionTable_Init_FireTemple() {
areaTable[RR_FIRE_TEMPLE_MQ_SHORTCUT_ROOM_LOWER] = Region("Fire Temple MQ Shortcut Room Lower", SCENE_FIRE_TEMPLE, {}, {}, {
//Exits
Entrance(RR_FIRE_TEMPLE_MQ_SHORTCUT_ROOM_MID, []{return (logic->HasFireSource() && (logic->IsAdult || (logic->CanUse(RG_HOOKSHOT)/* && (CanUse(RG_CLIMB)*/))) ||
(ctx->GetTrickOption(RT_FIRE_MQ_CLIMB) && logic->CanUse(RG_HOVER_BOOTS)/*&& CanUse(RG_CLIMB)*/);}),
Entrance(RR_FIRE_TEMPLE_MQ_SHORTCUT_ROOM_MID, []{return (logic->HasFireSource() && (logic->IsAdult || (logic->CanUse(RG_HOOKSHOT) && logic->HasItem(RG_CLIMB)))) ||
(ctx->GetTrickOption(RT_FIRE_MQ_CLIMB) && logic->CanUse(RG_HOVER_BOOTS) && logic->HasItem(RG_CLIMB));}),
Entrance(RR_FIRE_TEMPLE_MQ_LAVA_GEYSER_2F, []{return true;}),
Entrance(RR_FIRE_TEMPLE_MQ_SHORTCUT_CAGE, []{return logic->Get(LOGIC_FIRE_OPENED_UPPER_SHORTCUT);}),
});
@@ -688,7 +687,7 @@ void RegionTable_Init_FireTemple() {
areaTable[RR_FIRE_TEMPLE_MQ_SHORTCUT_ROOM_MID] = Region("Fire Temple MQ Shortcut Room Middle", SCENE_FIRE_TEMPLE, {}, {}, {
//Exits
Entrance(RR_FIRE_TEMPLE_MQ_SHORTCUT_ROOM_LOWER, []{return true;}),
Entrance(RR_FIRE_TEMPLE_MQ_SHORTCUT_ROOM_3F, []{return true/*(logic->CanUse(RG_HOOKSHOT) || (CanUse(RG_CLIMB))*/;}),
Entrance(RR_FIRE_TEMPLE_MQ_SHORTCUT_ROOM_3F, []{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT);}),
});
areaTable[RR_FIRE_TEMPLE_MQ_SHORTCUT_ROOM_3F] = Region("Fire Temple MQ Shortcut Room 3F", SCENE_FIRE_TEMPLE, {}, {}, {
@@ -782,7 +781,7 @@ void RegionTable_Init_FireTemple() {
LOCATION(RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_6, logic->CanBreakCrates()),
}, {
//Exits
Entrance(RR_FIRE_TEMPLE_MQ_UPPER_LIZALFOS_MAZE, []{return true/*CanUse(RG_CLIMB)*/;}),
Entrance(RR_FIRE_TEMPLE_MQ_UPPER_LIZALFOS_MAZE, []{return logic->HasItem(RG_CLIMB);}),
Entrance(RR_FIRE_TEMPLE_MQ_SHORTCUT_CAGE, []{return logic->Get(LOGIC_FIRE_OPENED_UPPER_SHORTCUT);}),
});
@@ -801,7 +800,7 @@ void RegionTable_Init_FireTemple() {
}, {}, {
//Exits
Entrance(RR_FIRE_TEMPLE_MQ_ABOVE_MAZE, []{return true;}),
Entrance(RR_FIRE_TEMPLE_MQ_BURNING_BLOCK, []{return logic->CanUse(RG_HOOKSHOT)/*&& CanUse(RG_CLIMB)*/;}),
Entrance(RR_FIRE_TEMPLE_MQ_BURNING_BLOCK, []{return logic->CanUse(RG_HOOKSHOT) && logic->HasItem(RG_CLIMB);}),
});
areaTable[RR_FIRE_TEMPLE_MQ_BURNING_BLOCK] = Region("Fire Temple MQ Burning Block", SCENE_FIRE_TEMPLE, {}, {
@@ -996,7 +995,7 @@ void RegionTable_Init_FireTemple() {
areaTable[RR_FIRE_TEMPLE_MQ_LOCKED_CLIMB] = Region("Fire Temple MQ Locked Climb", SCENE_FIRE_TEMPLE, {}, {}, {
//Exits
Entrance(RR_FIRE_TEMPLE_MQ_3F_FLARE_DANCER, []{return true;}),
Entrance(RR_FIRE_TEMPLE_MQ_NARROW_STAIRS_ROOM, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 4)/* && CanUse(RG_CLIMB)*/;}),
Entrance(RR_FIRE_TEMPLE_MQ_NARROW_STAIRS_ROOM, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 4) && logic->HasItem(RG_CLIMB);}),
});
areaTable[RR_FIRE_TEMPLE_MQ_NARROW_STAIRS_ROOM] = Region("Fire Temple MQ Narrow Stairs Room", SCENE_FIRE_TEMPLE, {
@@ -20,8 +20,8 @@ void RegionTable_Init_ForestTemple() {
areaTable[RR_FOREST_TEMPLE_TREES] = Region("Forest Temple Trees", SCENE_FOREST_TEMPLE, {}, {
//Locations
LOCATION(RC_FOREST_TEMPLE_FIRST_ROOM_CHEST, logic->HasItem(RG_OPEN_CHEST)),
LOCATION(RC_FOREST_TEMPLE_GS_FIRST_ROOM, (logic->IsAdult && logic->CanUse(RG_BOMB_BAG)) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOMBCHU_5) || logic->CanUse(RG_DINS_FIRE) || (ctx->GetTrickOption(RT_FOREST_FIRST_GS) && (logic->CanJumpslashExceptHammer() || (logic->IsChild && logic->CanUse(RG_BOMB_BAG))))),
LOCATION(RC_FOREST_TEMPLE_FIRST_ROOM_CHEST, (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT)) && logic->HasItem(RG_OPEN_CHEST)),
LOCATION(RC_FOREST_TEMPLE_GS_FIRST_ROOM, (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT)) && ((logic->IsAdult && logic->CanUse(RG_BOMB_BAG)) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOMBCHU_5) || logic->CanUse(RG_DINS_FIRE) || (ctx->GetTrickOption(RT_FOREST_FIRST_GS) && (logic->CanJumpslashExceptHammer() || (logic->IsChild && logic->CanUse(RG_BOMB_BAG)))))),
}, {
//Exits
Entrance(RR_FOREST_TEMPLE_ENTRYWAY, []{return true;}),
@@ -95,12 +95,19 @@ void RegionTable_Init_ForestTemple() {
LOCATION(RC_FOREST_TEMPLE_COURTYARD_LEFT_HEART, logic->CanUse(RG_BOOMERANG) && ctx->GetTrickOption(RT_FOREST_COURTYARD_HEARTS_BOOMERANG)),
}, {
//Exits
Entrance(RR_FOREST_TEMPLE_LOBBY, []{return true;}),
Entrance(RR_FOREST_TEMPLE_NW_COURTYARD_UPPER, []{return logic->CanUse(RG_HOVER_BOOTS) && ((ctx->GetTrickOption(RT_HOVER_BOOST_SIMPLE) && (logic->CanUse(RG_MEGATON_HAMMER) || (ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives()))) || (ctx->GetTrickOption(RT_GROUND_JUMP_HARD) && logic->IsAdult && logic->CanGroundJump()));}),
Entrance(RR_FOREST_TEMPLE_LOBBY, []{return true;}),
Entrance(RR_FOREST_TEMPLE_NW_COURTYARD_UPPER, []{return (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_HOVER_BOOTS) && ((ctx->GetTrickOption(RT_HOVER_BOOST_SIMPLE) && (ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives())) || (ctx->GetTrickOption(RT_GROUND_JUMP_HARD) && logic->IsAdult && logic->CanGroundJump()));}),
Entrance(RR_FOREST_TEMPLE_NW_COURTYARD_UPPER_ALCOVE, []{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT);}),
Entrance(RR_FOREST_TEMPLE_SEWER, []{return logic->HasItem(RG_GOLDEN_SCALE) || logic->CanUse(RG_IRON_BOOTS);}),
Entrance(RR_FOREST_TEMPLE_DRAINED_SEWER, []{return logic->Get(LOGIC_FOREST_DRAINED_WELL);}),
Entrance(RR_FOREST_TEMPLE_BOSS_ENTRYWAY, []{return false;}),
});
areaTable[RR_FOREST_TEMPLE_NW_COURTYARD_UPPER_ALCOVE] = Region("Forest Temple NW Courtyard Upper Alcove", SCENE_FOREST_TEMPLE, {}, {}, {
//Exits
Entrance(RR_FOREST_TEMPLE_NW_COURTYARD_LOWER, []{return true;}),
Entrance(RR_FOREST_TEMPLE_MAP_ROOM, []{return true;}),
Entrance(RR_FOREST_TEMPLE_SEWER, []{return logic->HasItem(RG_GOLDEN_SCALE) || logic->CanUse(RG_IRON_BOOTS);}),
Entrance(RR_FOREST_TEMPLE_DRAINED_SEWER, []{return logic->Get(LOGIC_FOREST_DRAINED_WELL);}),
Entrance(RR_FOREST_TEMPLE_BOSS_ENTRYWAY, []{return false;}),
Entrance(RR_FOREST_TEMPLE_NW_COURTYARD_UPPER, []{return ctx->GetTrickOption(RT_HOVER_BOOST_SIMPLE) && logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_MEGATON_HAMMER);}),
});
areaTable[RR_FOREST_TEMPLE_NW_COURTYARD_UPPER] = Region("Forest Temple NW Courtyard Upper", SCENE_FOREST_TEMPLE, {
@@ -126,11 +133,11 @@ void RegionTable_Init_ForestTemple() {
EventAccess(LOGIC_NUT_ACCESS, []{return logic->CanGetDekuBabaNuts();}),
}, {
//Locations
LOCATION(RC_FOREST_TEMPLE_GS_RAISED_ISLAND_COURTYARD, logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_FOREST_COURTYARD_EAST_GS) && logic->CanUse(RG_BOOMERANG))),
LOCATION(RC_FOREST_TEMPLE_GS_RAISED_ISLAND_COURTYARD, logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_FOREST_COURTYARD_EAST_GS) && logic->CanUse(RG_BOOMERANG))),
}, {
//Exits
Entrance(RR_FOREST_TEMPLE_LOBBY, []{return true;}),
Entrance(RR_FOREST_TEMPLE_NE_COURTYARD_UPPER, []{return logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_FOREST_VINES) && logic->CanUse(RG_HOOKSHOT));}),
Entrance(RR_FOREST_TEMPLE_NE_COURTYARD_UPPER, []{return logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_FOREST_VINES) && logic->CanUse(RG_HOOKSHOT) && logic->HasItem(RG_CLIMB));}),
Entrance(RR_FOREST_TEMPLE_NE_COURTYARD_ISLAND, []{return logic->CanUse(RG_HOOKSHOT);}),
Entrance(RR_FOREST_TEMPLE_SEWER, []{return (((logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_FOREST_WELL_SWIM) && logic->CanUse(RG_HOOKSHOT))) && logic->HasItem(RG_BRONZE_SCALE)) || logic->HasItem(RG_GOLDEN_SCALE)) && logic->WaterTimer() >= 16;}),
Entrance(RR_FOREST_TEMPLE_DRAINED_SEWER, []{return logic->Get(LOGIC_FOREST_DRAINED_WELL);}),
@@ -206,8 +213,8 @@ void RegionTable_Init_ForestTemple() {
LOCATION(RC_FOREST_TEMPLE_WELL_EAST_HEART, true),
}, {
//Exits
Entrance(RR_FOREST_TEMPLE_NW_COURTYARD_LOWER, []{return true;}),
Entrance(RR_FOREST_TEMPLE_NE_COURTYARD_LOWER, []{return true;}),
Entrance(RR_FOREST_TEMPLE_NW_COURTYARD_LOWER, []{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT);}),
Entrance(RR_FOREST_TEMPLE_NE_COURTYARD_LOWER, []{return logic->HasItem(RG_CLIMB);}),
});
areaTable[RR_FOREST_TEMPLE_BELOW_BOSS_KEY_CHEST] = Region("Forest Temple Below Boss Key Chest", SCENE_FOREST_TEMPLE, {}, {}, {
@@ -231,14 +238,21 @@ void RegionTable_Init_ForestTemple() {
areaTable[RR_FOREST_TEMPLE_RED_DOORMAT_HALLWAY_DOORMAT] = Region("Forest Temple West Hallway Doormat", SCENE_FOREST_TEMPLE, {}, {}, {
//Exits
Entrance(RR_FOREST_TEMPLE_RED_DOORMAT_HALLWAY, []{return logic->CanPassEnemy(RE_BIG_SKULLTULA);}),
Entrance(RR_FOREST_TEMPLE_LOWER_BLOCK_PUSH_ROOM, []{return true;}),
Entrance(RR_FOREST_TEMPLE_RED_DOORMAT_HALLWAY, []{return logic->CanPassEnemy(RE_BIG_SKULLTULA);}),
Entrance(RR_FOREST_TEMPLE_BLOCK_PUSH_FLOOR, []{return true;}),
});
areaTable[RR_FOREST_TEMPLE_BLOCK_PUSH_FLOOR] = Region("Forest Temple Lower Block Push Floor", SCENE_FOREST_TEMPLE, {}, {}, {
//Exits
Entrance(RR_FOREST_TEMPLE_RED_DOORMAT_HALLWAY_DOORMAT, []{return true;}),
Entrance(RR_FOREST_TEMPLE_LOWER_BLOCK_PUSH_ROOM, []{return logic->HasItem(RG_CLIMB) || (logic->IsAdult && logic->CanGroundJump());}),
});
areaTable[RR_FOREST_TEMPLE_LOWER_BLOCK_PUSH_ROOM] = Region("Forest Temple Lower Block Push Room", SCENE_FOREST_TEMPLE, {}, {}, {
//Exits
Entrance(RR_FOREST_TEMPLE_RED_DOORMAT_HALLWAY_DOORMAT, []{return true;}),
Entrance(RR_FOREST_TEMPLE_MIDDLE_BLOCK_PUSH_ROOM, []{return logic->HasItem(RG_GORONS_BRACELET);}),
Entrance(RR_FOREST_TEMPLE_BLOCK_PUSH_FLOOR, []{return true;}),
Entrance(RR_FOREST_TEMPLE_MIDDLE_BLOCK_PUSH_ROOM, []{return logic->HasItem(RG_CLIMB) && logic->HasItem(RG_GORONS_BRACELET);}),
Entrance(RR_FOREST_TEMPLE_UPPER_BLOCK_PUSH_ROOM, []{return logic->IsAdult && logic->CanGroundJump() && logic->HasItem(RG_GORONS_BRACELET) && logic->CanUse(RG_HOVER_BOOTS);}),
Entrance(RR_FOREST_TEMPLE_BLOCK_PUSH_ROOM_COURTYARD_ALCOVE, []{return logic->CanUse(RG_HOVER_BOOTS);}),
});
@@ -254,7 +268,13 @@ void RegionTable_Init_ForestTemple() {
areaTable[RR_FOREST_TEMPLE_UPPER_BLOCK_PUSH_ROOM] = Region("Forest Temple Upper Block Push Room", SCENE_FOREST_TEMPLE, {}, {}, {
//Exits
Entrance(RR_FOREST_TEMPLE_MIDDLE_BLOCK_PUSH_ROOM, []{return true;}),
Entrance(RR_FOREST_TEMPLE_MIDDLE_BLOCK_PUSH_ROOM, []{return true;}),
Entrance(RR_FOREST_TEMPLE_BLOCK_PUSH_ROOM_TOP, []{return logic->HasItem(RG_CLIMB);}),
});
areaTable[RR_FOREST_TEMPLE_BLOCK_PUSH_ROOM_TOP] = Region("Forest Temple Block Push Room Top", SCENE_FOREST_TEMPLE, {}, {}, {
//Exits
Entrance(RR_FOREST_TEMPLE_UPPER_BLOCK_PUSH_ROOM, []{return true;}),
Entrance(RR_FOREST_TEMPLE_NW_HALLWAY_TWISTED, []{return logic->SmallKeys(SCENE_FOREST_TEMPLE, 2);}),
Entrance(RR_FOREST_TEMPLE_NW_HALLWAY_STRAIGHTENED, []{return logic->CanHitEyeTargets() && logic->SmallKeys(SCENE_FOREST_TEMPLE, 2);}),
});
@@ -267,8 +287,8 @@ void RegionTable_Init_ForestTemple() {
areaTable[RR_FOREST_TEMPLE_NW_HALLWAY_TWISTED] = Region("Forest Temple NW Hallway Twisted", SCENE_FOREST_TEMPLE, {}, {}, {
//Exits
Entrance(RR_FOREST_TEMPLE_UPPER_BLOCK_PUSH_ROOM, []{return logic->SmallKeys(SCENE_FOREST_TEMPLE, 2);}),
Entrance(RR_FOREST_TEMPLE_RED_POE_ROOM, []{return logic->SmallKeys(SCENE_FOREST_TEMPLE, 3);}),
Entrance(RR_FOREST_TEMPLE_BLOCK_PUSH_ROOM_TOP, []{return logic->SmallKeys(SCENE_FOREST_TEMPLE, 2);}),
Entrance(RR_FOREST_TEMPLE_RED_POE_ROOM, []{return logic->SmallKeys(SCENE_FOREST_TEMPLE, 3);}),
});
areaTable[RR_FOREST_TEMPLE_NW_HALLWAY_STRAIGHTENED] = Region("Forest Temple NW Hallway Straightened", SCENE_FOREST_TEMPLE, {}, {
@@ -276,8 +296,8 @@ void RegionTable_Init_ForestTemple() {
LOCATION(RC_FOREST_TEMPLE_BOSS_KEY_CHEST, logic->HasItem(RG_OPEN_CHEST)),
}, {
//Exits
Entrance(RR_FOREST_TEMPLE_BELOW_BOSS_KEY_CHEST, []{return true;}),
Entrance(RR_FOREST_TEMPLE_UPPER_BLOCK_PUSH_ROOM, []{return logic->SmallKeys(SCENE_FOREST_TEMPLE, 2);}),
Entrance(RR_FOREST_TEMPLE_BELOW_BOSS_KEY_CHEST, []{return true;}),
Entrance(RR_FOREST_TEMPLE_BLOCK_PUSH_ROOM_TOP, []{return logic->SmallKeys(SCENE_FOREST_TEMPLE, 2);}),
});
areaTable[RR_FOREST_TEMPLE_RED_POE_ROOM] = Region("Forest Temple Red Poe Room", SCENE_FOREST_TEMPLE, {
@@ -399,7 +419,7 @@ void RegionTable_Init_ForestTemple() {
areaTable[RR_FOREST_TEMPLE_MQ_TREES] = Region("Forest Temple MQ Trees", SCENE_FOREST_TEMPLE, {}, {
//Locations
LOCATION(RC_FOREST_TEMPLE_MQ_FIRST_ROOM_CHEST, (logic->CanPassEnemy(RE_BIG_SKULLTULA, ED_SHORT_JUMPSLASH, false) || logic->CanUse(RG_HOVER_BOOTS)) && logic->HasItem(RG_OPEN_CHEST)),
LOCATION(RC_FOREST_TEMPLE_MQ_FIRST_ROOM_CHEST, (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT)) && (logic->CanPassEnemy(RE_BIG_SKULLTULA, ED_SHORT_JUMPSLASH, false) || logic->CanUse(RG_HOVER_BOOTS)) && logic->HasItem(RG_OPEN_CHEST)),
}, {
//Exits
Entrance(RR_FOREST_TEMPLE_ENTRYWAY, []{return true;}),
@@ -467,45 +487,73 @@ void RegionTable_Init_ForestTemple() {
areaTable[RR_FOREST_TEMPLE_MQ_RED_DOORMAT_HALLWAY] = Region("Forest Temple MQ Red Doormat Hallway", SCENE_FOREST_TEMPLE, {}, {}, {
//Exits
Entrance(RR_FOREST_TEMPLE_MQ_LOBBY, []{return AnyAgeTime([]{return logic->CanKillEnemy(RE_STALFOS);});}),
Entrance(RR_FOREST_TEMPLE_MQ_LOWER_BLOCK_PUZZLE, []{return AnyAgeTime([]{return logic->CanKillEnemy(RE_STALFOS);});}),
Entrance(RR_FOREST_TEMPLE_MQ_BLOCK_PUZZLE_FLOOR, []{return AnyAgeTime([]{return logic->CanKillEnemy(RE_STALFOS);});}),
});
areaTable[RR_FOREST_TEMPLE_MQ_LOWER_BLOCK_PUZZLE] = Region("Forest Temple MQ Lower Block Puzzle", SCENE_FOREST_TEMPLE, {
//longshot is capable of hitting the switch, but some invisible collision makes the shot harder than you would think, so it may be trickworthy
areaTable[RR_FOREST_TEMPLE_MQ_BLOCK_PUZZLE_FLOOR] = Region("Forest Temple MQ Block Puzzle Floor", SCENE_FOREST_TEMPLE, {
//Events
EventAccess(LOGIC_FOREST_MQ_BLOCK_ROOM_TARGETS, []{return (ctx->GetTrickOption(RT_FOREST_MQ_BLOCK_PUZZLE) && logic->CanUse(RG_BOMBCHU_5));}),
//It is barely possible to get this as child with master + hovers, but it's tight without bunny speed
EventAccess(LOGIC_FOREST_CAN_TWIST_HALLWAY, []{return (ctx->GetTrickOption(RT_FOREST_MQ_JS_HALLWAY_SWITCH) && logic->CanUse(RG_HOVER_BOOTS) && (logic->IsAdult && logic->CanJumpslash()) || (logic->CanUse(RG_STICKS) || logic->CanUse(RG_BIGGORON_SWORD) || (logic->Get(LOGIC_FOREST_MQ_BLOCK_ROOM_TARGETS) && logic->CanUse(RG_MASTER_SWORD)))) || (ctx->GetTrickOption(RT_FOREST_MQ_RANG_HALLWAY_SWITCH) && logic->CanUse(RG_BOOMERANG)) || (ctx->GetTrickOption(RT_FOREST_MQ_HOOKSHOT_HALLWAY_SWITCH) && logic->CanUse(RG_HOOKSHOT));}),
EventAccess(LOGIC_FOREST_CAN_TWIST_HALLWAY, []{return (ctx->GetTrickOption(RT_FOREST_MQ_RANG_HALLWAY_SWITCH) && logic->CanUse(RG_BOOMERANG)) || (ctx->GetTrickOption(RT_FOREST_MQ_HOOKSHOT_HALLWAY_SWITCH) && logic->CanUse(RG_HOOKSHOT));}),
}, {
//Locations
LOCATION(RC_FOREST_TEMPLE_MQ_GS_BLOCK_PUSH_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)),
}, {
//Exits
Entrance(RR_FOREST_TEMPLE_MQ_RED_DOORMAT_HALLWAY, []{return AnyAgeTime([]{return logic->CanKillEnemy(RE_STALFOS);});}),
Entrance(RR_FOREST_TEMPLE_MQ_MIDDLE_BLOCK_PUZZLE, []{return logic->HasItem(RG_GORONS_BRACELET) || (logic->Get(LOGIC_FOREST_MQ_BLOCK_ROOM_TARGETS) && logic->CanUse(RG_HOOKSHOT));}),
Entrance(RR_FOREST_TEMPLE_MQ_INDOOR_LEDGE, []{return logic->Get(LOGIC_FOREST_CAN_TWIST_HALLWAY) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS));}),
Entrance(RR_FOREST_TEMPLE_MQ_RED_DOORMAT_HALLWAY, []{return true;}),
Entrance(RR_FOREST_TEMPLE_MQ_LOWER_BLOCK_PUZZLE, []{return ((logic->HasItem(RG_CLIMB) || (logic->IsAdult && logic->CanGroundJump())) &&
(logic->HasItem(RG_GORONS_BRACELET) || logic->CanUse(RG_HOVER_BOOTS))) ||
(logic->Get(LOGIC_FOREST_MQ_BLOCK_ROOM_TARGETS) && logic->CanUse(RG_HOOKSHOT));}),
Entrance(RR_FOREST_TEMPLE_MQ_INDOOR_LEDGE, []{return logic->Get(LOGIC_FOREST_CAN_TWIST_HALLWAY) && logic->CanUse(RG_HOOKSHOT);}),
});
areaTable[RR_FOREST_TEMPLE_MQ_LOWER_BLOCK_PUZZLE] = Region("Forest Temple MQ Lower Block Puzzle", SCENE_FOREST_TEMPLE, {
//Events
//It is barely possible to get this as child with master + hovers, but it's tight without bunny speed
EventAccess(LOGIC_FOREST_CAN_TWIST_HALLWAY, []{return (ctx->GetTrickOption(RT_FOREST_MQ_JS_HALLWAY_SWITCH) && logic->CanUse(RG_HOVER_BOOTS) &&
(logic->IsAdult && logic->CanJumpslash()) ||
(logic->CanUse(RG_STICKS) || logic->CanUse(RG_BIGGORON_SWORD) || (logic->Get(LOGIC_FOREST_MQ_BLOCK_ROOM_TARGETS) && logic->CanUse(RG_MASTER_SWORD))));}),
}, {}, {
//Exits
Entrance(RR_FOREST_TEMPLE_MQ_BLOCK_PUZZLE_FLOOR, []{return true;}),
Entrance(RR_FOREST_TEMPLE_MQ_MIDDLE_BLOCK_PUZZLE, []{return (logic->HasItem(RG_GORONS_BRACELET) && (logic->HasItem(RG_CLIMB) || (logic->IsAdult && logic->CanGroundJump()))) ||
logic->Get(LOGIC_FOREST_MQ_BLOCK_ROOM_TARGETS);}),
Entrance(RR_FOREST_TEMPLE_MQ_INDOOR_LEDGE, []{return logic->Get(LOGIC_FOREST_CAN_TWIST_HALLWAY) && logic->CanUse(RG_HOVER_BOOTS);}),
});
areaTable[RR_FOREST_TEMPLE_MQ_MIDDLE_BLOCK_PUZZLE] = Region("Forest Temple MQ Middle Block Puzzle", SCENE_FOREST_TEMPLE, {
//longshot is capable of hitting the switch, but some invisible collision makes the shot more annoying than you would think, so it may be trickworthy
//Events
EventAccess(LOGIC_FOREST_MQ_BLOCK_ROOM_TARGETS, []{return (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_LONGSHOT));}),
EventAccess(LOGIC_FOREST_CAN_TWIST_HALLWAY, []{return ctx->GetTrickOption(RT_FOREST_MQ_JS_HALLWAY_SWITCH) && (logic->IsAdult && logic->CanJumpslash()) || (logic->CanUse(RG_HOVER_BOOTS) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MASTER_SWORD)));}),
EventAccess(LOGIC_FOREST_CAN_TWIST_HALLWAY, []{return ctx->GetTrickOption(RT_FOREST_MQ_JS_HALLWAY_SWITCH) &&
(logic->IsAdult && logic->CanJumpslash()) ||
(logic->CanUse(RG_HOVER_BOOTS) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MASTER_SWORD)));}),
}, {}, {
//Exits
Entrance(RR_FOREST_TEMPLE_MQ_LOWER_BLOCK_PUZZLE, []{return true;}),
Entrance(RR_FOREST_TEMPLE_MQ_UPPER_BLOCK_PUZZLE, []{return (logic->IsAdult && logic->HasItem(RG_GORONS_BRACELET)) || (logic->Get(LOGIC_FOREST_MQ_BLOCK_ROOM_TARGETS) && logic->CanUse(RG_HOOKSHOT));}),
Entrance(RR_FOREST_TEMPLE_MQ_UPPER_BLOCK_PUZZLE, []{return (logic->IsAdult && logic->HasItem(RG_GORONS_BRACELET)) ||
(logic->Get(LOGIC_FOREST_MQ_BLOCK_ROOM_TARGETS) && logic->CanUse(RG_HOOKSHOT));}),
//Hammer cannot recoil from here, but can make the jump forwards with a hammer jumpslash as adult
Entrance(RR_FOREST_TEMPLE_MQ_INDOOR_LEDGE, []{return logic->Get(LOGIC_FOREST_CAN_TWIST_HALLWAY) && logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_FOREST_OUTSIDE_BACKDOOR) && (logic->CanJumpslashExceptHammer() || (logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER))));}),
Entrance(RR_FOREST_TEMPLE_MQ_INDOOR_LEDGE, []{return logic->Get(LOGIC_FOREST_CAN_TWIST_HALLWAY) && logic->CanUse(RG_HOVER_BOOTS) ||
(ctx->GetTrickOption(RT_FOREST_OUTSIDE_BACKDOOR) && (logic->CanJumpslashExceptHammer() || (logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER))));}),
});
areaTable[RR_FOREST_TEMPLE_MQ_UPPER_BLOCK_PUZZLE] = Region("Forest Temple MQ After Block Puzzle", SCENE_FOREST_TEMPLE, {}, {}, {
areaTable[RR_FOREST_TEMPLE_MQ_UPPER_BLOCK_PUZZLE] = Region("Forest Temple MQ Upper Block Puzzle", SCENE_FOREST_TEMPLE, {
//Events
EventAccess(LOGIC_FOREST_MQ_BLOCK_ROOM_TARGETS, []{return logic->CanHitSwitch();}),
}, {}, {
//Exits
Entrance(RR_FOREST_TEMPLE_MQ_MIDDLE_BLOCK_PUZZLE, []{return true;}),
Entrance(RR_FOREST_TEMPLE_MQ_STRAIGHT_HALLWAY, []{return logic->SmallKeys(SCENE_FOREST_TEMPLE, 3);}),
Entrance(RR_FOREST_TEMPLE_MQ_JOELLE_ROOM, []{return logic->Get(LOGIC_FOREST_CAN_TWIST_HALLWAY) && logic->SmallKeys(SCENE_FOREST_TEMPLE, 4);}),
Entrance(RR_FOREST_TEMPLE_MQ_BLOCK_PUZZLE_TOP, []{return logic->HasItem(RG_CLIMB);}),
});
areaTable[RR_FOREST_TEMPLE_MQ_BLOCK_PUZZLE_TOP] = Region("Forest Temple MQ Block Puzzle Top", SCENE_FOREST_TEMPLE, {}, {}, {
//Exits
Entrance(RR_FOREST_TEMPLE_MQ_UPPER_BLOCK_PUZZLE, []{return true;}),
Entrance(RR_FOREST_TEMPLE_MQ_STRAIGHT_HALLWAY, []{return logic->SmallKeys(SCENE_FOREST_TEMPLE, 3);}),
Entrance(RR_FOREST_TEMPLE_MQ_JOELLE_ROOM, []{return logic->Get(LOGIC_FOREST_CAN_TWIST_HALLWAY) && logic->SmallKeys(SCENE_FOREST_TEMPLE, 4);}),
//!QUANTUM LOGIC!
//As there is no way in default logic to reach the other possible key use without going through RR_FOREST_TEMPLE_MQ_NW_COURTYARD, this is logically safe for now
//Breaks if there's any other way to RR_FOREST_TEMPLE_MQ_FALLING_ROOM than going through the eye targets in RR_FOREST_TEMPLE_MQ_LOBBY
//Requires a bow/sling ammo source once ammo logic is done, to avoid edge cases.
Entrance(RR_FOREST_TEMPLE_MQ_NW_COURTYARD, []{return logic->SmallKeys(SCENE_FOREST_TEMPLE, 2) && AnyAgeTime([]{return logic->CanKillEnemy(RE_FLOORMASTER);});}),
});
@@ -538,10 +586,11 @@ void RegionTable_Init_ForestTemple() {
LOCATION(RC_FOREST_TEMPLE_MQ_COURTYARD_LEFT_HEART, true),
}, {
//Exits
Entrance(RR_FOREST_TEMPLE_MQ_INDOOR_LEDGE, []{return true;}),
Entrance(RR_FOREST_TEMPLE_MQ_NW_COURTYARD, []{return true;}),
Entrance(RR_FOREST_TEMPLE_MQ_REDEAD_ROOM, []{return true;}),
Entrance(RR_FOREST_TEMPLE_MQ_FLOORMASTER_ROOM, []{return true;}),
Entrance(RR_FOREST_TEMPLE_MQ_INDOOR_LEDGE, []{return true;}),
Entrance(RR_FOREST_TEMPLE_MQ_NW_COURTYARD, []{return true;}),
Entrance(RR_FOREST_TEMPLE_MQ_NW_COURTYARD_WELL_LEDGE, []{return logic->CanUse(RG_HOVER_BOOTS);}),
Entrance(RR_FOREST_TEMPLE_MQ_REDEAD_ROOM, []{return true;}),
Entrance(RR_FOREST_TEMPLE_MQ_FLOORMASTER_ROOM, []{return true;}),
});
areaTable[RR_FOREST_TEMPLE_MQ_REDEAD_ROOM] = Region("Forest Temple MQ Redead Room", SCENE_FOREST_TEMPLE, {}, {
@@ -557,7 +606,6 @@ void RegionTable_Init_ForestTemple() {
EventAccess(LOGIC_FOREST_MQ_BURNED_WEB, []{return logic->CanUse(RG_FIRE_ARROWS);}),
}, {
//Locations
LOCATION(RC_FOREST_TEMPLE_MQ_GS_LEVEL_ISLAND_COURTYARD, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)),
//the well checks are considered from both areas instead of being a region because the draining is a temp flag and the skull (as well as the chest with hook glitch) has different breath timers from each side
LOCATION(RC_FOREST_TEMPLE_MQ_GS_WELL, (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8 && logic->CanUse(RG_HOOKSHOT))),
LOCATION(RC_FOREST_TEMPLE_MQ_COURTYARD_RIGHT_HEART, logic->CanUse(RG_BOOMERANG) && ctx->GetTrickOption(RT_FOREST_COURTYARD_HEARTS_BOOMERANG)),
@@ -568,9 +616,18 @@ void RegionTable_Init_ForestTemple() {
LOCATION(RC_FOREST_TEMPLE_MQ_WELL_EAST_HEART, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8),
}, {
//Exits
Entrance(RR_FOREST_TEMPLE_MQ_NE_COURTYARD, []{return logic->Get(LOGIC_FOREST_DRAINED_WELL) || ((((logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_FOREST_WELL_SWIM) && logic->CanUse(RG_HOOKSHOT))) && logic->HasItem(RG_BRONZE_SCALE)) || logic->HasItem(RG_GOLDEN_SCALE)) && logic->WaterTimer() >= 16);}),
Entrance(RR_FOREST_TEMPLE_MQ_NW_COURTYARD_UPPER_ALCOVE, []{return logic->Get(LOGIC_FOREST_MQ_BURNED_WEB) && (logic->CanKillEnemy(RE_BIG_SKULLTULA, ED_LONGSHOT) || logic->CanUse(RG_BOMBCHU_5));}),
Entrance(RR_FOREST_TEMPLE_MQ_NW_COURTYARD_LEDGE, []{return logic->CanUse(RG_HOVER_BOOTS) && ((ctx->GetTrickOption(RT_HOVER_BOOST_SIMPLE) && ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives()) || (ctx->GetTrickOption(RT_GROUND_JUMP_HARD) && logic->IsAdult && logic->CanGroundJump()));}),
Entrance(RR_FOREST_TEMPLE_MQ_NW_COURTYARD_WELL_LEDGE, []{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT);}),
Entrance(RR_FOREST_TEMPLE_MQ_NE_COURTYARD, []{return logic->HasItem(RG_CLIMB) && (logic->Get(LOGIC_FOREST_DRAINED_WELL) || ((((logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_FOREST_WELL_SWIM) && logic->CanUse(RG_HOOKSHOT))) && logic->HasItem(RG_BRONZE_SCALE)) || logic->HasItem(RG_GOLDEN_SCALE)) && logic->WaterTimer() >= 16));}),
Entrance(RR_FOREST_TEMPLE_MQ_NW_COURTYARD_UPPER_ALCOVE, []{return (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT)) && logic->Get(LOGIC_FOREST_MQ_BURNED_WEB) && (logic->CanKillEnemy(RE_BIG_SKULLTULA, ED_LONGSHOT) || logic->CanUse(RG_BOMBCHU_5));}),
});
areaTable[RR_FOREST_TEMPLE_MQ_NW_COURTYARD_WELL_LEDGE] = Region("Forest Temple MQ NW Courtyard Well Ledge", SCENE_FOREST_TEMPLE, {}, {
//Locations
LOCATION(RC_FOREST_TEMPLE_MQ_GS_LEVEL_ISLAND_COURTYARD, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)), // rang trick could get this from below
}, {
//Exits
Entrance(RR_FOREST_TEMPLE_MQ_NW_COURTYARD, []{return true;}),
Entrance(RR_FOREST_TEMPLE_MQ_NW_COURTYARD_LEDGE, []{return logic->CanUse(RG_HOVER_BOOTS) && ((ctx->GetTrickOption(RT_HOVER_BOOST_SIMPLE) && ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives()) || (ctx->GetTrickOption(RT_GROUND_JUMP_HARD) && logic->IsAdult && logic->CanGroundJump()));}),
});
areaTable[RR_FOREST_TEMPLE_MQ_NW_COURTYARD_UPPER_ALCOVE] = Region("Forest Temple MQ NW Courtyard Upper Alcove", SCENE_FOREST_TEMPLE, {
@@ -609,8 +666,8 @@ void RegionTable_Init_ForestTemple() {
}, {
//Exits
Entrance(RR_FOREST_TEMPLE_MQ_LOBBY, []{return true;}),
Entrance(RR_FOREST_TEMPLE_MQ_NW_COURTYARD, []{return (((logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_LONGSHOT)) && logic->HasItem(RG_BRONZE_SCALE)) || logic->HasItem(RG_GOLDEN_SCALE)) && logic->WaterTimer() >= 16;}),
Entrance(RR_FOREST_TEMPLE_MQ_COURTYARD_TOP_LEDGES, []{return logic->CanUse(RG_LONGSHOT) || (logic->CanUse(RG_HOOKSHOT) && ((logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)) || logic->CanUse(RG_SONG_OF_TIME)));}),
Entrance(RR_FOREST_TEMPLE_MQ_NW_COURTYARD, []{return (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT)) && (((logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_LONGSHOT)) && logic->HasItem(RG_BRONZE_SCALE)) || logic->HasItem(RG_GOLDEN_SCALE)) && logic->WaterTimer() >= 16;}),
Entrance(RR_FOREST_TEMPLE_MQ_COURTYARD_TOP_LEDGES, []{return logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_FOREST_VINES) && logic->CanUse(RG_HOOKSHOT) && logic->HasItem(RG_CLIMB)) || (logic->CanUse(RG_HOOKSHOT) && ((logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS) && logic->HasItem(RG_CLIMB)) || logic->CanUse(RG_SONG_OF_TIME)));}),
Entrance(RR_FOREST_TEMPLE_MQ_NE_COURTYARD_ISLAND, []{return logic->CanUse(RG_LONGSHOT);}),
});
@@ -45,7 +45,7 @@ void RegionTable_Init_GerudoTrainingGround() {
areaTable[RR_GERUDO_TRAINING_GROUND_CENTRAL_MAZE] = Region("Gerudo Training Ground Central Maze", SCENE_GERUDO_TRAINING_GROUND, {}, {
//Locations
LOCATION(RC_GERUDO_TRAINING_GROUND_HIDDEN_CEILING_CHEST, logic->SmallKeys(SCENE_GERUDO_TRAINING_GROUND, 3) && (ctx->GetTrickOption(RT_LENS_GTG) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasItem(RG_OPEN_CHEST)),
LOCATION(RC_GERUDO_TRAINING_GROUND_HIDDEN_CEILING_CHEST, logic->SmallKeys(SCENE_GERUDO_TRAINING_GROUND, 3) && (ctx->GetTrickOption(RT_LENS_GTG) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOOKSHOT) || logic->HasItem(RG_CLIMB)) && logic->HasItem(RG_OPEN_CHEST)),
LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_FIRST_CHEST, logic->SmallKeys(SCENE_GERUDO_TRAINING_GROUND, 4) && logic->HasItem(RG_OPEN_CHEST)),
LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_SECOND_CHEST, logic->SmallKeys(SCENE_GERUDO_TRAINING_GROUND, 6) && logic->HasItem(RG_OPEN_CHEST)),
LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_THIRD_CHEST, logic->SmallKeys(SCENE_GERUDO_TRAINING_GROUND, 7) && logic->HasItem(RG_OPEN_CHEST)),
@@ -203,7 +203,7 @@ void RegionTable_Init_GerudoTrainingGround() {
//Locations
LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_FIRST_CHEST, logic->HasItem(RG_OPEN_CHEST)),
LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_SECOND_CHEST, logic->HasItem(RG_OPEN_CHEST)),
LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_HIDDEN_CEILING_CHEST, (ctx->GetTrickOption(RT_LENS_GTG_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasItem(RG_OPEN_CHEST)),
LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_HIDDEN_CEILING_CHEST, (ctx->GetTrickOption(RT_LENS_GTG_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT)) && logic->HasItem(RG_OPEN_CHEST)),
}, {
//Exits
Entrance(RR_GERUDO_TRAINING_GROUND_MQ_LOBBY, []{return true;}),
@@ -49,7 +49,7 @@ void RegionTable_Init_JabuJabusBelly() {
LOCATION(RC_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_UPPER, logic->HookshotOrBoomerang()),
}, {
//Exits
Entrance(RR_JABU_JABUS_BELLY_HOLES_ROOM, []{return true /* logic->HasItem(RG_CLIMB) */;}),
Entrance(RR_JABU_JABUS_BELLY_HOLES_ROOM, []{return logic->HasItem(RG_CLIMB);}),
Entrance(RR_JABU_JABUS_BELLY_B1_JIGGLY, []{return true;}),
Entrance(RR_JABU_JABUS_BELLY_HOLES_LOWER_DOOR_LEDGE, []{return logic->IsAdult;}),
});
@@ -84,7 +84,7 @@ void RegionTable_Init_JabuJabusBelly() {
}, {
//Exits
//there's tricks for getting here with bunny-jumps or just side-hops
Entrance(RR_JABU_JABUS_BELLY_WATER_SWITCH_ROOM_LEDGE, []{return logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_HOVER_BOOTS);}),
Entrance(RR_JABU_JABUS_BELLY_WATER_SWITCH_ROOM_LEDGE, []{return (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_HOVER_BOOTS)) && logic->HasItem(RG_CLIMB);}),
Entrance(RR_JABU_JABUS_BELLY_WATER_SWITCH_ROOM_SOUTH, []{return logic->IsAdult || logic->HasItem(RG_BRONZE_SCALE);}),
Entrance(RR_JABU_JABUS_BELLY_HOLES_BASEMENT, []{return true;}),
});
@@ -95,7 +95,7 @@ void RegionTable_Init_JabuJabusBelly() {
}, {
//Exits
Entrance(RR_JABU_JABUS_BELLY_WATER_SWITCH_ROOM_NORTH, []{return logic->IsAdult || logic->HasItem(RG_BRONZE_SCALE);}),
Entrance(RR_JABU_JABUS_BELLY_WATER_SWITCH_ROOM_LEDGE, []{return logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_HOVER_BOOTS);}),
Entrance(RR_JABU_JABUS_BELLY_WATER_SWITCH_ROOM_LEDGE, []{return (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_HOVER_BOOTS)) && logic->HasItem(RG_CLIMB);}),
//Adult can barely reach it with BGS, but it's finnicky enough to be a trick, and too niche to be worth adding yet (only relevant in doorsanity)
Entrance(RR_JABU_JABUS_BELLY_LIFT_ROOM, []{return logic->CanHitSwitch(ED_BOMB_THROW);}),
});
@@ -248,11 +248,13 @@ void RegionTable_Init_JabuJabusBelly() {
areaTable[RR_JABU_JABUS_BELLY_NEAR_BOSS_ROOM] = Region("Jabu Jabus Belly Near Boss Room", SCENE_JABU_JABU, {}, {
//Locations
//can also use ruto
LOCATION(RC_JABU_JABUS_BELLY_GS_NEAR_BOSS, logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_BOMB_THROW)),
LOCATION(RC_JABU_JABUS_BELLY_GS_NEAR_BOSS, logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_BOMB_THROW) && (logic->HasItem(RG_CLIMB) || logic->HookshotOrBoomerang())),
}, {
//Exits
Entrance(RR_JABU_JABUS_BELLY_LIFT_ROOM, []{return true;}),
Entrance(RR_JABU_JABUS_BELLY_BOSS_ENTRYWAY, []{return logic->CanUse(RG_BOOMERANG) || (ctx->GetTrickOption(RT_JABU_NEAR_BOSS_RANGED) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT))) || (ctx->GetTrickOption(RT_JABU_NEAR_BOSS_EXPLOSIVES) && (logic->CanUse(RG_BOMBCHU_5) || (logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_BOMB_BAG))));}),
Entrance(RR_JABU_JABUS_BELLY_BOSS_ENTRYWAY, []{return (logic->HasItem(RG_CLIMB) && logic->CanUse(RG_BOOMERANG)) ||
(ctx->GetTrickOption(RT_JABU_NEAR_BOSS_RANGED) && (logic->CanUse(logic->HasItem(RG_CLIMB) ? RG_HOOKSHOT : RG_LONGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT))) ||
(ctx->GetTrickOption(RT_JABU_NEAR_BOSS_EXPLOSIVES) && (logic->CanUse(RG_BOMBCHU_5) || (logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_BOMB_BAG) && logic->HasItem(RG_CLIMB))));}),
});
#pragma endregion
@@ -342,7 +344,7 @@ void RegionTable_Init_JabuJabusBelly() {
LOCATION(RC_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_3, logic->CanCutShrubs()),
}, {
//Exits
Entrance(RR_JABU_JABUS_BELLY_MQ_HOLES_ROOM, []{return true /* logic->HasItem(RG_CLIMB) */;}),
Entrance(RR_JABU_JABUS_BELLY_MQ_HOLES_ROOM, []{return logic->HasItem(RG_CLIMB);}),
Entrance(RR_JABU_JABUS_BELLY_MQ_TO_BIGOCTO, []{return logic->Get(LOGIC_JABU_WEST_TENTACLE);}),
Entrance(RR_JABU_JABUS_BELLY_MQ_WATER_SWITCH_ROOM, []{return logic->HasItem(RG_POWER_BRACELET);}),
Entrance(RR_JABU_JABUS_BELLY_MQ_INVISIBLE_KEESE_ROOM, []{return logic->Get(LOGIC_JABU_NORTH_TENTACLE);}),
@@ -354,8 +356,8 @@ void RegionTable_Init_JabuJabusBelly() {
}, {
//Locations
LOCATION(RC_JABU_JABUS_BELLY_MQ_BOOMERANG_ROOM_SMALL_CHEST, logic->HasItem(RG_OPEN_CHEST)),
LOCATION(RC_JABU_JABUS_BELLY_MQ_BOOMERANG_CHEST, logic->CanKillEnemy(RE_LIZALFOS) && logic->HasItem(RG_OPEN_CHEST)),
LOCATION(RC_JABU_JABUS_BELLY_MQ_GS_BOOMERANG_CHEST_ROOM, (logic->CanUse(RG_SONG_OF_TIME) && (logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA) || logic->HasItem(RG_POWER_BRACELET))) || (ctx->GetTrickOption(RT_JABU_MQ_SOT_GS) && logic->CanUse(RG_BOOMERANG))),
LOCATION(RC_JABU_JABUS_BELLY_MQ_BOOMERANG_CHEST, (logic->IsAdult || logic->HasItem(RG_CLIMB)) && logic->CanKillEnemy(RE_LIZALFOS) && logic->HasItem(RG_OPEN_CHEST)),
LOCATION(RC_JABU_JABUS_BELLY_MQ_GS_BOOMERANG_CHEST_ROOM, (logic->CanUse(RG_SONG_OF_TIME) && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)) || (ctx->GetTrickOption(RT_JABU_MQ_SOT_GS) && logic->CanUse(RG_BOOMERANG))),
LOCATION(RC_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_1, logic->CanBreakPots()),
LOCATION(RC_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_2, logic->CanBreakPots()),
LOCATION(RC_JABU_JABUS_BELLY_MQ_BASEMENT_BOOMERANG_GRASS, logic->CanCutShrubs()),
@@ -466,7 +468,7 @@ void RegionTable_Init_JabuJabusBelly() {
&& ((logic->IsChild && logic->HasItem(RG_BRONZE_SCALE)) || (logic->IsAdult && logic->CanUse(RG_IRON_BOOTS)))))),
}, {
//Exits
Entrance(RR_JABU_JABUS_BELLY_MQ_HOLES_ROOM, []{return (logic->Get(LOGIC_JABU_NORTH_TENTACLE) || logic->TakeDamage()) && logic->HasItem(RG_BRONZE_SCALE);}),
Entrance(RR_JABU_JABUS_BELLY_MQ_HOLES_BASEMENT, []{return (logic->Get(LOGIC_JABU_NORTH_TENTACLE) || logic->TakeDamage()) && logic->HasItem(RG_BRONZE_SCALE);}),
});
// unlike other entrances behind tentacles, Link spawns behind the tentacle. Running into it throws him into main room still
@@ -536,8 +538,8 @@ void RegionTable_Init_JabuJabusBelly() {
EventAccess(LOGIC_FAIRY_ACCESS, []{return logic->CanBreakPots();}),
}, {
//Locations
LOCATION(RC_JABU_JABUS_BELLY_MQ_NEAR_BOSS_CHEST, logic->CanUse(RG_FAIRY_SLINGSHOT) && logic->HasItem(RG_OPEN_CHEST)),
LOCATION(RC_JABU_JABUS_BELLY_MQ_GS_NEAR_BOSS, logic->CanUse(RG_BOOMERANG) || (ctx->GetTrickOption(RT_JABU_NEAR_BOSS_RANGED) && logic->CanUse(RG_HOOKSHOT))),
LOCATION(RC_JABU_JABUS_BELLY_MQ_NEAR_BOSS_CHEST, logic->CanUse(RG_FAIRY_SLINGSHOT)),
LOCATION(RC_JABU_JABUS_BELLY_MQ_GS_NEAR_BOSS, (logic->HasItem(RG_CLIMB) && (logic->CanUse(RG_BOOMERANG) || (ctx->GetTrickOption(RT_JABU_NEAR_BOSS_RANGED) && logic->CanUse(RG_HOOKSHOT)))) || (ctx->GetTrickOption(RT_JABU_NEAR_BOSS_RANGED) && logic->CanUse(RG_LONGSHOT))),
LOCATION(RC_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_POT_1, logic->CanBreakPots()),
LOCATION(RC_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_GRASS_1, logic->CanCutShrubs()),
LOCATION(RC_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_GRASS_2, logic->CanCutShrubs()),
@@ -267,8 +267,8 @@ void RegionTable_Init_ShadowTemple() {
}, {
//Exits
Entrance(RR_SHADOW_TEMPLE_ROOM_TO_BOAT, []{return logic->SmallKeys(SCENE_SHADOW_TEMPLE, 4);}),
Entrance(RR_SHADOW_TEMPLE_SPINNING_BLADES, []{return logic->HasItem(RG_GORONS_BRACELET);}),
Entrance(RR_SHADOW_TEMPLE_BEYOND_BOAT, []{return ((logic->IsAdult && (logic->HasItem(RG_GORONS_BRACELET) || ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS))) || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_ZELDAS_LULLABY);}),
Entrance(RR_SHADOW_TEMPLE_SPINNING_BLADES, []{return logic->Get(LOGIC_SHADOW_SHORTCUT_BLOCK) && logic->HasItem(RG_CLIMB);}),
Entrance(RR_SHADOW_TEMPLE_BEYOND_BOAT, []{return ((logic->IsAdult && ((logic->HasItem(RG_GORONS_BRACELET) && logic->HasItem(RG_CLIMB)) || ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS))) || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_ZELDAS_LULLABY);}),
});
areaTable[RR_SHADOW_TEMPLE_BEYOND_BOAT] = Region("Shadow Temple Beyond Boat", SCENE_SHADOW_TEMPLE, {
@@ -640,9 +640,9 @@ void RegionTable_Init_ShadowTemple() {
LOCATION(RC_SHADOW_TEMPLE_MQ_SCARECROW_SOUTH_HEART, logic->ReachDistantScarecrow()),
}, {
//Exits
Entrance(RR_SHADOW_TEMPLE_MQ_SHORTCUT_PATH, []{return logic->Get(LOGIC_SHADOW_SHORTCUT_BLOCK);}),
Entrance(RR_SHADOW_TEMPLE_MQ_SHORTCUT_PATH, []{return logic->Get(LOGIC_SHADOW_SHORTCUT_BLOCK) && logic->HasItem(RG_CLIMB);}),
Entrance(RR_SHADOW_TEMPLE_MQ_B4_GIBDO_ROOM, []{return logic->SmallKeys(SCENE_SHADOW_TEMPLE, 5);}),
Entrance(RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT, []{return ((logic->IsAdult && (logic->HasItem(RG_GORONS_BRACELET) || ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS))) || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_ZELDAS_LULLABY);}),
Entrance(RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT, []{return ((logic->IsAdult && ((logic->HasItem(RG_GORONS_BRACELET) && logic->HasItem(RG_CLIMB)) || ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS))) || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_ZELDAS_LULLABY);}),
});
areaTable[RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT] = Region("Shadow Temple MQ Beyond Boat", SCENE_SHADOW_TEMPLE, {
@@ -34,7 +34,8 @@ void RegionTable_Init_SpiritTemple() {
areaTable[RR_SPIRIT_TEMPLE_CHILD_SIDE_HUB] = Region("Spirit Temple Child Side Hub", SCENE_SPIRIT_TEMPLE, {
//Events
EventAccess(LOGIC_NUT_ACCESS, []{return logic->CanBreakSmallCrates();}),
EventAccess(LOGIC_NUT_ACCESS, []{return logic->CanBreakSmallCrates();}),
EventAccess(LOGIC_SPIRIT_SILVER_RUPEE_BRIDGE_TORCHES, []{return AnyAgeTime([]{return logic->CanKillEnemy(RE_ARMOS);}) && logic->CanUse(RG_STICKS);}), // not usable in doorsanity
}, {}, {
//Exits
Entrance(RR_SPIRIT_TEMPLE_FOYER, []{return logic->CanUse(RG_CRAWL);}),
@@ -81,20 +82,23 @@ void RegionTable_Init_SpiritTemple() {
areaTable[RR_SPIRIT_TEMPLE_RUPEE_BRIDGE_NORTH] = Region("Spirit Temple Rupee Bridge North", SCENE_SPIRIT_TEMPLE, {
//Events
EventAccess(LOGIC_SPIRIT_SILVER_RUPEE_BRIDGE, []{return true/*CanClimb()*/;}),
EventAccess(LOGIC_SPIRIT_SILVER_RUPEE_BRIDGE, []{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT);}),
EventAccess(LOGIC_SPIRIT_SILVER_RUPEE_BRIDGE_TORCHES, []{return (logic->Get(LOGIC_SPIRIT_SILVER_RUPEE_BRIDGE) && logic->HasFireSourceWithTorch()) || logic->CanUse(RG_DINS_FIRE);}),
}, {
//Locations
// these assume SpiritRupeeBridge, silver rupee shuffle & shuffle climb will want to adjust
LOCATION(RC_SPIRIT_TEMPLE_CHILD_EARLY_TORCHES_CHEST, logic->HasFireSourceWithTorch() && logic->HasItem(RG_OPEN_CHEST)),
LOCATION(RC_SPIRIT_TEMPLE_CHILD_EARLY_TORCHES_CHEST, logic->Get(LOGIC_SPIRIT_SILVER_RUPEE_BRIDGE_TORCHES) && logic->HasItem(RG_OPEN_CHEST)),
// possible to collect without lowering fence, should be a trick
LOCATION(RC_SPIRIT_TEMPLE_GS_METAL_FENCE, logic->Get(LOGIC_SPIRIT_SILVER_RUPEE_BRIDGE) && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_BOMB_THROW)),
LOCATION(RC_SPIRIT_TEMPLE_GS_METAL_FENCE, logic->Get(LOGIC_SPIRIT_SILVER_RUPEE_BRIDGE) && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_BOMB_THROW) && logic->HasItem(RG_CLIMB)),
}, {
//Exits
Entrance(RR_SPIRIT_TEMPLE_RUPEE_BRIDGE_SOUTH, []{return logic->Get(LOGIC_SPIRIT_SILVER_RUPEE_BRIDGE);}),
Entrance(RR_SPIRIT_TEMPLE_1F_ANUBIS, []{return true;}),
});
areaTable[RR_SPIRIT_TEMPLE_RUPEE_BRIDGE_SOUTH] = Region("Spirit Temple Rupee Bridge South", SCENE_SPIRIT_TEMPLE, {}, {
areaTable[RR_SPIRIT_TEMPLE_RUPEE_BRIDGE_SOUTH] = Region("Spirit Temple Rupee Bridge South", SCENE_SPIRIT_TEMPLE, {
//Events
EventAccess(LOGIC_SPIRIT_SILVER_RUPEE_BRIDGE_TORCHES, []{return logic->HasFireSource();}),
}, {
//Locations
LOCATION(RC_SPIRIT_TEMPLE_GS_METAL_FENCE, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)),
}, {
@@ -121,7 +125,7 @@ void RegionTable_Init_SpiritTemple() {
}, {
//Exits
Entrance(RR_SPIRIT_TEMPLE_CHILD_BOXES, []{return logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 5);}),
Entrance(RR_SPIRIT_TEMPLE_SUN_ON_FLOOR_2F, []{return true/*CanClimbHigh()*/;}),
Entrance(RR_SPIRIT_TEMPLE_SUN_ON_FLOOR_2F, []{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT);}),
});
areaTable[RR_SPIRIT_TEMPLE_SUN_ON_FLOOR_2F] = Region("Spirit Temple Sun On Floor 2F", SCENE_SPIRIT_TEMPLE, {}, {
@@ -130,12 +134,11 @@ void RegionTable_Init_SpiritTemple() {
LOCATION(RC_SPIRIT_TEMPLE_CHILD_CLIMB_EAST_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_SUN_ON_FLOOR_2F, []{return logic->CanHitSwitch(ED_BOMB_THROW) && logic->HasItem(RG_OPEN_CHEST);})),
LOCATION(RC_SPIRIT_TEMPLE_GS_SUN_ON_FLOOR_ROOM, SpiritShared(RR_SPIRIT_TEMPLE_SUN_ON_FLOOR_2F, []{return logic->CanKillEnemy(RE_GOLD_SKULLTULA, logic->TakeDamage() ? ED_SHORT_JUMPSLASH : ED_BOMB_THROW);}, false,
RR_SPIRIT_TEMPLE_SUN_ON_FLOOR_1F, []{return logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG);})),
LOCATION(RC_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_BOMBCHU_5) || (logic->CanUse(RG_BOMB_BAG) && logic->IsAdult && ctx->GetTrickOption(RT_SPIRIT_LOWER_ADULT_SWITCH))) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanJumpslash())),
LOCATION(RC_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_BOMBCHU_5) || (logic->CanUse(RG_BOMB_BAG) && logic->IsAdult && ctx->GetTrickOption(RT_SPIRIT_LOWER_ADULT_SWITCH))) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanJumpslash())),
}, {
//Exits
Entrance(RR_SPIRIT_TEMPLE_SUN_ON_FLOOR_1F, []{return true;}),
///*CanClimbHigh() &&*/ (HasExplosives() || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && CanUse(RG_LIGHT_ARROWS)))
Entrance(RR_SPIRIT_TEMPLE_STATUE_ROOM, []{return logic->SpiritSunOnFloorToStatue();}),
Entrance(RR_SPIRIT_TEMPLE_STATUE_ROOM, []{return logic->HasExplosives() || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS));}),
});
areaTable[RR_SPIRIT_TEMPLE_ADULT_SIDE_HUB] = Region("Spirit Temple Adult Side Hub", SCENE_SPIRIT_TEMPLE, {}, {}, {
@@ -171,7 +174,7 @@ void RegionTable_Init_SpiritTemple() {
LOCATION(RC_SPIRIT_TEMPLE_GS_BOULDER_ROOM, logic->CanUse(RG_SONG_OF_TIME) && logic->CanKillEnemy(RE_GOLD_SKULLTULA)),
}, {
//Exits
Entrance(RR_SPIRIT_TEMPLE_ABOVE_BOULDERS, []{return true/*CanClimb() || IsAdult() || CanGroundJump*/;}),
Entrance(RR_SPIRIT_TEMPLE_ABOVE_BOULDERS, []{return logic->IsAdult || logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT) || logic->CanGroundJump();}),
Entrance(RR_SPIRIT_TEMPLE_PAST_BOULDERS, []{return logic->Get(LOGIC_SPIRIT_BOUNDERS_SILVERS);}),
});
@@ -187,7 +190,7 @@ void RegionTable_Init_SpiritTemple() {
areaTable[RR_SPIRIT_TEMPLE_1F_MIRROR_ROOM] = Region("Spirit Temple 1F Mirror Room", SCENE_SPIRIT_TEMPLE, {}, {}, {
//Exits
Entrance(RR_SPIRIT_TEMPLE_ADULT_SIDE_HUB, []{return logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 5);}),
Entrance(RR_SPIRIT_TEMPLE_2F_MIRROR_ROOM, []{return true/*CanClimbHigh()*/;}),
Entrance(RR_SPIRIT_TEMPLE_2F_MIRROR_ROOM, []{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT);}),
});
areaTable[RR_SPIRIT_TEMPLE_2F_MIRROR_ROOM] = Region("Spirit Temple 2F Mirror Room", SCENE_SPIRIT_TEMPLE, {}, {
@@ -260,7 +263,7 @@ void RegionTable_Init_SpiritTemple() {
LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_6, SpiritShared(RR_SPIRIT_TEMPLE_STATUE_ROOM, []{return logic->CanBreakPots();})),
}, {
//Exits
Entrance(RR_SPIRIT_TEMPLE_STATUE_ROOM_CHILD, []{return true/*CanClimb()*/;}),
Entrance(RR_SPIRIT_TEMPLE_STATUE_ROOM_CHILD, []{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT);}),
Entrance(RR_SPIRIT_TEMPLE_PLATFORM, []{return logic->Get(LOGIC_SPIRIT_PLATFORM_LOWERED) &&
(logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_SPIRIT_PLATFORM_HOOKSHOT) && logic->CanUse(RG_HOOKSHOT)));}),
//explicit adult check here is a precaution against possible child logic leaking, child with a hookshot can do this
@@ -274,8 +277,8 @@ void RegionTable_Init_SpiritTemple() {
//If you do not have explosives to kill Beamos, but do have a way to defeat Iron Knuckles, this becomes possible with 4 keys instead.
Entrance(RR_SPIRIT_TEMPLE_ADULT_SIDE_HUB, []{return ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF) &&
logic->CanUse(RG_SILVER_GAUNTLETS) && logic->IsAdult &&
((logic->CanKillEnemy(RE_BEAMOS) && logic->SmallKeys(SCENE_SPIRIT_TEMPLE, /*CanClimb() &&*/ logic->HasItem(RG_POWER_BRACELET) ? 2 : 3)) ||
(/*CanClimb() &&*/ logic->HasItem(RG_POWER_BRACELET) && logic->CanKillEnemy(RE_IRON_KNUCKLE) && logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 4)));}),
((logic->CanKillEnemy(RE_BEAMOS) && logic->SmallKeys(SCENE_SPIRIT_TEMPLE, (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT)) && logic->HasItem(RG_POWER_BRACELET) ? 2 : 3)) ||
((logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT)) && logic->HasItem(RG_POWER_BRACELET) && logic->CanKillEnemy(RE_IRON_KNUCKLE) && logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 4)));}),
});
areaTable[RR_SPIRIT_TEMPLE_EMPTY_STAIRS] = Region("Spirit Temple Empty Stairs", SCENE_SPIRIT_TEMPLE, {}, {}, {
@@ -356,7 +359,7 @@ void RegionTable_Init_SpiritTemple() {
areaTable[RR_SPIRIT_TEMPLE_INNER_LEFT_HAND] = Region("Spirit Temple Inner Left Hand", SCENE_SPIRIT_TEMPLE, {}, {
//Locations
//Assumes RR_SPIRIT_TEMPLE_INNER_WEST_HAND access via RR_SPIRIT_TEMPLE_STATUE_ROOM_CHILD and RR_SPIRIT_TEMPLE_STATUE_ROOM.
LOCATION(RC_SPIRIT_TEMPLE_STATUE_ROOM_HAND_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_INNER_LEFT_HAND, []{return logic->CanUse(RG_ZELDAS_LULLABY) && logic->HasItem(RG_OPEN_CHEST)/* && CanClimb()*/;})),
LOCATION(RC_SPIRIT_TEMPLE_STATUE_ROOM_HAND_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_INNER_LEFT_HAND, []{return logic->CanUse(RG_ZELDAS_LULLABY) && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT)) && logic->HasItem(RG_OPEN_CHEST);})),
}, {
//Exits
Entrance(RR_SPIRIT_TEMPLE_STATUE_ROOM, []{return true;}),
@@ -453,9 +456,8 @@ void RegionTable_Init_SpiritTemple() {
areaTable[RR_SPIRIT_TEMPLE_BIG_WALL_BASE] = Region("Spirit Temple Big Wall Base", SCENE_SPIRIT_TEMPLE, {}, {}, {
//Exits
Entrance(RR_SPIRIT_TEMPLE_BEAMOS_PITS, []{return true;}),
Entrance(RR_SPIRIT_TEMPLE_BIG_WALL_UPPER, []{return (ctx->GetTrickOption(RT_SPIRIT_WALL) ||
(logic->CanAvoidEnemy(RE_BEAMOS, true, 2) && logic->CanPassEnemy(RE_WALLTULA, ED_BOOMERANG)))
/*&& CanClimbHigh()*/;}),
Entrance(RR_SPIRIT_TEMPLE_BIG_WALL_UPPER, []{return (ctx->GetTrickOption(RT_SPIRIT_WALL) || (logic->CanAvoidEnemy(RE_BEAMOS, true, 2) && logic->CanPassEnemy(RE_WALLTULA, ED_BOOMERANG))) &&
(logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT));}),
});
areaTable[RR_SPIRIT_TEMPLE_BIG_WALL_UPPER] = Region("Spirit Temple Big Wall Upper", SCENE_SPIRIT_TEMPLE, {}, {
@@ -675,7 +677,7 @@ void RegionTable_Init_SpiritTemple() {
//Exits
//This covers adult and reverse access only, as child going forwards arrives here from the other side of this door
Entrance(RR_SPIRIT_TEMPLE_MQ_1F_CHEST_SWITCH, []{return logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 7);}),
Entrance(RR_SPIRIT_TEMPLE_MQ_SUN_ON_FLOOR, []{return logic->CanHitSwitch()/* && CanClimbHigh()*/;}),
Entrance(RR_SPIRIT_TEMPLE_MQ_SUN_ON_FLOOR, []{return logic->CanHitSwitch() && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT));}),
});
areaTable[RR_SPIRIT_TEMPLE_MQ_SUN_ON_FLOOR] = Region("Spirit Temple MQ Sun on Floor Room", SCENE_SPIRIT_TEMPLE, {}, {
@@ -767,7 +769,7 @@ void RegionTable_Init_SpiritTemple() {
(logic->CanUse(RG_BOOMERANG) && logic->HasExplosives());})),
}, {
//Exits
Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM_CHILD, []{return true/*logic->CanClimb()*/;}),
Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM_CHILD, []{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT);}),
Entrance(RR_SPIRIT_TEMPLE_MQ_BIG_BLOCKS_DOOR, []{return logic->Get(LOGIC_SPIRIT_STATUE_SOUTH_DOOR);}),
//explicit adult check here is a precaution against possible Child logic leaking, Child with a hookshot can do this
//It's possible to climb the legs of the statue to line up a longshot hit, but you can just go via West
@@ -890,7 +892,7 @@ void RegionTable_Init_SpiritTemple() {
areaTable[RR_SPIRIT_TEMPLE_MQ_3_SUNS_ROOM_1F] = Region("Spirit Temple MQ 3 Suns Room 1F", SCENE_SPIRIT_TEMPLE, {}, {}, {
//Exits
//It is possible to clip through here with longshot by aiming high enough
Entrance(RR_SPIRIT_TEMPLE_MQ_3_SUNS_ROOM_2F, []{return logic->Get(LOGIC_SPIRIT_MQ_3SUNS_ENEMIES)/* && CanClimbHigh()*/;}),
Entrance(RR_SPIRIT_TEMPLE_MQ_3_SUNS_ROOM_2F, []{return logic->Get(LOGIC_SPIRIT_MQ_3SUNS_ENEMIES) && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT));}),
Entrance(RR_SPIRIT_TEMPLE_MQ_BEHIND_GEYSER, []{return true;}),
});
@@ -932,7 +934,7 @@ void RegionTable_Init_SpiritTemple() {
areaTable[RR_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM_LOWER] = Region("Spirit Temple MQ Symphony Room Lower", SCENE_SPIRIT_TEMPLE, {}, {}, {
//Exits
Entrance(RR_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM_UPPER, []{return true/*CanClimb() || IsAdult || CanGroundJump()*/;}),
Entrance(RR_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM_UPPER, []{return logic->IsAdult || logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT) || logic->CanGroundJump();}),
//Implies CanPassEnemy(RE_MOBLIN_CHIEF)
Entrance(RR_SPIRIT_TEMPLE_MQ_SKULLTULA_ROOM, []{return logic->Get(LOGIC_SPIRIT_MQ_SYMPHONY_ROOM_DOOR);}),
});
@@ -1023,13 +1025,13 @@ void RegionTable_Init_SpiritTemple() {
//Exits
Entrance(RR_SPIRIT_TEMPLE_MQ_BEAMOS_PITS, []{return true;}),
//technically we only need to avoid them, but the sheer height and the moving walls makes getting to the top after only stunning them very difficult/impossible
Entrance(RR_SPIRIT_TEMPLE_MQ_BIG_WALL_UPPER, []{return /*(*/logic->CanKillEnemy(RE_KEESE) || logic->CanUse(RG_SKULL_MASK)/*) && CanClimbHigh()*/;}),
Entrance(RR_SPIRIT_TEMPLE_MQ_BIG_WALL_UPPER, []{return (logic->CanKillEnemy(RE_KEESE) || logic->CanUse(RG_SKULL_MASK)) && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT));}),
});
areaTable[RR_SPIRIT_TEMPLE_MQ_BIG_WALL_UPPER] = Region("Spirit Temple MQ Big Wall Upper", SCENE_SPIRIT_TEMPLE, {
//Events
//Getting some of these with just climbing downwards is theoretically possible but definitely a trick
EventAccess(LOGIC_SPIRIT_MQ_BIG_WALL_SILVERS, []{return /*(*/logic->CanKillEnemy(RE_KEESE)/*|| CanUse(RG_SKULL_MASK)) && CanClimbHigh()*/;}),
EventAccess(LOGIC_SPIRIT_MQ_BIG_WALL_SILVERS, []{return (logic->CanKillEnemy(RE_KEESE) || logic->CanUse(RG_SKULL_MASK)) && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT));}),
}, {}, {
//Exits
Entrance(RR_SPIRIT_TEMPLE_MQ_BIG_WALL_BASE, []{return true;}),
@@ -1128,7 +1130,7 @@ void RegionTable_Init_SpiritTemple() {
areaTable[RR_SPIRIT_TEMPLE_BOSS_ROOM] = Region("Spirit Temple Boss Room", SCENE_SPIRIT_TEMPLE_BOSS, {
// Events
EventAccess(LOGIC_SPIRIT_TEMPLE_CLEAR, []{return logic->CanKillEnemy(RE_TWINROVA);}),
EventAccess(LOGIC_SPIRIT_TEMPLE_CLEAR, []{return (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT)) && logic->CanKillEnemy(RE_TWINROVA);}),
}, {
// Locations
LOCATION(RC_SPIRIT_TEMPLE_TWINROVA_HEART, logic->Get(LOGIC_SPIRIT_TEMPLE_CLEAR)),
@@ -12,48 +12,91 @@ void RegionTable_Init_CastleGrounds() {
areaTable[RR_CASTLE_GROUNDS] = Region("Castle Grounds", SCENE_OUTSIDE_GANONS_CASTLE, TIME_DOESNT_PASS, {RA_CASTLE_GROUNDS}, {}, {}, {
//Exits
Entrance(RR_THE_MARKET, []{return true;}),
Entrance(RR_HYRULE_CASTLE_GROUNDS, []{return logic->IsChild;}),
Entrance(RR_HC_GATE, []{return logic->IsChild;}),
Entrance(RR_GANONS_CASTLE_GROUNDS, []{return logic->IsAdult;}),
});
areaTable[RR_HYRULE_CASTLE_GROUNDS] = Region("Hyrule Castle Grounds", SCENE_HYRULE_CASTLE, {
areaTable[RR_HC_GATE] = Region("Hyrule Castle Gate", SCENE_HYRULE_CASTLE, {
//Events
EventAccess(LOGIC_FAIRY_ACCESS, []{return logic->CallGossipFairy() || logic->CanUse(RG_STICKS);}),
EventAccess(LOGIC_BUG_ACCESS, []{return logic->HasItem(RG_POWER_BRACELET);}),
}, {
//Locations
LOCATION(RC_HC_MALON_EGG, true),
LOCATION(RC_HC_GS_TREE, logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_CLOSE) && logic->CanBonkTrees()),
LOCATION(RC_HC_MALON_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()),
LOCATION(RC_HC_MALON_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_HC_ROCK_WALL_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()),
LOCATION(RC_HC_ROCK_WALL_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_HC_MALON_GOSSIP_STONE, true),
LOCATION(RC_HC_ROCK_WALL_GOSSIP_STONE, true),
LOCATION(RC_HC_GRASS_1, logic->CanCutShrubs()),
LOCATION(RC_HC_GRASS_2, logic->CanCutShrubs()),
LOCATION(RC_HC_GROTTO_TREE, logic->CanBonkTrees()),
LOCATION(RC_HC_NL_TREE_1, false),
LOCATION(RC_HC_NL_TREE_2, false),
LOCATION(RC_HC_SKULLTULA_TREE, logic->CanBonkTrees()),
LOCATION(RC_HC_NEAR_GUARDS_TREE_1, logic->CanBonkTrees()),
LOCATION(RC_HC_NEAR_GUARDS_TREE_2, logic->CanBonkTrees()),
LOCATION(RC_HC_NEAR_GUARDS_TREE_3, logic->CanBonkTrees()),
LOCATION(RC_HC_NEAR_GUARDS_TREE_4, logic->CanBonkTrees()),
LOCATION(RC_HC_NEAR_GUARDS_TREE_5, logic->CanBonkTrees()),
LOCATION(RC_HC_NEAR_GUARDS_TREE_6, logic->CanBonkTrees()),
LOCATION(RC_HC_MALON_EGG, true),
LOCATION(RC_HC_GS_TREE, logic->CanBonkTrees() && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_CLOSE)),
LOCATION(RC_HC_SKULLTULA_TREE, logic->CanBonkTrees()),
}, {
//Exits
Entrance(RR_CASTLE_GROUNDS, []{return true;}),
Entrance(RR_HC_LEDGE, []{return (logic->CanUse(RG_WEIRD_EGG) && logic->HasItem(RG_POWER_BRACELET)) || (ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives() && logic->CanJumpslash());}),
Entrance(RR_HC_GREAT_FAIRY_FOUNTAIN, []{return logic->CanUse(RG_CRAWL) && logic->BlastOrSmash();}),
Entrance(RR_HC_STORMS_GROTTO, []{return logic->CanOpenStormsGrotto();}),
Entrance(RR_CASTLE_GROUNDS, []{return true;}),
Entrance(RR_HC_ABOVE_VINE, []{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT);}),
Entrance(RR_HC_PAST_GATE, []{return logic->HasItem(RG_CHILD_WALLET);}),
});
areaTable[RR_HC_LEDGE] = Region("HC Ledge", SCENE_HYRULE_CASTLE, {}, {}, {
areaTable[RR_HC_ABOVE_VINE] = Region("Hyrule Castle Above Vine", SCENE_HYRULE_CASTLE, {
//Events
EventAccess(LOGIC_FAIRY_ACCESS, []{return logic->CallGossipFairy();}),
}, {
//Locations
LOCATION(RC_HC_MALON_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()),
LOCATION(RC_HC_MALON_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_HC_MALON_GOSSIP_STONE, true),
}, {
//Exits
Entrance(RR_HYRULE_CASTLE_GROUNDS, []{return true;}),
Entrance(RR_HC_GARDEN, []{return logic->CanUse(RG_CRAWL);}),
Entrance(RR_HC_GATE, []{return true;}),
Entrance(RR_HC_PAST_GATE, []{return true;}),
});
areaTable[RR_HC_PAST_GATE] = Region("Hyrule Castle Past Gate", SCENE_HYRULE_CASTLE, {
//Events
EventAccess(LOGIC_FAIRY_ACCESS, []{return logic->CanUse(RG_STICKS);}),
}, {
//Locations
LOCATION(RC_HC_NEAR_GUARDS_TREE_1, logic->CanBonkTrees()),
LOCATION(RC_HC_NEAR_GUARDS_TREE_2, logic->CanBonkTrees()),
LOCATION(RC_HC_NEAR_GUARDS_TREE_3, logic->CanBonkTrees()),
LOCATION(RC_HC_NEAR_GUARDS_TREE_4, logic->CanBonkTrees()),
LOCATION(RC_HC_NEAR_GUARDS_TREE_5, logic->CanBonkTrees()),
LOCATION(RC_HC_NEAR_GUARDS_TREE_6, logic->CanBonkTrees()),
LOCATION(RC_HC_NL_TREE_1, false),
LOCATION(RC_HC_NL_TREE_2, false),
}, {
//Exits
Entrance(RR_HC_GATE, []{return true;}),
Entrance(RR_HC_ABOVE_VINE, []{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT);}),
Entrance(RR_HC_ABOVE_CLIMBABLE_ROCKS, []{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT);}),
Entrance(RR_HC_GREAT_FAIRY_FOUNTAIN, []{return logic->BlastOrSmash() && logic->CanUse(RG_CRAWL);}),
});
areaTable[RR_HC_ABOVE_CLIMBABLE_ROCKS] = Region("Hyrule Castle Above Climbable Rocks", SCENE_HYRULE_CASTLE, {
//Events
EventAccess(LOGIC_FAIRY_ACCESS, []{return logic->CallGossipFairy();}),
}, {
//Locations
LOCATION(RC_HC_ROCK_WALL_GOSSIP_STONE, true),
LOCATION(RC_HC_ROCK_WALL_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()),
LOCATION(RC_HC_ROCK_WALL_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
}, {
//Exits
Entrance(RR_HC_PAST_GATE, []{return true;}),
Entrance(RR_HC_MOAT, []{return true;}),
});
areaTable[RR_HC_MOAT] = Region("Hyrule Castle Grounds", SCENE_HYRULE_CASTLE, {}, {
//Locations
LOCATION(RC_HC_GRASS_1, logic->CanCutShrubs()),
LOCATION(RC_HC_GRASS_2, logic->CanCutShrubs()),
LOCATION(RC_HC_GROTTO_TREE, logic->CanBonkTrees()),
}, {
//Exits
Entrance(RR_HC_GATE, []{return true;}),
Entrance(RR_HC_STORMS_GROTTO, []{return logic->CanOpenStormsGrotto();}),
Entrance(RR_HC_GARDEN, []{return (logic->CanUse(RG_WEIRD_EGG) && logic->HasItem(RG_POWER_BRACELET)) || (ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->TakeDamage() && logic->HasExplosives() && logic->CanJumpslash());}),
});
areaTable[RR_HC_DRAIN_LEDGE] = Region("Hyrule Castle Drain Ledge", SCENE_HYRULE_CASTLE, {}, {}, {
//Exits
Entrance(RR_HC_MOAT, []{return true;}),
Entrance(RR_HC_GARDEN, []{return logic->CanUse(RG_CRAWL);}),
});
areaTable[RR_HC_GARDEN] = Region("HC Garden", SCENE_CASTLE_COURTYARD_ZELDA, {}, {
@@ -62,7 +105,7 @@ void RegionTable_Init_CastleGrounds() {
LOCATION(RC_SONG_FROM_IMPA, true),
}, {
//Exits
Entrance(RR_HC_LEDGE, []{return true;}), // if this ever gets shuffled leaving garden area should come out crawlspace
Entrance(RR_HC_DRAIN_LEDGE, []{return true;}), // if this ever gets shuffled leaving garden area should come out crawlspace
});
areaTable[RR_HC_GREAT_FAIRY_FOUNTAIN] = Region("HC Great Fairy Fountain", SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, {}, {
@@ -70,7 +113,7 @@ void RegionTable_Init_CastleGrounds() {
LOCATION(RC_HC_GREAT_FAIRY_REWARD, logic->CanUse(RG_ZELDAS_LULLABY)),
}, {
//Exits
Entrance(RR_CASTLE_GROUNDS, []{return true;}),
Entrance(RR_HC_PAST_GATE, []{return true;}),
});
areaTable[RR_HC_STORMS_GROTTO] = Region("HC Storms Grotto", SCENE_GROTTOS, {}, {
@@ -78,7 +121,7 @@ void RegionTable_Init_CastleGrounds() {
LOCATION(RC_HC_GS_STORMS_GROTTO, logic->CanUse(RG_BOOMERANG) && ctx->GetTrickOption(RT_HC_STORMS_GS)),
}, {
//Exits
Entrance(RR_CASTLE_GROUNDS, []{return true;}),
Entrance(RR_HC_MOAT, []{return true;}),
Entrance(RR_HC_STORMS_GROTTO_BEHIND_WALLS, []{return logic->CanBreakMudWalls();}),
});
@@ -125,8 +168,8 @@ void RegionTable_Init_CastleGrounds() {
areaTable[RR_CASTLE_GROUNDS_FROM_GANONS_CASTLE] = Region("Castle Grounds From Ganon's Castle", SCENE_OUTSIDE_GANONS_CASTLE, {}, {}, {
// Exits
Entrance(RR_HYRULE_CASTLE_GROUNDS, []{return logic->IsChild;}),
Entrance(RR_GANONS_CASTLE_LEDGE, []{return logic->IsAdult;}),
Entrance(RR_HC_DRAIN_LEDGE, []{return logic->IsChild;}),
Entrance(RR_GANONS_CASTLE_LEDGE, []{return logic->IsAdult;}),
});
areaTable[RR_GANONS_CASTLE_LEDGE] = Region("Ganon's Castle Ledge", SCENE_OUTSIDE_GANONS_CASTLE, {}, {}, {
@@ -38,7 +38,7 @@ void RegionTable_Init_DeathMountainCrater() {
LOCATION(RC_DMC_DEKU_SCRUB, logic->IsChild && logic->CanStunDeku() && GetCheckPrice() <= GetWalletCapacity()),
}, {
//Exits
Entrance(RR_DMC_UPPER_NEARBY, []{return logic->Hearts() >= 3;}),
Entrance(RR_DMC_UPPER_NEARBY, []{return (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT)) && logic->Hearts() >= 3;}),
Entrance(RR_DMC_LOWER_NEARBY, []{return logic->Hearts() >= 3 && (logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_DMC_BOULDER_JS) && logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)) || (ctx->GetTrickOption(RT_DMC_BOULDER_SKIP) && logic->IsAdult));}),
});
@@ -70,7 +70,7 @@ void RegionTable_Init_DeathMountainCrater() {
LOCATION(RC_SHEIK_IN_CRATER, logic->IsAdult && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)),
}, {
//Exits
Entrance(RR_DMC_CENTRAL_LOCAL, []{return logic->FireTimer() >= 48;}),
Entrance(RR_DMC_CENTRAL_LOCAL, []{return logic->FireTimer() >= 48;}),
});
areaTable[RR_DMC_CENTRAL_LOCAL] = Region("DMC Central Local", SCENE_DEATH_MOUNTAIN_CRATER, {
@@ -92,11 +92,11 @@ void RegionTable_Init_DeathMountainCrater() {
LOCATION(RC_DMC_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)),
}, {
//Exits
Entrance(RR_DMC_CENTRAL_NEARBY, []{return true;}),
Entrance(RR_DMC_LOWER_NEARBY, []{return (logic->IsAdult && CanPlantBean(RR_DMC_CENTRAL_LOCAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT);}),
Entrance(RR_DMC_UPPER_NEARBY, []{return logic->IsAdult && CanPlantBean(RR_DMC_CENTRAL_LOCAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL);}),
Entrance(RR_FIRE_TEMPLE_ENTRYWAY, []{return (logic->IsChild && logic->Hearts() >= 3 && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF)) || (logic->IsAdult && logic->FireTimer() >= 24);}),
Entrance(RR_DMC_DISTANT_PLATFORM, []{return logic->FireTimer() >= 48 && logic->IsAdult && logic->ReachDistantScarecrow();}),
Entrance(RR_DMC_CENTRAL_NEARBY, []{return true;}),
Entrance(RR_DMC_LOWER_NEARBY, []{return (logic->IsAdult && CanPlantBean(RR_DMC_CENTRAL_LOCAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)) || (logic->CanUse(RG_HOVER_BOOTS) && (logic->IsAdult || logic->HasItem(RG_CLIMB))) || logic->CanUse(RG_HOOKSHOT);}),
Entrance(RR_DMC_UPPER_NEARBY, []{return logic->IsAdult && CanPlantBean(RR_DMC_CENTRAL_LOCAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL);}),
Entrance(RR_DMC_OUTSIDE_FIRE_TEMPLE, []{return (logic->IsChild && logic->Hearts() >= 3 && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF)) || (logic->IsAdult && logic->FireTimer() >= 24);}),
Entrance(RR_DMC_DISTANT_PLATFORM, []{return logic->FireTimer() >= 48 && logic->IsAdult && logic->ReachDistantScarecrow();}),
});
areaTable[RR_DMC_GREAT_FAIRY_FOUNTAIN] = Region("DMC Great Fairy Fountain", SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, {}, {
@@ -150,5 +150,11 @@ void RegionTable_Init_DeathMountainCrater() {
Entrance(RR_DMC_CENTRAL_LOCAL, []{return logic->FireTimer() >= 48 && logic->IsAdult && logic->ReachDistantScarecrow();}),
});
areaTable[RR_DMC_OUTSIDE_FIRE_TEMPLE] = Region("DMC Outside Fire Temple", SCENE_DEATH_MOUNTAIN_CRATER, {}, {}, {
//Exits
Entrance(RR_FIRE_TEMPLE_ENTRYWAY, []{return true;}),
Entrance(RR_DMC_CENTRAL_LOCAL, []{return logic->FireTimer() >= 48 && logic->HasItem(RG_CLIMB);}),
});
// clang-format on
}
@@ -13,7 +13,7 @@ void RegionTable_Init_DeathMountainTrail() {
LOCATION(RC_DMT_CHEST, (logic->BlastOrSmash() || (ctx->GetTrickOption(RT_DMT_BOMBABLE) && logic->IsChild && logic->HasItem(RG_GORONS_BRACELET))) && logic->HasItem(RG_OPEN_CHEST)),
LOCATION(RC_DMT_FREESTANDING_POH, logic->TakeDamage() || logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && CanPlantBean(RR_DEATH_MOUNTAIN_TRAIL, RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET)))),
LOCATION(RC_DMT_GS_BEAN_PATCH, logic->CanSpawnSoilSkull(RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET) || (ctx->GetTrickOption(RT_DMT_SOIL_GS) && (logic->TakeDamage() || logic->CanUse(RG_HOVER_BOOTS)) && logic->CanUse(RG_BOOMERANG)))),
LOCATION(RC_DMT_GS_NEAR_KAK, logic->BlastOrSmash()),
LOCATION(RC_DMT_GS_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_HOOKSHOT_EXTENSION) && logic->CanUse(RG_HOOKSHOT)) || (ctx->GetTrickOption(RT_DMT_BEAN_LOWER_GS) && CanPlantBean(RR_DEATH_MOUNTAIN_TRAIL, RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL)) || (ctx->GetTrickOption(RT_DMT_HOVERS_LOWER_GS) && logic->CanUse(RG_HOVER_BOOTS)) || (ctx->GetTrickOption(RT_DMT_JS_LOWER_GS) && logic->CanJumpslash()) || (ctx->GetTrickOption(RT_DISTANT_BOULDER_COLLISION) && logic->CanUse(RG_LONGSHOT)))),
LOCATION(RC_DMT_BLUE_RUPEE, logic->IsChild && logic->BlastOrSmash()),
LOCATION(RC_DMT_RED_RUPEE, logic->IsChild && logic->BlastOrSmash()),
@@ -25,11 +25,21 @@ void RegionTable_Init_DeathMountainTrail() {
//Exits
Entrance(RR_KAK_BEHIND_GATE, []{return true;}),
Entrance(RR_GORON_CITY, []{return true;}),
Entrance(RR_DEATH_MOUNTAIN_SUMMIT, []{return 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, []{return 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_DODONGOS_CAVERN_ENTRYWAY, []{return logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET) || logic->IsAdult;}),
Entrance(RR_DMT_STORMS_GROTTO, []{return logic->CanOpenStormsGrotto();}),
});
areaTable[RR_DEATH_MOUNTAIN_ROCKFALL] = Region("Death Mountain Avalanche", SCENE_DEATH_MOUNTAIN_TRAIL, {}, {
//Locations
LOCATION(RC_DMT_GS_FALLING_ROCKS_PATH, logic->IsAdult && logic->CanGetNightTimeGS() && (logic->CanUse(RG_MEGATON_HAMMER) || (ctx->GetTrickOption(RT_DMT_UPPER_GS) && (logic->CanJumpslash() || logic->HasExplosives() || ((ctx->GetTrickOption(RT_DISTANT_BOULDER_COLLISION) || ctx->GetTrickOption(RT_HOOKSHOT_EXTENSION)) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT))))) || (ctx->GetTrickOption(RT_DISTANT_BOULDER_COLLISION) && logic->CanUse(RG_LONGSHOT)))),
}, {
//Exits
Entrance(RR_DEATH_MOUNTAIN_TRAIL, []{return true;}),
Entrance(RR_DEATH_MOUNTAIN_SUMMIT, []{return logic->HasItem(RG_CLIMB);}),
Entrance(RR_DMT_COW_GROTTO, []{return AnyAgeTime([]{return logic->BlastOrSmash();});}),
});
areaTable[RR_DEATH_MOUNTAIN_SUMMIT] = Region("Death Mountain Summit", SCENE_DEATH_MOUNTAIN_TRAIL, {
//Events
EventAccess(LOGIC_FAIRY_ACCESS, []{return logic->CallGossipFairy();}),
@@ -39,17 +49,14 @@ void RegionTable_Init_DeathMountainTrail() {
LOCATION(RC_DMT_TRADE_BROKEN_SWORD, logic->IsAdult && logic->CanUse(RG_BROKEN_SWORD)),
LOCATION(RC_DMT_TRADE_EYEDROPS, logic->IsAdult && logic->CanUse(RG_EYEDROPS)),
LOCATION(RC_DMT_TRADE_CLAIM_CHECK, logic->IsAdult && logic->CanUse(RG_CLAIM_CHECK)),
// backflip can collect token, allowing use of explosives (or bow from afar), but it's a trick
LOCATION(RC_DMT_GS_FALLING_ROCKS_PATH, logic->IsAdult && logic->CanGetNightTimeGS() && (logic->CanUse(RG_MEGATON_HAMMER) || (ctx->GetTrickOption(RT_DMT_UPPER_GS) && (logic->CanJumpslash() || logic->HasExplosives() || ((ctx->GetTrickOption(RT_DISTANT_BOULDER_COLLISION) || ctx->GetTrickOption(RT_HOOKSHOT_EXTENSION)) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT))))) || (ctx->GetTrickOption(RT_DISTANT_BOULDER_COLLISION) && logic->CanUse(RG_LONGSHOT)))),
LOCATION(RC_DMT_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()),
LOCATION(RC_DMT_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_DMT_GOSSIP_STONE, true),
}, {
//Exits
Entrance(RR_DEATH_MOUNTAIN_TRAIL, []{return true;}),
Entrance(RR_DEATH_MOUNTAIN_ROCKFALL, []{return true;}),
Entrance(RR_DMC_UPPER_LOCAL, []{return true;}),
Entrance(RR_DMT_OWL_FLIGHT, []{return logic->IsChild;}, false),
Entrance(RR_DMT_COW_GROTTO, []{return AnyAgeTime([]{return logic->BlastOrSmash();});}),
Entrance(RR_DMT_GREAT_FAIRY_FOUNTAIN, []{return AnyAgeTime([]{return logic->BlastOrSmash();});}),
});
@@ -78,7 +85,7 @@ void RegionTable_Init_DeathMountainTrail() {
LOCATION(RC_DMT_COW_GROTTO_GRASS_2, logic->CanCutShrubs()),
}, {
//Exits
Entrance(RR_DEATH_MOUNTAIN_SUMMIT, []{return true;}),
Entrance(RR_DEATH_MOUNTAIN_ROCKFALL, []{return true;}),
});
areaTable[RR_DMT_STORMS_GROTTO] = Region("DMT Storms Grotto", SCENE_GROTTOS, grottoEvents, {
@@ -9,7 +9,7 @@ void RegionTable_Init_GerudoFortress() {
areaTable[RR_GF_OUTSKIRTS] = Region("Gerudo Fortress Outskirts", SCENE_GERUDOS_FORTRESS, {
//Events
EventAccess(LOGIC_GF_GATE_OPEN, []{return logic->IsAdult && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD);}), //needs climb
EventAccess(LOGIC_GF_GATE_OPEN, []{return logic->IsAdult && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && logic->HasItem(RG_CLIMB);}), // longshot can get up without climb, but jank is hard
}, {
//Locations
LOCATION(RC_GF_OUTSKIRTS_NE_CRATE, (logic->IsChild || logic->CanPassEnemy(RE_GERUDO_GUARD)) && logic->CanBreakCrates()),
@@ -92,7 +92,7 @@ void RegionTable_Init_GerudoFortress() {
//Exits
Entrance(RR_TH_STEEP_SLOPE_CELL, []{return true;}),
Entrance(RR_GF_NEAR_GROTTO, []{return true;}),
Entrance(RR_GF_TOP_OF_LOWER_VINES, []{return true /* logic->CanClimb() */;}),
Entrance(RR_GF_TOP_OF_LOWER_VINES, []{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT);}),
Entrance(RR_GF_ABOVE_GTG, []{return true;}),
Entrance(RR_GF_BELOW_GS, []{return logic->IsAdult && logic->CanGroundJump();}),
});
@@ -134,14 +134,14 @@ void RegionTable_Init_GerudoFortress() {
Entrance(RR_GF_OUTSIDE_GTG, []{return true;}),
Entrance(RR_GF_TOP_OF_LOWER_VINES, []{return true;}),
Entrance(RR_GF_SLOPED_ROOF, []{return logic->IsAdult && (logic->CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS));}),
Entrance(RR_GF_TOP_OF_UPPER_VINES, []{return true /* logic->CanClimb() */;}),
Entrance(RR_GF_TOP_OF_UPPER_VINES, []{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT);}),
Entrance(RR_GF_TO_GTG, []{return logic->IsAdult && ctx->GetTrickOption(RT_GF_LEDGE_CLIP_INTO_GTG).Get();}),
});
areaTable[RR_GF_TOP_OF_UPPER_VINES] = Region("GF Top of Upper Vines", SCENE_GERUDOS_FORTRESS, {}, {
//Locations
//if RR_GF_SLOPED_ROOF > RR_GF_TOP_OF_UPPER_VINES is ever made part of RT_UNINTUITIVE_JUMPS, climb is needed to get back up
LOCATION(RC_GF_GS_TOP_FLOOR, logic->IsAdult && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_SHORT_JUMPSLASH) && logic->CanGetNightTimeGS()),
LOCATION(RC_GF_GS_TOP_FLOOR, logic->IsAdult && logic->CanGetNightTimeGS() && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_SHORT_JUMPSLASH) && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_BOOMERANG) || ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS))),
}, {
//Exits
Entrance(RR_GF_TOP_OF_LOWER_VINES, []{return true;}),
@@ -10,16 +10,18 @@ void RegionTable_Init_GerudoValley() {
EventAccess(LOGIC_BUG_ACCESS, []{return logic->IsChild && logic->HasItem(RG_POWER_BRACELET);}),
}, {
//Locations
LOCATION(RC_GV_GS_SMALL_BRIDGE, logic->IsChild && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()),
LOCATION(RC_GV_GS_SMALL_BRIDGE, logic->IsChild && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()),
}, {
//Exits
Entrance(RR_HYRULE_FIELD, []{return true;}),
Entrance(RR_GV_UPPER_STREAM, []{return (logic->IsChild && logic->HasItem(RG_POWER_BRACELET)) || logic->HasItem(RG_BRONZE_SCALE) || logic->TakeDamage();}),
Entrance(RR_GV_CRATE_LEDGE, []{return (logic->IsChild && logic->HasItem(RG_POWER_BRACELET)) || logic->CanUse(RG_LONGSHOT);}),
Entrance(RR_GV_GROTTO_LEDGE, []{return true;}),
Entrance(RR_GV_FORTRESS_SIDE, []{return (logic->IsAdult && (logic->SummonEpona() || logic->CanUse(RG_LONGSHOT) || ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE) || logic->Get(LOGIC_TH_RESCUED_ALL_CARPENTERS))) || (ctx->GetTrickOption(RT_HOVER_BOOST_SIMPLE) && logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_HOVER_BOOTS)) ||
((logic->IsChild || ctx->GetTrickOption(RT_HOOKSHOT_EXTENSION)) && logic->CanUse(RG_HOOKSHOT)) || (logic->IsChild && ctx->GetTrickOption(RT_GV_CHILD_CUCCO_JUMP) && logic->HasItem(RG_POWER_BRACELET) && logic->CanJumpslash());}),
Entrance(RR_GV_LOWER_STREAM, []{return logic->IsChild && logic->HasItem(RG_POWER_BRACELET);}),
Entrance(RR_HYRULE_FIELD, []{return true;}),
Entrance(RR_GV_UPPER_STREAM, []{return (logic->IsChild && logic->HasItem(RG_POWER_BRACELET)) || logic->TakeDamage();}),
Entrance(RR_GV_UPPER_STREAM_WATER, []{return true;}),
Entrance(RR_GV_CRATE_LEDGE, []{return (logic->IsChild && logic->HasItem(RG_POWER_BRACELET)) || logic->CanUse(RG_LONGSHOT);}),
Entrance(RR_GV_GROTTO_LEDGE, []{return true;}),
Entrance(RR_GV_FORTRESS_SIDE, []{return (logic->IsAdult && (logic->SummonEpona() || logic->CanUse(RG_LONGSHOT) || ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE) || logic->Get(LOGIC_TH_RESCUED_ALL_CARPENTERS))) || (ctx->GetTrickOption(RT_HOVER_BOOST_SIMPLE) && logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_HOVER_BOOTS)) ||
((logic->IsChild || ctx->GetTrickOption(RT_HOOKSHOT_EXTENSION)) && logic->CanUse(RG_HOOKSHOT)) || (logic->IsChild && ctx->GetTrickOption(RT_GV_CHILD_CUCCO_JUMP) && logic->HasItem(RG_POWER_BRACELET) && logic->CanJumpslash());}),
Entrance(RR_GV_WATERFALL_ALCOVE, []{return logic->IsChild && logic->HasItem(RG_POWER_BRACELET);}),
Entrance(RR_GV_LOWER_STREAM, []{return logic->IsChild && logic->HasItem(RG_POWER_BRACELET);}),
});
areaTable[RR_GV_UPPER_STREAM] = Region("GV Upper Stream", SCENE_GERUDO_VALLEY, {
@@ -27,19 +29,26 @@ void RegionTable_Init_GerudoValley() {
EventAccess(LOGIC_FAIRY_ACCESS, []{return logic->CallGossipFairy() || (logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_GERUDO_VALLEY_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS));}),
}, {
//Locations
LOCATION(RC_GV_WATERFALL_FREESTANDING_POH, (logic->IsChild && logic->HasItem(RG_POWER_BRACELET)) || logic->HasItem(RG_BRONZE_SCALE) || CanPlantBean(RR_GV_UPPER_STREAM, RG_GERUDO_VALLEY_BEAN_SOUL)),
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_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_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_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()),
}, {
//Exits
Entrance(RR_GV_LOWER_STREAM, []{return logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS);}),
Entrance(RR_GV_UPPER_STREAM_WATER, []{return true;}),
Entrance(RR_GV_WATERFALL_ALCOVE, []{return (logic->CanUse(RG_HOOKSHOT) && logic->HasItem(RG_CLIMB)) || logic->CanUse(RG_LONGSHOT) || CanPlantBean(RR_GV_UPPER_STREAM, RG_GERUDO_VALLEY_BEAN_SOUL);}),
});
areaTable[RR_GV_UPPER_STREAM_WATER] = Region("GV Upper Stream Water", SCENE_GERUDO_VALLEY, {}, {}, {
//Exits
Entrance(RR_GV_UPPER_STREAM, []{return logic->HasItem(RG_BRONZE_SCALE);}),
Entrance(RR_GV_LOWER_STREAM, []{return logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS);}),
Entrance(RR_GV_WATERFALL_ALCOVE, []{return (logic->HasItem(RG_BRONZE_SCALE) || (logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT))) && logic->HasItem(RG_CLIMB);}),
});
// scale/boots logic is outside lower stream, as lower stream combines access to lake hylia for entrance randomizer's sake
@@ -48,9 +57,18 @@ void RegionTable_Init_GerudoValley() {
Entrance(RR_LAKE_HYLIA, []{return true;}),
});
areaTable[RR_GV_WATERFALL_ALCOVE] = Region("GV Waterfall Alcove", SCENE_GERUDO_VALLEY, {}, {
//Locations
LOCATION(RC_GV_WATERFALL_FREESTANDING_POH, true),
}, {
//Exits
Entrance(RR_GV_UPPER_STREAM, []{return logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS);}),
Entrance(RR_GV_UPPER_STREAM_WATER, []{return true;}),
});
areaTable[RR_GV_GROTTO_LEDGE] = Region("GV Grotto Ledge", SCENE_GERUDO_VALLEY, {}, {}, {
//Exits
Entrance(RR_GV_UPPER_STREAM, []{return ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives();}),
Entrance(RR_GV_UPPER_STREAM, []{return ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives() && logic->TakeDamage();}),
Entrance(RR_GV_LOWER_STREAM, []{return logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS);}),
Entrance(RR_GV_OCTOROK_GROTTO, []{return logic->CanUse(RG_SILVER_GAUNTLETS);}),
Entrance(RR_GV_CRATE_LEDGE, []{return logic->CanUse(RG_LONGSHOT);}),
@@ -62,7 +80,7 @@ void RegionTable_Init_GerudoValley() {
LOCATION(RC_GV_FREESTANDING_POH_CRATE, logic->CanBreakCrates()),
}, {
//Exits
Entrance(RR_GV_UPPER_STREAM, []{return ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives();}),
Entrance(RR_GV_UPPER_STREAM, []{return ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives() && logic->TakeDamage();}),
Entrance(RR_GV_LOWER_STREAM, []{return logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS);}),
});
@@ -78,12 +96,13 @@ void RegionTable_Init_GerudoValley() {
LOCATION(RC_GV_CRATE_BRIDGE_4, logic->IsChild && logic->CanBreakCrates()),
}, {
//Exits
Entrance(RR_GF_OUTSKIRTS, []{return true;}),
Entrance(RR_GV_UPPER_STREAM, []{return true;}),
Entrance(RR_GERUDO_VALLEY, []{return logic->IsChild || logic->SummonEpona() || logic->CanUse(RG_LONGSHOT) || ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE) || logic->Get(LOGIC_TH_RESCUED_ALL_CARPENTERS) || (ctx->GetTrickOption(RT_HOVER_BOOST_SIMPLE) && logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_HOVER_BOOTS));}),
Entrance(RR_GV_CARPENTER_TENT, []{return logic->IsAdult || ctx->GetTrickOption(RT_GV_CHILD_TENT);}),
Entrance(RR_GV_STORMS_GROTTO, []{return logic->IsAdult && logic->CanOpenStormsGrotto();}),
Entrance(RR_GV_CRATE_LEDGE, []{return (ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives()) || (ctx->GetTrickOption(RT_GV_CRATE_HOVERS) && logic->TakeDamage() && logic->CanUse(RG_HOVER_BOOTS) && (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)));}),
Entrance(RR_GF_OUTSKIRTS, []{return true;}),
Entrance(RR_GV_UPPER_STREAM, []{return logic->TakeDamage();}),
Entrance(RR_GV_UPPER_STREAM_WATER, []{return true;}),
Entrance(RR_GERUDO_VALLEY, []{return logic->IsChild || logic->SummonEpona() || logic->CanUse(RG_LONGSHOT) || ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE) || logic->Get(LOGIC_TH_RESCUED_ALL_CARPENTERS) || (ctx->GetTrickOption(RT_HOVER_BOOST_SIMPLE) && logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_HOVER_BOOTS));}),
Entrance(RR_GV_CARPENTER_TENT, []{return logic->IsAdult || ctx->GetTrickOption(RT_GV_CHILD_TENT);}),
Entrance(RR_GV_STORMS_GROTTO, []{return logic->IsAdult && logic->CanOpenStormsGrotto();}),
Entrance(RR_GV_CRATE_LEDGE, []{return (ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives()) || (ctx->GetTrickOption(RT_GV_CRATE_HOVERS) && logic->TakeDamage() && logic->CanUse(RG_HOVER_BOOTS) && (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)));}),
});
areaTable[RR_GV_CARPENTER_TENT] = Region("GV Carpenter Tent", SCENE_CARPENTERS_TENT, {}, {}, {
@@ -171,13 +171,13 @@ void RegionTable_Init_HyruleField() {
}, {
//Exits
Entrance(RR_LW_BRIDGE, []{return true;}),
Entrance(RR_LAKE_HYLIA, []{return true;}),
Entrance(RR_GERUDO_VALLEY, []{return true;}),
Entrance(RR_MARKET_ENTRANCE, []{return true;}),
Entrance(RR_KAKARIKO_VILLAGE, []{return true;}),
Entrance(RR_ZR_FRONT, []{return true;}),
Entrance(RR_LON_LON_RANCH, []{return true;}),
Entrance(RR_HF_SOUTHEAST_GROTTO, []{return AnyAgeTime([]{return logic->BlastOrSmash();});}),
Entrance(RR_HF_TO_LAKE_HYLIA, []{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT) || logic->SummonEpona();}),
Entrance(RR_HF_OPEN_GROTTO, []{return true;}),
Entrance(RR_HF_INSIDE_FENCE_GROTTO, []{return logic->CanOpenBombGrotto();}),
Entrance(RR_HF_COW_GROTTO, []{return (logic->CanUse(RG_MEGATON_HAMMER) || logic->IsChild) && logic->CanOpenBombGrotto();}),
@@ -187,6 +187,12 @@ void RegionTable_Init_HyruleField() {
Entrance(RR_HF_TEKTITE_GROTTO, []{return logic->CanOpenBombGrotto();}),
});
areaTable[RR_HF_TO_LAKE_HYLIA] = Region("HF to Lake Hylia", SCENE_HYRULE_FIELD, {}, {}, {
//Exits
Entrance(RR_LAKE_HYLIA, []{return true;}),
Entrance(RR_HYRULE_FIELD, []{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT) || logic->SummonEpona();}),
});
areaTable[RR_HF_SOUTHEAST_GROTTO] = Region("HF Southeast Grotto", SCENE_GROTTOS, grottoEvents, {
//Locations
LOCATION(RC_HF_SOUTHEAST_GROTTO_CHEST, logic->HasItem(RG_OPEN_CHEST)),
@@ -15,8 +15,7 @@ void RegionTable_Init_Kakariko() {
}, {
//Locations
LOCATION(RC_SHEIK_IN_KAKARIKO, logic->IsAdult && logic->HasItem(RG_FOREST_MEDALLION) && logic->HasItem(RG_FIRE_MEDALLION) && logic->HasItem(RG_WATER_MEDALLION)),
// RANDOTODO Readd chickens to rando settings
LOCATION(RC_KAK_ANJU_AS_CHILD, logic->IsChild && logic->AtDay && logic->HasItem(RG_POWER_BRACELET) && logic->CanBreakCrates()),
LOCATION(RC_KAK_ANJU_AS_CHILD, logic->IsChild && logic->AtDay && logic->HasItem(RG_CLIMB) && logic->HasItem(RG_POWER_BRACELET) && logic->CanBreakCrates()), // RANDOTODO adjust requirements to cucco settings
LOCATION(RC_KAK_ANJU_AS_ADULT, logic->IsAdult && logic->AtDay),
LOCATION(RC_KAK_TRADE_POCKET_CUCCO, logic->IsAdult && logic->AtDay && (logic->CanUse(RG_POCKET_EGG) && logic->Get(LOGIC_WAKE_UP_ADULT_TALON))),
//Can kill lower kak skulls with pots
@@ -24,7 +23,7 @@ void RegionTable_Init_Kakariko() {
LOCATION(RC_KAK_GS_SKULLTULA_HOUSE, logic->IsChild && logic->CanGetNightTimeGS() && (logic->HasItem(RG_POWER_BRACELET) || logic->CanKillEnemy(RE_GOLD_SKULLTULA))),
LOCATION(RC_KAK_GS_GUARDS_HOUSE, logic->IsChild && logic->CanGetNightTimeGS() && (logic->HasItem(RG_POWER_BRACELET) || logic->CanKillEnemy(RE_GOLD_SKULLTULA))),
LOCATION(RC_KAK_GS_TREE, logic->IsChild && logic->CanGetNightTimeGS() && logic->CanBonkTrees() && (logic->HasItem(RG_POWER_BRACELET) || logic->CanKillEnemy(RE_GOLD_SKULLTULA))),
LOCATION(RC_KAK_GS_WATCHTOWER, logic->IsChild && (logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_LONGSHOT) || (ctx->GetTrickOption(RT_KAK_TOWER_GS) && logic->CanJumpslashExceptHammer())) && logic->CanGetNightTimeGS()),
LOCATION(RC_KAK_GS_WATCHTOWER, logic->IsChild && logic->HasItem(RG_CLIMB) && (logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_LONGSHOT) || (ctx->GetTrickOption(RT_KAK_TOWER_GS) && logic->CanJumpslashExceptHammer())) && logic->CanGetNightTimeGS()),
LOCATION(RC_KAK_NEAR_POTION_SHOP_POT_1, logic->IsChild && logic->CanBreakPots()),
LOCATION(RC_KAK_NEAR_POTION_SHOP_POT_2, logic->IsChild && logic->CanBreakPots()),
LOCATION(RC_KAK_NEAR_POTION_SHOP_POT_3, logic->IsChild && logic->CanBreakPots()),
@@ -74,7 +73,7 @@ void RegionTable_Init_Kakariko() {
Entrance(RR_KAK_POTION_SHOP_FRONT, []{return (logic->AtDay || logic->IsChild) && logic->CanOpenOverworldDoor(RG_KAK_POTION_SHOP_KEY);}),
Entrance(RR_KAK_REDEAD_GROTTO, []{return logic->CanOpenBombGrotto();}),
Entrance(RR_KAK_IMPAS_LEDGE, []{return (logic->IsChild && logic->AtDay && logic->HasItem(RG_POWER_BRACELET)) || (logic->IsAdult && ctx->GetTrickOption(RT_VISIBLE_COLLISION));}),
Entrance(RR_KAK_WATCHTOWER, []{return logic->IsAdult || logic->AtDay || logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_LONGSHOT) || (ctx->GetTrickOption(RT_KAK_TOWER_GS) && logic->CanJumpslashExceptHammer());}),
Entrance(RR_KAK_WATCHTOWER, []{return logic->HasItem(RG_CLIMB) && (logic->IsAdult || logic->AtDay || logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_LONGSHOT) || (ctx->GetTrickOption(RT_KAK_TOWER_GS) && logic->CanJumpslashExceptHammer()));}),
Entrance(RR_KAK_ROOFTOP, []{return logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_UNINTUITIVE_JUMPS) && logic->IsAdult);}),
Entrance(RR_KAK_IMPAS_ROOFTOP, []{return logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_KAK_ROOFTOP_GS) && logic->CanUse(RG_HOVER_BOOTS));}),
Entrance(RR_THE_GRAVEYARD, []{return true;}),
@@ -280,7 +279,7 @@ void RegionTable_Init_Kakariko() {
areaTable[RR_KAK_WELL] = Region("Kak Well", SCENE_KAKARIKO_VILLAGE, {}, {}, {
//Exits
Entrance(RR_KAKARIKO_VILLAGE, []{return logic->IsAdult || logic->HasItem(RG_BRONZE_SCALE) || logic->Get(LOGIC_DRAIN_WELL);}),
Entrance(RR_KAKARIKO_VILLAGE, []{return logic->HasItem(RG_CLIMB) && (logic->IsAdult || logic->HasItem(RG_BRONZE_SCALE) || logic->Get(LOGIC_DRAIN_WELL));}),
Entrance(RR_BOTW_ENTRYWAY, []{return logic->IsChild || (logic->Get(LOGIC_DRAIN_WELL) && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF));}),
});
@@ -19,8 +19,6 @@ void RegionTable_Init_KokiriForest() {
LOCATION(RC_KF_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_KOKIRI_FOREST_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_KF_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_KOKIRI_FOREST_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_KF_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_KOKIRI_FOREST_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_KF_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()),
LOCATION(RC_KF_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_KF_BRIDGE_RUPEE, logic->IsChild),
LOCATION(RC_KF_BEHIND_MIDOS_RUPEE, logic->IsChild),
LOCATION(RC_KF_SOUTH_GRASS_WEST_RUPEE, logic->IsChild),
@@ -37,7 +35,6 @@ void RegionTable_Init_KokiriForest() {
LOCATION(RC_KF_SARIAS_ROOF_WEST_HEART, logic->IsChild),
LOCATION(RC_KF_SARIAS_ROOF_EAST_HEART, logic->IsChild),
LOCATION(RC_KF_SARIAS_ROOF_NORTH_HEART, logic->IsChild),
LOCATION(RC_KF_GOSSIP_STONE, true),
LOCATION(RC_KF_CHILD_GRASS_1, logic->IsChild && logic->CanCutShrubs()),
LOCATION(RC_KF_CHILD_GRASS_2, logic->IsChild && logic->CanCutShrubs()),
LOCATION(RC_KF_CHILD_GRASS_3, logic->IsChild && logic->CanCutShrubs()),
@@ -73,16 +70,16 @@ void RegionTable_Init_KokiriForest() {
}, {
//Exits
Entrance(RR_KF_BOULDER_LOOP, []{return logic->CanUse(RG_CRAWL);}),
Entrance(RR_KF_LINKS_HOUSE, []{return true;}),
Entrance(RR_KF_LINKS_PORCH, []{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOVER_BOOTS);}),
Entrance(RR_KF_MIDOS_HOUSE, []{return true;}),
Entrance(RR_KF_SARIAS_HOUSE, []{return true;}),
Entrance(RR_KF_HOUSE_OF_TWINS, []{return true;}),
Entrance(RR_KF_KNOW_IT_ALL_HOUSE, []{return true;}),
Entrance(RR_KF_KOKIRI_SHOP, []{return true;}),
Entrance(RR_KF_OUTSIDE_DEKU_TREE, []{return (logic->IsAdult && (logic->CanPassEnemy(RE_BIG_SKULLTULA) || logic->Get(LOGIC_FOREST_TEMPLE_CLEAR))) || ctx->GetOption(RSK_FOREST).Is(RO_CLOSED_FOREST_OFF) || logic->Get(LOGIC_SHOWED_MIDO_SWORD_AND_SHIELD);}),
Entrance(RR_THE_LOST_WOODS, []{return true;}),
Entrance(RR_KF_OUTSIDE_LOST_WOODS, []{return 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, []{return logic->IsAdult && CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL);}),
Entrance(RR_LW_BRIDGE_FROM_FOREST, []{return logic->IsAdult || ctx->GetOption(RSK_FOREST).IsNot(RO_CLOSED_FOREST_ON) || logic->Get(LOGIC_DEKU_TREE_CLEAR);}),
Entrance(RR_KF_STORMS_GROTTO, []{return logic->CanOpenStormsGrotto();}),
});
areaTable[RR_KF_BOULDER_LOOP] = Region("KF Boulder Loop", SCENE_KOKIRI_FOREST, {}, {
@@ -118,13 +115,18 @@ void RegionTable_Init_KokiriForest() {
Entrance(RR_KOKIRI_FOREST, []{return (logic->IsAdult && (logic->CanPassEnemy(RE_BIG_SKULLTULA) || logic->Get(LOGIC_DEKU_TREE_CLEAR))) || ctx->GetOption(RSK_FOREST).Is(RO_CLOSED_FOREST_OFF) || logic->Get(LOGIC_SHOWED_MIDO_SWORD_AND_SHIELD);}),
});
areaTable[RR_KF_LINKS_PORCH] = Region("KF Link's Porch", SCENE_KOKIRI_FOREST, {}, {}, {
Entrance(RR_KOKIRI_FOREST, []{return true;}),
Entrance(RR_KF_LINKS_HOUSE, []{return true;}),
});
areaTable[RR_KF_LINKS_HOUSE] = Region("KF Link's House", SCENE_LINKS_HOUSE, {}, {
//Locations
LOCATION(RC_KF_LINKS_HOUSE_COW, logic->IsAdult && logic->CanUse(RG_EPONAS_SONG) && logic->Get(LOGIC_LINKS_COW)),
LOCATION(RC_KF_LINKS_HOUSE_POT, logic->CanBreakPots()),
}, {
//Exits
Entrance(RR_KOKIRI_FOREST, []{return true;})
Entrance(RR_KF_LINKS_PORCH, []{return true;})
});
areaTable[RR_KF_MIDOS_HOUSE] = Region("KF Mido's House", SCENE_MIDOS_HOUSE, {}, {
@@ -182,6 +184,39 @@ void RegionTable_Init_KokiriForest() {
Entrance(RR_KOKIRI_FOREST, []{return true;}),
});
areaTable[RR_KF_OUTSIDE_LOST_WOODS] = Region("KF Outside Lost Woods", SCENE_KOKIRI_FOREST, {}, {
//Locations
LOCATION(RC_KF_BEAN_RUPEE_1, logic->IsAdult && logic->CanUse(RG_BOOMERANG)),
LOCATION(RC_KF_BEAN_RUPEE_2, logic->IsAdult && logic->CanUse(RG_BOOMERANG)),
LOCATION(RC_KF_BEAN_RUPEE_3, logic->IsAdult && logic->CanUse(RG_BOOMERANG)),
LOCATION(RC_KF_BEAN_RUPEE_4, logic->IsAdult && logic->CanUse(RG_BOOMERANG)),
LOCATION(RC_KF_BEAN_RUPEE_5, logic->IsAdult && logic->CanUse(RG_BOOMERANG)),
LOCATION(RC_KF_BEAN_RUPEE_6, logic->IsAdult && logic->CanUse(RG_BOOMERANG)),
LOCATION(RC_KF_BEAN_RED_RUPEE, logic->IsAdult && logic->CanUse(RG_BOOMERANG)),
LOCATION(RC_KF_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()),
LOCATION(RC_KF_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_KF_GOSSIP_STONE, true),
}, {
//Exits
Entrance(RR_KOKIRI_FOREST, []{return true;}),
Entrance(RR_THE_LOST_WOODS, []{return true;}),
Entrance(RR_KF_RUPEE_ALCOVE, []{return logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || logic->CanUse(RG_HOVER_BOOTS));}),
Entrance(RR_KF_STORMS_GROTTO, []{return logic->CanOpenStormsGrotto();}),
});
areaTable[RR_KF_RUPEE_ALCOVE] = Region("KF Alcove", SCENE_KOKIRI_FOREST, {}, {
//Locations
LOCATION(RC_KF_BEAN_RUPEE_1, logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)),
LOCATION(RC_KF_BEAN_RUPEE_2, logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)),
LOCATION(RC_KF_BEAN_RUPEE_3, logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)),
LOCATION(RC_KF_BEAN_RUPEE_4, logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)),
LOCATION(RC_KF_BEAN_RUPEE_5, logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)),
LOCATION(RC_KF_BEAN_RUPEE_6, logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)),
LOCATION(RC_KF_BEAN_RED_RUPEE, logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)),
}, {
Entrance(RR_KOKIRI_FOREST, []{return true;}),
});
areaTable[RR_KF_STORMS_GROTTO] = Region("KF Storms Grotto", SCENE_GROTTOS, grottoEvents, {
//Locations
LOCATION(RC_KF_STORMS_GROTTO_CHEST, logic->HasItem(RG_OPEN_CHEST)),
@@ -197,7 +232,7 @@ void RegionTable_Init_KokiriForest() {
LOCATION(RC_KF_STORMS_GROTTO_GRASS_4, logic->CanCutShrubs()),
}, {
//Exits
Entrance(RR_KOKIRI_FOREST, []{return true;})
Entrance(RR_KF_OUTSIDE_LOST_WOODS, []{return true;})
});
// clang-format on
@@ -15,7 +15,7 @@ void RegionTable_Init_LakeHylia() {
//Locations
LOCATION(RC_LH_UNDERWATER_ITEM, logic->IsChild && logic->HasItem(RG_SILVER_SCALE)),
LOCATION(RC_LH_SUN, logic->IsAdult && ((logic->Get(LOGIC_WATER_TEMPLE_CLEAR) && logic->HasItem(RG_BRONZE_SCALE)) || logic->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)),
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_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)),
@@ -81,7 +81,7 @@ void RegionTable_Init_LakeHylia() {
LOCATION(RC_LH_WARP_PAD_GRASS_2, logic->CanCutShrubs()),
}, {
//Exits
Entrance(RR_HYRULE_FIELD, []{return true;}),
Entrance(RR_HF_TO_LAKE_HYLIA, []{return true;}),
Entrance(RR_LH_FROM_SHORTCUT, []{return true;}),
Entrance(RR_LH_OWL_FLIGHT, []{return logic->IsChild;}),
Entrance(RR_LH_FISHING_ISLAND, []{return ((logic->IsChild || logic->Get(LOGIC_WATER_TEMPLE_CLEAR)) && logic->HasItem(RG_BRONZE_SCALE)) || (logic->IsAdult && (logic->ReachScarecrow() || CanPlantBean(RR_LAKE_HYLIA, RG_LAKE_HYLIA_BEAN_SOUL)));}),
@@ -7,7 +7,7 @@ void RegionTable_Init_LostWoods() {
// clang-format off
areaTable[RR_LW_FOREST_EXIT] = Region("LW Forest Exit", SCENE_LOST_WOODS, {}, {}, {
//Exits
Entrance(RR_KOKIRI_FOREST, []{return true;})
Entrance(RR_KF_OUTSIDE_LOST_WOODS, []{return true;})
});
areaTable[RR_THE_LOST_WOODS] = Region("Lost Woods", SCENE_LOST_WOODS, {
@@ -12,31 +12,50 @@ void RegionTable_Init_SacredForestMeadow() {
Entrance(RR_SFM_WOLFOS_GROTTO, []{return logic->CanOpenBombGrotto();}),
});
areaTable[RR_SACRED_FOREST_MEADOW] = Region("Sacred Forest Meadow", SCENE_SACRED_FOREST_MEADOW, {
areaTable[RR_SFM_ABOVE_MAZE] = Region("SFM Maze", SCENE_SACRED_FOREST_MEADOW, {
//Events
EventAccess(LOGIC_FAIRY_ACCESS, []{return logic->CallGossipFairyExceptSuns();}),
}, {
//Locations
LOCATION(RC_SONG_FROM_SARIA, logic->IsChild && logic->HasItem(RG_ZELDAS_LETTER)),
LOCATION(RC_SHEIK_IN_FOREST, logic->IsAdult),
LOCATION(RC_SFM_GS, logic->IsAdult && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()),
LOCATION(RC_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()),
LOCATION(RC_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()),
LOCATION(RC_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_SFM_SARIA_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()),
LOCATION(RC_SFM_SARIA_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_SFM_MAZE_LOWER_GOSSIP_STONE, true),
LOCATION(RC_SFM_MAZE_UPPER_GOSSIP_STONE, true),
LOCATION(RC_SFM_SARIA_GOSSIP_STONE, true),
}, {
//Exits
Entrance(RR_SFM_ENTRYWAY, []{return true;}),
Entrance(RR_SFM_ENTRYWAY, []{return true;}),
Entrance(RR_SFM_OUTSIDE_FAIRY_GROTTO, []{return true;}),
Entrance(RR_SACRED_FOREST_MEADOW, []{return true;}),
});
areaTable[RR_SACRED_FOREST_MEADOW] = Region("Sacred Forest Meadow", SCENE_SACRED_FOREST_MEADOW, {
//Events
EventAccess(LOGIC_FAIRY_ACCESS, []{return logic->CallGossipFairyExceptSuns();}),
}, {
//Locations
LOCATION(RC_SONG_FROM_SARIA, logic->IsChild && logic->HasItem(RG_ZELDAS_LETTER)),
LOCATION(RC_SHEIK_IN_FOREST, logic->IsAdult),
LOCATION(RC_SFM_SARIA_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()),
LOCATION(RC_SFM_SARIA_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)),
LOCATION(RC_SFM_SARIA_GOSSIP_STONE, true),
}, {
//Exits
Entrance(RR_FOREST_TEMPLE_ENTRYWAY, []{return logic->CanUse(RG_HOOKSHOT);}),
Entrance(RR_SFM_FAIRY_GROTTO, []{return true;}),
Entrance(RR_SFM_ENTRYWAY, []{return true;}),
// adult can jump up, but it's a trick. being hit directly by club moblin while wearing hover boots also works, but relies on coming from LW
Entrance(RR_SFM_ABOVE_MAZE, []{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanGroundJump());}),
Entrance(RR_SFM_STORMS_GROTTO, []{return logic->CanOpenStormsGrotto();}),
});
areaTable[RR_SFM_OUTSIDE_FAIRY_GROTTO] = Region("SFM Outside Fairy Grotto", SCENE_SACRED_FOREST_MEADOW, {}, {}, {
//Exits
Entrance(RR_SFM_FAIRY_GROTTO, []{return true;}),
Entrance(RR_SFM_ABOVE_MAZE, []{return logic->HasItem(RG_CLIMB) || logic->HasItem(RG_HOOKSHOT);}),
});
areaTable[RR_SFM_FAIRY_GROTTO] = Region("SFM Fairy Grotto", SCENE_GROTTOS, {
//Events
EventAccess(LOGIC_FAIRY_ACCESS, []{return true;}),
@@ -52,7 +71,7 @@ void RegionTable_Init_SacredForestMeadow() {
LOCATION(RC_SFM_FAIRY_GROTTO_FAIRY_8, true),
}, {
//Exits
Entrance(RR_SACRED_FOREST_MEADOW, []{return true;}),
Entrance(RR_SFM_OUTSIDE_FAIRY_GROTTO, []{return true;}),
});
areaTable[RR_SFM_WOLFOS_GROTTO] = Region("SFM Wolfos Grotto", SCENE_GROTTOS, {}, {
@@ -95,7 +95,7 @@ void RegionTable_Init_ZorasFountain() {
//Exits
//There are invisible big skultullas here as adult but they do not block the path and can be "seen" with Z-target
//Lens is not currently needed for this either, implying they are not considered blocking, but it's open for discussion long-term
Entrance(RR_ZF_HIDDEN_LEDGE, []{return true;}),
Entrance(RR_ZF_HIDDEN_LEDGE, []{return logic->HasItem(RG_CLIMB) || logic->CanUse(RG_LONGSHOT);}),
});
areaTable[RR_ZF_HIDDEN_LEDGE] = Region("ZF Hidden Ledge", SCENE_ZORAS_FOUNTAIN, {}, {
@@ -59,7 +59,7 @@ void RegionTable_Init_ZoraRiver() {
}, {
//Exits
Entrance(RR_ZR_FRONT, []{return true;}),
Entrance(RR_ZR_ATOP_LADDER, []{return (logic->IsAdult || logic->HasItem(RG_POWER_BRACELET)) /*&& (logic->CanUse(RG_CLIMB) || (logic->IsAdult && logic->CanUse(RG_HOOKSHOT)))*/;}),
Entrance(RR_ZR_ATOP_LADDER, []{return (logic->IsAdult || logic->HasItem(RG_POWER_BRACELET)) && (logic->HasItem(RG_CLIMB) || (logic->IsAdult && logic->CanUse(RG_HOOKSHOT)) || CanPlantBean(RR_ZORAS_RIVER, RG_ZORAS_RIVER_BEAN_SOUL));}),
Entrance(RR_ZR_PILLAR, []{return (logic->IsChild && logic->HasItem(RG_POWER_BRACELET)) || logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && ctx->GetTrickOption(RT_ZR_LOWER));}),
Entrance(RR_ZR_FROM_SHORTCUT, []{return logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS);}),
Entrance(RR_ZR_STORMS_GROTTO, []{return logic->CanOpenStormsGrotto();}),
+21 -13
View File
@@ -253,6 +253,8 @@ bool Logic::HasItem(RandomizerGet itemName) {
return CurrentUpgrade(UPG_SCALE) >= 1;
case RG_GOLDEN_SCALE:
return CurrentUpgrade(UPG_SCALE) >= 2;
case RG_CLIMB:
return CheckRandoInf(RAND_INF_CAN_CLIMB);
case RG_CRAWL:
return CheckRandoInf(RAND_INF_CAN_CRAWL);
case RG_OPEN_CHEST:
@@ -1758,6 +1760,9 @@ void Logic::ApplyItemEffect(Item& item, bool state) {
case RG_CLAIM_CHECK:
SetRandoInf(randoGet - RG_COJIRO + RAND_INF_ADULT_TRADES_HAS_COJIRO, state);
break;
case RG_CLIMB:
SetRandoInf(RAND_INF_CAN_CLIMB, state);
break;
case RG_CRAWL:
SetRandoInf(RAND_INF_CAN_CRAWL, state);
break;
@@ -2539,10 +2544,6 @@ bool Logic::IsReverseAccessPossible() {
(ctx->GetOption(RSK_MIX_OVERWORLD_ENTRANCES) || ctx->GetOption(RSK_MIX_INTERIOR_ENTRANCES))));
}
bool Logic::SpiritSunOnFloorToStatue() {
return /*CanClimbHigh() &&*/ (HasExplosives() || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && CanUse(RG_LIGHT_ARROWS)));
}
bool Logic::SpiritExplosiveKeyLogic() {
return SmallKeys(SCENE_SPIRIT_TEMPLE, HasExplosives() ? 1 : 2);
}
@@ -2578,7 +2579,7 @@ bool Logic::MQSpiritStatueToSunBlock() {
bool Logic::MQSpiritStatueSouthDoor() {
return HasFireSource() || (ctx->GetTrickOption(RT_SPIRIT_MQ_FROZEN_EYE) && CanUse(RG_FAIRY_BOW) &&
CanUse(RG_SONG_OF_TIME) /* && CanClimb()*/);
CanUse(RG_SONG_OF_TIME) && (HasItem(RG_CLIMB) || CanUse(RG_HOOKSHOT)));
}
bool Logic::MQSpirit4KeyColossus() {
@@ -2614,7 +2615,7 @@ bool Logic::CouldMQSpirit4KeyWestHand() {
// If we have the longshot, we can also guarantee access to the outer west hand as you can longshot from the east hand
// to the west Implies CanKillEnemy(RE_IRON_KNUCKLE)
bool Logic::OuterWestHandLogic() {
return HasExplosives() /*&& CanClimbHigh()*/ && HasItem(RG_POWER_BRACELET) &&
return HasExplosives() && (HasItem(RG_CLIMB) || CanUse(RG_LONGSHOT)) && HasItem(RG_POWER_BRACELET) &&
SmallKeys(SCENE_SPIRIT_TEMPLE, HasItem(RG_LONGSHOT) ? 3 : 5);
}
@@ -2628,8 +2629,10 @@ bool Logic::StatueRoomMQKeyLogic() {
// the ability to hit switches and the ability to climb because only child can reach the initial child lock
// without opening the Statue room to Broken Wall Room lock first
// if adult can ever cross crawlspaces this becomes more complicated.
return SmallKeys(SCENE_SPIRIT_TEMPLE,
IsChild && Get(LOGIC_REVERSE_SPIRIT_CHILD) && CanHitSwitch() /* && CanClimbHigh()*/ ? 6 : 7);
return SmallKeys(SCENE_SPIRIT_TEMPLE, IsChild && Get(LOGIC_REVERSE_SPIRIT_CHILD) && CanHitSwitch() &&
(HasItem(RG_CLIMB) || CanUse(RG_LONGSHOT))
? 6
: 7);
}
void Logic::Reset(bool resetSaveContext /*= true*/) {
@@ -2657,16 +2660,21 @@ void Logic::Reset(bool resetSaveContext /*= true*/) {
SetRandoInf(RAND_INF_CAN_SWIM, true);
}
// If we're not shuffling crawl, we start with it
if (ctx->GetOption(RSK_SHUFFLE_CRAWL).Is(false)) {
SetRandoInf(RAND_INF_CAN_CRAWL, true);
}
// If we're not shuffling grab, we start with it
if (ctx->GetOption(RSK_SHUFFLE_GRAB).Is(false)) {
SetRandoInf(RAND_INF_CAN_GRAB, true);
}
// If we're not shuffling climb, we start with it
if (ctx->GetOption(RSK_SHUFFLE_CLIMB).Is(false)) {
SetRandoInf(RAND_INF_CAN_CLIMB, true);
}
// If we're not shuffling crawl, we start with it
if (ctx->GetOption(RSK_SHUFFLE_CRAWL).Is(false)) {
SetRandoInf(RAND_INF_CAN_CRAWL, true);
}
// If we're not shuffling open chest, we start with it
if (ctx->GetOption(RSK_SHUFFLE_OPEN_CHEST).Is(false)) {
SetRandoInf(RAND_INF_CAN_OPEN_CHEST, true);
-1
View File
@@ -153,7 +153,6 @@ class Logic {
static std::map<RandomizerGet, uint32_t> RandoGetToEquipFlag;
static std::map<RandomizerGet, uint32_t> RandoGetToRandInf;
bool IsReverseAccessPossible();
bool SpiritSunOnFloorToStatue();
bool SpiritEastToSwitch();
bool SpiritWestToSkull();
bool SpiritSunBlockSouthLedge();
@@ -258,9 +258,10 @@ void Settings::CreateOptionDescriptions() {
"\n"
"If you enter a water entrance without swim you will be respawned on land to prevent infinite death loops.\n"
"If you void out in Water Temple you will immediately be kicked out to prevent a softlock.";
mOptionDescriptions[RSK_SHUFFLE_CRAWL] = "Shuffles the ability to use crawlspaces into the item pool.";
mOptionDescriptions[RSK_SHUFFLE_GRAB] =
"Shuffle the ability to grab as a progressive upgrade before Goron Bracelet.";
mOptionDescriptions[RSK_SHUFFLE_CLIMB] = "Shuffle the ability to climb ladders into the item pool.";
mOptionDescriptions[RSK_SHUFFLE_CRAWL] = "Shuffles the ability to use crawlspaces into the item pool.";
mOptionDescriptions[RSK_SHUFFLE_OPEN_CHEST] = "Shuffles the ability to open chests into the item pool.";
mOptionDescriptions[RSK_SHUFFLE_WEIRD_EGG] = "Shuffles the Weird Egg from Malon in to the item pool. Enabling "
"\"Skip Child Zelda\" disables this feature.\n"
@@ -12,7 +12,6 @@
#include "3drando/random.hpp"
#include "soh/ResourceManagerHelpers.h"
#include "soh/SohGui/SohGui.hpp"
#include "3drando/custom_messages.hpp"
#include <imgui.h>
#include <imgui_internal.h>
#include "../custom-message/CustomMessageTypes.h"
@@ -125,6 +124,7 @@ std::map<RandomizerGet, RandomizerInf> randomizerGetToRandInf = {
{ RG_FISHING_POLE, RAND_INF_FISHING_POLE_FOUND },
{ RG_BRONZE_SCALE, RAND_INF_CAN_SWIM },
{ RG_POWER_BRACELET, RAND_INF_CAN_GRAB },
{ RG_CLIMB, RAND_INF_CAN_CLIMB },
{ RG_CRAWL, RAND_INF_CAN_CRAWL },
{ RG_OPEN_CHEST, RAND_INF_CAN_OPEN_CHEST },
{ RG_QUIVER_INF, RAND_INF_HAS_INFINITE_QUIVER },
@@ -316,6 +316,7 @@ typedef enum {
LOGIC_SPIRIT_1F_SILVER_RUPEES,
LOGIC_SPIRIT_CHILD_SWITCH_BRIDGE,
LOGIC_SPIRIT_SILVER_RUPEE_BRIDGE,
LOGIC_SPIRIT_SILVER_RUPEE_BRIDGE_TORCHES,
LOGIC_SPIRIT_SUN_BLOCK_TORCH,
LOGIC_SPIRIT_BOUNDERS_SILVERS,
LOGIC_SPIRIT_STATUE_SOUTH_DOOR,
@@ -531,6 +532,7 @@ typedef enum {
RR_NOCTURNE_OF_SHADOW_WARP,
RR_PRELUDE_OF_LIGHT_WARP,
RR_KOKIRI_FOREST,
RR_KF_LINKS_PORCH,
RR_KF_BOULDER_LOOP,
RR_KF_LINKS_HOUSE,
RR_KF_MIDOS_HOUSE,
@@ -539,6 +541,8 @@ typedef enum {
RR_KF_KNOW_IT_ALL_HOUSE,
RR_KF_KOKIRI_SHOP,
RR_KF_OUTSIDE_DEKU_TREE,
RR_KF_OUTSIDE_LOST_WOODS,
RR_KF_RUPEE_ALCOVE,
RR_KF_STORMS_GROTTO,
RR_THE_LOST_WOODS,
RR_LW_BRIDGE_FROM_FOREST,
@@ -549,11 +553,15 @@ typedef enum {
RR_DEKU_THEATER,
RR_LW_SCRUBS_GROTTO,
RR_SFM_ENTRYWAY,
RR_SFM_MAZE,
RR_SFM_ABOVE_MAZE,
RR_SFM_OUTSIDE_FAIRY_GROTTO,
RR_SACRED_FOREST_MEADOW,
RR_SFM_WOLFOS_GROTTO,
RR_SFM_FAIRY_GROTTO,
RR_SFM_STORMS_GROTTO,
RR_HYRULE_FIELD,
RR_HF_TO_LAKE_HYLIA,
RR_HF_SOUTHEAST_GROTTO,
RR_HF_OPEN_GROTTO,
RR_HF_INSIDE_FENCE_GROTTO,
@@ -573,7 +581,9 @@ typedef enum {
RR_LH_GROTTO,
RR_GERUDO_VALLEY,
RR_GV_UPPER_STREAM,
RR_GV_UPPER_STREAM_WATER,
RR_GV_LOWER_STREAM,
RR_GV_WATERFALL_ALCOVE,
RR_GV_GROTTO_LEDGE,
RR_GV_CRATE_LEDGE,
RR_GV_OCTOROK_GROTTO,
@@ -637,9 +647,13 @@ typedef enum {
RR_TOT_BEYOND_DOOR_OF_TIME,
RR_CASTLE_GROUNDS,
RR_CASTLE_GROUNDS_FROM_GANONS_CASTLE,
RR_HYRULE_CASTLE_GROUNDS,
RR_HC_LEDGE,
RR_HC_GATE,
RR_HC_ABOVE_VINE,
RR_HC_PAST_GATE,
RR_HC_ABOVE_CLIMBABLE_ROCKS,
RR_HC_DRAIN_LEDGE,
RR_HC_GARDEN,
RR_HC_MOAT,
RR_HC_GREAT_FAIRY_FOUNTAIN,
RR_HC_STORMS_GROTTO,
RR_HC_STORMS_GROTTO_BEHIND_WALLS,
@@ -676,6 +690,7 @@ typedef enum {
RR_GRAVEYARD_HEART_PIECE_GRAVE,
RR_GRAVEYARD_WARP_PAD_REGION,
RR_DEATH_MOUNTAIN_TRAIL,
RR_DEATH_MOUNTAIN_ROCKFALL,
RR_DEATH_MOUNTAIN_SUMMIT,
RR_DMT_OWL_FLIGHT,
RR_DMT_GREAT_FAIRY_FOUNTAIN,
@@ -699,6 +714,7 @@ typedef enum {
RR_DMC_HAMMER_GROTTO,
RR_DMC_GREAT_FAIRY_FOUNTAIN,
RR_DMC_DISTANT_PLATFORM,
RR_DMC_OUTSIDE_FIRE_TEMPLE,
RR_ZR_FRONT,
RR_ZORAS_RIVER,
RR_ZR_ATOP_LADDER,
@@ -741,6 +757,8 @@ typedef enum {
RR_GANONS_CASTLE_ENTRYWAY,
RR_DEKU_TREE_LOBBY,
RR_DEKU_TREE_LOBBY_2F,
RR_DEKU_TREE_LOBBY_3F,
RR_DEKU_TREE_2F_MIDDLE_ROOM,
RR_DEKU_TREE_SLINGSHOT_ROOM,
RR_DEKU_TREE_COMPASS_ROOM,
@@ -891,6 +909,7 @@ typedef enum {
RR_FOREST_TEMPLE_NORTH_HALLWAY,
RR_FOREST_TEMPLE_LOWER_STALFOS,
RR_FOREST_TEMPLE_NW_COURTYARD_LOWER,
RR_FOREST_TEMPLE_NW_COURTYARD_UPPER_ALCOVE,
RR_FOREST_TEMPLE_NW_COURTYARD_UPPER,
RR_FOREST_TEMPLE_NE_COURTYARD_LOWER,
RR_FOREST_TEMPLE_NE_COURTYARD_UPPER,
@@ -904,9 +923,11 @@ typedef enum {
RR_FOREST_TEMPLE_FLOORMASTER_ROOM,
RR_FOREST_TEMPLE_RED_DOORMAT_HALLWAY,
RR_FOREST_TEMPLE_RED_DOORMAT_HALLWAY_DOORMAT,
RR_FOREST_TEMPLE_BLOCK_PUSH_FLOOR,
RR_FOREST_TEMPLE_LOWER_BLOCK_PUSH_ROOM,
RR_FOREST_TEMPLE_MIDDLE_BLOCK_PUSH_ROOM,
RR_FOREST_TEMPLE_UPPER_BLOCK_PUSH_ROOM,
RR_FOREST_TEMPLE_BLOCK_PUSH_ROOM_TOP,
RR_FOREST_TEMPLE_BLOCK_PUSH_ROOM_COURTYARD_ALCOVE,
RR_FOREST_TEMPLE_NW_HALLWAY_TWISTED,
RR_FOREST_TEMPLE_NW_HALLWAY_STRAIGHTENED,
@@ -929,15 +950,18 @@ typedef enum {
RR_FOREST_TEMPLE_MQ_NORTH_HALLWAY,
RR_FOREST_TEMPLE_MQ_WOLFOS_ROOM,
RR_FOREST_TEMPLE_MQ_RED_DOORMAT_HALLWAY,
RR_FOREST_TEMPLE_MQ_BLOCK_PUZZLE_FLOOR,
RR_FOREST_TEMPLE_MQ_LOWER_BLOCK_PUZZLE,
RR_FOREST_TEMPLE_MQ_MIDDLE_BLOCK_PUZZLE,
RR_FOREST_TEMPLE_MQ_UPPER_BLOCK_PUZZLE,
RR_FOREST_TEMPLE_MQ_BLOCK_PUZZLE_TOP,
RR_FOREST_TEMPLE_MQ_STRAIGHT_HALLWAY,
RR_FOREST_TEMPLE_MQ_FLOORMASTER_ROOM,
RR_FOREST_TEMPLE_MQ_INDOOR_LEDGE,
RR_FOREST_TEMPLE_MQ_NW_COURTYARD_LEDGE,
RR_FOREST_TEMPLE_MQ_REDEAD_ROOM,
RR_FOREST_TEMPLE_MQ_NW_COURTYARD,
RR_FOREST_TEMPLE_MQ_NW_COURTYARD_WELL_LEDGE,
RR_FOREST_TEMPLE_MQ_NW_COURTYARD_UPPER_ALCOVE,
RR_FOREST_TEMPLE_MQ_NORTH_PASSAGE,
RR_FOREST_TEMPLE_MQ_NE_COURTYARD,
@@ -4608,8 +4632,9 @@ typedef enum {
RG_HINT,
RG_TYCOON_WALLET,
RG_BRONZE_SCALE,
RG_CRAWL,
RG_POWER_BRACELET,
RG_CLIMB,
RG_CRAWL,
RG_OPEN_CHEST,
RG_CHILD_WALLET,
RG_PROGRESSIVE_BOMBCHU_BAG,
@@ -5826,6 +5851,7 @@ typedef enum {
RHT_MASK_ZORA,
RHT_MASK_GERUDO,
RHT_MASK_TRUTH,
RHT_CLIMB,
RHT_CRAWL,
RHT_OPEN_CHEST,
RHT_FISHING_POLE,
@@ -6423,8 +6449,9 @@ typedef enum {
RSK_SHUFFLE_OCARINA,
RSK_SHUFFLE_OCARINA_BUTTONS,
RSK_SHUFFLE_SWIM,
RSK_SHUFFLE_CRAWL,
RSK_SHUFFLE_GRAB,
RSK_SHUFFLE_CLIMB,
RSK_SHUFFLE_CRAWL,
RSK_SHUFFLE_OPEN_CHEST,
RSK_STARTING_DEKU_SHIELD,
RSK_STARTING_KOKIRI_SWORD,
@@ -1139,6 +1139,7 @@ DEFINE_RAND_INF(RAND_INF_ZF_BUSH_6)
DEFINE_RAND_INF(RAND_INF_CAUGHT_LOACH)
DEFINE_RAND_INF(RAND_INF_CAN_SWIM)
DEFINE_RAND_INF(RAND_INF_CAN_CLIMB)
DEFINE_RAND_INF(RAND_INF_CAN_CRAWL)
DEFINE_RAND_INF(RAND_INF_CAN_GRAB)
DEFINE_RAND_INF(RAND_INF_CAN_OPEN_CHEST)
+8 -4
View File
@@ -313,14 +313,18 @@ extern "C" void Randomizer_InitSaveFile() {
Flags_SetRandomizerInf(RAND_INF_CAN_SWIM);
}
if (Randomizer_GetSettingValue(RSK_SHUFFLE_CRAWL) == RO_GENERIC_OFF) {
Flags_SetRandomizerInf(RAND_INF_CAN_CRAWL);
}
if (Randomizer_GetSettingValue(RSK_SHUFFLE_GRAB) == RO_GENERIC_OFF) {
Flags_SetRandomizerInf(RAND_INF_CAN_GRAB);
}
if (Randomizer_GetSettingValue(RSK_SHUFFLE_CLIMB) == RO_GENERIC_OFF) {
Flags_SetRandomizerInf(RAND_INF_CAN_CLIMB);
}
if (Randomizer_GetSettingValue(RSK_SHUFFLE_CRAWL) == RO_GENERIC_OFF) {
Flags_SetRandomizerInf(RAND_INF_CAN_CRAWL);
}
if (Randomizer_GetSettingValue(RSK_SHUFFLE_OPEN_CHEST) == RO_GENERIC_OFF) {
Flags_SetRandomizerInf(RAND_INF_CAN_OPEN_CHEST);
}
+6 -3
View File
@@ -785,8 +785,9 @@ void Settings::CreateOptions() {
});
OPT_BOOL(RSK_SHUFFLE_OCARINA_BUTTONS, "Shuffle Ocarina Buttons", CVAR_RANDOMIZER_SETTING("ShuffleOcarinaButtons"), mOptionDescriptions[RSK_SHUFFLE_OCARINA_BUTTONS]);
OPT_BOOL(RSK_SHUFFLE_SWIM, "Shuffle Swim", CVAR_RANDOMIZER_SETTING("ShuffleSwim"), mOptionDescriptions[RSK_SHUFFLE_SWIM]);
OPT_BOOL(RSK_SHUFFLE_GRAB, "Shuffle Grab", CVAR_RANDOMIZER_SETTING("ShuffleGrab"), mOptionDescriptions[RSK_SHUFFLE_GRAB]);
OPT_BOOL(RSK_SHUFFLE_CLIMB, "Shuffle Climb", CVAR_RANDOMIZER_SETTING("ShuffleClimb"), mOptionDescriptions[RSK_SHUFFLE_CLIMB]);
OPT_BOOL(RSK_SHUFFLE_CRAWL, "Shuffle Crawl", CVAR_RANDOMIZER_SETTING("ShuffleCrawl"), mOptionDescriptions[RSK_SHUFFLE_CRAWL]);
OPT_BOOL(RSK_SHUFFLE_GRAB, "Shuffle Grab", CVAR_RANDOMIZER_SETTING("ShuffleGrab"), mOptionDescriptions[RSK_SHUFFLE_GRAB]);
OPT_BOOL(RSK_SHUFFLE_OPEN_CHEST, "Shuffle Open Chest", CVAR_RANDOMIZER_SETTING("ShuffleOpenChest"), mOptionDescriptions[RSK_SHUFFLE_OPEN_CHEST]);
OPT_BOOL(RSK_SHUFFLE_WEIRD_EGG, "Shuffle Weird Egg", CVAR_RANDOMIZER_SETTING("ShuffleWeirdEgg"), mOptionDescriptions[RSK_SHUFFLE_WEIRD_EGG]);
OPT_BOOL(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD, "Shuffle Gerudo Membership Card", CVAR_RANDOMIZER_SETTING("ShuffleGerudoToken"), mOptionDescriptions[RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD]);
@@ -1712,8 +1713,8 @@ void Settings::CreateOptions() {
"room using a precisely-aimed use of the Slingshot, Bow, or Longshot. As well, if you climb to the top of the "
"vines you can stand on the right edge of the platform and shoot around the glass. From this distance, even "
"the Hookshot can reach the switch. This trick is only relevant if \"Shuffle Boss Entrances\" is enabled. MQ "
"Jabu: A Gold Skulltula Token can be collected with the Hookshot or Longshot using the same methods as hitting "
"the switch in Vanilla. This MQ trick is not currently relevant in logic.");
"Jabu: A Gold Skulltula Token can be collected with Longshot using the same methods as hitting the switch in "
"Vanilla.");
OPT_TRICK(RT_JABU_NEAR_BOSS_EXPLOSIVES, RCQUEST_VANILLA, RA_JABU_JABUS_BELLY, { Tricks::Tag::INTERMEDIATE },
"Jabu Near Boss Ceiling Switch with Explosives",
"You can hit the switch that opens the door to the boss room using a precisely-aimed Bombchu. Also, "
@@ -2400,6 +2401,7 @@ void Settings::CreateOptions() {
&mOptions[RSK_SHUFFLE_OCARINA_BUTTONS],
&mOptions[RSK_SHUFFLE_SWIM],
&mOptions[RSK_SHUFFLE_GRAB],
&mOptions[RSK_SHUFFLE_CLIMB],
&mOptions[RSK_SHUFFLE_CRAWL],
&mOptions[RSK_SHUFFLE_OPEN_CHEST],
&mOptions[RSK_SHUFFLE_BEAN_SOULS],
@@ -2621,6 +2623,7 @@ void Settings::CreateOptions() {
&mOptions[RSK_SHUFFLE_OCARINA_BUTTONS],
&mOptions[RSK_SHUFFLE_SWIM],
&mOptions[RSK_SHUFFLE_GRAB],
&mOptions[RSK_SHUFFLE_CLIMB],
&mOptions[RSK_SHUFFLE_CRAWL],
&mOptions[RSK_SHUFFLE_OPEN_CHEST],
&mOptions[RSK_SHUFFLE_WEIRD_EGG],
@@ -13401,6 +13401,10 @@ void Player_Action_8084BF1C(Player* this, PlayState* play) {
this->fallStartHeight = this->actor.world.pos.y;
this->stateFlags2 |= PLAYER_STATE2_DISABLE_ROTATION_ALWAYS;
if (!GameInteractor_Should(VB_CLIMB, true, &sp80, &sp84)) {
return;
}
if ((this->av1.actionVar1 != 0) && (ABS(sp84) < ABS(sp80))) {
phi_f0 = ABS(sp80) * 0.0325f;
sp84 = 0;