From 03d8a15ca5c5e8cdc4255e324de1ef2b58f82521 Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Sun, 13 Jul 2025 18:09:30 +0200 Subject: [PATCH 1/3] Implement `RT_ISG` & `RT_HOVERING` --- .../dungeons/jabujabus_belly.cpp | 1 + .../dungeons/shadow_temple.cpp | 1 + .../location_access/dungeons/water_temple.cpp | 2 +- .../overworld/castle_grounds.cpp | 4 +- .../overworld/death_mountain_crater.cpp | 2 +- .../overworld/desert_colossus.cpp | 2 +- .../overworld/gerudo_fortress.cpp | 2 +- .../overworld/gerudo_valley.cpp | 21 +++--- .../location_access/overworld/goron_city.cpp | 2 +- .../location_access/overworld/graveyard.cpp | 6 +- .../overworld/haunted_wasteland.cpp | 6 +- .../location_access/overworld/kakariko.cpp | 2 +- .../overworld/kokiri_forest.cpp | 18 ++--- .../location_access/overworld/lake_hylia.cpp | 6 +- .../overworld/lon_lon_ranch.cpp | 10 ++- .../location_access/overworld/lost_woods.cpp | 7 +- .../location_access/overworld/market.cpp | 2 +- .../overworld/sacred_forest_meadow.cpp | 4 +- .../overworld/thieves_hideout.cpp | 8 +- .../overworld/zoras_domain.cpp | 6 +- .../overworld/zoras_fountain.cpp | 6 +- .../location_access/overworld/zoras_river.cpp | 8 +- soh/soh/Enhancements/randomizer/logic.cpp | 42 ++++++++++- soh/soh/Enhancements/randomizer/logic.h | 3 + .../Enhancements/randomizer/randomizerTypes.h | 15 ++-- soh/soh/Enhancements/randomizer/settings.cpp | 74 ++++++++++++++----- 26 files changed, 176 insertions(+), 84 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/jabujabus_belly.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/jabujabus_belly.cpp index 51e80fc0c..3bb656d2c 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/jabujabus_belly.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/jabujabus_belly.cpp @@ -43,6 +43,7 @@ void RegionTable_Init_JabuJabusBelly() { Entrance(RR_JABU_JABUS_BELLY_GREEN_TENTACLE, []{return logic->JabuEastTentacle;}), Entrance(RR_JABU_JABUS_BELLY_BIGOCTO_LEDGE, []{return logic->JabuNorthTentacle;}), Entrance(RR_JABU_JABUS_BELLY_NEAR_BOSS_ROOM, []{return logic->LoweredJabuPath || (ctx->GetTrickOption(RT_JABU_BOSS_HOVER) && logic->CanUse(RG_HOVER_BOOTS));}), + Entrance(RR_JABU_JABUS_BELLY_LIFT_UPPER, []{return logic->CanHover(true, true);}), }); //contains B1 of hole room (aside from the ledge leading to big octo), 2 octorock room and north water switch room 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 d276fc418..921dfba4b 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/shadow_temple.cpp @@ -90,6 +90,7 @@ void RegionTable_Init_ShadowTemple() { LOCATION(RC_SHADOW_TEMPLE_SCARECROW_SOUTH_HEART, logic->CanUse(RG_DISTANT_SCARECROW) && logic->SmallKeys(RR_SHADOW_TEMPLE, 4, 5)), }, { //Exits + // there is a hover to get past the boat but it requires rba & a hess, among other things Entrance(RR_SHADOW_TEMPLE_BEYOND_BOAT, []{return logic->CanJumpslashExceptHammer() && logic->CanUse(RG_ZELDAS_LULLABY) && logic->SmallKeys(RR_SHADOW_TEMPLE, 4, 5);}), }); diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp index 03cc44645..480a1119b 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp @@ -35,7 +35,7 @@ void RegionTable_Init_WaterTemple() { Entrance(RR_WATER_TEMPLE_HIGH_WATER, []{return logic->IsAdult && (logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_DAMAGE_BOOST) && logic->CanUse(RG_BOMB_BAG) && logic->TakeDamage()));}), Entrance(RR_WATER_TEMPLE_BLOCK_CORRIDOR, []{return (logic->CanWaterTempleLowFromHigh || logic->CanWaterTempleMiddle) && (logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW)) && (logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_WATER_CENTRAL_BOW) && (logic->IsAdult || logic->CanWaterTempleMiddle)));}), Entrance(RR_WATER_TEMPLE_FALLING_PLATFORM_ROOM, []{return logic->CanWaterTempleHigh && logic->SmallKeys(RR_WATER_TEMPLE, 4);}), - Entrance(RR_WATER_TEMPLE_PRE_BOSS_ROOM, []{return (logic->CanWaterTempleHigh && logic->CanUse(RG_LONGSHOT)) || (ctx->GetTrickOption(RT_HOVER_BOOST_SIMPLE) && ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives() && logic->CanUse(RG_HOVER_BOOTS));}), + Entrance(RR_WATER_TEMPLE_PRE_BOSS_ROOM, []{return (logic->CanWaterTempleHigh && logic->CanUse(RG_LONGSHOT)) || (ctx->GetTrickOption(RT_HOVER_BOOST_SIMPLE) && ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives() && logic->CanUse(RG_HOVER_BOOTS)) || logic->CanHover();}), }); areaTable[RR_WATER_TEMPLE_EAST_LOWER] = Region("Water Temple East Lower", SCENE_WATER_TEMPLE, { diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp index b9525386c..b500ef8eb 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp @@ -74,7 +74,7 @@ void RegionTable_Init_CastleGrounds() { EventAccess(&logic->WanderingBugs, []{return true;}), }, { //Locations - LOCATION(RC_HC_GS_STORMS_GROTTO, logic->HookshotOrBoomerang()), + LOCATION(RC_HC_GS_STORMS_GROTTO, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG, true)), LOCATION(RC_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), LOCATION(RC_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_HC_STORMS_GROTTO_GOSSIP_STONE, true), @@ -97,7 +97,7 @@ void RegionTable_Init_CastleGrounds() { //Exits Entrance(RR_CASTLE_GROUNDS, []{return logic->AtNight;}), Entrance(RR_OGC_GREAT_FAIRY_FOUNTAIN, []{return logic->CanUse(RG_GOLDEN_GAUNTLETS) && logic->AtNight;}), - Entrance(RR_GANONS_CASTLE_LEDGE, []{return logic->BuiltRainbowBridge;}), + Entrance(RR_GANONS_CASTLE_LEDGE, []{return logic->BuiltRainbowBridge || logic->CanHover();}), }); areaTable[RR_OGC_GREAT_FAIRY_FOUNTAIN] = Region("OGC Great Fairy Fountain", SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, {}, { 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 be1b2043a..32943ab61 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 @@ -96,7 +96,7 @@ void RegionTable_Init_DeathMountainCrater() { Entrance(RR_DMC_LOWER_NEARBY, []{return (logic->IsAdult && CanPlantBean(RR_DMC_CENTRAL_LOCAL)) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT);}), Entrance(RR_DMC_UPPER_NEARBY, []{return logic->IsAdult && CanPlantBean(RR_DMC_CENTRAL_LOCAL);}), 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->CanUse(RG_DISTANT_SCARECROW) || logic->CanHover());}), }); areaTable[RR_DMC_GREAT_FAIRY_FOUNTAIN] = Region("DMC Great Fairy Fountain", SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, {}, { 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 f4b8b01c3..3ddddf2b5 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/desert_colossus.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/desert_colossus.cpp @@ -13,7 +13,7 @@ void RegionTable_Init_DesertColossus() { //Locations LOCATION(RC_COLOSSUS_FREESTANDING_POH, logic->IsAdult && CanPlantBean(RR_DESERT_COLOSSUS)), LOCATION(RC_COLOSSUS_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && logic->CanAttack()), - LOCATION(RC_COLOSSUS_GS_TREE, logic->IsAdult && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), + LOCATION(RC_COLOSSUS_GS_TREE, logic->IsAdult && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG, true) && logic->CanGetNightTimeGS()), LOCATION(RC_COLOSSUS_GS_HILL, logic->IsAdult && ((CanPlantBean(RR_DESERT_COLOSSUS) && logic->CanAttack()) || logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_COLOSSUS_GS) && logic->CanUse(RG_HOOKSHOT))) && logic->CanGetNightTimeGS()), LOCATION(RC_COLOSSUS_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_COLOSSUS_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), 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 3929faf86..92c1c2f71 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp @@ -210,7 +210,7 @@ void RegionTable_Init_GerudoFortress() { //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_RANGE_GS, logic->IsAdult && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG) && logic->CanGetNightTimeGS()), + LOCATION(RC_GF_HBA_RANGE_GS, logic->IsAdult && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG, true) && logic->CanGetNightTimeGS()), LOCATION(RC_GF_HBA_RANGE_CRATE_1, logic->CanBreakCrates()), LOCATION(RC_GF_HBA_RANGE_CRATE_2, logic->CanBreakCrates()), LOCATION(RC_GF_HBA_RANGE_CRATE_3, 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 a9f0299ba..9d194e591 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp @@ -10,15 +10,15 @@ void RegionTable_Init_GerudoValley() { EventAccess(&logic->BugRock, []{return logic->IsChild;}), }, { //Locations - LOCATION(RC_GV_GS_SMALL_BRIDGE, logic->IsChild && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), + LOCATION(RC_GV_GS_SMALL_BRIDGE, logic->IsChild && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG, true) && logic->CanGetNightTimeGS()), }, { //Exits Entrance(RR_HYRULE_FIELD, []{return true;}), - 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_UPPER_STREAM, []{return logic->IsChild || logic->HasItem(RG_BRONZE_SCALE) || logic->TakeDamage() || logic->CanHover();}), //can use cucco as child + Entrance(RR_GV_CRATE_LEDGE, []{return logic->IsChild || logic->CanUse(RG_LONGSHOT) || logic->CanHover();}), //can use cucco as child 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->THRescuedAllCarpenters)) || (logic->IsChild && logic->CanUse(RG_HOOKSHOT));}), - Entrance(RR_GV_LOWER_STREAM, []{return logic->IsChild;}), //can use cucco as child + Entrance(RR_GV_FORTRESS_SIDE, []{return logic->CanHover() || (logic->IsAdult && (logic->CanUse(RG_EPONA) || logic->CanUse(RG_LONGSHOT) || ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE) || logic->THRescuedAllCarpenters)) || (logic->IsChild && logic->CanUse(RG_HOOKSHOT));}), + Entrance(RR_GV_LOWER_STREAM, []{return logic->IsChild || logic->CanHover();}), //can use cucco as child }); areaTable[RR_GV_UPPER_STREAM] = Region("GV Upper Stream", SCENE_GERUDO_VALLEY, { @@ -40,6 +40,7 @@ void RegionTable_Init_GerudoValley() { }, { //Exits Entrance(RR_GV_LOWER_STREAM, []{return logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS);}), + Entrance(RR_GERUDO_VALLEY, []{return logic->CanHover();}), }); // scale/boots logic is outside lower stream, as lower stream combines access to lake hylia for entrance randomizer's sake @@ -50,6 +51,7 @@ void RegionTable_Init_GerudoValley() { areaTable[RR_GV_GROTTO_LEDGE] = Region("GV Grotto Ledge", SCENE_GERUDO_VALLEY, {}, {}, { //Exits + Entrance(RR_GERUDO_VALLEY, []{return logic->CanHover();}), Entrance(RR_GV_UPPER_STREAM, []{return ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives();}), 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);}), @@ -62,6 +64,7 @@ void RegionTable_Init_GerudoValley() { LOCATION(RC_GV_FREESTANDING_POH_CRATE, logic->CanBreakCrates()), }, { //Exits + Entrance(RR_GERUDO_VALLEY, []{return logic->CanHover();}), Entrance(RR_GV_UPPER_STREAM, []{return ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives();}), Entrance(RR_GV_LOWER_STREAM, []{return logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS);}), }); @@ -70,17 +73,17 @@ void RegionTable_Init_GerudoValley() { //Locations LOCATION(RC_GV_CHEST, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), LOCATION(RC_GV_TRADE_SAW, logic->IsAdult && logic->CanUse(RG_POACHERS_SAW)), - LOCATION(RC_GV_GS_BEHIND_TENT, logic->IsAdult && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), - LOCATION(RC_GV_GS_PILLAR, logic->IsAdult && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), + LOCATION(RC_GV_GS_BEHIND_TENT, logic->IsAdult && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG, true) && logic->CanGetNightTimeGS()), + LOCATION(RC_GV_GS_PILLAR, logic->IsAdult && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG, true) && logic->CanGetNightTimeGS()), LOCATION(RC_GV_CRATE_BRIDGE_1, logic->IsChild && logic->CanBreakCrates()), LOCATION(RC_GV_CRATE_BRIDGE_2, logic->IsChild && logic->CanBreakCrates()), LOCATION(RC_GV_CRATE_BRIDGE_3, logic->IsChild && logic->CanBreakCrates()), LOCATION(RC_GV_CRATE_BRIDGE_4, logic->IsChild && logic->CanBreakCrates()), }, { //Exits - Entrance(RR_GF_OUTSKIRTS, []{return true;}), + 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->THRescuedAllCarpenters;}), + Entrance(RR_GERUDO_VALLEY, []{return logic->CanHover() || logic->IsChild || logic->CanUse(RG_EPONA) || logic->CanUse(RG_LONGSHOT) || ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE) || logic->THRescuedAllCarpenters;}), Entrance(RR_GV_CARPENTER_TENT, []{return logic->IsAdult;}), Entrance(RR_GV_STORMS_GROTTO, []{return logic->IsAdult && logic->CanOpenStormsGrotto();}), Entrance(RR_GV_CRATE_LEDGE, []{return ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives();}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/goron_city.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/goron_city.cpp index 9d155c3a0..03edc1fc0 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/goron_city.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/goron_city.cpp @@ -44,7 +44,7 @@ void RegionTable_Init_GoronCity() { Entrance(RR_GC_WOODS_WARP, []{return logic->GCWoodsWarpOpen;}), Entrance(RR_GC_SHOP, []{return (logic->IsAdult && logic->StopGCRollingGoronAsAdult) || (logic->IsChild && (logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET) || logic->GoronCityChildFire || logic->CanUse(RG_FAIRY_BOW)));}), Entrance(RR_GC_DARUNIAS_CHAMBER, []{return (logic->IsAdult && logic->StopGCRollingGoronAsAdult) || (logic->IsChild && logic->GCDaruniasDoorOpenChild);}), - Entrance(RR_GC_GROTTO_PLATFORM, []{return logic->IsAdult && ((logic->CanUse(RG_SONG_OF_TIME) && ((logic->EffectiveHealth() > 2) || logic->CanUse(RG_GORON_TUNIC) || logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_NAYRUS_LOVE))) || (logic->EffectiveHealth() > 1 && logic->CanUse(RG_GORON_TUNIC) && logic->CanUse(RG_HOOKSHOT)) || (logic->CanUse(RG_NAYRUS_LOVE) && logic->CanUse(RG_HOOKSHOT)) || (logic->EffectiveHealth() > 2 && logic->CanUse(RG_HOOKSHOT) && ctx->GetTrickOption(RT_GC_GROTTO)));}), + Entrance(RR_GC_GROTTO_PLATFORM, []{return logic->CanHover() || (logic->IsAdult && ((logic->CanUse(RG_SONG_OF_TIME) && ((logic->EffectiveHealth() > 2) || logic->CanUse(RG_GORON_TUNIC) || logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_NAYRUS_LOVE))) || (logic->EffectiveHealth() > 1 && logic->CanUse(RG_GORON_TUNIC) && logic->CanUse(RG_HOOKSHOT)) || (logic->CanUse(RG_NAYRUS_LOVE) && logic->CanUse(RG_HOOKSHOT)) || (logic->EffectiveHealth() > 2 && logic->CanUse(RG_HOOKSHOT) && ctx->GetTrickOption(RT_GC_GROTTO))));}), }); areaTable[RR_GC_MEDIGORON] = Region("GC Medigoron", SCENE_GORON_CITY, {}, { diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp index 2fce0854f..95c2bbcac 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp @@ -13,9 +13,9 @@ void RegionTable_Init_Graveyard() { EventAccess(&logic->BorrowBunnyHood, []{return logic->IsChild && logic->AtDay && logic->BorrowSpookyMask && logic->HasItem(RG_CHILD_WALLET);}), }, { //Locations - LOCATION(RC_GRAVEYARD_FREESTANDING_POH, (((logic->IsAdult && CanPlantBean(RR_THE_GRAVEYARD)) || logic->CanUse(RG_LONGSHOT)) && logic->CanBreakCrates()) || (ctx->GetTrickOption(RT_GY_POH) && logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_GRAVEYARD_FREESTANDING_POH, (logic->CanHover() && logic->CanBreakCrates()) || (((logic->IsAdult && CanPlantBean(RR_THE_GRAVEYARD)) || logic->CanUse(RG_LONGSHOT)) && logic->CanBreakCrates()) || (ctx->GetTrickOption(RT_GY_POH) && logic->CanUse(RG_BOOMERANG))), LOCATION(RC_GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR, logic->HasItem(RG_CHILD_WALLET) && logic->IsChild && logic->AtNight), //TODO: This needs to change - LOCATION(RC_GRAVEYARD_GS_WALL, logic->IsChild && logic->HookshotOrBoomerang() && logic->AtNight && logic->CanGetNightTimeGS()), + LOCATION(RC_GRAVEYARD_GS_WALL, logic->IsChild && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG, true) && logic->AtNight && logic->CanGetNightTimeGS()), LOCATION(RC_GRAVEYARD_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && logic->CanAttack()), LOCATION(RC_GRAVEYARD_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_GRAVEYARD_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), @@ -41,7 +41,7 @@ void RegionTable_Init_Graveyard() { Entrance(RR_GRAVEYARD_DAMPES_GRAVE, []{return logic->IsAdult;}), Entrance(RR_GRAVEYARD_DAMPES_HOUSE, []{return logic->IsAdult && logic->CanOpenOverworldDoor(RG_DAMPES_HUT_KEY) /*|| logic->AtDampeTime*/;}), //TODO: This needs to be handled in ToD rework Entrance(RR_KAKARIKO_VILLAGE, []{return true;}), - Entrance(RR_GRAVEYARD_WARP_PAD_REGION, []{return false;}), + Entrance(RR_GRAVEYARD_WARP_PAD_REGION, []{return logic->CanHover();}), }); areaTable[RR_GRAVEYARD_SHIELD_GRAVE] = Region("Graveyard Shield Grave", SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, {}, { diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/haunted_wasteland.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/haunted_wasteland.cpp index 930ffcb4f..fbdcca9a0 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/haunted_wasteland.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/haunted_wasteland.cpp @@ -12,7 +12,7 @@ void RegionTable_Init_HauntedWasteland() { }, { //Exits Entrance(RR_GF_OUTSIDE_GATE, []{return true;}), - Entrance(RR_HAUNTED_WASTELAND, []{return logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_LONGSHOT) || ctx->GetTrickOption(RT_HW_CROSSING);}), + Entrance(RR_HAUNTED_WASTELAND, []{return logic->CanHover() || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_LONGSHOT) || ctx->GetTrickOption(RT_HW_CROSSING);}), }); areaTable[RR_HAUNTED_WASTELAND] = Region("Haunted Wasteland", SCENE_HAUNTED_WASTELAND, { @@ -24,7 +24,7 @@ void RegionTable_Init_HauntedWasteland() { //Locations LOCATION(RC_WASTELAND_CHEST, logic->HasFireSource()), LOCATION(RC_WASTELAND_BOMBCHU_SALESMAN, logic->CanJumpslash() || logic->CanUse(RG_HOVER_BOOTS)), - LOCATION(RC_WASTELAND_GS, logic->HookshotOrBoomerang()), + LOCATION(RC_WASTELAND_GS, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG, true)), LOCATION(RC_WASTELAND_NEAR_GS_POT_1, logic->CanBreakPots()), LOCATION(RC_WASTELAND_NEAR_GS_POT_2, logic->CanBreakPots()), LOCATION(RC_WASTELAND_NEAR_GS_POT_3, logic->CanBreakPots()), @@ -35,7 +35,7 @@ void RegionTable_Init_HauntedWasteland() { }, { //Exits Entrance(RR_WASTELAND_NEAR_COLOSSUS, []{return ctx->GetTrickOption(RT_LENS_HW) || logic->CanUse(RG_LENS_OF_TRUTH);}), - Entrance(RR_WASTELAND_NEAR_FORTRESS, []{return logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_LONGSHOT) || ctx->GetTrickOption(RT_HW_CROSSING);}), + Entrance(RR_WASTELAND_NEAR_FORTRESS, []{return logic->CanHover() || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_LONGSHOT) || ctx->GetTrickOption(RT_HW_CROSSING);}), }); areaTable[RR_WASTELAND_NEAR_COLOSSUS] = Region("Wasteland Near Colossus", SCENE_HAUNTED_WASTELAND, {}, { diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp index 92bc9aa37..1592d8612 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp @@ -74,7 +74,7 @@ void RegionTable_Init_Kakariko() { Entrance(RR_KAK_IMPAS_LEDGE, []{return (logic->IsChild && logic->AtDay) || (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_ROOFTOP, []{return logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_KAK_MAN_ON_ROOF) && 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_KAK_IMPAS_ROOFTOP, []{return logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_KAK_ROOFTOP_GS) && logic->CanUse(RG_HOVER_BOOTS)) || logic->CanHover();}), Entrance(RR_THE_GRAVEYARD, []{return true;}), Entrance(RR_KAK_BEHIND_GATE, []{return logic->IsAdult || logic->KakarikoVillageGateOpen;}), //adult can jump from the fence near the windmill to ledgegrab the fence near granny's shop. is in logic on N64 diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp index 5d8ef11ec..0bb443c5e 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp @@ -15,7 +15,7 @@ void RegionTable_Init_KokiriForest() { LOCATION(RC_KF_KOKIRI_SWORD_CHEST, logic->IsChild), LOCATION(RC_KF_GS_KNOW_IT_ALL_HOUSE, logic->IsChild && logic->CanAttack() && logic->CanGetNightTimeGS()), LOCATION(RC_KF_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && logic->CanAttack()), - LOCATION(RC_KF_GS_HOUSE_OF_TWINS, logic->IsAdult && (logic->HookshotOrBoomerang() || (ctx->GetTrickOption(RT_KF_ADULT_GS) && logic->CanUse(RG_HOVER_BOOTS))) && logic->CanGetNightTimeGS()), + LOCATION(RC_KF_GS_HOUSE_OF_TWINS, logic->IsAdult && (logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG, true) || (ctx->GetTrickOption(RT_KF_ADULT_GS) && logic->CanUse(RG_HOVER_BOOTS))) && logic->CanGetNightTimeGS()), LOCATION(RC_KF_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_KF_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_KF_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), @@ -29,13 +29,13 @@ void RegionTable_Init_KokiriForest() { LOCATION(RC_KF_NORTH_GRASS_EAST_RUPEE, logic->IsChild), LOCATION(RC_KF_BOULDER_RUPEE_1, logic->IsChild), LOCATION(RC_KF_BOULDER_RUPEE_2, logic->IsChild), - LOCATION(RC_KF_BEAN_RUPEE_1, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_KF_BEAN_RUPEE_2, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_KF_BEAN_RUPEE_3, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_KF_BEAN_RUPEE_4, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_KF_BEAN_RUPEE_5, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_KF_BEAN_RUPEE_6, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_KF_BEAN_RED_RUPEE, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_1, logic->IsAdult && (logic->CanHover() || CanPlantBean(RR_KOKIRI_FOREST) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_2, logic->IsAdult && (logic->CanHover() || CanPlantBean(RR_KOKIRI_FOREST) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_3, logic->IsAdult && (logic->CanHover() || CanPlantBean(RR_KOKIRI_FOREST) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_4, logic->IsAdult && (logic->CanHover() || CanPlantBean(RR_KOKIRI_FOREST) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_5, logic->IsAdult && (logic->CanHover() || CanPlantBean(RR_KOKIRI_FOREST) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_6, logic->IsAdult && (logic->CanHover() || CanPlantBean(RR_KOKIRI_FOREST) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RED_RUPEE, logic->IsAdult && (logic->CanHover() || CanPlantBean(RR_KOKIRI_FOREST) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), LOCATION(RC_KF_SARIAS_ROOF_WEST_HEART, logic->IsChild), LOCATION(RC_KF_SARIAS_ROOF_EAST_HEART, logic->IsChild), LOCATION(RC_KF_SARIAS_ROOF_NORTH_HEART, logic->IsChild), @@ -83,7 +83,7 @@ void RegionTable_Init_KokiriForest() { 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->ForestTempleClear)) || ctx->GetOption(RSK_FOREST).Is(RO_CLOSED_FOREST_OFF) || logic->ShowedMidoSwordAndShield;}), + Entrance(RR_KF_OUTSIDE_DEKU_TREE, []{return logic->CanHover() || (logic->IsAdult && (logic->CanPassEnemy(RE_BIG_SKULLTULA) || logic->ForestTempleClear)) || ctx->GetOption(RSK_FOREST).Is(RO_CLOSED_FOREST_OFF) || logic->ShowedMidoSwordAndShield;}), Entrance(RR_THE_LOST_WOODS, []{return true;}), Entrance(RR_LW_BRIDGE_FROM_FOREST, []{return logic->IsAdult || ctx->GetOption(RSK_FOREST).IsNot(RO_CLOSED_FOREST_ON) || logic->DekuTreeClear;}), Entrance(RR_KF_STORMS_GROTTO, []{return logic->CanOpenStormsGrotto();}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp index 964b781ce..3965e8e4b 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp @@ -20,8 +20,8 @@ void RegionTable_Init_LakeHylia() { LOCATION(RC_LH_FREESTANDING_POH, logic->IsAdult && (logic->CanUse(RG_SCARECROW) || CanPlantBean(RR_LAKE_HYLIA))), LOCATION(RC_LH_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && 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)), - LOCATION(RC_LH_GS_TREE, logic->IsAdult && logic->CanUse(RG_LONGSHOT) && logic->CanGetNightTimeGS()), + LOCATION(RC_LH_GS_SMALL_ISLAND, logic->IsChild && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA) && logic->CanGetNightTimeGS() && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanHover())), + LOCATION(RC_LH_GS_TREE, logic->IsAdult && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_LONGSHOT, true) && logic->CanGetNightTimeGS()), LOCATION(RC_LH_FRONT_RUPEE, logic->IsChild && logic->HasItem(RG_BRONZE_SCALE)), LOCATION(RC_LH_MIDDLE_RUPEE, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))), LOCATION(RC_LH_BACK_RUPEE, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))), @@ -86,7 +86,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->WaterTempleClear) && logic->HasItem(RG_BRONZE_SCALE)) || (logic->IsAdult && (logic->CanUse(RG_SCARECROW) || CanPlantBean(RR_LAKE_HYLIA)));}), + Entrance(RR_LH_FISHING_ISLAND, []{return logic->CanHover() || ((logic->IsChild || logic->WaterTempleClear) && logic->HasItem(RG_BRONZE_SCALE)) || (logic->IsAdult && (logic->CanUse(RG_SCARECROW) || CanPlantBean(RR_LAKE_HYLIA)));}), 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 c29a5924e..ecf02bb54 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 @@ -12,10 +12,10 @@ void RegionTable_Init_LonLonRanch() { }, { //Locations LOCATION(RC_SONG_FROM_MALON, logic->IsChild && logic->HasItem(RG_ZELDAS_LETTER) && logic->HasItem(RG_FAIRY_OCARINA) && logic->AtDay), - LOCATION(RC_LLR_GS_TREE, logic->IsChild), - LOCATION(RC_LLR_GS_RAIN_SHED, logic->IsChild && logic->CanGetNightTimeGS()), - LOCATION(RC_LLR_GS_HOUSE_WINDOW, logic->IsChild && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), - LOCATION(RC_LLR_GS_BACK_WALL, logic->IsChild && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), + LOCATION(RC_LLR_GS_TREE, logic->IsChild && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_CLOSE, true)), + LOCATION(RC_LLR_GS_RAIN_SHED, logic->IsChild && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_CLOSE, true) && logic->CanGetNightTimeGS()), + LOCATION(RC_LLR_GS_HOUSE_WINDOW, logic->IsChild && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG, true) && logic->CanGetNightTimeGS()), + LOCATION(RC_LLR_GS_BACK_WALL, logic->IsChild && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG, true) && logic->CanGetNightTimeGS()), LOCATION(RC_LLR_FRONT_POT_1, logic->IsChild && logic->CanBreakPots()), LOCATION(RC_LLR_FRONT_POT_2, logic->IsChild && logic->CanBreakPots()), LOCATION(RC_LLR_FRONT_POT_3, logic->IsChild && logic->CanBreakPots()), @@ -42,6 +42,8 @@ void RegionTable_Init_LonLonRanch() { }, { //Exits Entrance(RR_LON_LON_RANCH, []{return true;}), + // possible if items aren't restricted (there's a convoluted glitch that could be implemented in the future) + Entrance(RR_LLR_STABLES, []{return false && logic->CanHover();}), }); areaTable[RR_LLR_STABLES] = Region("LLR Stables", SCENE_STABLE, {}, { diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/lost_woods.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/lost_woods.cpp index 6c6bdb536..c5b137f36 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/lost_woods.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/lost_woods.cpp @@ -31,7 +31,8 @@ void RegionTable_Init_LostWoods() { //4 buttons => 25.3125% //5 buttons => 100% LOCATION(RC_LW_OCARINA_MEMORY_GAME, logic->IsChild && logic->HasItem(RG_FAIRY_OCARINA) && logic->OcarinaButtons() >= 5), - LOCATION(RC_LW_TARGET_IN_WOODS, logic->IsChild && logic->CanUse(RG_FAIRY_SLINGSHOT)), + // qpa + LOCATION(RC_LW_TARGET_IN_WOODS, logic->IsChild && (logic->CanUse(RG_FAIRY_SLINGSHOT) || (false && logic->CanHover()))), LOCATION(RC_LW_DEKU_SCRUB_NEAR_BRIDGE, logic->IsChild && logic->CanStunDeku()), LOCATION(RC_LW_GS_BEAN_PATCH_NEAR_BRIDGE, logic->CanSpawnSoilSkull() && logic->CanAttack()), //RANDOTODO handle collecting some of these as you leave the shortcut from the other side @@ -57,7 +58,7 @@ void RegionTable_Init_LostWoods() { //Exits Entrance(RR_LW_FOREST_EXIT, []{return true;}), Entrance(RR_GC_WOODS_WARP, []{return true;}), - Entrance(RR_LW_BRIDGE, []{return (logic->IsAdult && (CanPlantBean(RR_THE_LOST_WOODS) || ctx->GetTrickOption(RT_LW_BRIDGE))) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_LONGSHOT);}), + Entrance(RR_LW_BRIDGE, []{return logic->CanHover() || (logic->IsAdult && (CanPlantBean(RR_THE_LOST_WOODS) || ctx->GetTrickOption(RT_LW_BRIDGE))) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_LONGSHOT);}), Entrance(RR_ZR_FROM_SHORTCUT, []{return logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS) || (ctx->GetTrickOption(RT_LOST_WOOD_NAVI_DIVE) && logic->IsChild && logic->HasItem(RG_BRONZE_SCALE) && logic->CanJumpslash());}), Entrance(RR_LW_BEYOND_MIDO, []{return logic->IsChild || logic->CanUse(RG_SARIAS_SONG) || ctx->GetTrickOption(RT_LW_MIDO_BACKFLIP);}), Entrance(RR_LW_NEAR_SHORTCUTS_GROTTO, []{return Here(RR_THE_LOST_WOODS, []{return logic->BlastOrSmash();});}), @@ -70,7 +71,7 @@ void RegionTable_Init_LostWoods() { //Locations LOCATION(RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, logic->IsChild && logic->CanStunDeku()), LOCATION(RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, logic->IsChild && logic->CanStunDeku()), - LOCATION(RC_LW_GS_ABOVE_THEATER, logic->IsAdult && ((CanPlantBean(RR_LW_BEYOND_MIDO) && logic->CanAttack()) || (ctx->GetTrickOption(RT_LW_GS_BEAN) && logic->CanUse(RG_HOOKSHOT) && (logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOMBCHU_5) || logic->CanUse(RG_DINS_FIRE)))) && logic->CanGetNightTimeGS()), + LOCATION(RC_LW_GS_ABOVE_THEATER, logic->IsAdult && (logic->CanHover() || (CanPlantBean(RR_LW_BEYOND_MIDO) && logic->CanAttack()) || (ctx->GetTrickOption(RT_LW_GS_BEAN) && logic->CanUse(RG_HOOKSHOT) && (logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOMBCHU_5) || logic->CanUse(RG_DINS_FIRE)))) && logic->CanGetNightTimeGS()), LOCATION(RC_LW_GS_BEAN_PATCH_NEAR_THEATER, logic->CanSpawnSoilSkull() && (logic->CanAttack() || (ctx->GetOption(RSK_SHUFFLE_SCRUBS).Is(RO_SCRUBS_OFF) && logic->CanReflectNuts()))), LOCATION(RC_LW_BOULDER_RUPEE, logic->BlastOrSmash()), LOCATION(RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_1, logic->IsChild && logic->HasItem(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp index 4f62d437f..2629ac5a6 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp @@ -55,7 +55,7 @@ void RegionTable_Init_Market() { }, { //Locations LOCATION(RC_MARKET_10_BIG_POES, logic->IsAdult && (logic->BigPoeKill || logic->BigPoes >= ctx->GetOption(RSK_BIG_POE_COUNT).Get())), - LOCATION(RC_MARKET_GS_GUARD_HOUSE, logic->IsChild), + LOCATION(RC_MARKET_GS_GUARD_HOUSE, logic->IsChild && logic->CanBreakCrates()), LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_1, logic->IsChild && logic->CanBreakPots()), LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_2, logic->IsChild && logic->CanBreakPots()), LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_3, logic->IsChild && logic->CanBreakPots()), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/sacred_forest_meadow.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/sacred_forest_meadow.cpp index 9d641ac98..35f809f39 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/sacred_forest_meadow.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/sacred_forest_meadow.cpp @@ -8,7 +8,7 @@ void RegionTable_Init_SacredForestMeadow() { areaTable[RR_SFM_ENTRYWAY] = Region("SFM Entryway", SCENE_SACRED_FOREST_MEADOW, {}, {}, { //Exits Entrance(RR_LW_BEYOND_MIDO, []{return true;}), - Entrance(RR_SACRED_FOREST_MEADOW, []{return logic->IsAdult || logic->CanKillEnemy(RE_WOLFOS);}), + Entrance(RR_SACRED_FOREST_MEADOW, []{return logic->IsAdult || logic->CanKillEnemy(RE_WOLFOS) || logic->CanHover();}), Entrance(RR_SFM_WOLFOS_GROTTO, []{return logic->CanOpenBombGrotto();}), }); @@ -19,7 +19,7 @@ void RegionTable_Init_SacredForestMeadow() { //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_GS, logic->IsAdult && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG, true) && 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()), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/thieves_hideout.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/thieves_hideout.cpp index 0a70e77e8..94a534af5 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/thieves_hideout.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/thieves_hideout.cpp @@ -110,8 +110,8 @@ void RegionTable_Init_ThievesHideout() { //Exits Entrance(RR_TH_KITCHEN_MAIN, []{return true;}), //hookshot to cross using the rafters is implied in logic->CanPassEnemy(RE_GERUDO_GUARD) - Entrance(RR_GF_NEAR_GS, []{return logic->CanPassEnemy(RE_GERUDO_GUARD) || logic->CanUse(RG_HOVER_BOOTS);}), - Entrance(RR_GF_TOP_OF_LOWER_VINES, []{return logic->CanPassEnemy(RE_GERUDO_GUARD) || logic->CanUse(RG_HOVER_BOOTS);}), + Entrance(RR_GF_NEAR_GS, []{return logic->CanPassEnemy(RE_GERUDO_GUARD) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanHover();}), + Entrance(RR_GF_TOP_OF_LOWER_VINES, []{return logic->CanPassEnemy(RE_GERUDO_GUARD) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanHover();}), }); areaTable[RR_TH_BREAK_ROOM] = Region("Thieves Hideout Break Room", SCENE_THIEVES_HIDEOUT, {}, { @@ -130,12 +130,12 @@ void RegionTable_Init_ThievesHideout() { //Exits Entrance(RR_GF_BELOW_CHEST, []{return logic->CanPassEnemy(RE_GERUDO_GUARD);}), //Implies logic->CanPassEnemy(RE_GERUDO_GUARD) - Entrance(RR_TH_BREAK_ROOM_CORRIDOR, []{return logic->CanUse(RG_HOOKSHOT);}), + Entrance(RR_TH_BREAK_ROOM_CORRIDOR, []{return logic->CanUse(RG_HOOKSHOT) || logic->CanHover();}), }); areaTable[RR_TH_BREAK_ROOM_CORRIDOR] = Region("Thieves Hideout Break Room", SCENE_THIEVES_HIDEOUT, {}, {}, { //Exits - Entrance(RR_TH_BREAK_ROOM, []{return logic->CanUse(RG_HOOKSHOT);}), + Entrance(RR_TH_BREAK_ROOM, []{return logic->CanUse(RG_HOOKSHOT) || logic->CanHover();}), Entrance(RR_GF_ABOVE_JAIL, []{return true;}), }); } diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp index 3a626a2f9..734515bb9 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp @@ -39,14 +39,14 @@ void RegionTable_Init_ZorasDomain() { //Exits Entrance(RR_ZR_BEHIND_WATERFALL, []{return true;}), Entrance(RR_LH_FROM_SHORTCUT, []{return logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS));}), - Entrance(RR_ZD_BEHIND_KING_ZORA, []{return logic->DeliverLetter || ctx->GetOption(RSK_ZORAS_FOUNTAIN).Is(RO_ZF_OPEN) || (ctx->GetOption(RSK_ZORAS_FOUNTAIN).Is(RO_ZF_CLOSED_CHILD) && logic->IsAdult) || (ctx->GetTrickOption(RT_ZD_KING_ZORA_SKIP) && logic->IsAdult);}), + Entrance(RR_ZD_BEHIND_KING_ZORA, []{return logic->CanHover() || logic->DeliverLetter || ctx->GetOption(RSK_ZORAS_FOUNTAIN).Is(RO_ZF_OPEN) || (ctx->GetOption(RSK_ZORAS_FOUNTAIN).Is(RO_ZF_CLOSED_CHILD) && logic->IsAdult) || (ctx->GetTrickOption(RT_ZD_KING_ZORA_SKIP) && logic->IsAdult);}), Entrance(RR_ZD_SHOP, []{return logic->IsChild || logic->BlueFire();}), Entrance(RR_ZORAS_DOMAIN_ISLAND, []{return true;}), }); areaTable[RR_ZORAS_DOMAIN_ISLAND] = Region("Zoras Domain Island", SCENE_ZORAS_DOMAIN, {}, {}, { //Exits - Entrance(RR_ZORAS_DOMAIN, []{return logic->IsAdult || logic->HasItem(RG_BRONZE_SCALE);}), + Entrance(RR_ZORAS_DOMAIN, []{return logic->IsAdult || logic->HasItem(RG_BRONZE_SCALE) || logic->CanHover();}), Entrance(RR_ZD_STORMS_GROTTO, []{return logic->CanOpenStormsGrotto();}), }); @@ -58,7 +58,7 @@ void RegionTable_Init_ZorasDomain() { LOCATION(RC_ZD_BEHIND_KING_ZORA_BEEHIVE, logic->IsChild && logic->CanBreakUpperBeehives()), }, { //Exits - Entrance(RR_ZORAS_DOMAIN, []{return logic->DeliverLetter || ctx->GetOption(RSK_ZORAS_FOUNTAIN).Is(RO_ZF_OPEN) || (ctx->GetOption(RSK_ZORAS_FOUNTAIN).Is(RO_ZF_CLOSED_CHILD) && logic->IsAdult);}), + Entrance(RR_ZORAS_DOMAIN, []{return logic->CanHover() || logic->DeliverLetter || ctx->GetOption(RSK_ZORAS_FOUNTAIN).Is(RO_ZF_OPEN) || (ctx->GetOption(RSK_ZORAS_FOUNTAIN).Is(RO_ZF_CLOSED_CHILD) && logic->IsAdult);}), Entrance(RR_ZORAS_FOUNTAIN, []{return true;}), }); 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 e1062caf9..0eae2ab8b 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp @@ -12,7 +12,7 @@ void RegionTable_Init_ZorasFountain() { }, { //Locations LOCATION(RC_ZF_GS_TREE, logic->IsChild), - LOCATION(RC_ZF_GS_ABOVE_THE_LOG, logic->IsChild && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), + LOCATION(RC_ZF_GS_ABOVE_THE_LOG, logic->IsChild && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG, true) && logic->CanGetNightTimeGS()), LOCATION(RC_ZF_FAIRY_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()), LOCATION(RC_ZF_FAIRY_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_ZF_JABU_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()), @@ -33,6 +33,8 @@ void RegionTable_Init_ZorasFountain() { Entrance(RR_ZF_ROCK, []{return logic->IsAdult && logic->CanUse(RG_SCARECROW);}), 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));}), + Entrance(RR_ZF_HIDDEN_LEDGE, []{return logic->CanHover();}), + Entrance(RR_ZF_LEDGE, []{return logic->CanHover();}), }); areaTable[RR_ZF_ICEBERGS] = Region("ZF Icebergs", SCENE_ZORAS_FOUNTAIN, {}, { @@ -104,7 +106,7 @@ void RegionTable_Init_ZorasFountain() { areaTable[RR_ZF_ROCK] = Region("ZF Rock", SCENE_ZORAS_FOUNTAIN, {}, { //Locations - //Has a wonder item + //Has a wonder item except in ntsc 1.0 }, { //Exits Entrance(RR_ZORAS_FOUNTAIN, []{return true;}), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp index 5473ee2ca..b83719d1b 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp @@ -7,7 +7,7 @@ void RegionTable_Init_ZoraRiver() { // clang-format off areaTable[RR_ZR_FRONT] = Region("ZR Front", SCENE_ZORAS_RIVER, {}, { //Locations - LOCATION(RC_ZR_GS_TREE, logic->IsChild && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_CLOSE)), + LOCATION(RC_ZR_GS_TREE, logic->IsChild && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_CLOSE)), LOCATION(RC_ZR_GRASS_1, logic->CanCutShrubs()), LOCATION(RC_ZR_GRASS_2, logic->CanCutShrubs()), LOCATION(RC_ZR_GRASS_3, logic->CanCutShrubs()), @@ -44,9 +44,9 @@ void RegionTable_Init_ZoraRiver() { LOCATION(RC_ZR_FROGS_SONG_OF_TIME, logic->IsChild && logic->CanUse(RG_SONG_OF_TIME)), LOCATION(RC_ZR_NEAR_OPEN_GROTTO_FREESTANDING_POH, logic->IsChild || logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && ctx->GetTrickOption(RT_ZR_LOWER))), LOCATION(RC_ZR_NEAR_DOMAIN_FREESTANDING_POH, logic->IsChild || logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && ctx->GetTrickOption(RT_ZR_UPPER))), - LOCATION(RC_ZR_GS_LADDER, logic->IsChild && logic->CanAttack() && logic->CanGetNightTimeGS()), - LOCATION(RC_ZR_GS_NEAR_RAISED_GROTTOS, logic->IsAdult && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), - LOCATION(RC_ZR_GS_ABOVE_BRIDGE, logic->IsAdult && logic->CanUse(RG_HOOKSHOT) && logic->CanGetNightTimeGS()), + LOCATION(RC_ZR_GS_LADDER, logic->IsChild && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_CLOSE, true) && logic->CanGetNightTimeGS()), + LOCATION(RC_ZR_GS_NEAR_RAISED_GROTTOS, logic->IsAdult && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG, true) && logic->CanGetNightTimeGS()), + LOCATION(RC_ZR_GS_ABOVE_BRIDGE, logic->IsAdult && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_HOOKSHOT, true) && logic->CanGetNightTimeGS()), LOCATION(RC_ZR_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_ZR_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_ZR_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index eea79e92d..52efefb5e 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -482,7 +482,9 @@ 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 + +// Can we kill this enemy bool Logic::CanKillEnemy(RandomizerEnemy enemy, EnemyDistance distance, bool wallOrFloor, uint8_t quantity, bool timer, bool inWater) { bool killed = false; @@ -491,6 +493,9 @@ bool Logic::CanKillEnemy(RandomizerEnemy enemy, EnemyDistance distance, bool wal case RE_BREAK_ROOM_GUARD: return false; case RE_GOLD_SKULLTULA: + if (CanHover()) { + return true; + } switch (distance) { case ED_CLOSE: // hammer jumpslash cannot damage these, but hammer swing can @@ -1075,6 +1080,41 @@ bool Logic::CanJumpslash() { return CanJumpslashExceptHammer() || CanUse(RG_MEGATON_HAMMER); } +bool Logic::CanCrouchStab() { + return (CanUse(RG_DEKU_SHIELD) || CanUse(RG_MIRROR_SHIELD) || (IsAdult && HasItem(RG_HYLIAN_SHIELD))) && (CanUseSword() || CanUse(RG_STICKS) || CanUse(RG_MEGATON_HAMMER)); +} + +/// @brief Checks if the player can do ISG (does not check for being able to interrupt the crouchstab) +/// @return Whether ISG can be done or not +bool Logic::CanDoISG() { + // need something to interrupt the crouchstab: + // - blocking textbox (sign / npc / enemy navi check) + // - grabable actor (rock / bush / small crate / cucoo / silver gauntelts rock) + // - bombs (should probably be a separate trick as it's harder due to the time limit) + // - bombchus (even harder) + return ctx->GetTrickOption(RT_ISG) && CanCrouchStab(); +} + +/// @brief Checks if the player can hover (does not account for the static explosion radius enhancement) +/// @param againstWall Whether the hover must done against a wall or not +/// @param persistentDamageSource Whether a persistent damage source to shield exists (eg biri hover) +/// @return Whether hovering an be done or not +bool Logic::CanHover(bool againstWall, bool persistentDamageSource) { + return + ctx->GetTrickOption(RT_HOVERING) && + CanDoISG() && + ( + persistentDamageSource || + CanUse(RG_BOMB_BAG) || + ( + !againstWall && + CanUse(RG_PROGRESSIVE_BOMBCHUS) + ) + ) && + // if not against a wall, need either hover boots to shorten the backflips or an item to do a contorsion hover + (againstWall || CanUse(RG_HOVER_BOOTS) || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_FAIRY_BOW) || CanUse(RG_BOOMERANG)); +} + bool Logic::CanHitSwitch(EnemyDistance distance, bool inWater) { bool hit = false; switch (distance) { diff --git a/soh/soh/Enhancements/randomizer/logic.h b/soh/soh/Enhancements/randomizer/logic.h index 2bfea75e9..9fa15756a 100644 --- a/soh/soh/Enhancements/randomizer/logic.h +++ b/soh/soh/Enhancements/randomizer/logic.h @@ -217,6 +217,9 @@ class Logic { bool CanUseSword(); bool CanJumpslashExceptHammer(); bool CanJumpslash(); + bool CanCrouchStab(); + bool CanDoISG(); + bool CanHover(bool againstWall = false, bool persistentDamageSource = false); bool CanHitSwitch(EnemyDistance distance = ED_CLOSE, bool inWater = false); bool CanDamage(); bool CanAttack(); diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 15a2fbd37..4d8883d8f 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -3534,6 +3534,14 @@ typedef enum { RT_BOMBCHU_BEEHIVES, RT_BLUE_FIRE_MUD_WALLS, RT_OPEN_UNDERWATER_CHEST, + RT_ISG, + RT_HOVERING, + // 3ds splits hovering into multiple tricks + //RT_HOVERING_BOW_SLINGSHOT, + //RT_HOVERING_CONTORTION, + //RT_HOVERING_ENEMY, + //RT_HOVERING_HOVERBOOTS, + //RT_HOVERING_WALL, RT_KF_ADULT_GS, // -- location tricks RT_LW_BRIDGE, RT_LW_MIDO_BACKFLIP, @@ -3728,13 +3736,6 @@ typedef enum { RT_HESS, RT_HOOKSHOT_CLIP, RT_HOOKSHOT_JUMP, - RT_HOVERING, - RT_HOVERING_BOW_SLINGSHOT, - RT_HOVERING_CONTORTION, - RT_HOVERING_ENEMY, - RT_HOVERING_HOVERBOOTS, - RT_HOVERING_WALL, - RT_ISG, RT_LADDER_CLIP, RT_LADDER_CLIP_HOOKSHOT, RT_LEDGE_CANCEL, diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index 5f8c60ac0..fd0d1a18b 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -339,35 +339,56 @@ void Settings::CreateOptions() { mExcludeLocationsOptionsAreas.reserve(RCAREA_INVALID); - // the following are glitches and are currently disabled + // the following are currently disabled + // OPT_TRICK(RT_ACUTE_ANGLE_CLIP, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, // Tricks::Tag::GLITCH}, "Acute angle clip", "Enables locations requiring jumpslash clips through walls which meet - // at an acute angle."); OPT_TRICK(RT_ADVANCED_CLIPS, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, + // at an acute angle."); + + // OPT_TRICK(RT_ADVANCED_CLIPS, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, // Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "Advanced clips", "Enables locations requiring clips through - // walls and objects requiring precise jumps or other tricks."); OPT_TRICK(RT_BLANK_A, RCQUEST_BOTH, RA_NONE, + // walls and objects requiring precise jumps or other tricks."); + + // OPT_TRICK(RT_BLANK_A, RCQUEST_BOTH, RA_NONE, // {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "Blank A", "Enables locations requiring - // blank A button; NOTE: this requires the 'Quick Putaway' restoration."); OPT_TRICK(RT_DOOM_JUMP, RCQUEST_BOTH, + // blank A button; NOTE: this requires the 'Quick Putaway' restoration."); + + // OPT_TRICK(RT_DOOM_JUMP, RCQUEST_BOTH, // RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "Doom Jump", "Enables locations - // requiring doom jumps."); OPT_TRICK(RT_EPG, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, + // requiring doom jumps."); + + // OPT_TRICK(RT_EPG, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, // Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "EPG", "Enables locations requiring use of the Entrance Point - // Glitch."); OPT_TRICK(RT_EQUIP_SWAP, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, + // Glitch."); + + // OPT_TRICK(RT_EQUIP_SWAP, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, // Tricks::Tag::GLITCH}, "Equip Swap", "Enables locations requiring use of equip swap; NOTE: this may expect the - // 'Allow cursor to be over any slot' enhancement to be turned off."); OPT_TRICK(RT_EQUIP_SWAP_EXPECTS_DINS, + // 'Allow cursor to be over any slot' enhancement to be turned off."); + + // OPT_TRICK(RT_EQUIP_SWAP_EXPECTS_DINS, // RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "Equip Swap // Require's Din's Fire", "Enables locations requiring use of equip swap once Din's Fire is found."); + // OPT_TRICK(RT_FLAME_STORAGE, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, - // Tricks::Tag::GLITCH}, "Flame Storage", "Enables locations requiring flame storage."); OPT_TRICK(RT_GROUND_CLIP, + // Tricks::Tag::GLITCH}, "Flame Storage", "Enables locations requiring flame storage."); + + // OPT_TRICK(RT_GROUND_CLIP, // RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "Ground Clip", - // "Enables locations requiring ground clips."); OPT_TRICK(RT_GROUND_JUMP, RCQUEST_BOTH, RA_NONE, + // "Enables locations requiring ground clips."); + + // OPT_TRICK(RT_GROUND_JUMP, RCQUEST_BOTH, RA_NONE, // {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "Ground Jump", "Enables locations - // requiring ground jumps."); OPT_TRICK(RT_HESS, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, + // requiring ground jumps."); + + // OPT_TRICK(RT_HESS, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, // Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "HESS", "Enables locations requiring a Hyper Extended Super - // Slide."); OPT_TRICK(RT_HOOKSHOT_CLIP, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, + // Slide."); + + // OPT_TRICK(RT_HOOKSHOT_CLIP, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, // Tricks::Tag::GLITCH}, "Hookshot Clip", "Enables locations requiring Hookshot clips."); + // OPT_TRICK(RT_HOOKSHOT_JUMP, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, - // Tricks::Tag::GLITCH}, "Hookshot Jump", "Enables locations requiring Hookshot jumps."); OPT_TRICK(RT_ISG, - // RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "ISG", "Enables - // locations requiring use of the infinite sword glitch."); + // Tricks::Tag::GLITCH}, "Hookshot Jump", "Enables locations requiring Hookshot jumps."); OPT_TRICK(RT_VISIBLE_COLLISION, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::NOVICE }, "Pass Through Visible One-Way Collision", @@ -387,7 +408,9 @@ void Settings::CreateOptions() { "The chests encircled in flames in Gerudo Training Ground and in Spirit Temple can be opened by running " "into the flames while Link is invincible after taking damage."); // disabled for now, can't check for being able to use bunny hood & bunny hood speedup is currently completely - // decoupled from rando OPT_TRICK(RT_BUNNY_HOOD_JUMPS, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED}, "Bunny Hood + // decoupled from rando + + // OPT_TRICK(RT_BUNNY_HOOD_JUMPS, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED}, "Bunny Hood // Jumps", "Allows reaching locations using Bunny Hood's extended jumps."); OPT_TRICK(RT_DAMAGE_BOOST_SIMPLE, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL }, "Simple damage boosts", @@ -404,6 +427,15 @@ void Settings::CreateOptions() { "apply to MQ Dead Hand bomb flowers.\nUsing blue fire on bombflower to stop rolling goron also requires " "\"Stop Link the Goron with Din's Fire\".\nUsing blue fire arrows to break floor in King Dodongo's " "chamber also requires \"Dodongo\'s Cavern Smash the Boss Lobby Floor\"."); + OPT_TRICK(RT_ISG, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::NOVICE, Tricks::Tag::GLITCH }, + "Infinite Sword Glitch", + "By interrupting a crouchstab, the sword hitbox is never disabled."); + OPT_TRICK(RT_HOVERING, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::INTERMEDIATE, Tricks::Tag::GLITCH }, + "Hovering", + "By shielding damage while midair and doing ISG, you can hover in place." + "\nIt is possible to the backflip (or sideflip) and shield another damage source to get higher." + "\n" + "\nRequires the \"Infinite Sword Glitch\" trick to be enabled"); OPT_TRICK(RT_OPEN_UNDERWATER_CHEST, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::NOVICE, Tricks::Tag::GLITCH }, "Open Underwater Chests", "Underwater chests can be opened by wearing iron boots and hookshotting the chest."); @@ -498,7 +530,9 @@ void Settings::CreateOptions() { "Death Mountain Trail Upper Red Rock GS without Hammer", "After killing the Skulltula, the token can be collected by backflipping into the rock at the correct angle."); // disabled for now, only applies when trade quest is not shuffled so there's a timer (currently not considered in - // logic) OPT_TRICK(RT_DMT_BOLERO_BIGGORON, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, {Tricks::Tag::INTERMEDIATE}, + // logic) + + // OPT_TRICK(RT_DMT_BOLERO_BIGGORON, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, {Tricks::Tag::INTERMEDIATE}, // "Deliver Eye Drops with Bolero of Fire", "Playing a warp song normally causes a trade item to spoil immediately, // however, it is possible use Bolero to reach Biggoron and still deliver the Eye Drops before they spoil. If you do // not wear the Goron Tunic, the heat timer inside the crater will override the trade item\'s timer. When you exit @@ -595,7 +629,9 @@ void Settings::CreateOptions() { "Ledge Clip into Training Ground", "Adult Link can use a ledge clip to enter Gerudo Training Ground without Gerudo Card."); // disabled for now, can't check for being able to use bunny hood & bunny hood speedup is currently completely - // decoupled from rando OPT_TRICK(RT_HW_BUNNY_CROSSING, RCQUEST_BOTH, RA_HAUNTED_WASTELAND, {Tricks::Tag::NOVICE}, + // decoupled from rando + + // OPT_TRICK(RT_HW_BUNNY_CROSSING, RCQUEST_BOTH, RA_HAUNTED_WASTELAND, {Tricks::Tag::NOVICE}, // "Wasteland Crossing with Bunny Hood", "You can beat the quicksand by using the increased speed of the Bunny Hood. // Note that jumping to the carpet merchant as child typically requires a fairly precise jump slash."); OPT_TRICK(RT_HW_CROSSING, RCQUEST_BOTH, RA_HAUNTED_WASTELAND, { Tricks::Tag::INTERMEDIATE }, @@ -1048,7 +1084,9 @@ void Settings::CreateOptions() { "or Song of Time (in MQ): - Spirit Temple Statue Room Northeast Chest - Spirit Temple GS Lobby - Spirit Temple " "MQ Central Chamber Top Left Pot (Left) - Spirit Temple MQ Central Chamber Top Left Pot (Right)"); // disabled since "Spirit Temple boss shortcuts" (pre-lowers the platform where you break the statues face) isn't a - // setting in ship OPT_TRICK(RT_SPIRIT_PLATFORM_HOOKSHOT, RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, + // setting in ship + + // OPT_TRICK(RT_SPIRIT_PLATFORM_HOOKSHOT, RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, // {Tricks::Tag::INTERMEDIATE}, "Spirit Temple Main Room Hookshot to Boss Platform", "Precise hookshot aiming at the // platform chains can be used to reach the boss platform from the middle landings. Using a jump slash immediately // after reaching a chain makes aiming more lenient. Relevant only when Spirit Temple boss shortcuts are on."); From 4d645d440dfc9534ebacc2e0afc2edd6c9de1e04 Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Sun, 13 Jul 2025 18:14:42 +0200 Subject: [PATCH 2/3] Update lake_hylia.cpp --- .../randomizer/location_access/overworld/lake_hylia.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 3965e8e4b..420fc73c1 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp @@ -17,7 +17,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->WaterTempleClear && 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))), + LOCATION(RC_LH_FREESTANDING_POH, logic->IsAdult && (logic->CanUse(RG_SCARECROW) || CanPlantBean(RR_LAKE_HYLIA) || logic->CanHover())), LOCATION(RC_LH_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && 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) || logic->CanHover())), From 564a130b72dfa4a3a26245b378c0715c85b072c6 Mon Sep 17 00:00:00 2001 From: Pepe20129 <72659707+Pepe20129@users.noreply.github.com> Date: Sun, 13 Jul 2025 18:32:32 +0200 Subject: [PATCH 3/3] clang --- soh/soh/Enhancements/randomizer/logic.cpp | 22 +++++++------------ .../Enhancements/randomizer/randomizerTypes.h | 10 ++++----- soh/soh/Enhancements/randomizer/settings.cpp | 6 ++--- 3 files changed, 15 insertions(+), 23 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index 52efefb5e..e1fc0ba0f 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -1081,7 +1081,8 @@ bool Logic::CanJumpslash() { } bool Logic::CanCrouchStab() { - return (CanUse(RG_DEKU_SHIELD) || CanUse(RG_MIRROR_SHIELD) || (IsAdult && HasItem(RG_HYLIAN_SHIELD))) && (CanUseSword() || CanUse(RG_STICKS) || CanUse(RG_MEGATON_HAMMER)); + return (CanUse(RG_DEKU_SHIELD) || CanUse(RG_MIRROR_SHIELD) || (IsAdult && HasItem(RG_HYLIAN_SHIELD))) && + (CanUseSword() || CanUse(RG_STICKS) || CanUse(RG_MEGATON_HAMMER)); } /// @brief Checks if the player can do ISG (does not check for being able to interrupt the crouchstab) @@ -1100,19 +1101,12 @@ bool Logic::CanDoISG() { /// @param persistentDamageSource Whether a persistent damage source to shield exists (eg biri hover) /// @return Whether hovering an be done or not bool Logic::CanHover(bool againstWall, bool persistentDamageSource) { - return - ctx->GetTrickOption(RT_HOVERING) && - CanDoISG() && - ( - persistentDamageSource || - CanUse(RG_BOMB_BAG) || - ( - !againstWall && - CanUse(RG_PROGRESSIVE_BOMBCHUS) - ) - ) && - // if not against a wall, need either hover boots to shorten the backflips or an item to do a contorsion hover - (againstWall || CanUse(RG_HOVER_BOOTS) || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_FAIRY_BOW) || CanUse(RG_BOOMERANG)); + return ctx->GetTrickOption(RT_HOVERING) && CanDoISG() && + (persistentDamageSource || CanUse(RG_BOMB_BAG) || (!againstWall && CanUse(RG_PROGRESSIVE_BOMBCHUS))) && + // if not against a wall, need either hover boots to shorten the backflips or an item to do a contorsion + // hover + (againstWall || CanUse(RG_HOVER_BOOTS) || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_FAIRY_BOW) || + CanUse(RG_BOOMERANG)); } bool Logic::CanHitSwitch(EnemyDistance distance, bool inWater) { diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 4d8883d8f..274e12947 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -3537,11 +3537,11 @@ typedef enum { RT_ISG, RT_HOVERING, // 3ds splits hovering into multiple tricks - //RT_HOVERING_BOW_SLINGSHOT, - //RT_HOVERING_CONTORTION, - //RT_HOVERING_ENEMY, - //RT_HOVERING_HOVERBOOTS, - //RT_HOVERING_WALL, + // RT_HOVERING_BOW_SLINGSHOT, + // RT_HOVERING_CONTORTION, + // RT_HOVERING_ENEMY, + // RT_HOVERING_HOVERBOOTS, + // RT_HOVERING_WALL, RT_KF_ADULT_GS, // -- location tricks RT_LW_BRIDGE, RT_LW_MIDO_BACKFLIP, diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index fd0d1a18b..4c79d8b79 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -427,11 +427,9 @@ void Settings::CreateOptions() { "apply to MQ Dead Hand bomb flowers.\nUsing blue fire on bombflower to stop rolling goron also requires " "\"Stop Link the Goron with Din's Fire\".\nUsing blue fire arrows to break floor in King Dodongo's " "chamber also requires \"Dodongo\'s Cavern Smash the Boss Lobby Floor\"."); - OPT_TRICK(RT_ISG, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::NOVICE, Tricks::Tag::GLITCH }, - "Infinite Sword Glitch", + OPT_TRICK(RT_ISG, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::NOVICE, Tricks::Tag::GLITCH }, "Infinite Sword Glitch", "By interrupting a crouchstab, the sword hitbox is never disabled."); - OPT_TRICK(RT_HOVERING, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::INTERMEDIATE, Tricks::Tag::GLITCH }, - "Hovering", + OPT_TRICK(RT_HOVERING, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::INTERMEDIATE, Tricks::Tag::GLITCH }, "Hovering", "By shielding damage while midair and doing ISG, you can hover in place." "\nIt is possible to the backflip (or sideflip) and shield another damage source to get higher." "\n"