Rewrite DC MQ Logic (#4355)

* Doodongs Cavern

* rewrite MQ DC Logic

* forgot some cleanup

* remove an unused region

* post-merge cleanups

* change CanUse for HasITem on gorons braclet

* git ate half the rewrite

* more small error fixes

---------

Co-authored-by: aMannus <mannusmenting@gmail.com>
This commit is contained in:
Pepper0ni 2024-10-05 21:29:38 +01:00 committed by GitHub
parent c4d211bc3a
commit 0a3eeb8339
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 361 additions and 76 deletions

View File

@ -215,7 +215,7 @@ void Region::ResetVariables() {
std::array<Region, RR_MAX> areaTable;
bool Here(const RandomizerRegion region, ConditionFn condition) {
return areaTable[region].HereCheck(condition);
return areaTable[region].Here(condition);
}
bool CanPlantBean(const RandomizerRegion region) {
@ -246,7 +246,7 @@ void RegionTable_Init() {
ctx = Context::GetInstance().get();
logic = ctx->GetLogic(); //RANDOTODO do not hardcode, instead allow accepting a Logic class somehow
grottoEvents = {
EventAccess(&logic->GossipStoneFairy, { [] { return logic->GossipStoneFairy || logic->CallGossipFairy(); } }),
EventAccess(&logic->GossipStoneFairy, { [] { return logic->CallGossipFairy(); } }),
EventAccess(&logic->ButterflyFairy, { [] { return logic->ButterflyFairy || (logic->CanUse(RG_STICKS)); } }),
EventAccess(&logic->BugShrub, { [] { return logic->CanCutShrubs(); } }),
EventAccess(&logic->LoneFish, { [] { return true; } }),

View File

@ -210,7 +210,7 @@ public:
//access to this area. For example: if there are rocks that block a path
//which both child and adult can access, adult having hammer can give
//both child and adult access to the path.
bool HereCheck(ConditionFn condition) {
bool Here(ConditionFn condition) {
//store current age variables
bool pastAdult = logic->IsAdult;
@ -246,7 +246,7 @@ public:
extern std::array<Region, RR_MAX> areaTable;
extern std::vector<EventAccess> grottoEvents;
bool Here(const RandomizerRegion region, ConditionFn condition);
bool Here(const RandomizerRegion region, ConditionFn condition); //RANDOTODO make a less stupid way to check own at either age than self referncing with this
bool CanPlantBean(const RandomizerRegion region);
bool BothAges(const RandomizerRegion region);
bool ChildCanAccess(const RandomizerRegion region);

View File

@ -35,7 +35,7 @@ void RegionTable_Init_CastleTown() {
areaTable[RR_TOT_ENTRANCE] = Region("ToT Entrance", "ToT Entrance", RA_THE_MARKET, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->GossipStoneFairy, {[]{return logic->GossipStoneFairy || logic->CallGossipFairyExceptSuns();}}),
EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairyExceptSuns();}}),
}, {
//Locations
LOCATION(RC_TOT_LEFTMOST_GOSSIP_STONE, true),
@ -82,7 +82,7 @@ void RegionTable_Init_CastleTown() {
areaTable[RR_HYRULE_CASTLE_GROUNDS] = Region("Hyrule Castle Grounds", "Castle Grounds", RA_HYRULE_CASTLE, DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->GossipStoneFairy, {[]{return logic->GossipStoneFairy || logic->CallGossipFairy();}}),
EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairy();}}),
EventAccess(&logic->ButterflyFairy, {[]{return logic->ButterflyFairy || logic->CanUse(RG_STICKS);}}),
EventAccess(&logic->BugRock, {[]{return true;}}),
}, {
@ -121,7 +121,7 @@ void RegionTable_Init_CastleTown() {
areaTable[RR_HC_STORMS_GROTTO] = Region("HC Storms Grotto", "HC Storms Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->NutPot, {[]{return logic->NutPot || logic->BlastOrSmash();}}),
EventAccess(&logic->GossipStoneFairy, {[]{return logic->GossipStoneFairy || (logic->BlastOrSmash() && logic->CallGossipFairy());}}),
EventAccess(&logic->GossipStoneFairy, {[]{return logic->CanBreakMudWalls() && logic->CallGossipFairy();}}),
EventAccess(&logic->WanderingBugs, {[]{return logic->WanderingBugs || logic->BlastOrSmash();}}),
}, {
//Locations

View File

@ -26,7 +26,7 @@ void RegionTable_Init_DeathMountain() {
areaTable[RR_DEATH_MOUNTAIN_SUMMIT] = Region("Death Mountain Summit", "Death Mountain", RA_DEATH_MOUNTAIN_TRAIL, DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->PrescriptionAccess, {[]{return logic->PrescriptionAccess || (logic->IsAdult && (logic->BrokenSwordAccess || logic->CanUse(RG_BROKEN_SWORD)));}}),
EventAccess(&logic->GossipStoneFairy, {[]{return logic->GossipStoneFairy || logic->CallGossipFairy();}}),
EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairy();}}),
EventAccess(&logic->BugRock, {[]{return logic->BugRock || logic->IsChild;}}),
}, {
//Locations
@ -81,7 +81,7 @@ void RegionTable_Init_DeathMountain() {
areaTable[RR_GORON_CITY] = Region("Goron City", "Goron City", RA_GORON_CITY, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->GossipStoneFairy, {[]{return logic->GossipStoneFairy || logic->CallGossipFairyExceptSuns();}}),
EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairyExceptSuns();}}),
EventAccess(&logic->StickPot, {[]{return logic->StickPot || logic->IsChild;}}),
EventAccess(&logic->BugRock, {[]{return logic->BugRock || (logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS));}}),
EventAccess(&logic->GoronCityChildFire, {[]{return logic->GoronCityChildFire || (logic->IsChild && logic->CanUse(RG_DINS_FIRE));}}),

View File

@ -22,17 +22,17 @@ void RegionTable_Init_DodongosCavern() {
areaTable[RR_DODONGOS_CAVERN_BEGINNING] = Region("Dodongos Cavern Beginning", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, {
//Exits
Entrance(RR_DODONGOS_CAVERN_ENTRYWAY, {[]{return true;}}),
Entrance(RR_DODONGOS_CAVERN_LOBBY, {[]{return Here(RR_DODONGOS_CAVERN_BEGINNING, []{return logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET);});}}),
Entrance(RR_DODONGOS_CAVERN_LOBBY, {[]{return Here(RR_DODONGOS_CAVERN_BEGINNING, []{return logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET);});}}),
});
areaTable[RR_DODONGOS_CAVERN_LOBBY] = Region("Dodongos Cavern Lobby", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->GossipStoneFairy, {[]{return logic->GossipStoneFairy || (logic->CallGossipFairy() && Here(RR_DODONGOS_CAVERN_LOBBY, []{return logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET);}));}}),
EventAccess(&logic->GossipStoneFairy, {[]{return (Here(RR_DODONGOS_CAVERN_LOBBY, []{return logic->CanBreakMudWalls();}) || logic->HasItem(RG_GORONS_BRACELET)) && logic->CallGossipFairy();}}),
}, {
//Locations
LOCATION(RC_DODONGOS_CAVERN_MAP_CHEST, Here(RR_DODONGOS_CAVERN_LOBBY, []{return logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET);})),
LOCATION(RC_DODONGOS_CAVERN_MAP_CHEST, Here(RR_DODONGOS_CAVERN_LOBBY, []{return logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET);})),
LOCATION(RC_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY, logic->CanStunDeku() || logic->HasItem(RG_GORONS_BRACELET)),
LOCATION(RC_DODONGOS_CAVERN_GOSSIP_STONE, Here(RR_DODONGOS_CAVERN_LOBBY, []{return logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET);})),
LOCATION(RC_DODONGOS_CAVERN_GOSSIP_STONE, Here(RR_DODONGOS_CAVERN_LOBBY, []{return logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET);})),
}, {
//Exits
Entrance(RR_DODONGOS_CAVERN_BEGINNING, {[]{return true;}}),
@ -219,60 +219,219 @@ 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->DekuBabaSticks, {[]{return logic->DekuBabaSticks || (logic->IsAdult || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_BOOMERANG));}}),
EventAccess(&logic->GossipStoneFairy, {[]{return logic->GossipStoneFairy || logic->CallGossipFairy();}}),
EventAccess(&logic->GossipStoneFairy, {[]{return (Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->CanBreakMudWalls();}) || logic->CanUse(RG_GORONS_BRACELET)) && logic->CallGossipFairy();}}),
}, {
//Locations
LOCATION(RC_DODONGOS_CAVERN_MQ_MAP_CHEST, true),
LOCATION(RC_DODONGOS_CAVERN_MQ_COMPASS_CHEST, logic->CanAttack() || logic->CanUse(RG_NUTS)),
LOCATION(RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CHEST, (logic->IsChild && logic->CanUse(RG_STICKS)) || logic->HasFireSource()),
LOCATION(RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_CHEST, logic->BlastOrSmash() || (logic->IsChild && logic->CanUse(RG_STICKS)) || logic->CanUse(RG_DINS_FIRE) || (logic->IsAdult && (ctx->GetTrickOption(RT_DC_JUMP) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT)))),
LOCATION(RC_DODONGOS_CAVERN_MQ_GS_SONG_OF_TIME_BLOCK_ROOM, logic->CanUse(RG_SONG_OF_TIME) && logic->CanAttack()),
LOCATION(RC_DODONGOS_CAVERN_MQ_GS_LARVAE_ROOM, (logic->IsChild && logic->CanUse(RG_STICKS)) || logic->HasFireSource()),
LOCATION(RC_DODONGOS_CAVERN_MQ_GS_LIZALFOS_ROOM, logic->BlastOrSmash()),
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_MQ_DEKU_SCRUB_STAIRCASE, logic->CanStunDeku()),
LOCATION(RC_DODONGOS_CAVERN_GOSSIP_STONE, true),
LOCATION(RC_DODONGOS_CAVERN_MQ_MAP_CHEST, logic->CanBreakMudWalls() || logic->CanUse(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);})),
}, {
//Exits
Entrance(RR_DODONGOS_CAVERN_MQ_LOWER_RIGHT_SIDE, {[]{return Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->BlastOrSmash() || (((logic->IsChild && logic->CanUse(RG_STICKS)) || logic->CanUse(RG_DINS_FIRE)) && logic->TakeDamage());});}}),
Entrance(RR_DODONGOS_CAVERN_MQ_BOMB_BAG_AREA, {[]{return logic->IsAdult || (Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->IsAdult;}) && logic->HasExplosives()) || (ctx->GetTrickOption(RT_DC_MQ_CHILD_BOMBS) && logic->CanJumpslash() && logic->TakeDamage());}}),
//Trick: logic->IsAdult || logic->HasExplosives() || (LogicDCMQChildBombs && (logic->CanUse(RG_KOKIRI_SWORD) || logic->Sticks) && DamageMultiplier.IsNot(DAMAGEMULTIPLIER_OHKO))
Entrance(RR_DODONGOS_CAVERN_MQ_BOSS_AREA, {[]{return logic->HasExplosives() || (logic->HasItem(RG_GORONS_BRACELET) && ((logic->IsAdult && ctx->GetTrickOption(RT_DC_MQ_ADULT_EYES)) || (logic->IsChild && ctx->GetTrickOption(RT_DC_MQ_CHILD_EYES))) && ((logic->IsChild && (logic->CanUse(RG_STICKS))) || logic->CanUse(RG_DINS_FIRE) || (logic->IsAdult && (ctx->GetTrickOption(RT_DC_JUMP) || logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT)))));}}),
//Trick: logic->HasExplosives() || (LogicDCMQEyes && logic->HasItem(RG_GORONS_BRACELET) && (logic->IsAdult || LogicDCMQChildBack) && ((logic->IsChild && logic->CanUse(RG_STICKS)) || logic->CanUse(RG_DINS_FIRE) || (logic->IsAdult && (LogicDCJump || logic->Hammer || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT)))))
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_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;}}),
Entrance(RR_DODONGOS_CAVERN_MQ_BEHIND_MOUTH, {[]{return Here(RR_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE, []{return logic->HasExplosives() || (logic->ClearMQDCUpperLobbyRocks && logic->HasItem(RG_GORONS_BRACELET) &&
((logic->IsAdult && ctx->GetTrickOption(RT_DC_MQ_ADULT_EYES)) ||
(logic->IsChild && ctx->GetTrickOption(RT_DC_MQ_CHILD_EYES))));});}}),
});
areaTable[RR_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE] = Region("Dodongos Cavern MQ Mouth Side Bridge", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->ClearMQDCUpperLobbyRocks, {[]{return logic->BlastOrSmash() || logic->CanUse(RG_DINS_FIRE);}}),
}, {}, {
//Exits
Entrance(RR_DODONGOS_CAVERN_MQ_LOBBY, {[]{return true;}}),
Entrance(RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_UPPER, {[]{return logic->ClearMQDCUpperLobbyRocks;}}),
//Bunny hood jump + jumpslash can also make it directly from the raising platform
Entrance(RR_DODONGOS_CAVERN_MQ_POES_ROOM, {[]{return logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_DC_MQ_CHILD_BOMBS) && logic->CanJumpslash() && logic->TakeDamage());}}), //RANDOTODO is this possible with equip swapped hammer?
//it is possible to use bunny hood speed, hovers and a jumpslash to go between here and the other bridge (included with TORCH_ROOM_LOWER), but this would be a trick
});
areaTable[RR_DODONGOS_CAVERN_MQ_STAIRS_LOWER] = Region("Dodongos Cavern MQ Stairs Lower", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {
//Events
//EventAccess(&logic->CanClimbDCStairs, {[]{return logic->HasExplosives || logic->CanUse(RG_DINS_FIRE) || (ctx->GetTrickOption(RT_DC_STAIRCASE) && logic->CanUse(RG_FAIRY_BOW));}}),
}, {}, {
//Exits
//This is possible with sticks and shield, igniting a first flower by "touch" then very quickly crouch stabbing in a way that cuts the corner to light the 3rd bomb on the other side, but that's a trick
Entrance(RR_DODONGOS_CAVERN_MQ_STAIRS_UPPER, {[]{return Here(RR_DODONGOS_CAVERN_MQ_STAIRS_LOWER, []{return logic->HasExplosives() || logic->CanUse(RG_DINS_FIRE) ||
(ctx->GetTrickOption(RT_DC_STAIRCASE) && logic->CanUse(RG_FAIRY_BOW));});}}),
Entrance(RR_DODONGOS_CAVERN_MQ_STAIRS_PAST_MUD_WALL, {[]{return Here(RR_DODONGOS_CAVERN_MQ_STAIRS_LOWER, []{return logic->CanBreakMudWalls();});}}),
});
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));}}),
}, {
//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_LOWER, {[]{return true;}}),
});
areaTable[RR_DODONGOS_CAVERN_MQ_STAIRS_UPPER] = Region("Dodongos Cavern MQ Stairs Upper", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {
//Locations
LOCATION(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE, logic->CanStunDeku()),
}, {
//Exits
Entrance(RR_DODONGOS_CAVERN_MQ_STAIRS_LOWER, {[]{return true;}}),
Entrance(RR_DODONGOS_CAVERN_MQ_STAIRS_PAST_BIG_SKULLTULAS, {[]{return logic->CanPassEnemy(RE_BIG_SKULLTULA) || logic->CanUse(RG_HOVER_BOOTS);}}),
});
areaTable[RR_DODONGOS_CAVERN_MQ_STAIRS_PAST_BIG_SKULLTULAS] = Region("Dodongos Cavern MQ Past Big Skulltulas", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, {
//Exits
Entrance(RR_DODONGOS_CAVERN_MQ_STAIRS_UPPER, {[]{return logic->CanPassEnemy(RE_BIG_SKULLTULA) || logic->CanUse(RG_HOVER_BOOTS);}}),
Entrance(RR_DODONGOS_CAVERN_MQ_STAIRS_LOWER, {[]{return logic->TakeDamage();}}),
//If some case comes up where you can directly (void?)warp here without going through Dodongo room or climbing up from below,
//the commented out logic is to handle going down and reclimbing to get silver rupees. A new eventVar will need decalring to handle this.
/*(logic->CanPassEnemy(RE_BIG_SKULLTULA) || CanUse(RG_HOVER_BOOTS)) && logic->CanClimbDCStairs;*/
Entrance(RR_DODONGOS_CAVERN_MQ_DODONGO_ROOM, {[]{return true;}}),//if we add BONKO or other crate logic, logic for silver rupees goes here
});
areaTable[RR_DODONGOS_CAVERN_MQ_DODONGO_ROOM] = Region("Dodongos Cavern MQ Dodongo Room", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {
//Locations
LOCATION(RC_DODONGOS_CAVERN_MQ_COMPASS_CHEST, logic->CanKillEnemy(RE_DODONGO) || logic->HasItem(RG_GORONS_BRACELET)),
}, {
//Exits
Entrance(RR_DODONGOS_CAVERN_MQ_STAIRS_PAST_BIG_SKULLTULAS, {[]{return true;}}),
Entrance(RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_LOWER, {[]{return Here(RR_DODONGOS_CAVERN_MQ_DODONGO_ROOM, []{return logic->CanKillEnemy(RE_DODONGO) || logic->HasItem(RG_GORONS_BRACELET);});}}),
});
areaTable[RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_LOWER] = Region("Dodongos Cavern MQ Torch Puzzle Lower", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->ClearMQDCUpperLobbyRocks, {[]{return (((logic->IsAdult /*or bunny hood jump*/) && ctx->GetTrickOption(RT_DC_JUMP)) || logic->CanUse(RG_HOVER_BOOTS)) && logic->CanUse(RG_STICKS);}}),
}, {}, {
//Exits
Entrance(RR_DODONGOS_CAVERN_MQ_LOBBY, {[]{return logic->TakeDamage();}}),
Entrance(RR_DODONGOS_CAVERN_MQ_DODONGO_ROOM, {[]{return true;}}),
Entrance(RR_DODONGOS_CAVERN_MQ_LARVAE_ROOM, {[]{return logic->HasFireSourceWithTorch();}}),//torch checks here need strength 0 with sticks when that is implemented
Entrance(RR_DODONGOS_CAVERN_MQ_BIG_BLOCK_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_LOWER, []{return logic->HasFireSourceWithTorch();});}}), //Includes an implied CanPass(RE_BIG_SKULLTULA)
Entrance(RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_UPPER, {[]{return ((logic->IsAdult /*or bunny hood jump*/) && ctx->GetTrickOption(RT_DC_JUMP)) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT);}}),
Entrance(RR_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS, {[]{return logic->CanUse(RG_STICKS) && logic->HasItem(RG_GORONS_BRACELET);}}), //Implies access to RR_DODONGOS_CAVERN_MQ_BIG_BLOCK_ROOM from here
});
areaTable[RR_DODONGOS_CAVERN_MQ_BIG_BLOCK_ROOM] = Region("Dodongos Cavern MQ Torch Puzzle Lower", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, {
//Exits
Entrance(RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_LOWER, {[]{return logic->CanPassEnemy(RE_BIG_SKULLTULA);}}),
Entrance(RR_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS, {[]{return (logic->HasFireSource() && logic->HasItem(RG_GORONS_BRACELET)) || logic->CanBreakMudWalls();}}), //Requires stregnth 0, If you can somehow warp into this room, add logic->CanPassEnemy(RE_BIG_SKULLTULA)
});
areaTable[RR_DODONGOS_CAVERN_MQ_LARVAE_ROOM] = Region("Dodongos Cavern MQ Larvae Room", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {
//Locations
LOCATION(RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CHEST, true), //implied logic->CanKillEnemy(RE_GOHMA_LARVA) based on entry reqs with a trick to kill with nuts
LOCATION(RC_DODONGOS_CAVERN_MQ_GS_LARVAE_ROOM, true), //implied logic->CanKillEnemy(RE_GOLD_SKULTULLA) based on entry reqs. Add crate logic when BONKO is added
}, {
//Exits
Entrance(RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_LOWER, {[]{return true;}}), //implied logic->CanKillEnemy(RE_GOHMA_LARVA) based on entry reqs with a trick to kill with nuts
});
areaTable[RR_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS] = Region("Dodongos Cavern MQ Before Upper Lizalfos", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {
//Locations
LOCATION(RC_DODONGOS_CAVERN_MQ_GS_LIZALFOS_ROOM, logic->BlastOrSmash()), //Implied CanGetEnemyDrop(RE_GOLD_SKULLTULA)
}, {
//Exits
//Falling down gets you stuck with nothing there, not a useful exit for logic
Entrance(RR_DODONGOS_CAVERN_MQ_BIG_BLOCK_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS, []{return logic->CanKillEnemy(RE_LIZALFOS);});}}),
Entrance(RR_DODONGOS_CAVERN_MQ_TWO_FIRES_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS, []{return logic->CanKillEnemy(RE_LIZALFOS);});}}),
});
areaTable[RR_DODONGOS_CAVERN_MQ_TWO_FIRES_ROOM] = Region("Dodongos Cavern MQ Before Upper Lizalfos", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, {
//Exits
Entrance(RR_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS, {[]{return true;}}),
Entrance(RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_UPPER, {[]{return logic->IsAdult || (Here(RR_DODONGOS_CAVERN_MQ_TWO_FIRES_ROOM, []{return logic->BlastOrSmash() || (logic->CanAttack() && logic->HasItem(RG_GORONS_BRACELET));}));}}),
});
areaTable[RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_UPPER] = Region("Dodongos Cavern MQ Torch Puzzle Upper", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->ClearMQDCUpperLobbyRocks, {[]{return logic->CanDetonateUprightBombFlower() || logic->CanUse(RG_MEGATON_HAMMER);}}),
}, {
//Locations
LOCATION(RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_CHEST, true),
}, {
//Exits
Entrance(RR_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE, {[]{return logic->ClearMQDCUpperLobbyRocks;}}),
Entrance(RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_LOWER, {[]{return true;}}),
Entrance(RR_DODONGOS_CAVERN_MQ_TWO_FIRES_ROOM, {[]{return true;}}),
});
areaTable[RR_DODONGOS_CAVERN_MQ_LOWER_RIGHT_SIDE] = Region("Dodongos Cavern MQ Lower Right Side", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {
//Locations
LOCATION(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS, logic->CanStunDeku()),
LOCATION(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS, (logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET)) && logic->CanStunDeku()),
}, {
//Exits
Entrance(RR_DODONGOS_CAVERN_MQ_BOMB_BAG_AREA, {[]{return (Here(RR_DODONGOS_CAVERN_MQ_LOWER_RIGHT_SIDE, []{return logic->IsAdult && logic->CanUse(RG_FAIRY_BOW);}) || logic->HasItem(RG_GORONS_BRACELET) ||
logic->CanUse(RG_DINS_FIRE) || logic->HasExplosives()) &&
logic->IsChild && logic->CanUse(RG_FAIRY_SLINGSHOT);}}),
Entrance(RR_DODONGOS_CAVERN_MQ_LOWER_LIZALFOS, {[]{return Here(RR_DODONGOS_CAVERN_MQ_LOWER_RIGHT_SIDE, []{return logic->CanDetonateBombFlowers() || logic->HasItem(RG_GORONS_BRACELET);}) && logic->CanHitEyeTargets();}}),
});
areaTable[RR_DODONGOS_CAVERN_MQ_BOMB_BAG_AREA] = Region("Dodongos Cavern MQ Bomb Bag Region", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {
areaTable[RR_DODONGOS_CAVERN_MQ_LOWER_LIZALFOS] = Region("Dodongos Cavern MQ Lower Lizalfos", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {
//When you add wonder item logic for behind the lavafall, use Here(RR_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS) to account for jumping down instead of an exit
//because the doors are sealed when entering from the top and you can't spawn the lower lizalfos
}, {}, {
//Exits
Entrance(RR_DODONGOS_CAVERN_MQ_LOWER_RIGHT_SIDE, {[]{return Here(RR_DODONGOS_CAVERN_MQ_LOWER_LIZALFOS, []{return logic->CanKillEnemy(RE_LIZALFOS);});}}),
Entrance(RR_DODONGOS_CAVERN_MQ_POES_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_MQ_LOWER_LIZALFOS, []{return logic->CanKillEnemy(RE_LIZALFOS);});}}),
});
areaTable[RR_DODONGOS_CAVERN_MQ_POES_ROOM] = Region("Dodongos Cavern MQ Poes Room", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {
//Locations
LOCATION(RC_DODONGOS_CAVERN_MQ_BOMB_BAG_CHEST, true),
LOCATION(RC_DODONGOS_CAVERN_MQ_GS_SCRUB_ROOM, (Here(RR_DODONGOS_CAVERN_MQ_BOMB_BAG_AREA, []{return logic->IsAdult && logic->CanUse(RG_FAIRY_BOW);}) || logic->HasItem(RG_GORONS_BRACELET) || logic->CanUse(RG_DINS_FIRE) || logic->HasExplosives()) && logic->HookshotOrBoomerang()),
LOCATION(RC_DODONGOS_CAVERN_MQ_BOMB_BAG_CHEST, true), //If you can get to the locked part of POES_ROOM without a way to open it or passing the chest, this will need it's own room
LOCATION(RC_DODONGOS_CAVERN_MQ_GS_SCRUB_ROOM, (Here(RR_DODONGOS_CAVERN_MQ_POES_ROOM, []{return logic->CanDetonateBombFlowers() || logic->HasItem(RG_GORONS_BRACELET);}) && //could be a seperate room if it gets busy
logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_RANG_OR_HOOKSHOT, true))), //Implies you can avoid/kill the enemies with what you use on the skull, if this assumption is broken, add
//&& (Here(RR_DODONGOS_CAVERN_MQ_POES_ROOM, []{return logic->CanKillEnemy(RE_FIRE_KEESE) && logic->CanKillEnemy(RE_MAD_SCRUB);}) || (logic->CanAvoidEnemy(RE_FIRE_KEESE) && logic->CanAvoidEnemy(RE_MAD_SCRUB)))
}, {
//Exits
Entrance(RR_DODONGOS_CAVERN_MQ_LOWER_RIGHT_SIDE, {[]{return true;}}),
Entrance(RR_DODONGOS_CAVERN_MQ_LOWER_RIGHT_SIDE, {[]{return Here(RR_DODONGOS_CAVERN_MQ_POES_ROOM, []{return logic->CanDetonateBombFlowers() || logic->HasItem(RG_GORONS_BRACELET);});}}),
Entrance(RR_DODONGOS_CAVERN_MQ_LOWER_LIZALFOS, {[]{return true;}}),
Entrance(RR_DODONGOS_CAVERN_MQ_MAD_SCRUB_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_MQ_POES_ROOM, []{return logic->CanDetonateBombFlowers() || logic->HasItem(RG_GORONS_BRACELET);});}}),
});
areaTable[RR_DODONGOS_CAVERN_MQ_BOSS_AREA] = Region("Dodongos Cavern MQ BossArea", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {
areaTable[RR_DODONGOS_CAVERN_MQ_MAD_SCRUB_ROOM] = Region("Dodongos Cavern Mad Scrub Room", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {
//Locations
LOCATION(RC_DODONGOS_CAVERN_MQ_GS_SCRUB_ROOM, (logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_RANG_OR_HOOKSHOT, true))), //Implies you can avoid/kill the enemies with what you use on the skull, if this assumption is broken, add
//&& (Here(RR_DODONGOS_CAVERN_MQ_POES_ROOM, []{return logic->CanKillEnemy(RE_FIRE_KEESE) && logic->CanKillEnemy(RE_MAD_SCRUB);}) || (logic->CanAvoidEnemy(RE_FIRE_KEESE) && logic->CanAvoidEnemy(RE_MAD_SCRUB)))
}, {
//Exits
Entrance(RR_DODONGOS_CAVERN_MQ_POES_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_MQ_MAD_SCRUB_ROOM, []{return logic->CanKillEnemy(RE_FIRE_KEESE) && logic->CanKillEnemy(RE_MAD_SCRUB);});}}),
});
areaTable[RR_DODONGOS_CAVERN_MQ_BEHIND_MOUTH] = Region("Dodongos Cavern MQ Behind Mouth", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, {
//Exits
Entrance(RR_DODONGOS_CAVERN_MQ_LOBBY, {[]{return true;}}),
//using pots to get past the fire is in default logic. if stregnth 0 gets added, this will need to be:
//stregnth 0 || explosives, or projectiles if str0 isn't needed to pull graves (it's a narrow shot though, may be trick worthy)
Entrance(RR_DODONGOS_CAVERN_MQ_BACK_BEHIND_FIRE, {[]{return true;}}),
Entrance(RR_DODONGOS_CAVERN_MQ_BACK_SWITCH_GRAVE, {[]{return logic->IsAdult;}}),
});
areaTable[RR_DODONGOS_CAVERN_MQ_BACK_BEHIND_FIRE] = Region("Dodongos Cavern MQ Back Behind Fire", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {
//Locations
LOCATION(RC_DODONGOS_CAVERN_MQ_UNDER_GRAVE_CHEST, true), //pulling the grave isn't required, as you can open the chest through it
}, {
//Exits
Entrance(RR_DODONGOS_CAVERN_MQ_BEHIND_MOUTH, {[]{return logic->CanAttack();}}),
//There's a trick N64 rolls into the child eyes trick for using armos blow up the bomb flowers when dieing, which would be killing an armos
Entrance(RR_DODONGOS_CAVERN_MQ_BACK_SWITCH_GRAVE, {[]{return Here(RR_DODONGOS_CAVERN_MQ_BACK_BEHIND_FIRE, []{return logic->CanDetonateBombFlowers();}) ||
Here(RR_DODONGOS_CAVERN_MQ_BACK_SWITCH_GRAVE, []{return logic->CanAttack();});}}),
});
areaTable[RR_DODONGOS_CAVERN_MQ_BACK_SWITCH_GRAVE] = Region("Dodongos Cavern MQ BossArea", "Dodongos Cavern", RA_DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->FairyPot, {[]{return true;}}),
EventAccess(&logic->FairyPot, {[]{return true;}}),
}, {
//Locations
LOCATION(RC_DODONGOS_CAVERN_MQ_UNDER_GRAVE_CHEST, true),
LOCATION(RC_DODONGOS_CAVERN_MQ_GS_BACK_AREA, true),
LOCATION(RC_DODONGOS_CAVERN_MQ_GS_BACK_AREA, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA) || logic->HasItem(RG_GORONS_BRACELET) || //even if you somehow warp to BACK_BEHIND_FIRE, if you can kill the skull at range, you can get to BEHIND_MOUTH
Here(RR_DODONGOS_CAVERN_MQ_BEHIND_MOUTH, []{return (logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_RANG_OR_HOOKSHOT)) ||
(logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS) /* || bunny jumps*/);})),
}, {
//Exits
Entrance(RR_DODONGOS_CAVERN_BOSS_ENTRYWAY, {[]{return true;}}),
Entrance(RR_DODONGOS_CAVERN_MQ_BACK_BEHIND_FIRE, {[]{return true;}}),
Entrance(RR_DODONGOS_CAVERN_BOSS_ENTRYWAY, {[]{return true;}}), //if strength 0 prevents grave pulls, add it here
});
}
/*---------------------------
@ -283,7 +442,7 @@ void RegionTable_Init_DodongosCavern() {
{
// Exits
Entrance(RR_DODONGOS_CAVERN_BOSS_AREA, { [] { return ctx->GetDungeon(DODONGOS_CAVERN)->IsVanilla(); } }),
Entrance(RR_DODONGOS_CAVERN_MQ_BOSS_AREA, { [] { return ctx->GetDungeon(DODONGOS_CAVERN)->IsMQ(); } }),
Entrance(RR_DODONGOS_CAVERN_MQ_BEHIND_MOUTH, { [] { return ctx->GetDungeon(DODONGOS_CAVERN)->IsMQ(); } }),
Entrance(RR_DODONGOS_CAVERN_BOSS_ROOM, { [] { return true; } }),
});

View File

@ -21,7 +21,7 @@ void RegionTable_Init_GerudoValley() {
areaTable[RR_GV_UPPER_STREAM] = Region("GV Upper Stream", "Gerudo Valley", RA_GERUDO_VALLEY, DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->GossipStoneFairy, {[]{return logic->GossipStoneFairy || logic->CallGossipFairy();}}),
EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairy();}}),
EventAccess(&logic->BeanPlantFairy, {[]{return logic->BeanPlantFairy || (CanPlantBean(RR_GV_UPPER_STREAM) && logic->CanUse(RG_SONG_OF_STORMS));}}),
}, {
//Locations

View File

@ -111,7 +111,7 @@ void RegionTable_Init_HyruleField() {
areaTable[RR_LAKE_HYLIA] = Region("Lake Hylia", "Lake Hylia", RA_LAKE_HYLIA, DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->GossipStoneFairy, {[]{return logic->GossipStoneFairy || logic->CallGossipFairy();}}),
EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairy();}}),
EventAccess(&logic->BeanPlantFairy, {[]{return logic->BeanPlantFairy || (CanPlantBean(RR_LAKE_HYLIA) && logic->CanUse(RG_SONG_OF_STORMS));}}),
EventAccess(&logic->ButterflyFairy, {[]{return logic->ButterflyFairy || logic->CanUse(RG_STICKS);}}),
EventAccess(&logic->BugShrub, {[]{return logic->BugShrub || (logic->IsChild && logic->CanCutShrubs());}}),

View File

@ -278,7 +278,7 @@ void RegionTable_Init_Kakariko() {
areaTable[RR_GRAVEYARD_WARP_PAD_REGION] = Region("Graveyard Warp Pad Region", "Graveyard", RA_THE_GRAVEYARD, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->GossipStoneFairy, {[]{return logic->GossipStoneFairy || logic->CallGossipFairyExceptSuns();}}),
EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairyExceptSuns();}}),
}, {
//Locations
LOCATION(RC_GRAVEYARD_GOSSIP_STONE, true),

View File

@ -7,7 +7,7 @@ void RegionTable_Init_LostWoods() {
areaTable[RR_KOKIRI_FOREST] = Region("Kokiri Forest", "Kokiri Forest", RA_KOKIRI_FOREST, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->BeanPlantFairy, {[]{return logic->BeanPlantFairy || (CanPlantBean(RR_KOKIRI_FOREST) && logic->CanUse(RG_SONG_OF_STORMS));}}),
EventAccess(&logic->GossipStoneFairy, {[]{return logic->GossipStoneFairy || logic->CallGossipFairyExceptSuns();}}),
EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairyExceptSuns();}}),
EventAccess(&logic->ShowedMidoSwordAndShield, {[]{return logic->ShowedMidoSwordAndShield || (logic->IsChild && logic->CanUse(RG_KOKIRI_SWORD) && logic->CanUse(RG_DEKU_SHIELD));}}),
}, {
//Locations
@ -24,7 +24,7 @@ void RegionTable_Init_LostWoods() {
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("Big Skulltula") || logic->ForestTempleClear)) || ctx->GetOption(RSK_FOREST).Is(RO_FOREST_OPEN) || logic->ShowedMidoSwordAndShield;}}),
Entrance(RR_KF_OUTSIDE_DEKU_TREE, {[]{return (logic->IsAdult && (logic->CanPassEnemy(RE_BIG_SKULLTULA) || logic->ForestTempleClear)) || ctx->GetOption(RSK_FOREST).Is(RO_FOREST_OPEN) || logic->ShowedMidoSwordAndShield;}}),
Entrance(RR_THE_LOST_WOODS, {[]{return true;}}),
Entrance(RR_LW_BRIDGE_FROM_FOREST, {[]{return logic->IsAdult || ctx->GetOption(RSK_FOREST).IsNot(RO_FOREST_CLOSED) || logic->DekuTreeClear;}}),
Entrance(RR_KF_STORMS_GROTTO, {[]{return logic->CanOpenStormsGrotto();}}),
@ -42,7 +42,7 @@ void RegionTable_Init_LostWoods() {
}, {
//Exits
Entrance(RR_DEKU_TREE_ENTRYWAY, {[]{return logic->IsChild || (ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF) && (ctx->GetOption(RSK_FOREST).Is(RO_FOREST_OPEN) || logic->ShowedMidoSwordAndShield));}}),
Entrance(RR_KOKIRI_FOREST, {[]{return (logic->IsAdult && (logic->CanPassEnemy("Big Skulltula") || logic->ForestTempleClear)) || ctx->GetOption(RSK_FOREST).Is(RO_FOREST_OPEN) || logic->ShowedMidoSwordAndShield;}}),
Entrance(RR_KOKIRI_FOREST, {[]{return (logic->IsAdult && (logic->CanPassEnemy(RE_BIG_SKULLTULA) || logic->ForestTempleClear)) || ctx->GetOption(RSK_FOREST).Is(RO_FOREST_OPEN) || logic->ShowedMidoSwordAndShield;}}),
});
areaTable[RR_KF_LINKS_HOUSE] = Region("KF Link's House", "KF Link's House", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, {
@ -115,7 +115,7 @@ void RegionTable_Init_LostWoods() {
//Events
EventAccess(&logic->OddMushroomAccess, {[]{return logic->OddMushroomAccess || (logic->IsAdult && (logic->CojiroAccess || logic->CanUse(RG_COJIRO)));}}),
EventAccess(&logic->PoachersSawAccess, {[]{return logic->PoachersSawAccess || (logic->IsAdult && logic->OddPoulticeAccess);}}),
EventAccess(&logic->GossipStoneFairy, {[]{return logic->GossipStoneFairy || logic->CallGossipFairyExceptSuns();}}),
EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairyExceptSuns();}}),
EventAccess(&logic->BeanPlantFairy, {[]{return logic->BeanPlantFairy || logic->CanUse(RG_SONG_OF_STORMS);}}),
EventAccess(&logic->BugShrub, {[]{return logic->IsChild && logic->CanCutShrubs();}}),
}, {
@ -204,7 +204,7 @@ void RegionTable_Init_LostWoods() {
areaTable[RR_SACRED_FOREST_MEADOW] = Region("Sacred Forest Meadow", "Sacred Forest Meadow", RA_SACRED_FOREST_MEADOW, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->GossipStoneFairy, {[]{return logic->GossipStoneFairy || logic->CallGossipFairyExceptSuns();}}),
EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairyExceptSuns();}}),
}, {
//Locations
LOCATION(RC_SONG_FROM_SARIA, logic->IsChild && logic->HasItem(RG_ZELDAS_LETTER)),

View File

@ -15,7 +15,7 @@ void RegionTable_Init_ZorasDomain() {
areaTable[RR_ZORAS_RIVER] = Region("Zora River", "Zora River", RA_ZORAS_RIVER, DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->GossipStoneFairy, {[]{return logic->GossipStoneFairy || logic->CallGossipFairy();}}),
EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairy();}}),
EventAccess(&logic->BeanPlantFairy, {[]{return logic->BeanPlantFairy || (CanPlantBean(RR_ZORAS_RIVER) && logic->CanUse(RG_SONG_OF_STORMS));}}),
EventAccess(&logic->ButterflyFairy, {[]{return logic->ButterflyFairy || logic->CanUse(RG_STICKS);}}),
EventAccess(&logic->BugShrub, {[]{return logic->BugShrub || logic->CanCutShrubs();}}),
@ -85,7 +85,7 @@ void RegionTable_Init_ZorasDomain() {
areaTable[RR_ZORAS_DOMAIN] = Region("Zoras Domain", "Zoras Domain", RA_ZORAS_DOMAIN, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->EyeballFrogAccess, {[]{return logic->EyeballFrogAccess || (logic->IsAdult && logic->KingZoraThawed && (logic->CanUse(RG_EYEDROPS) || logic->CanUse(RG_EYEBALL_FROG) || logic->CanUse(RG_PRESCRIPTION) || logic->PrescriptionAccess));}}),
EventAccess(&logic->GossipStoneFairy, {[]{return logic->GossipStoneFairy || logic->CallGossipFairyExceptSuns();}}),
EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairyExceptSuns();}}),
EventAccess(&logic->NutPot, {[]{return true;}}),
EventAccess(&logic->StickPot, {[]{return logic->StickPot || logic->IsChild;}}),
EventAccess(&logic->FishGroup, {[]{return logic->FishGroup || logic->IsChild;}}),
@ -149,7 +149,7 @@ void RegionTable_Init_ZorasDomain() {
areaTable[RR_ZORAS_FOUNTAIN] = Region("Zoras Fountain", "Zoras Fountain", RA_ZORAS_FOUNTAIN, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->GossipStoneFairy, {[]{return logic->GossipStoneFairy || logic->CallGossipFairyExceptSuns();}}),
EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairyExceptSuns();}}),
EventAccess(&logic->ButterflyFairy, {[]{return logic->ButterflyFairy || (logic->CanUse(RG_STICKS) && logic->AtDay);}}),
}, {
//Locations

View File

@ -428,25 +428,109 @@ namespace Rando {
return false;
}
//NOTE, when adding dark link,add Hearts() > 0
bool Logic::CanKillEnemy(std::string enemy) {
//switch(enemy) {} RANDOTODO implement enemies enum
if (enemy == "Big Skulltula"){
return CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT) || CanJumpslash() || CanUse(RG_MEGATON_HAMMER) || CanUse(RG_HOOKSHOT) || CanUse(RG_DINS_FIRE) || HasExplosives();
bool Logic::CanKillEnemy(RandomizerEnemy enemy, EnemyDistance distance) {
switch(enemy) {
case RE_GOLD_SKULLTULA:
case RE_GOHMA_LARVA:
case RE_MAD_SCRUB:
return CanAttack();
case RE_BIG_SKULLTULA:
return CanDamage() || CanUse(RG_HOOKSHOT);
case RE_DODONGO:
case RE_LIZALFOS:
return CanJumpslash() || HasExplosives() || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_FAIRY_BOW) || CanUse(RG_MEGATON_HAMMER);
case RE_KEESE:
case RE_FIRE_KEESE:
return CanJumpslash() || HasExplosives() || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_FAIRY_BOW) || CanUse(RG_MEGATON_HAMMER) || CanUse(RG_HOOKSHOT) || CanUse(RG_BOOMERANG);
default:
SPDLOG_ERROR("CanKillEnemy reached `default`.");
assert(false);
return false;
}
//Shouldn't be reached
return false;
}
bool Logic::CanPassEnemy(std::string enemy) {
//switch(enemy) {} RANDOTODO implement enemies enum
bool Logic::CanPassEnemy(RandomizerEnemy enemy) {
if (CanKillEnemy(enemy)){
return true;
}
if (enemy == "Big Skulltula"){
return CanUse(RG_NUTS) || CanUse(RG_BOOMERANG);
switch(enemy) {
case RE_GOLD_SKULLTULA:
case RE_GOHMA_LARVA:
case RE_LIZALFOS:
case RE_DODONGO: //RANDOTODO do dodongos block the way in tight corridors?
case RE_MAD_SCRUB:
case RE_KEESE:
case RE_FIRE_KEESE:
return true;
case RE_BIG_SKULLTULA:
return CanUse(RG_NUTS) || CanUse(RG_BOOMERANG);
default:
SPDLOG_ERROR("CanPassEnemy reached `default`.");
assert(false);
return false;
}
return false;
}
bool Logic::CanAvoidEnemy(RandomizerEnemy enemy) {
if (CanKillEnemy(enemy)){
return true;
}
switch(enemy) {
case RE_GOLD_SKULLTULA:
case RE_GOHMA_LARVA:
case RE_LIZALFOS:
case RE_DODONGO: //RANDOTODO do dodongos block the way in tight corridors?
case RE_BIG_SKULLTULA:
return true;
case RE_MAD_SCRUB:
case RE_KEESE:
case RE_FIRE_KEESE:
return CanUse(RG_NUTS);
default:
SPDLOG_ERROR("CanPassEnemy reached `default`.");
assert(false);
return false;
}
}
bool Logic::CanGetEnemyDrop(RandomizerEnemy enemy, EnemyDistance distance, bool aboveLink) {
if (!CanKillEnemy(enemy, distance)){
return false;
}
if (distance <= ED_MASTER_SWORD_JUMPSLASH){
return true;
}
switch(enemy) {
case RE_GOLD_SKULLTULA:
//RANDOTODO double check all jumpslash kills that might be out of jump/backflip range
return distance <= ED_HAMMER_JUMPSLASH || (distance <= ED_RANG_OR_HOOKSHOT && (CanUse(RG_HOOKSHOT) || CanUse(RG_BOOMERANG))) || (distance == ED_LONGSHOT && CanUse(RG_LONGSHOT));
case RE_KEESE:
case RE_FIRE_KEESE:
return true;
default:
return aboveLink || (distance <= ED_RANG_OR_HOOKSHOT && CanUse(RG_BOOMERANG));
}
}
bool Logic::CanBreakMudWalls() {
//RANDOTODO blue fire tricks
return BlastOrSmash();
}
bool Logic::CanGetDekuBabaSticks() {
return DekuBabaSticks || (CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_BOOMERANG));
}
bool Logic::CanHitEyeTargets() {
return CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT);
}
bool Logic::CanDetonateBombFlowers() {
return CanUse(RG_FAIRY_BOW) || HasExplosives() || CanUse(RG_DINS_FIRE);
}
bool Logic::CanDetonateUprightBombFlower() {
return CanDetonateBombFlowers() || CanUse(RG_GORONS_BRACELET);
}
Logic::Logic() {
@ -546,8 +630,9 @@ namespace Rando {
return CallGossipFairyExceptSuns() || CanUse(RG_SUNS_SONG);
}
bool Logic::EffectiveHealth(){
return CallGossipFairyExceptSuns() || CanUse(RG_SUNS_SONG);
uint8_t Logic::EffectiveHealth(){
uint8_t Multiplier = (ctx->GetOption(RSK_DAMAGE_MULTIPLIER).Value<uint8_t>() < 6) ? ctx->GetOption(RSK_DAMAGE_MULTIPLIER).Value<uint8_t>() : 10;
return ((Hearts() << (2 + HasItem(RG_DOUBLE_DEFENSE))) >> Multiplier) + ((Hearts() << (2 + HasItem(RG_DOUBLE_DEFENSE))) % (1 << Multiplier) > 0);
}
uint8_t Logic::Hearts(){

View File

@ -141,6 +141,7 @@ class Logic {
bool FireLoopSwitch = false;
bool LinksCow = false;
bool DeliverLetter = false;
bool ClearMQDCUpperLobbyRocks = false;
/* --- END OF HELPERS AND LOCATION ACCESS --- */
@ -154,8 +155,15 @@ class Logic {
bool SmallKeys(RandomizerRegion dungeon, uint8_t requiredAmountGlitchless, uint8_t requiredAmountGlitched);
bool CanDoGlitch(GlitchType glitch);
bool CanEquipSwap(RandomizerGet itemName);
bool CanKillEnemy(std::string enemy);
bool CanPassEnemy(std::string enemy);
bool CanKillEnemy(RandomizerEnemy enemy, EnemyDistance distance = ED_CLOSE);
bool CanPassEnemy(RandomizerEnemy enemy);
bool CanAvoidEnemy(RandomizerEnemy enemy);
bool CanGetEnemyDrop(RandomizerEnemy enemy, EnemyDistance distance = ED_CLOSE, bool aboveLink = false);
bool CanBreakMudWalls();
bool CanGetDekuBabaSticks();
bool CanHitEyeTargets();
bool CanDetonateBombFlowers();
bool CanDetonateUprightBombFlower();
uint8_t BottleCount();
uint8_t OcarinaButtons();
bool HasBottle();
@ -176,7 +184,7 @@ class Logic {
bool CanLeaveForest();
bool CallGossipFairy();
bool CallGossipFairyExceptSuns();
bool EffectiveHealth();
uint8_t EffectiveHealth();
uint8_t Hearts();
uint8_t StoneCount();
uint8_t MedallionCount();

View File

@ -539,10 +539,25 @@ typedef enum {
RR_DODONGOS_CAVERN_MQ_BEGINNING,
RR_DODONGOS_CAVERN_MQ_LOBBY,
RR_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE,
RR_DODONGOS_CAVERN_MQ_STAIRS_PAST_MUD_WALL,
RR_DODONGOS_CAVERN_MQ_STAIRS_LOWER,
RR_DODONGOS_CAVERN_MQ_STAIRS_UPPER,
RR_DODONGOS_CAVERN_MQ_STAIRS_PAST_BIG_SKULLTULAS,
RR_DODONGOS_CAVERN_MQ_DODONGO_ROOM,
RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_LOWER,
RR_DODONGOS_CAVERN_MQ_BIG_BLOCK_ROOM,
RR_DODONGOS_CAVERN_MQ_LARVAE_ROOM,
RR_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS,
RR_DODONGOS_CAVERN_MQ_TWO_FIRES_ROOM,
RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_UPPER,
RR_DODONGOS_CAVERN_MQ_LOWER_RIGHT_SIDE,
RR_DODONGOS_CAVERN_MQ_BOMB_BAG_AREA,
RR_DODONGOS_CAVERN_MQ_BOSS_AREA,
RR_DODONGOS_CAVERN_MQ_LOWER_LIZALFOS,
RR_DODONGOS_CAVERN_MQ_POES_ROOM,
RR_DODONGOS_CAVERN_MQ_MAD_SCRUB_ROOM,
RR_DODONGOS_CAVERN_MQ_BEHIND_MOUTH,
RR_DODONGOS_CAVERN_MQ_BACK_BEHIND_FIRE,
RR_DODONGOS_CAVERN_MQ_BACK_SWITCH_GRAVE,
RR_DODONGOS_CAVERN_BOSS_ENTRYWAY,
RR_DODONGOS_CAVERN_BOSS_ROOM,
@ -4345,4 +4360,22 @@ typedef enum {
TH_MESSAGE_SURPLUS,
} TriforceHuntMessages;
typedef enum {
RE_GOLD_SKULLTULA,
RE_BIG_SKULLTULA,
RE_DODONGO,
RE_LIZALFOS,
RE_GOHMA_LARVA,
RE_KEESE,
RE_FIRE_KEESE,
RE_MAD_SCRUB,
} RandomizerEnemy;
typedef enum {
ED_CLOSE,
ED_HAMMER_JUMPSLASH,
ED_MASTER_SWORD_JUMPSLASH,
ED_RANG_OR_HOOKSHOT,
ED_LONGSHOT,
ED_FAR,
} EnemyDistance;