From e3865e28afa30dfc918a1d992c65fabc64e81e5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Sat, 3 Jan 2026 13:50:38 +0000 Subject: [PATCH] Remove pseudo RGs: RG_EPONA, RG_SCARECROW, RG_DISTANT_SCARECROW (#6078) --- .../dungeons/dodongos_cavern.cpp | 2 +- .../location_access/dungeons/fire_temple.cpp | 4 +-- .../location_access/dungeons/ice_cavern.cpp | 2 +- .../dungeons/shadow_temple.cpp | 18 ++++++------- .../dungeons/spirit_temple.cpp | 4 +-- .../overworld/death_mountain_crater.cpp | 6 ++--- .../overworld/desert_colossus.cpp | 2 +- .../overworld/gerudo_fortress.cpp | 6 ++--- .../overworld/gerudo_valley.cpp | 4 +-- .../overworld/hyrule_field.cpp | 2 +- .../location_access/overworld/lake_hylia.cpp | 8 +++--- .../overworld/lon_lon_ranch.cpp | 2 +- .../overworld/zoras_fountain.cpp | 2 +- soh/soh/Enhancements/randomizer/logic.cpp | 27 ++++++++++--------- soh/soh/Enhancements/randomizer/logic.h | 3 +++ .../Enhancements/randomizer/randomizerTypes.h | 3 --- 16 files changed, 48 insertions(+), 47 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp index 19a4a1f55..99df5272c 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp @@ -55,7 +55,7 @@ void RegionTable_Init_DodongosCavern() { areaTable[RR_DODONGOS_CAVERN_SE_CORRIDOR] = Region("Dodongos Cavern SE Corridor", SCENE_DODONGOS_CAVERN, {}, { //Locations - LOCATION(RC_DODONGOS_CAVERN_GS_SCARECROW, logic->CanUse(RG_SCARECROW) || (logic->IsAdult && logic->CanUse(RG_LONGSHOT)) || (ctx->GetTrickOption(RT_DC_SCARECROW_GS) && (logic->CanAttack()))), + LOCATION(RC_DODONGOS_CAVERN_GS_SCARECROW, logic->ReachScarecrow() || (logic->IsAdult && logic->CanUse(RG_LONGSHOT)) || (ctx->GetTrickOption(RT_DC_SCARECROW_GS) && logic->CanKillEnemy(RE_GOLD_SKULLTULA))), LOCATION(RC_DODONGOS_CAVERN_SIDE_ROOM_POT_1, logic->CanBreakPots()), LOCATION(RC_DODONGOS_CAVERN_SIDE_ROOM_POT_2, logic->CanBreakPots()), LOCATION(RC_DODONGOS_CAVERN_SIDE_ROOM_POT_3, logic->CanBreakPots()), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp index bfb91d450..c817211fd 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp @@ -255,7 +255,7 @@ void RegionTable_Init_FireTemple() { Entrance(RR_FIRE_TEMPLE_SHORTCUT_CLIMB, []{return logic->HasExplosives();}), Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_LOWER, []{return true;}), Entrance(RR_FIRE_TEMPLE_FIRE_WALL_CHASE, []{return true;}), - Entrance(RR_FIRE_TEMPLE_GS_CLIMB_4F, []{return logic->CanUse(RG_SCARECROW) || (ctx->GetTrickOption(RT_FIRE_SCARECROW) && logic->IsAdult && logic->CanUse(RG_LONGSHOT));}), + 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, {}, {}, { @@ -1006,7 +1006,7 @@ void RegionTable_Init_FireTemple() { //Locations //This requires nothing in N64 logic, but is tight enough to need rollspam with the one-point on which is stricter than I would normally consider in logic //Child basically needs the scarecrow or a bunny hood though due to a worse ledge grab. - LOCATION(RC_FIRE_TEMPLE_MQ_CHEST_ON_FIRE, logic->IsAdult || logic->CanUse(RG_SCARECROW)), + LOCATION(RC_FIRE_TEMPLE_MQ_CHEST_ON_FIRE, logic->IsAdult || logic->ReachScarecrow()), }, { //Exits //The dropdown here is unusual in that it hits 1 of 3 locations: RR_FIRE_TEMPLE_MQ_2_FIRE_WALLS_LOWER, RR_FIRE_TEMPLE_MQ_2_FIRE_WALLS_UPPER_DOOR, and RR_FIRE_TEMPLE_MQ_2_FIRE_WALLS_SWITCH diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp index 993bd2fb0..9def56850 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/ice_cavern.cpp @@ -174,7 +174,7 @@ void RegionTable_Init_IceCavern() { }, { //Locations LOCATION(RC_ICE_CAVERN_MQ_GS_ICE_BLOCK, (logic->BlueFire() && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)) || (logic->IsAdult && logic->CanHitSwitch(ED_LONG_JUMPSLASH))), - LOCATION(RC_ICE_CAVERN_MQ_GS_SCARECROW, logic->CanUse(RG_SCARECROW) || (logic->IsAdult && (logic->CanUse(RG_LONGSHOT) || logic->CanGroundJump() || ctx->GetTrickOption(RT_ICE_MQ_SCARECROW)))), + LOCATION(RC_ICE_CAVERN_MQ_GS_SCARECROW, logic->ReachScarecrow() || (logic->IsAdult && (logic->CanUse(RG_LONGSHOT) || logic->CanGroundJump() || ctx->GetTrickOption(RT_ICE_MQ_SCARECROW)))), }, { //Exits Entrance(RR_ICE_CAVERN_MQ_HUB, []{return logic->BlueFire();}), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp index 22c268823..18c7159c1 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp @@ -262,8 +262,8 @@ void RegionTable_Init_ShadowTemple() { }, { //Locations LOCATION(RC_SHADOW_TEMPLE_GS_NEAR_SHIP, logic->CanUse(RG_LONGSHOT)), - LOCATION(RC_SHADOW_TEMPLE_SCARECROW_NORTH_HEART, logic->CanUse(RG_DISTANT_SCARECROW)), - LOCATION(RC_SHADOW_TEMPLE_SCARECROW_SOUTH_HEART, logic->CanUse(RG_DISTANT_SCARECROW)), + LOCATION(RC_SHADOW_TEMPLE_SCARECROW_NORTH_HEART, logic->ReachDistantScarecrow()), + LOCATION(RC_SHADOW_TEMPLE_SCARECROW_SOUTH_HEART, logic->ReachDistantScarecrow()), }, { //Exits Entrance(RR_SHADOW_TEMPLE_ROOM_TO_BOAT, []{return logic->SmallKeys(SCENE_SHADOW_TEMPLE, 4);}), @@ -281,7 +281,7 @@ void RegionTable_Init_ShadowTemple() { }, { //Exits Entrance(RR_SHADOW_TEMPLE_MAZE, []{return true;}), - Entrance(RR_SHADOW_TEMPLE_ACROSS_CHASM, []{return logic->Get(LOGIC_SHADOW_BRIDGE_BEYOND_BOAT_LOWERED) || logic->CanUse(RG_DISTANT_SCARECROW);}), + Entrance(RR_SHADOW_TEMPLE_ACROSS_CHASM, []{return logic->Get(LOGIC_SHADOW_BRIDGE_BEYOND_BOAT_LOWERED) || logic->ReachDistantScarecrow();}), }); areaTable[RR_SHADOW_TEMPLE_ACROSS_CHASM] = Region("Shadow Temple Across Chasm", SCENE_SHADOW_TEMPLE, { @@ -292,10 +292,10 @@ void RegionTable_Init_ShadowTemple() { LOCATION(RC_SHADOW_TEMPLE_AFTER_BOAT_POT_3, logic->CanBreakPots()), LOCATION(RC_SHADOW_TEMPLE_AFTER_BOAT_POT_4, logic->CanBreakPots()), // don't actually need to use hookshot extension - LOCATION(RC_SHADOW_TEMPLE_AFTER_SHIP_UPPER_LEFT_HEART, logic->CanUse(ctx->GetTrickOption(RT_HOOKSHOT_EXTENSION) && logic->IsAdult && logic->CanUse(RG_SONG_OF_TIME) ? RG_SCARECROW : RG_DISTANT_SCARECROW)), - LOCATION(RC_SHADOW_TEMPLE_AFTER_SHIP_UPPER_RIGHT_HEART, logic->CanUse(ctx->GetTrickOption(RT_HOOKSHOT_EXTENSION) && logic->IsAdult && logic->CanUse(RG_SONG_OF_TIME) ? RG_SCARECROW : RG_DISTANT_SCARECROW)), - // can reach with logic->IsAdult && logic->CanUse(RG_DISTANT_SCARECROW) && logic->CanJumpslash(), but precise enough to be trick - LOCATION(RC_SHADOW_TEMPLE_AFTER_SHIP_LOWER_HEART, (logic->IsAdult && logic->CanUse(RG_SONG_OF_TIME)) || (logic->CanUse(RG_DISTANT_SCARECROW) && logic->CanUse(RG_HOVER_BOOTS))), + LOCATION(RC_SHADOW_TEMPLE_AFTER_SHIP_UPPER_LEFT_HEART, ctx->GetTrickOption(RT_HOOKSHOT_EXTENSION) && logic->IsAdult && logic->CanUse(RG_SONG_OF_TIME) ? logic->ReachScarecrow() : logic->ReachDistantScarecrow()), + LOCATION(RC_SHADOW_TEMPLE_AFTER_SHIP_UPPER_RIGHT_HEART, ctx->GetTrickOption(RT_HOOKSHOT_EXTENSION) && logic->IsAdult && logic->CanUse(RG_SONG_OF_TIME) ? logic->ReachScarecrow() : logic->ReachDistantScarecrow()), + // can reach with logic->IsAdult && logic->ReachDistantScarecrow() && logic->CanJumpslash(), but precise enough to be trick + LOCATION(RC_SHADOW_TEMPLE_AFTER_SHIP_LOWER_HEART, (logic->IsAdult && logic->CanUse(RG_SONG_OF_TIME)) || (logic->ReachDistantScarecrow() && logic->CanUse(RG_HOVER_BOOTS))), }, { //Exits Entrance(RR_SHADOW_TEMPLE_BEYOND_BOAT, []{return logic->Get(LOGIC_SHADOW_BRIDGE_BEYOND_BOAT_LOWERED) && logic->IsAdult;}), @@ -635,8 +635,8 @@ void RegionTable_Init_ShadowTemple() { EventAccess(LOGIC_SHADOW_SHORTCUT_BLOCK, []{return logic->HasItem(RG_GORONS_BRACELET);}), }, { //Locations - LOCATION(RC_SHADOW_TEMPLE_MQ_SCARECROW_NORTH_HEART, logic->CanUse(RG_DISTANT_SCARECROW)), - LOCATION(RC_SHADOW_TEMPLE_MQ_SCARECROW_SOUTH_HEART, logic->CanUse(RG_DISTANT_SCARECROW)), + LOCATION(RC_SHADOW_TEMPLE_MQ_SCARECROW_NORTH_HEART, logic->ReachDistantScarecrow()), + 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);}), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp index 363b52af1..8295018eb 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp @@ -211,7 +211,7 @@ void RegionTable_Init_SpiritTemple() { //Exits Entrance(RR_SPIRIT_TEMPLE_SUN_ON_FLOOR_2F, []{return true;}), Entrance(RR_SPIRIT_TEMPLE_INNER_WEST_HAND, []{return true;}), - Entrance(RR_SPIRIT_TEMPLE_GS_LEDGE, []{return logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_SCARECROW);}), + Entrance(RR_SPIRIT_TEMPLE_GS_LEDGE, []{return logic->CanUse(RG_HOVER_BOOTS) || logic->ReachScarecrow();}), // RT_SPIRIT_PLATFORM_HOOKSHOT is currently disabled 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)));}), @@ -775,7 +775,7 @@ void RegionTable_Init_SpiritTemple() { 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 - Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM_ADULT, []{return logic->IsAdult && logic->CanUse(RG_SCARECROW);}), + Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM_ADULT, []{return logic->IsAdult && logic->ReachScarecrow();}), }); areaTable[RR_SPIRIT_TEMPLE_MQ_FLAMETHROWER_STAIRS] = Region("Spirit Temple MQ Flamethrower Stairs", SCENE_SPIRIT_TEMPLE, {}, {}, { diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_crater.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_crater.cpp index 3e07a6bc2..5d3372223 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_crater.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_crater.cpp @@ -28,7 +28,7 @@ void RegionTable_Init_DeathMountainCrater() { //Exits Entrance(RR_DMC_UPPER_NEARBY, []{return true;}), Entrance(RR_DMC_LADDER_AREA_NEARBY, []{return logic->FireTimer() >= 16 || logic->Hearts() >= 3;}), - Entrance(RR_DMC_CENTRAL_NEARBY, []{return logic->IsAdult && logic->CanUse(RG_GORON_TUNIC) && logic->CanUse(RG_DISTANT_SCARECROW) && ((logic->EffectiveHealth() > 2) || (logic->CanUse(RG_BOTTLE_WITH_FAIRY) && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF)) || logic->CanUse(RG_NAYRUS_LOVE));}), + Entrance(RR_DMC_CENTRAL_NEARBY, []{return logic->IsAdult && logic->CanUse(RG_GORON_TUNIC) && logic->ReachDistantScarecrow() && ((logic->EffectiveHealth() > 2) || (logic->CanUse(RG_BOTTLE_WITH_FAIRY) && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF)) || logic->CanUse(RG_NAYRUS_LOVE));}), Entrance(RR_DMC_LOWER_NEARBY, []{return false;}), Entrance(RR_DMC_DISTANT_PLATFORM, []{return (logic->FireTimer() >= 48 && logic->Hearts() >= 2) || logic->Hearts() >= 3;}), }); @@ -96,7 +96,7 @@ void RegionTable_Init_DeathMountainCrater() { Entrance(RR_DMC_LOWER_NEARBY, []{return (logic->IsAdult && CanPlantBean(RR_DMC_CENTRAL_LOCAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL)) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT);}), Entrance(RR_DMC_UPPER_NEARBY, []{return logic->IsAdult && CanPlantBean(RR_DMC_CENTRAL_LOCAL, RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL);}), Entrance(RR_FIRE_TEMPLE_ENTRYWAY, []{return (logic->IsChild && logic->Hearts() >= 3 && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF)) || (logic->IsAdult && logic->FireTimer() >= 24);}), - Entrance(RR_DMC_DISTANT_PLATFORM, []{return logic->FireTimer() >= 48 && logic->CanUse(RG_DISTANT_SCARECROW);}), + 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, {}, { @@ -147,7 +147,7 @@ void RegionTable_Init_DeathMountainCrater() { LOCATION(RC_DMC_DISTANT_PLATFORM_RED_RUPEE, logic->IsAdult), }, { //Exits - Entrance(RR_DMC_CENTRAL_LOCAL, []{return logic->FireTimer() >= 48 && logic->CanUse(RG_DISTANT_SCARECROW);}), + Entrance(RR_DMC_CENTRAL_LOCAL, []{return logic->FireTimer() >= 48 && logic->IsAdult && logic->ReachDistantScarecrow();}), }); // clang-format on diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/desert_colossus.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/desert_colossus.cpp index fcdfe2d2c..428281602 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/desert_colossus.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/desert_colossus.cpp @@ -23,7 +23,7 @@ void RegionTable_Init_DesertColossus() { }, { //Exits //You can kinda get the fairies without entering the water, but it relies on them cooperating and leevers are jerks. should be a trick - Entrance(RR_DESERT_COLOSSUS_OASIS, []{return logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->HasItem(RG_EMPTY_BOTTLE));}), + Entrance(RR_DESERT_COLOSSUS_OASIS, []{return logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->HasBottle());}), Entrance(RR_COLOSSUS_GREAT_FAIRY_FOUNTAIN, []{return logic->HasExplosives();}), Entrance(RR_SPIRIT_TEMPLE_ENTRYWAY, []{return true;}), Entrance(RR_WASTELAND_NEAR_COLOSSUS, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp index 98f373eea..51bfc2be1 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp @@ -147,7 +147,7 @@ void RegionTable_Init_GerudoFortress() { Entrance(RR_GF_TOP_OF_LOWER_VINES, []{return true;}), Entrance(RR_GF_SLOPED_ROOF, []{return true;}), Entrance(RR_GF_BOTTOM_OF_UPPER_VINES, []{return true;}), - Entrance(RR_GF_NEAR_CHEST, []{return logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && logic->CanUse(RG_SCARECROW) && logic->CanUse(RG_HOOKSHOT)) || logic->CanUse(RG_LONGSHOT);}), + Entrance(RR_GF_NEAR_CHEST, []{return logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && logic->ReachScarecrow()) || logic->CanUse(RG_LONGSHOT);}), }); areaTable[RR_GF_NEAR_CHEST] = Region("GF Near Chest", SCENE_GERUDOS_FORTRESS, {}, { @@ -212,8 +212,8 @@ void RegionTable_Init_GerudoFortress() { areaTable[RR_GF_HBA_RANGE] = Region("GF HBA Range", SCENE_GERUDOS_FORTRESS, {}, { //Locations - LOCATION(RC_GF_HBA_1000_POINTS, logic->IsAdult && logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && logic->CanUse(RG_EPONA) && logic->CanUse(RG_FAIRY_BOW) && logic->AtDay), - LOCATION(RC_GF_HBA_1500_POINTS, logic->IsAdult && logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && logic->CanUse(RG_EPONA) && logic->CanUse(RG_FAIRY_BOW) && logic->AtDay), + LOCATION(RC_GF_HBA_1000_POINTS, logic->IsAdult && logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && logic->SummonEpona() && logic->CanUse(RG_FAIRY_BOW) && logic->AtDay), + LOCATION(RC_GF_HBA_1500_POINTS, logic->IsAdult && logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && logic->SummonEpona() && logic->CanUse(RG_FAIRY_BOW) && logic->AtDay), LOCATION(RC_GF_HBA_RANGE_GS, logic->IsAdult && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG) && logic->CanGetNightTimeGS()), LOCATION(RC_GF_HBA_RANGE_CRATE_1, logic->CanBreakCrates()), LOCATION(RC_GF_HBA_RANGE_CRATE_2, logic->CanBreakCrates()), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp index 2cf6a8d5b..1ee435adf 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp @@ -17,7 +17,7 @@ void RegionTable_Init_GerudoValley() { Entrance(RR_GV_UPPER_STREAM, []{return logic->IsChild || logic->HasItem(RG_BRONZE_SCALE) || logic->TakeDamage();}), Entrance(RR_GV_CRATE_LEDGE, []{return logic->IsChild || logic->CanUse(RG_LONGSHOT);}), Entrance(RR_GV_GROTTO_LEDGE, []{return true;}), - Entrance(RR_GV_FORTRESS_SIDE, []{return (logic->IsAdult && (logic->CanUse(RG_EPONA) || logic->CanUse(RG_LONGSHOT) || ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE) || logic->Get(LOGIC_TH_RESCUED_ALL_CARPENTERS))) || ((logic->IsChild || ctx->GetTrickOption(RT_HOOKSHOT_EXTENSION)) && logic->CanUse(RG_HOOKSHOT)) || (logic->IsChild && ctx->GetTrickOption(RT_GV_CHILD_CUCCO_JUMP) && logic->CanJumpslash());}), + 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))) || ((logic->IsChild || ctx->GetTrickOption(RT_HOOKSHOT_EXTENSION)) && logic->CanUse(RG_HOOKSHOT)) || (logic->IsChild && ctx->GetTrickOption(RT_GV_CHILD_CUCCO_JUMP) && logic->CanJumpslash());}), Entrance(RR_GV_LOWER_STREAM, []{return logic->IsChild;}), //can use cucco as child }); @@ -79,7 +79,7 @@ void RegionTable_Init_GerudoValley() { //Exits Entrance(RR_GF_OUTSKIRTS, []{return true;}), Entrance(RR_GV_UPPER_STREAM, []{return true;}), - Entrance(RR_GERUDO_VALLEY, []{return logic->IsChild || logic->CanUse(RG_EPONA) || logic->CanUse(RG_LONGSHOT) || ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE) || logic->Get(LOGIC_TH_RESCUED_ALL_CARPENTERS);}), + 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);}), 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)));}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp index b534d9c94..83bbfcff7 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp @@ -7,7 +7,7 @@ void RegionTable_Init_HyruleField() { // clang-format off areaTable[RR_HYRULE_FIELD] = Region("Hyrule Field", SCENE_HYRULE_FIELD, { //Events - EventAccess(LOGIC_BIG_POE_KILL, []{return logic->HasBottle() && logic->CanUse(RG_FAIRY_BOW) && (logic->CanUse(RG_EPONA) || ctx->GetTrickOption(RT_HF_BIG_POE_WITHOUT_EPONA));}), + EventAccess(LOGIC_BIG_POE_KILL, []{return logic->HasBottle() && logic->CanUse(RG_FAIRY_BOW) && (logic->SummonEpona() || ctx->GetTrickOption(RT_HF_BIG_POE_WITHOUT_EPONA));}), EventAccess(LOGIC_BORROW_RIGHT_MASKS, []{return logic->IsChild && logic->Get(LOGIC_BORROW_BUNNY_HOOD) && logic->HasItem(RG_KOKIRI_EMERALD) && logic->HasItem(RG_GORON_RUBY) && logic->HasItem(RG_ZORA_SAPPHIRE) && logic->HasItem(RG_CHILD_WALLET);}), }, { //Locations diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp index ad114cbe9..344b609da 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp @@ -14,8 +14,8 @@ void RegionTable_Init_LakeHylia() { }, { //Locations LOCATION(RC_LH_UNDERWATER_ITEM, logic->IsChild && logic->HasItem(RG_SILVER_SCALE)), - LOCATION(RC_LH_SUN, logic->IsAdult && ((logic->Get(LOGIC_WATER_TEMPLE_CLEAR) && logic->HasItem(RG_BRONZE_SCALE)) || logic->CanUse(RG_DISTANT_SCARECROW)) && logic->CanUse(RG_FAIRY_BOW)), - LOCATION(RC_LH_FREESTANDING_POH, logic->IsAdult && (logic->CanUse(RG_SCARECROW) || CanPlantBean(RR_LAKE_HYLIA, RG_LAKE_HYLIA_BEAN_SOUL)) && logic->CanAvoidEnemy(RE_GUAY, false)), + 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_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)), @@ -33,7 +33,7 @@ void RegionTable_Init_LakeHylia() { LOCATION(RC_LH_SOUTHEAST_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_LH_SOUTHWEST_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), LOCATION(RC_LH_SOUTHWEST_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), - LOCATION(RC_LH_ISLAND_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG) && ((logic->HasItem(RG_BRONZE_SCALE) && (logic->IsChild || logic->Get(LOGIC_WATER_TEMPLE_CLEAR))) || logic->CanUse(RG_DISTANT_SCARECROW))), + LOCATION(RC_LH_ISLAND_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG) && ((logic->HasItem(RG_BRONZE_SCALE) && (logic->IsChild || logic->Get(LOGIC_WATER_TEMPLE_CLEAR))) || logic->ReachDistantScarecrow())), LOCATION(RC_LH_LAB_GOSSIP_STONE, true), LOCATION(RC_LH_SOUTHEAST_GOSSIP_STONE, true), LOCATION(RC_LH_SOUTHWEST_GOSSIP_STONE, true), @@ -84,7 +84,7 @@ void RegionTable_Init_LakeHylia() { Entrance(RR_HYRULE_FIELD, []{return true;}), Entrance(RR_LH_FROM_SHORTCUT, []{return true;}), Entrance(RR_LH_OWL_FLIGHT, []{return logic->IsChild;}), - Entrance(RR_LH_FISHING_ISLAND, []{return ((logic->IsChild || logic->Get(LOGIC_WATER_TEMPLE_CLEAR)) && logic->HasItem(RG_BRONZE_SCALE)) || (logic->IsAdult && (logic->CanUse(RG_SCARECROW) || CanPlantBean(RR_LAKE_HYLIA, RG_LAKE_HYLIA_BEAN_SOUL)));}), + 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)));}), Entrance(RR_LH_LAB, []{return logic->CanOpenOverworldDoor(RG_HYLIA_LAB_KEY);}), Entrance(RR_LH_FROM_WATER_TEMPLE, []{return true;}), Entrance(RR_LH_GROTTO, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/lon_lon_ranch.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/lon_lon_ranch.cpp index 7ee0e8575..e40f514fa 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/lon_lon_ranch.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/lon_lon_ranch.cpp @@ -7,7 +7,7 @@ void RegionTable_Init_LonLonRanch() { // clang-format off areaTable[RR_LON_LON_RANCH] = Region("Lon Lon Ranch", SCENE_LON_LON_RANCH, { //Events - EventAccess(LOGIC_FREED_EPONA, []{return (logic->HasItem(RG_CHILD_WALLET) || ctx->GetOption(RSK_SKIP_EPONA_RACE)) && logic->CanUse(RG_EPONAS_SONG) && logic->IsAdult && logic->AtDay;}), + EventAccess(LOGIC_FREED_EPONA, []{return logic->HasItem(RG_CHILD_WALLET) && logic->CanUse(RG_EPONAS_SONG) && logic->IsAdult && logic->AtDay;}), EventAccess(LOGIC_LINKS_COW, []{return logic->HasItem(RG_CHILD_WALLET) && logic->CanUse(RG_EPONAS_SONG) && logic->IsAdult && logic->AtDay;}), }, { //Locations diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp index bc5fe165e..83ce7061f 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp @@ -36,7 +36,7 @@ void RegionTable_Init_ZorasFountain() { Entrance(RR_ZF_LAKEBED, []{return logic->CanUse(RG_IRON_BOOTS);}), //child can break the brown rock without lifting the silver rock and it stays gone for adult, but it's not intuitive and there's no reasonable case where it matters. Entrance(RR_ZF_HIDDEN_CAVE, []{return logic->CanUse(RG_SILVER_GAUNTLETS) && logic->BlastOrSmash();}), - Entrance(RR_ZF_ROCK, []{return logic->IsAdult && logic->CanUse(RG_SCARECROW);}), + Entrance(RR_ZF_ROCK, []{return logic->IsAdult && logic->ReachScarecrow();}), Entrance(RR_JABU_JABUS_BELLY_ENTRYWAY, []{return logic->IsChild && (ctx->GetOption(RSK_JABU_OPEN).Is(RO_JABU_OPEN) || logic->CanUse(RG_BOTTLE_WITH_FISH));}), Entrance(RR_ZF_GREAT_FAIRY_FOUNTAIN, []{return logic->HasExplosives() || (ctx->GetTrickOption(RT_ZF_GREAT_FAIRY_WITHOUT_EXPLOSIVES) && logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_SILVER_GAUNTLETS));}), }); diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index 3cba30061..4ad758565 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -64,11 +64,6 @@ bool Logic::HasItem(RandomizerGet itemName) { case RG_PROGRESSIVE_NUT_UPGRADE: case RG_NUTS: return CurrentUpgrade(UPG_NUTS); - // RANDOTODO handle cases where the scarecrow is persistent between age better when OI is added - case RG_SCARECROW: - return ScarecrowsSong() && CanUse(RG_HOOKSHOT); - case RG_DISTANT_SCARECROW: - return ScarecrowsSong() && CanUse(RG_LONGSHOT); case RG_MAGIC_BEAN: return GetAmmo(ITEM_BEAN) > 0 || CheckInventory(ITEM_BEAN, true); case RG_KOKIRI_SWORD: @@ -185,8 +180,6 @@ bool Logic::HasItem(RandomizerGet itemName) { case RG_RUTOS_LETTER: return CheckRandoInf(RandoGetToRandInf.at(itemName)); // Boss Keys - case RG_EPONA: - return Get(LOGIC_FREED_EPONA); case RG_FOREST_TEMPLE_BOSS_KEY: case RG_FIRE_TEMPLE_BOSS_KEY: case RG_WATER_TEMPLE_BOSS_KEY: @@ -299,8 +292,6 @@ bool Logic::CanUse(RandomizerGet itemName) { return IsAdult; // || HoverBootsAsChild; case RG_HOOKSHOT: case RG_LONGSHOT: - case RG_SCARECROW: - case RG_DISTANT_SCARECROW: return IsAdult; // || HookshotAsChild; case RG_GORON_TUNIC: return IsAdult; // || GoronTunicAsChild; @@ -386,8 +377,6 @@ bool Logic::CanUse(RandomizerGet itemName) { // Misc. Items case RG_FISHING_POLE: return HasItem(RG_CHILD_WALLET); // as long as you have enough rubies - case RG_EPONA: - return IsAdult && CanUse(RG_EPONAS_SONG); // Bottle Items case RG_BOTTLE_WITH_BUGS: @@ -504,7 +493,7 @@ bool Logic::CanDoGlitch(GlitchType glitch) { } // RANDOTODO quantity is a placeholder for proper ammo use calculation logic. in time will want updating to account for -// ammo capacity Can we kill this enemy +// ammo capacity bool Logic::CanKillEnemy(RandomizerEnemy enemy, EnemyDistance distance, bool wallOrFloor, uint8_t quantity, bool timer, bool inWater) { bool killed = false; @@ -2435,6 +2424,18 @@ bool Logic::IsFireLoopLocked() { ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_ANY_DUNGEON); } +bool Logic::ReachScarecrow() { + return ScarecrowsSong() && CanUse(RG_HOOKSHOT); +} + +bool Logic::ReachDistantScarecrow() { + return ScarecrowsSong() && CanUse(RG_LONGSHOT); +} + +bool Logic::SummonEpona() { + return IsAdult && Get(LOGIC_FREED_EPONA) && CanUse(RG_EPONAS_SONG); +} + bool Logic::IsReverseAccessPossible() { // If we ever allow dungeon entrances to connect to boss rooms directly in dungeon chains, or for 1 boss door to // lead to another dungeons boss door, add RSK_MIX_DUNGEON_ENTRANCES to the final condition @@ -2455,7 +2456,7 @@ bool Logic::SpiritExplosiveKeyLogic() { } bool Logic::SpiritWestToSkull() { - return (IsAdult && ctx->GetTrickOption(RT_SPIRIT_STATUE_JUMP)) || CanUse(RG_HOVER_BOOTS) || CanUse(RG_SCARECROW); + return (IsAdult && ctx->GetTrickOption(RT_SPIRIT_STATUE_JUMP)) || CanUse(RG_HOVER_BOOTS) || ReachScarecrow(); } bool Logic::SpiritSunBlockSouthLedge() { diff --git a/soh/soh/Enhancements/randomizer/logic.h b/soh/soh/Enhancements/randomizer/logic.h index 4ca376198..a65fde0bb 100644 --- a/soh/soh/Enhancements/randomizer/logic.h +++ b/soh/soh/Enhancements/randomizer/logic.h @@ -113,6 +113,9 @@ class Logic { bool CanBuildRainbowBridge(); bool CanTriggerLACS(); bool IsFireLoopLocked(); + bool ReachScarecrow(); + bool ReachDistantScarecrow(); + bool SummonEpona(); void Reset(bool resetSaveContext = true); void SetContext(std::shared_ptr _ctx); bool Get(LogicVal logicVal); diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 061a86c8e..bac5fa2ee 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -4635,7 +4635,6 @@ typedef enum { RG_DEKU_STICK_CAPACITY_30, RG_HOOKSHOT, RG_LONGSHOT, - RG_SCARECROW, // Overworld keys RG_GUARD_HOUSE_KEY, @@ -4663,10 +4662,8 @@ typedef enum { RG_HYLIA_LAB_KEY, RG_FISHING_HOLE_KEY, // Logic Only - RG_DISTANT_SCARECROW, RG_STICKS, RG_NUTS, - RG_EPONA, RG_MAX } RandomizerGet;