diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_deku_tree.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_deku_tree.cpp index bee7f3b40..1e98831bc 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_deku_tree.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_deku_tree.cpp @@ -166,7 +166,7 @@ void RegionTable_Init_DekuTree() { Entrance(RR_DEKU_TREE_MQ_2F, {[]{return true;}}), //Swim is not required because you can jump with enough momentum to hit land. //You even avoid fall damage if you hit the shallow water, though it's obscure knowledge so may be a trick - //if it is, then we need a landing room with (IsAdult || CanUse(RG_BRONZE_SCALE) || TakeDamage() || that trick) to reach basement + //if it is, then we need a landing room with (IsAdult || HasItem(RG_BRONZE_SCALE) || TakeDamage() || that trick) to reach basement Entrance(RR_DEKU_TREE_MQ_BASEMENT, {[]{return logic->BrokeDeku1FWeb;}}), //is it possible to recoil from here to the ledge with a trick? }); diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_dodongos_cavern.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_dodongos_cavern.cpp index df66ec9f5..23f17cf21 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_dodongos_cavern.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_dodongos_cavern.cpp @@ -219,17 +219,17 @@ void RegionTable_Init_DodongosCavern() { areaTable[RR_DODONGOS_CAVERN_MQ_LOBBY] = Region("Dodongos Cavern MQ Lobby", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->GossipStoneFairy, {[]{return (Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->CanBreakMudWalls();}) || logic->CanUse(RG_GORONS_BRACELET)) && logic->CallGossipFairy();}}), + EventAccess(&logic->GossipStoneFairy, {[]{return (Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->CanBreakMudWalls();}) || logic->HasItem(RG_GORONS_BRACELET)) && logic->CallGossipFairy();}}), }, { //Locations - LOCATION(RC_DODONGOS_CAVERN_MQ_MAP_CHEST, logic->CanBreakMudWalls() || logic->CanUse(RG_GORONS_BRACELET)), + LOCATION(RC_DODONGOS_CAVERN_MQ_MAP_CHEST, logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET)), LOCATION(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR, logic->CanStunDeku()), LOCATION(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT, logic->CanStunDeku()), - LOCATION(RC_DODONGOS_CAVERN_GOSSIP_STONE, Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->CanBreakMudWalls() || logic->CanUse(RG_GORONS_BRACELET);})), + LOCATION(RC_DODONGOS_CAVERN_GOSSIP_STONE, Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET);})), }, { //Exits - Entrance(RR_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE, {[]{return Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->BlastOrSmash() || logic->CanUse(RG_GORONS_BRACELET);});}}), - Entrance(RR_DODONGOS_CAVERN_MQ_STAIRS_LOWER, {[]{return Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->BlastOrSmash() || logic->CanUse(RG_GORONS_BRACELET);});}}), + Entrance(RR_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE, {[]{return Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET);});}}), + Entrance(RR_DODONGOS_CAVERN_MQ_STAIRS_LOWER, {[]{return Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET);});}}), Entrance(RR_DODONGOS_CAVERN_MQ_LOWER_RIGHT_SIDE, {[]{return Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->CanBreakMudWalls();}) || Here(RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_UPPER, []{return logic->HasItem(RG_GORONS_BRACELET) && logic->TakeDamage();});}}), //strength 1 and bunny speed works too Entrance(RR_DODONGOS_CAVERN_MQ_POES_ROOM, {[]{return logic->IsAdult;}}), @@ -264,13 +264,13 @@ void RegionTable_Init_DodongosCavern() { areaTable[RR_DODONGOS_CAVERN_MQ_STAIRS_PAST_MUD_WALL] = Region("Dodongos Cavern MQ Stairs Past Mud Wall", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->DekuBabaSticks, {[]{return logic->CanGetDekuBabaSticks();}}), - //EventAccess(&logic->CanClimbDCStairs, {[]{return logic->CanUse(RG_GORONS_BRACELET) && (logic->CanUse(RG_STICKS));}}), + //EventAccess(&logic->CanClimbDCStairs, {[]{return logic->HasItem(RG_GORONS_BRACELET) && (logic->CanUse(RG_STICKS));}}), }, { //Locations LOCATION(RC_DODONGOS_CAVERN_MQ_GS_SONG_OF_TIME_BLOCK_ROOM, logic->CanUse(RG_SONG_OF_TIME) && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)), }, { //Exits - Entrance(RR_DODONGOS_CAVERN_MQ_STAIRS_UPPER, {[]{return logic->CanUse(RG_GORONS_BRACELET) && (logic->CanUse(RG_STICKS));}}), + Entrance(RR_DODONGOS_CAVERN_MQ_STAIRS_UPPER, {[]{return logic->HasItem(RG_GORONS_BRACELET) && (logic->CanUse(RG_STICKS));}}), Entrance(RR_DODONGOS_CAVERN_MQ_STAIRS_LOWER, {[]{return true;}}), }); diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index 514dcad98..ab5aa360e 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -15,18 +15,6 @@ #include namespace Rando { - bool Logic::IsMagicItem(RandomizerGet item) { - return item == RG_DINS_FIRE || - item == RG_FARORES_WIND || - item == RG_NAYRUS_LOVE || - item == RG_LENS_OF_TRUTH; - } - - bool Logic::IsMagicArrow(RandomizerGet item) { - return item == RG_FIRE_ARROWS || - item == RG_ICE_ARROWS || - item == RG_LIGHT_ARROWS; - } bool Logic::HasItem(RandomizerGet itemName) { switch (itemName) { @@ -238,6 +226,19 @@ namespace Rando { return false; switch (itemName) { + // Magic items + case RG_MAGIC_SINGLE: + return AmmoCanDrop || (HasBottle() && GetInLogic(LOGIC_BUY_MAGIC_POTION)); + case RG_DINS_FIRE: + case RG_FARORES_WIND: + case RG_NAYRUS_LOVE: + case RG_LENS_OF_TRUTH: + return CanUse(RG_MAGIC_SINGLE); + case RG_FIRE_ARROWS: + case RG_ICE_ARROWS: + case RG_LIGHT_ARROWS: + return CanUse(RG_MAGIC_SINGLE) && CanUse(RG_FAIRY_BOW); + // Adult items // TODO: Uncomment those if we ever implement more item usability settings case RG_FAIRY_BOW: @@ -249,28 +250,34 @@ namespace Rando { case RG_HOVER_BOOTS: return IsAdult;// || HoverBootsAsChild; case RG_HOOKSHOT: - return IsAdult;// || HookshotAsChild; case RG_LONGSHOT: + case RG_SCARECROW: + case RG_DISTANT_SCARECROW: return IsAdult;// || HookshotAsChild; - case RG_SILVER_GAUNTLETS: - case RG_GOLDEN_GAUNTLETS: - return IsAdult; case RG_GORON_TUNIC: return IsAdult;// || GoronTunicAsChild; case RG_ZORA_TUNIC: return IsAdult;// || ZoraTunicAsChild; - case RG_SCARECROW: - return IsAdult;// || HookshotAsChild; - case RG_DISTANT_SCARECROW: - return IsAdult;// || HookshotAsChild; - case RG_HYLIAN_SHIELD: - return true; case RG_MIRROR_SHIELD: return IsAdult;// || MirrorShieldAsChild; case RG_MASTER_SWORD: return IsAdult;// || MasterSwordAsChild; case RG_BIGGORON_SWORD: return IsAdult;// || BiggoronSwordAsChild; + case RG_SILVER_GAUNTLETS: + case RG_GOLDEN_GAUNTLETS: + // Adult Trade + case RG_POCKET_EGG: + case RG_COJIRO: + case RG_ODD_MUSHROOM: + case RG_ODD_POTION: + case RG_POACHERS_SAW: + case RG_BROKEN_SWORD: + case RG_PRESCRIPTION: + case RG_EYEBALL_FROG: + case RG_EYEDROPS: + case RG_CLAIM_CHECK: + return IsAdult; // Child items case RG_FAIRY_SLINGSHOT: @@ -285,8 +292,6 @@ namespace Rando { return IsChild /* || StickAsAdult;*/&& (StickPot || DekuBabaSticks); case RG_DEKU_SHIELD: return IsChild;// || DekuShieldAsAdult; - case RG_WEIRD_EGG: - return IsChild; case RG_PROGRESSIVE_BOMB_BAG: case RG_BOMB_BAG: return AmmoCanDrop || GetInLogic(LOGIC_BUY_BOMB); @@ -295,48 +300,31 @@ namespace Rando { case RG_BOMBCHU_10: case RG_BOMBCHU_20: return BombchuRefill() && BombchusEnabled(); + case RG_WEIRD_EGG: case RG_RUTOS_LETTER: return IsChild; - // Adult Trade - case RG_POCKET_EGG: - case RG_COJIRO: - case RG_ODD_MUSHROOM: - case RG_ODD_POTION: - case RG_POACHERS_SAW: - case RG_BROKEN_SWORD: - case RG_PRESCRIPTION: - case RG_EYEBALL_FROG: - case RG_EYEDROPS: - case RG_CLAIM_CHECK: - return IsAdult; - // Songs case RG_ZELDAS_LULLABY: - return HasItem(RG_FAIRY_OCARINA) && HasItem(RG_OCARINA_C_LEFT_BUTTON) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_UP_BUTTON); case RG_EPONAS_SONG: + case RG_PRELUDE_OF_LIGHT: return HasItem(RG_FAIRY_OCARINA) && HasItem(RG_OCARINA_C_LEFT_BUTTON) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_UP_BUTTON); case RG_SARIAS_SONG: return HasItem(RG_FAIRY_OCARINA) && HasItem(RG_OCARINA_C_LEFT_BUTTON) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_DOWN_BUTTON); case RG_SUNS_SONG: return HasItem(RG_FAIRY_OCARINA) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_UP_BUTTON) && HasItem(RG_OCARINA_C_DOWN_BUTTON); case RG_SONG_OF_TIME: + case RG_BOLERO_OF_FIRE: + case RG_REQUIEM_OF_SPIRIT: return HasItem(RG_FAIRY_OCARINA) && HasItem(RG_OCARINA_A_BUTTON) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_DOWN_BUTTON); case RG_SONG_OF_STORMS: return HasItem(RG_FAIRY_OCARINA) && HasItem(RG_OCARINA_A_BUTTON) && HasItem(RG_OCARINA_C_UP_BUTTON) && HasItem(RG_OCARINA_C_DOWN_BUTTON); case RG_MINUET_OF_FOREST: return HasItem(RG_FAIRY_OCARINA) && HasItem(RG_OCARINA_A_BUTTON) && HasItem(RG_OCARINA_C_LEFT_BUTTON) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_UP_BUTTON); - case RG_BOLERO_OF_FIRE: - return HasItem(RG_FAIRY_OCARINA) && HasItem(RG_OCARINA_A_BUTTON) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_DOWN_BUTTON); case RG_SERENADE_OF_WATER: - return HasItem(RG_FAIRY_OCARINA) && HasItem(RG_OCARINA_A_BUTTON) && HasItem(RG_OCARINA_C_LEFT_BUTTON) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_DOWN_BUTTON); - case RG_REQUIEM_OF_SPIRIT: - return HasItem(RG_FAIRY_OCARINA) && HasItem(RG_OCARINA_A_BUTTON) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_DOWN_BUTTON); case RG_NOCTURNE_OF_SHADOW: return HasItem(RG_FAIRY_OCARINA) && HasItem(RG_OCARINA_A_BUTTON) && HasItem(RG_OCARINA_C_LEFT_BUTTON) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_DOWN_BUTTON); - case RG_PRELUDE_OF_LIGHT: - return HasItem(RG_FAIRY_OCARINA) && HasItem(RG_OCARINA_C_LEFT_BUTTON) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_UP_BUTTON); - + // Misc. Items case RG_FISHING_POLE: return HasItem(RG_CHILD_WALLET); // as long as you have enough rubies @@ -353,11 +341,10 @@ namespace Rando { case RG_BOTTLE_WITH_FAIRY: return FairyPot || GossipStoneFairy || BeanPlantFairy || ButterflyFairy || FreeFairies || FairyPond || GetInLogic(LOGIC_FAIRY_ACCESS); - // Magic items - case RG_MAGIC_SINGLE: - return AmmoCanDrop || (HasBottle() && GetInLogic(LOGIC_BUY_MAGIC_POTION)); default: - return CanUse(RG_MAGIC_SINGLE) && (IsMagicItem(itemName) || (IsMagicArrow(itemName) && CanUse(RG_FAIRY_BOW))); + SPDLOG_ERROR("CanUse reached `default` for {}. Assuming intention is no extra requirements for use so returning true, but HasItem should be used instead.", static_cast(itemName)); + assert(false); + return true; } } @@ -599,7 +586,7 @@ namespace Rando { } bool Logic::CanDetonateUprightBombFlower() { - return CanDetonateBombFlowers() || CanUse(RG_GORONS_BRACELET); + return CanDetonateBombFlowers() || HasItem(RG_GORONS_BRACELET); } Logic::Logic() { @@ -681,7 +668,7 @@ namespace Rando { } bool Logic::CanReflectNuts(){ - return CanUse(RG_DEKU_SHIELD) || (IsAdult && CanUse(RG_HYLIAN_SHIELD)); + return CanUse(RG_DEKU_SHIELD) || (IsAdult && HasItem(RG_HYLIAN_SHIELD)); } bool Logic::CanCutShrubs(){ @@ -832,11 +819,11 @@ namespace Rando { } bool Logic::CanStandingShield(){ - return CanUse(RG_MIRROR_SHIELD) || (IsAdult && CanUse(RG_HYLIAN_SHIELD)) || CanUse(RG_DEKU_SHIELD); + return CanUse(RG_MIRROR_SHIELD) || (IsAdult && HasItem(RG_HYLIAN_SHIELD)) || CanUse(RG_DEKU_SHIELD); } bool Logic::CanShield(){ - return CanUse(RG_MIRROR_SHIELD) || CanUse(RG_HYLIAN_SHIELD) || CanUse(RG_DEKU_SHIELD); + return CanUse(RG_MIRROR_SHIELD) || HasItem(RG_HYLIAN_SHIELD) || CanUse(RG_DEKU_SHIELD); } bool Logic::CanUseProjectile(){ diff --git a/soh/soh/Enhancements/randomizer/logic.h b/soh/soh/Enhancements/randomizer/logic.h index 3e22d5889..2b7ea2bed 100644 --- a/soh/soh/Enhancements/randomizer/logic.h +++ b/soh/soh/Enhancements/randomizer/logic.h @@ -247,8 +247,6 @@ class Logic { static std::map RandoGetToRandInf; private: - static bool IsMagicItem(RandomizerGet item); - static bool IsMagicArrow(RandomizerGet item); std::shared_ptr ctx; bool inLogic[LOGIC_MAX]; }; // class Logic