diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp index 1ccc05d21..bfb91d450 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp @@ -9,101 +9,112 @@ void RegionTable_Init_FireTemple() { // Vanilla/MQ Decider areaTable[RR_FIRE_TEMPLE_ENTRYWAY] = Region("Fire Temple Entryway", SCENE_FIRE_TEMPLE, {}, {}, { //Exits - Entrance(RR_FIRE_TEMPLE_FIRST_ROOM, []{return ctx->GetDungeon(FIRE_TEMPLE)->IsVanilla();}), - Entrance(RR_FIRE_TEMPLE_MQ_FIRST_ROOM_LOWER, []{return ctx->GetDungeon(FIRE_TEMPLE)->IsMQ();}), - Entrance(RR_DMC_CENTRAL_LOCAL, []{return true;}), + Entrance(RR_FIRE_TEMPLE_FOYER, []{return ctx->GetDungeon(FIRE_TEMPLE)->IsVanilla();}), + Entrance(RR_FIRE_TEMPLE_MQ_FOYER_LOWER, []{return ctx->GetDungeon(FIRE_TEMPLE)->IsMQ();}), + Entrance(RR_DMC_CENTRAL_LOCAL, []{return true;}), }); #pragma region Vanilla - areaTable[RR_FIRE_TEMPLE_FIRST_ROOM] = Region("Fire Temple First Room", SCENE_FIRE_TEMPLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_FOYER] = Region("Fire Temple Foyer", SCENE_FIRE_TEMPLE, {}, {}, { //Exits - Entrance(RR_FIRE_TEMPLE_ENTRYWAY, []{return true;}), - Entrance(RR_FIRE_TEMPLE_NEAR_BOSS_ROOM, []{return logic->FireTimer() >= 24;}), - Entrance(RR_FIRE_TEMPLE_LOOP_ENEMIES, []{return AnyAgeTime([]{return logic->CanUse(RG_MEGATON_HAMMER);}) && (logic->SmallKeys(SCENE_FIRE_TEMPLE, 8) || !logic->IsFireLoopLocked());}), - Entrance(RR_FIRE_TEMPLE_LOOP_EXIT, []{return true;}), - Entrance(RR_FIRE_TEMPLE_BIG_LAVA_ROOM, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 2) && logic->FireTimer() >= 24;}), + Entrance(RR_FIRE_TEMPLE_ENTRYWAY, []{return true;}), + Entrance(RR_FIRE_TEMPLE_NEAR_BOSS_ROOM, []{return true;}), + Entrance(RR_FIRE_TEMPLE_LOOP_HEXAGON_ROOM, []{return AnyAgeTime([]{return logic->CanUse(RG_MEGATON_HAMMER);}) && (logic->SmallKeys(SCENE_FIRE_TEMPLE, 8) || !logic->IsFireLoopLocked());}), + Entrance(RR_FIRE_TEMPLE_LOOP_CAGE_FOYER_SIDE, []{return true;}), + Entrance(RR_FIRE_TEMPLE_BIG_LAVA_ROOM, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 2) && logic->FireTimer() >= 24;}), }); - areaTable[RR_FIRE_TEMPLE_NEAR_BOSS_ROOM] = Region("Fire Temple Near Boss Room", SCENE_FIRE_TEMPLE, { + areaTable[RR_FIRE_TEMPLE_NEAR_BOSS_ROOM] = Region("Fire Temple Near Boss Room", SCENE_FIRE_TEMPLE, {}, { + //Locations + LOCATION(RC_FIRE_TEMPLE_NEAR_BOSS_CHEST, logic->FireTimer() >= 16), + //It's plausible to get the pots with rang from the larger square platform, but it's a blind shot that likely needs a setup + //and I've only been able to get the nearest 2, regardless it's a trick and probably a specific one like GY crate freestanding with rang + }, { + //Exits + Entrance(RR_FIRE_TEMPLE_FOYER, []{return (logic->IsAdult || logic->CanUse(RG_HOVER_BOOTS)) && (logic->FireTimer() >= 16 || (logic->Get(LOGIC_FIRE_HIT_PLATFORM) && logic->FireTimer() >= 8));}), + Entrance(RR_FIRE_TEMPLE_NEAR_BOSS_UPPER, []{return logic->IsAdult && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS)) && logic->FireTimer() >= 16;}), + Entrance(RR_FIRE_TEMPLE_BOSS_ENTRYWAY, []{return logic->FireTimer() >= 16 && (logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && (ctx->GetTrickOption(RT_FIRE_BOSS_DOOR_JUMP) || logic->Get(LOGIC_FIRE_HIT_PLATFORM))));}), + }); + + //This region assumes tunic logic is handled on entry. + areaTable[RR_FIRE_TEMPLE_NEAR_BOSS_UPPER] = Region("Fire Temple Near Boss Upper", SCENE_FIRE_TEMPLE, { //Events - EventAccess(LOGIC_FAIRY_ACCESS, []{return logic->CanUse(RG_HOOKSHOT) || (logic->CanBreakPots() && logic->CanUse(RG_HOVER_BOOTS));}), + EventAccess(LOGIC_FAIRY_ACCESS, []{return logic->CanBreakPots();}), }, { //Locations - LOCATION(RC_FIRE_TEMPLE_NEAR_BOSS_CHEST, true), - LOCATION(RC_FIRE_TEMPLE_NEAR_BOSS_POT_1, (logic->CanBreakPots() && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT)))), - LOCATION(RC_FIRE_TEMPLE_NEAR_BOSS_POT_2, (logic->CanBreakPots() && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT)))), - LOCATION(RC_FIRE_TEMPLE_NEAR_BOSS_POT_3, (logic->CanBreakPots() && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT)))), - LOCATION(RC_FIRE_TEMPLE_NEAR_BOSS_POT_4, (logic->CanBreakPots() && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT)))), + LOCATION(RC_FIRE_TEMPLE_NEAR_BOSS_POT_1, logic->CanBreakPots()), + LOCATION(RC_FIRE_TEMPLE_NEAR_BOSS_POT_2, logic->CanBreakPots()), + LOCATION(RC_FIRE_TEMPLE_NEAR_BOSS_POT_3, logic->CanBreakPots()), + LOCATION(RC_FIRE_TEMPLE_NEAR_BOSS_POT_4, logic->CanBreakPots()), }, { - //Exits - Entrance(RR_FIRE_TEMPLE_FIRST_ROOM, []{return true;}), - Entrance(RR_FIRE_TEMPLE_BOSS_ENTRYWAY, []{return logic->IsAdult && (ctx->GetTrickOption(RT_FIRE_BOSS_DOOR_JUMP) || logic->Get(LOGIC_FIRE_HIT_PLATFORM) || logic->CanUse(RG_HOVER_BOOTS));}), + //Exits should be handled if there's any way here directly }); - areaTable[RR_FIRE_TEMPLE_LOOP_ENEMIES] = Region("Fire Temple Loop Enemies", SCENE_FIRE_TEMPLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_LOOP_HEXAGON_ROOM] = Region("Fire Temple Loop Hexagon Room", SCENE_FIRE_TEMPLE, {}, {}, { //Exits - Entrance(RR_FIRE_TEMPLE_FIRST_ROOM, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 8) || !logic->IsFireLoopLocked();}), - Entrance(RR_FIRE_TEMPLE_LOOP_TILES, []{return AnyAgeTime([]{return logic->CanKillEnemy(RE_TORCH_SLUG) && logic->CanKillEnemy(RE_FIRE_KEESE);});}), + Entrance(RR_FIRE_TEMPLE_FOYER, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 8) || !logic->IsFireLoopLocked();}), + Entrance(RR_FIRE_TEMPLE_LOOP_5_TILE_ROOM, []{return AnyAgeTime([]{return logic->CanKillEnemy(RE_TORCH_SLUG) && logic->CanKillEnemy(RE_FIRE_KEESE);});}), }); - areaTable[RR_FIRE_TEMPLE_LOOP_TILES] = Region("Fire Temple Loop Tiles", SCENE_FIRE_TEMPLE, {}, { + areaTable[RR_FIRE_TEMPLE_LOOP_5_TILE_ROOM] = Region("Fire Temple Loop 5 Tile Room", SCENE_FIRE_TEMPLE, {}, { //Locations - LOCATION(RC_FIRE_TEMPLE_GS_BOSS_KEY_LOOP, logic->CanAttack()), + LOCATION(RC_FIRE_TEMPLE_GS_BOSS_KEY_LOOP, logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_CLOSE)), }, { //Exits - Entrance(RR_FIRE_TEMPLE_LOOP_ENEMIES, []{return true;}), + Entrance(RR_FIRE_TEMPLE_LOOP_HEXAGON_ROOM, []{return true;}), Entrance(RR_FIRE_TEMPLE_LOOP_FLARE_DANCER, []{return true;}), }); areaTable[RR_FIRE_TEMPLE_LOOP_FLARE_DANCER] = Region("Fire Temple Loop Flare Dancer", SCENE_FIRE_TEMPLE, {}, { //Locations - LOCATION(RC_FIRE_TEMPLE_FLARE_DANCER_CHEST, (logic->HasExplosives() || logic->CanUse(RG_MEGATON_HAMMER)) && (logic->IsAdult || logic->CanGroundJump())), + LOCATION(RC_FIRE_TEMPLE_FLARE_DANCER_CHEST, AnyAgeTime([]{return logic->CanKillEnemy(RE_FLARE_DANCER);}) && (logic->IsAdult || logic->CanGroundJump() || logic->CanUse(RG_HOOKSHOT))), }, { //Exits - Entrance(RR_FIRE_TEMPLE_LOOP_TILES, []{return true;}), - Entrance(RR_FIRE_TEMPLE_LOOP_HAMMER_SWITCH, []{return AnyAgeTime([]{return logic->CanKillEnemy(RE_FLARE_DANCER);});}), + Entrance(RR_FIRE_TEMPLE_LOOP_5_TILE_ROOM, []{return AnyAgeTime([]{return logic->CanKillEnemy(RE_FLARE_DANCER);});}), + Entrance(RR_FIRE_TEMPLE_LOOP_CAGE_SWITCH, []{return AnyAgeTime([]{return logic->CanKillEnemy(RE_FLARE_DANCER);});}), }); - areaTable[RR_FIRE_TEMPLE_LOOP_HAMMER_SWITCH] = Region("Fire Temple Loop Hammer Switch", SCENE_FIRE_TEMPLE, { + areaTable[RR_FIRE_TEMPLE_LOOP_CAGE_SWITCH] = Region("Fire Temple Loop Cage Switch", SCENE_FIRE_TEMPLE, { //Events EventAccess(LOGIC_FIRE_LOOP_SWITCH, []{return logic->CanUse(RG_MEGATON_HAMMER);}), }, {}, { //Exits Entrance(RR_FIRE_TEMPLE_LOOP_FLARE_DANCER, []{return true;}), - Entrance(RR_FIRE_TEMPLE_LOOP_GORON_ROOM, []{return logic->Get(LOGIC_FIRE_LOOP_SWITCH);}), + Entrance(RR_FIRE_TEMPLE_LOOP_GORON_CAGE, []{return logic->Get(LOGIC_FIRE_LOOP_SWITCH);}), }); - areaTable[RR_FIRE_TEMPLE_LOOP_GORON_ROOM] = Region("Fire Temple Loop Goron Room", SCENE_FIRE_TEMPLE, {}, { + areaTable[RR_FIRE_TEMPLE_LOOP_GORON_CAGE] = Region("Fire Temple Loop Goron Cage", SCENE_FIRE_TEMPLE, {}, { //Locations LOCATION(RC_FIRE_TEMPLE_BOSS_KEY_CHEST, true), }, { //Exits - Entrance(RR_FIRE_TEMPLE_LOOP_HAMMER_SWITCH, []{return logic->Get(LOGIC_FIRE_LOOP_SWITCH);}), - Entrance(RR_FIRE_TEMPLE_LOOP_EXIT, []{return logic->Get(LOGIC_FIRE_LOOP_SWITCH);}), + Entrance(RR_FIRE_TEMPLE_LOOP_CAGE_SWITCH, []{return logic->Get(LOGIC_FIRE_LOOP_SWITCH);}), + Entrance(RR_FIRE_TEMPLE_LOOP_CAGE_FOYER_SIDE, []{return logic->Get(LOGIC_FIRE_LOOP_SWITCH);}), }); - areaTable[RR_FIRE_TEMPLE_LOOP_EXIT] = Region("Fire Temple Loop Exit", SCENE_FIRE_TEMPLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_LOOP_CAGE_FOYER_SIDE] = Region("Fire Temple Cage Foyer Side", SCENE_FIRE_TEMPLE, {}, {}, { //Exits - Entrance(RR_FIRE_TEMPLE_FIRST_ROOM, []{return true;}), - Entrance(RR_FIRE_TEMPLE_LOOP_GORON_ROOM, []{return logic->Get(LOGIC_FIRE_LOOP_SWITCH);}), + Entrance(RR_FIRE_TEMPLE_FOYER, []{return true;}), + Entrance(RR_FIRE_TEMPLE_LOOP_GORON_CAGE, []{return logic->Get(LOGIC_FIRE_LOOP_SWITCH);}), }); areaTable[RR_FIRE_TEMPLE_BIG_LAVA_ROOM] = Region("Fire Temple Big Lava Room", SCENE_FIRE_TEMPLE, {}, { //Locations - LOCATION(RC_FIRE_TEMPLE_BIG_LAVA_POT_1, logic->CanBreakPots()), - LOCATION(RC_FIRE_TEMPLE_BIG_LAVA_POT_2, logic->CanBreakPots()), - LOCATION(RC_FIRE_TEMPLE_BIG_LAVA_POT_3, logic->CanBreakPots()), + LOCATION(RC_FIRE_TEMPLE_BIG_LAVA_POT_1, logic->CanBreakPots() && logic->FireTimer() >= 32), + LOCATION(RC_FIRE_TEMPLE_BIG_LAVA_POT_2, logic->CanBreakPots() && logic->FireTimer() >= 32), + LOCATION(RC_FIRE_TEMPLE_BIG_LAVA_POT_3, logic->CanBreakPots() && logic->FireTimer() >= 32), }, { //Exits - Entrance(RR_FIRE_TEMPLE_FIRST_ROOM, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 2);}), - Entrance(RR_FIRE_TEMPLE_BIG_LAVA_ROOM_NORTH_GORON, []{return true;}), - Entrance(RR_FIRE_TEMPLE_BIG_LAVA_ROOM_NORTH_TILES, []{return logic->IsAdult && (logic->CanUse(RG_SONG_OF_TIME) || ctx->GetTrickOption(RT_FIRE_SOT));}), - Entrance(RR_FIRE_TEMPLE_BIG_LAVA_ROOM_SOUTH_GORON, []{return logic->IsAdult && logic->HasExplosives();}), - Entrance(RR_FIRE_TEMPLE_FIRE_PILLAR_ROOM, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 3);}), + Entrance(RR_FIRE_TEMPLE_FOYER, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 2) && logic->FireTimer() >= 24;}), + Entrance(RR_FIRE_TEMPLE_1F_CURVED_CAGE, []{return logic->FireTimer() >= 24;}), + Entrance(RR_FIRE_TEMPLE_8_TILE_ROOM, []{return logic->IsAdult && logic->FireTimer() >= 32 && (logic->CanUse(RG_SONG_OF_TIME) || ctx->GetTrickOption(RT_FIRE_SOT));}), + Entrance(RR_FIRE_TEMPLE_STRAIGHTFORWARD_CAGE, []{return (logic->IsAdult && logic->HasExplosives() && logic->FireTimer() >= 32) || (logic->CanGroundJump() && logic->FireTimer() >= 40);}), + // Fewer tunic requirements ends here + Entrance(RR_FIRE_TEMPLE_LAVA_GEYSER_1F, []{return logic->CanUse(RG_GORON_TUNIC) && logic->SmallKeys(SCENE_FIRE_TEMPLE, 3);}), }); - areaTable[RR_FIRE_TEMPLE_BIG_LAVA_ROOM_NORTH_GORON] = Region("Fire Temple Big Lava Room North Goron", SCENE_FIRE_TEMPLE, {}, { + areaTable[RR_FIRE_TEMPLE_1F_CURVED_CAGE] = Region("Fire Temple 1F Curved Cage", SCENE_FIRE_TEMPLE, {}, { //Locations LOCATION(RC_FIRE_TEMPLE_BIG_LAVA_ROOM_LOWER_OPEN_DOOR_CHEST, true), }, { @@ -111,16 +122,17 @@ void RegionTable_Init_FireTemple() { Entrance(RR_FIRE_TEMPLE_BIG_LAVA_ROOM, []{return true;}), }); - areaTable[RR_FIRE_TEMPLE_BIG_LAVA_ROOM_NORTH_TILES] = Region("Fire Temple Big Lava Room North Tiles", SCENE_FIRE_TEMPLE, {}, { + areaTable[RR_FIRE_TEMPLE_8_TILE_ROOM] = Region("Fire Temple 8 Tile Room", SCENE_FIRE_TEMPLE, {}, { //Locations - //RANDOTODO check if child can reach - LOCATION(RC_FIRE_TEMPLE_GS_SONG_OF_TIME_ROOM, (logic->IsAdult && logic->CanAttack()) || logic->HookshotOrBoomerang()), + //it's also possible to use the like like trick to grab this as child, but there's no generic version of that yet + LOCATION(RC_FIRE_TEMPLE_GS_SONG_OF_TIME_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, logic->IsAdult ? ED_CLOSE : ED_BOOMERANG) || + logic->CanGroundJumpJumpSlash()), }, { //Exits Entrance(RR_FIRE_TEMPLE_BIG_LAVA_ROOM, []{return true;}), }); - areaTable[RR_FIRE_TEMPLE_BIG_LAVA_ROOM_SOUTH_GORON] = Region("Fire Temple Big Lava Room South Goron", SCENE_FIRE_TEMPLE, {}, { + areaTable[RR_FIRE_TEMPLE_STRAIGHTFORWARD_CAGE] = Region("Fire Temple Straightforward Cage", SCENE_FIRE_TEMPLE, {}, { //Locations LOCATION(RC_FIRE_TEMPLE_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST, true), }, { @@ -128,50 +140,70 @@ void RegionTable_Init_FireTemple() { Entrance(RR_FIRE_TEMPLE_BIG_LAVA_ROOM, []{return true;}), }); - areaTable[RR_FIRE_TEMPLE_FIRE_PILLAR_ROOM] = Region("Fire Temple Fire Pillar Room", SCENE_FIRE_TEMPLE, {}, { + areaTable[RR_FIRE_TEMPLE_LAVA_GEYSER_1F] = Region("Fire Temple Lava Geyser 1F", SCENE_FIRE_TEMPLE, {}, {}, { + //Exits + Entrance(RR_FIRE_TEMPLE_BIG_LAVA_ROOM, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 3);}), + Entrance(RR_FIRE_TEMPLE_LAVA_GEYSER_GRATE, []{return logic->FireTimer() >= 40/* && CanClimbHigh()*/;}), + Entrance(RR_FIRE_TEMPLE_LAVA_GEYSER_TORCH, []{return logic->CanUse(RG_LONGSHOT) && logic->FireTimer() >= 40;}), + }); + + areaTable[RR_FIRE_TEMPLE_LAVA_GEYSER_GRATE] = Region("Fire Temple Lava Geyser Grate", SCENE_FIRE_TEMPLE, {}, { //Locations - LOCATION(RC_FIRE_TEMPLE_FIRE_PILLAR_LEFT_HEART, logic->FireTimer() >= 56), - LOCATION(RC_FIRE_TEMPLE_FIRE_PILLAR_RIGHT_HEART, logic->FireTimer() >= 56), - LOCATION(RC_FIRE_TEMPLE_FIRE_PILLAR_BACK_HEART, logic->FireTimer() >= 56), + LOCATION(RC_FIRE_TEMPLE_FIRE_PILLAR_LEFT_HEART, true), + LOCATION(RC_FIRE_TEMPLE_FIRE_PILLAR_RIGHT_HEART, true), + LOCATION(RC_FIRE_TEMPLE_FIRE_PILLAR_BACK_HEART, true), }, { //Exits - Entrance(RR_FIRE_TEMPLE_BIG_LAVA_ROOM, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 3);}), - Entrance(RR_FIRE_TEMPLE_SHORTCUT_ROOM, []{return logic->FireTimer() >= 56 && logic->SmallKeys(SCENE_FIRE_TEMPLE, 4);}), + Entrance(RR_FIRE_TEMPLE_LAVA_GEYSER_1F, []{return logic->TakeDamage();}), + Entrance(RR_FIRE_TEMPLE_LAVA_GEYSER_2F, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 4) && logic->FireTimer() >= 48/* && str0*/;}), + }); + + //you can get the hearts with an indirect boomerang from here, but it's a trick + areaTable[RR_FIRE_TEMPLE_LAVA_GEYSER_TORCH] = Region("Fire Temple Lava Geyser Torch", SCENE_FIRE_TEMPLE, {}, {}, { + //Exits + Entrance(RR_FIRE_TEMPLE_LAVA_GEYSER_1F, []{return true;}), + Entrance(RR_FIRE_TEMPLE_LAVA_GEYSER_GRATE, []{return logic->CanUse(RG_HOOKSHOT);}), + }); + + areaTable[RR_FIRE_TEMPLE_LAVA_GEYSER_2F] = Region("Fire Temple Lava Geyser 2F", SCENE_FIRE_TEMPLE, {}, {}, { + //Exits + Entrance(RR_FIRE_TEMPLE_LAVA_GEYSER_TORCH, []{return logic->TakeDamage() && logic->FireTimer() >= 24;}), + Entrance(RR_FIRE_TEMPLE_SHORTCUT_ROOM, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 4);}), }); areaTable[RR_FIRE_TEMPLE_SHORTCUT_ROOM] = Region("Fire Temple Shortcut Room", SCENE_FIRE_TEMPLE, {}, { }, { //Exits - Entrance(RR_FIRE_TEMPLE_FIRE_PILLAR_ROOM, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 4);}), - Entrance(RR_FIRE_TEMPLE_SHORTCUT_CLIMB, []{return logic->Get(LOGIC_FIRE_OPENED_SHORTCUT_CLIMB);}), - Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_LOWER, []{return logic->IsAdult && (logic->HasItem(RG_GORONS_BRACELET) || ctx->GetTrickOption(RT_FIRE_STRENGTH) || logic->CanGroundJump()) && (logic->HasExplosives() || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_SLINGSHOT));}), + Entrance(RR_FIRE_TEMPLE_LAVA_GEYSER_1F, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 4);}), + Entrance(RR_FIRE_TEMPLE_SHORTCUT_CLIMB, []{return logic->Get(LOGIC_FIRE_OPENED_UPPER_SHORTCUT);}), + Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_LOWER, []{return logic->IsAdult && (((logic->HasItem(RG_GORONS_BRACELET) || ctx->GetTrickOption(RT_FIRE_STRENGTH))/*CanUse(RG_CLIMB)*/) || logic->CanGroundJump()) && logic->CanHitSwitch(ED_BOMB_THROW);}), }); areaTable[RR_FIRE_TEMPLE_SHORTCUT_CLIMB] = Region("Fire Temple Shortcut Climb", SCENE_FIRE_TEMPLE, { //Events - EventAccess(LOGIC_FIRE_OPENED_SHORTCUT_CLIMB, []{return true;}), + EventAccess(LOGIC_FIRE_OPENED_UPPER_SHORTCUT, []{return true;}), }, { //Locations LOCATION(RC_FIRE_TEMPLE_BOULDER_MAZE_SHORTCUT_CHEST, true), }, { //Exits Entrance(RR_FIRE_TEMPLE_SHORTCUT_ROOM, []{return true;}), - Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_UPPER, []{return true;}), + Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_UPPER, []{return true/*CanUse(RG_CLIMB)*/;}), }); areaTable[RR_FIRE_TEMPLE_BOULDER_MAZE_LOWER] = Region("Fire Temple Boulder Maze Lower", SCENE_FIRE_TEMPLE, {}, { //Locations LOCATION(RC_FIRE_TEMPLE_BOULDER_MAZE_LOWER_CHEST, true), - LOCATION(RC_FIRE_TEMPLE_GS_BOULDER_MAZE, logic->HasExplosives() && (logic->IsAdult || logic->HookshotOrBoomerang())), + LOCATION(RC_FIRE_TEMPLE_GS_BOULDER_MAZE, logic->HasExplosives() && (logic->IsAdult || logic->HookshotOrBoomerang() || logic->CanGroundJumpJumpSlash())), }, { //Exits - Entrance(RR_FIRE_TEMPLE_SHORTCUT_ROOM, []{return true;}), - Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_LOWER_SIDE_ROOM, []{return true;}), - Entrance(RR_FIRE_TEMPLE_EAST_CENTRAL_ROOM, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 5);}), - Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_UPPER, []{return false;}), + Entrance(RR_FIRE_TEMPLE_SHORTCUT_ROOM, []{return true;}), + Entrance(RR_FIRE_TEMPLE_3F_CURVED_CAGE, []{return true;}), + Entrance(RR_FIRE_TEMPLE_NARROW_PATH_ROOM, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 5);}), + Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_UPPER, []{return false;}), }); - areaTable[RR_FIRE_TEMPLE_BOULDER_MAZE_LOWER_SIDE_ROOM] = Region("Fire Temple Boulder Maze Lower Side Room", SCENE_FIRE_TEMPLE, {}, { + areaTable[RR_FIRE_TEMPLE_3F_CURVED_CAGE] = Region("Fire Temple 3F Curved Cage", SCENE_FIRE_TEMPLE, {}, { //Locations LOCATION(RC_FIRE_TEMPLE_BOULDER_MAZE_SIDE_ROOM_CHEST, true), }, { @@ -179,7 +211,7 @@ void RegionTable_Init_FireTemple() { Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_LOWER, []{return true;}), }); - areaTable[RR_FIRE_TEMPLE_EAST_CENTRAL_ROOM] = Region("Fire Temple East Central Room", SCENE_FIRE_TEMPLE, {}, { + areaTable[RR_FIRE_TEMPLE_NARROW_PATH_ROOM] = Region("Fire Temple Narrow Path Room", SCENE_FIRE_TEMPLE, {}, { //Locations LOCATION(RC_FIRE_TEMPLE_EAST_CENTRAL_LEFT_HEART, true), LOCATION(RC_FIRE_TEMPLE_EAST_CENTRAL_RIGHT_HEART, true), @@ -189,28 +221,30 @@ void RegionTable_Init_FireTemple() { Entrance(RR_FIRE_TEMPLE_BIG_LAVA_ROOM, []{return logic->TakeDamage();}), Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_LOWER, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 5);}), Entrance(RR_FIRE_TEMPLE_FIRE_WALL_CHASE, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 6);}), - Entrance(RR_FIRE_TEMPLE_MAP_AREA, []{return logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW);}), + Entrance(RR_FIRE_TEMPLE_FIRE_WALL_CAGE, []{return logic->CanHitEyeTargets();}), }); areaTable[RR_FIRE_TEMPLE_FIRE_WALL_CHASE] = Region("Fire Temple Fire Wall Chase", SCENE_FIRE_TEMPLE, {}, { //Locations LOCATION(RC_FIRE_TEMPLE_FIRE_WALL_EAST_HEART, logic->FireTimer() >= 24 && (logic->IsAdult || logic->CanUse(RG_BOOMERANG))), LOCATION(RC_FIRE_TEMPLE_FIRE_WALL_WEST_HEART, logic->FireTimer() >= 24 && (logic->IsAdult || logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_FIRE_TEMPLE_FIRE_WALL_EXIT_HEART, logic->FireTimer() >= 24), + LOCATION(RC_FIRE_TEMPLE_FIRE_WALL_EXIT_HEART, logic->FireTimer() >= 16), }, { //Exits - Entrance(RR_FIRE_TEMPLE_EAST_CENTRAL_ROOM, []{return logic->FireTimer() >= 24 && logic->SmallKeys(SCENE_FIRE_TEMPLE, 6);}), - Entrance(RR_FIRE_TEMPLE_MAP_AREA, []{return logic->IsAdult;}), + Entrance(RR_FIRE_TEMPLE_NARROW_PATH_ROOM, []{return logic->FireTimer() >= 24 && logic->SmallKeys(SCENE_FIRE_TEMPLE, 6);}), + Entrance(RR_FIRE_TEMPLE_FIRE_WALL_CAGE, []{return logic->FireTimer() >= 16 && logic->IsAdult;}), Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_UPPER, []{return logic->FireTimer() >= 24 && logic->IsAdult;}), - Entrance(RR_FIRE_TEMPLE_CORRIDOR, []{return logic->FireTimer() >= 24 && logic->IsAdult && logic->SmallKeys(SCENE_FIRE_TEMPLE, 7);}), + Entrance(RR_FIRE_TEMPLE_CORRIDOR, []{return logic->FireTimer() >= 16 && logic->IsAdult && logic->SmallKeys(SCENE_FIRE_TEMPLE, 7);}), }); - areaTable[RR_FIRE_TEMPLE_MAP_AREA] = Region("Fire Temple Map Region", SCENE_FIRE_TEMPLE, {}, { + //firetimer for entering this area from RR_FIRE_TEMPLE_FIRE_WALL_CHASE is handled there + areaTable[RR_FIRE_TEMPLE_FIRE_WALL_CAGE] = Region("Fire Temple Fire Wall Cage", SCENE_FIRE_TEMPLE, {}, { //Locations - LOCATION(RC_FIRE_TEMPLE_MAP_CHEST, true), + LOCATION(RC_FIRE_TEMPLE_MAP_CHEST, logic->FireTimer() >= 8), }, { //Exits - Entrance(RR_FIRE_TEMPLE_EAST_CENTRAL_ROOM, []{return true;}), + Entrance(RR_FIRE_TEMPLE_NARROW_PATH_ROOM, []{return true;}), + Entrance(RR_FIRE_TEMPLE_FIRE_WALL_CHASE, []{return false;}), }); areaTable[RR_FIRE_TEMPLE_BOULDER_MAZE_UPPER] = Region("Fire Temple Boulder Maze Upper", SCENE_FIRE_TEMPLE, {}, { @@ -221,85 +255,110 @@ void RegionTable_Init_FireTemple() { Entrance(RR_FIRE_TEMPLE_SHORTCUT_CLIMB, []{return logic->HasExplosives();}), Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_LOWER, []{return true;}), Entrance(RR_FIRE_TEMPLE_FIRE_WALL_CHASE, []{return true;}), - Entrance(RR_FIRE_TEMPLE_SCARECROW_ROOM, []{return logic->CanUse(RG_SCARECROW) || (ctx->GetTrickOption(RT_FIRE_SCARECROW) && logic->IsAdult && logic->CanUse(RG_LONGSHOT));}), + Entrance(RR_FIRE_TEMPLE_GS_CLIMB_4F, []{return logic->CanUse(RG_SCARECROW) || (ctx->GetTrickOption(RT_FIRE_SCARECROW) && logic->IsAdult && logic->CanUse(RG_LONGSHOT));}), }); - areaTable[RR_FIRE_TEMPLE_SCARECROW_ROOM] = Region("Fire Temple Scarecrow Room", SCENE_FIRE_TEMPLE, {}, { - //Locations - LOCATION(RC_FIRE_TEMPLE_GS_SCARECROW_CLIMB, logic->CanJumpslashExceptHammer() || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG) || logic->HasExplosives() || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_DINS_FIRE)), - }, { + areaTable[RR_FIRE_TEMPLE_GS_CLIMB_4F] = Region("Fire Temple GS Climb 4F", SCENE_FIRE_TEMPLE, {}, {}, { //Exits Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_UPPER, []{return true;}), - Entrance(RR_FIRE_TEMPLE_EAST_PEAK, []{return true;}), + Entrance(RR_FIRE_TEMPLE_GS_CLIMB_5F, []{return true/*CanUse(RG_CLIMB)*/;}), }); - areaTable[RR_FIRE_TEMPLE_EAST_PEAK] = Region("Fire Temple East Peak", SCENE_FIRE_TEMPLE, {}, { + areaTable[RR_FIRE_TEMPLE_GS_CLIMB_5F] = Region("Fire Temple GS Climb 5F", SCENE_FIRE_TEMPLE, {}, { //Locations - LOCATION(RC_FIRE_TEMPLE_SCARECROW_CHEST, true), - LOCATION(RC_FIRE_TEMPLE_GS_SCARECROW_TOP, logic->CanUseProjectile()), + LOCATION(RC_FIRE_TEMPLE_GS_SCARECROW_CLIMB, logic->CanKillEnemy(RE_GOLD_SKULLTULA, /*CanUse(RG_CLIMB) ?*/ED_SHORT_JUMPSLASH/*: ED_BOMB_THROW*/)), }, { //Exits - Entrance(RR_FIRE_TEMPLE_SCARECROW_ROOM, []{return true;}), - Entrance(RR_FIRE_TEMPLE_EAST_CENTRAL_ROOM, []{return logic->TakeDamage();}), + Entrance(RR_FIRE_TEMPLE_GS_CLIMB_4F, []{return true;}), + Entrance(RR_FIRE_TEMPLE_5F_RUINS, []{return true;}), + }); + + //RANDOTODO find a better name + areaTable[RR_FIRE_TEMPLE_5F_RUINS] = Region("Fire Temple 5F Ruins", SCENE_FIRE_TEMPLE, {}, { + //Locations + LOCATION(RC_FIRE_TEMPLE_SCARECROW_CHEST, true), + LOCATION(RC_FIRE_TEMPLE_GS_SCARECROW_TOP, logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_BOMB_THROW)), + }, { + //Exits + Entrance(RR_FIRE_TEMPLE_GS_CLIMB_4F, []{return true;}), + Entrance(RR_FIRE_TEMPLE_NARROW_PATH_ROOM, []{return logic->TakeDamage();}), }); areaTable[RR_FIRE_TEMPLE_CORRIDOR] = Region("Fire Temple Corridor", SCENE_FIRE_TEMPLE, {}, {}, { //Exits Entrance(RR_FIRE_TEMPLE_FIRE_WALL_CHASE, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 7);}), - Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_ROOM, []{return true;}), + Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_MAIN, []{return true;}), }); - areaTable[RR_FIRE_TEMPLE_FIRE_MAZE_ROOM] = Region("Fire Temple Fire Maze Room", SCENE_FIRE_TEMPLE, {}, { - // Locations + areaTable[RR_FIRE_TEMPLE_FIRE_MAZE_MAIN] = Region("Fire Temple Fire Maze Main", SCENE_FIRE_TEMPLE, {}, { + //Locations LOCATION(RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_1, logic->CanBreakPots()), LOCATION(RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_2, logic->CanBreakPots()), LOCATION(RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_3, logic->CanBreakPots()), LOCATION(RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_4, logic->CanBreakPots()), }, { //Exits + //Accounting for either air-drifting to the platform you want and taking fall damage or landing on the platform and jumping off + Entrance(RR_FIRE_TEMPLE_NEAR_BOSS_ROOM, []{return logic->Get(LOGIC_FIRE_HIT_PLATFORM) && (logic->IsAdult || logic->CanUse(RG_HOVER_BOOTS) || logic->TakeDamage());}), Entrance(RR_FIRE_TEMPLE_CORRIDOR, []{return true;}), - Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_UPPER, []{return logic->CanUse(RG_HOVER_BOOTS) || logic->CanGroundJump();}), - Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_SIDE_ROOM, []{return true;}), - Entrance(RR_FIRE_TEMPLE_WEST_CENTRAL_LOWER, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 8);}), - Entrance(RR_FIRE_TEMPLE_LATE_FIRE_MAZE, []{return (bool)ctx->GetTrickOption(RT_FIRE_SKIP_FLAME_WALLS);}), + Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_PLATFORMS, []{return logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && (logic->Get(LOGIC_FIRE_HIT_ABOVE_MAZE_PLATFORM) || logic->CanGroundJump()));}), + Entrance(RR_FIRE_TEMPLE_CAGELESS_CHEST_ROOM, []{return true;}), + Entrance(RR_FIRE_TEMPLE_SOT_CAGE_LOWER, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 8);}), + Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_SWITCH, []{return (bool)ctx->GetTrickOption(RT_FIRE_SKIP_FLAME_WALLS);}), }); - areaTable[RR_FIRE_TEMPLE_FIRE_MAZE_UPPER] = Region("Fire Temple Fire Maze Upper", SCENE_FIRE_TEMPLE, { + areaTable[RR_FIRE_TEMPLE_FIRE_MAZE_PLATFORMS] = Region("Fire Temple Fire Maze Platforms", SCENE_FIRE_TEMPLE, { //Events EventAccess(LOGIC_FIRE_HIT_PLATFORM, []{return logic->CanUse(RG_MEGATON_HAMMER);}), }, {}, { //Exits - Entrance(RR_FIRE_TEMPLE_NEAR_BOSS_ROOM, []{return logic->CanUse(RG_MEGATON_HAMMER);}), - Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_ROOM, []{return true;}), - Entrance(RR_FIRE_TEMPLE_WEST_CENTRAL_UPPER, []{return logic->CanUse(RG_MEGATON_HAMMER);}), + Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_MAIN, []{return true;}), + Entrance(RR_FIRE_TEMPLE_SOT_CAGE_UPPER_DOOR, []{return logic->CanUse(RG_MEGATON_HAMMER);}), }); - areaTable[RR_FIRE_TEMPLE_FIRE_MAZE_SIDE_ROOM] = Region("Fire Temple Fire Maze Side Room", SCENE_FIRE_TEMPLE, {}, { + areaTable[RR_FIRE_TEMPLE_CAGELESS_CHEST_ROOM] = Region("Fire Temple Cageless Chest Room", SCENE_FIRE_TEMPLE, {}, { //Locations LOCATION(RC_FIRE_TEMPLE_COMPASS_CHEST, true), }, { //Exits - Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_ROOM, []{return true;}), + Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_MAIN, []{return true;}), }); - areaTable[RR_FIRE_TEMPLE_WEST_CENTRAL_LOWER] = Region("Fire Temple West Central Lower", SCENE_FIRE_TEMPLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_SOT_CAGE_LOWER] = Region("Fire Temple Sot Cage Lower", SCENE_FIRE_TEMPLE, {}, {}, { //Exits - Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_ROOM, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 8);}), - Entrance(RR_FIRE_TEMPLE_WEST_CENTRAL_UPPER, []{return logic->IsAdult && logic->CanUse(RG_SONG_OF_TIME);}), - Entrance(RR_FIRE_TEMPLE_LATE_FIRE_MAZE, []{return true;}), + Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_MAIN, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 8);}), + Entrance(RR_FIRE_TEMPLE_SOT_CAGE_UPPER_DOOR, []{return logic->IsAdult && logic->CanUse(RG_SONG_OF_TIME);}), + Entrance(RR_FIRE_TEMPLE_SOT_CAGE_SWITCH, []{return logic->IsAdult && logic->CanUse(RG_SONG_OF_TIME);}), + Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_SWITCH, []{return true;}), }); - areaTable[RR_FIRE_TEMPLE_WEST_CENTRAL_UPPER] = Region("Fire Temple West Central Upper", SCENE_FIRE_TEMPLE, {}, { + areaTable[RR_FIRE_TEMPLE_SOT_CAGE_UPPER_DOOR] = Region("Fire Temple Sot Cage Upper Door", SCENE_FIRE_TEMPLE, {}, {}, { + //Exits + Entrance(RR_FIRE_TEMPLE_BOSS_ENTRYWAY, []{return false;}), + Entrance(RR_FIRE_TEMPLE_SOT_CAGE_SWITCH, []{return logic->IsAdult || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_SONG_OF_TIME);}), + Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_PLATFORMS, []{return true;}), + Entrance(RR_FIRE_TEMPLE_SOT_CAGE_LOWER, []{return true;}), + }); + + areaTable[RR_FIRE_TEMPLE_SOT_CAGE_SWITCH] = Region("Fire Temple Sot Cage Switch", SCENE_FIRE_TEMPLE, {}, { //Locations LOCATION(RC_FIRE_TEMPLE_HIGHEST_GORON_CHEST, (logic->CanUse(RG_SONG_OF_TIME) || ctx->GetTrickOption(RT_RUSTED_SWITCHES)) && logic->CanUse(RG_MEGATON_HAMMER)), }, { //Exits - Entrance(RR_FIRE_TEMPLE_BOSS_ENTRYWAY, []{return false;}), - Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_UPPER, []{return true;}), - Entrance(RR_FIRE_TEMPLE_WEST_CENTRAL_LOWER, []{return true;}), + Entrance(RR_FIRE_TEMPLE_BOSS_ENTRYWAY, []{return false;}), + Entrance(RR_FIRE_TEMPLE_SOT_CAGE_UPPER_DOOR, []{return logic->IsAdult || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_SONG_OF_TIME);}), + Entrance(RR_FIRE_TEMPLE_SOT_CAGE_LOWER, []{return true;}), }); - areaTable[RR_FIRE_TEMPLE_LATE_FIRE_MAZE] = Region("Fire Temple Late Fire Maze", SCENE_FIRE_TEMPLE, {}, { + areaTable[RR_FIRE_TEMPLE_FIRE_MAZE_SWITCH] = Region("Fire Temple Fire Maze Switch", SCENE_FIRE_TEMPLE, {}, {}, { + //Exits + Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_MAIN, []{return (ctx->GetTrickOption(RT_FIRE_SKIP_FLAME_WALLS) && logic->TakeDamage()) || + (logic->IsAdult && logic->CanGroundJump() && ctx->GetTrickOption(RT_GROUND_JUMP_HARD) && (logic->CanJumpslash() || logic->CanUse(RG_HOVER_BOOTS)));}), + Entrance(RR_FIRE_TEMPLE_SOT_CAGE_LOWER, []{return true;}), + Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_PAST_WALL, []{return true;}), + }); + + areaTable[RR_FIRE_TEMPLE_FIRE_MAZE_PAST_WALL] = Region("Fire Temple Fire Maze Past Wall", SCENE_FIRE_TEMPLE, {}, { // Locations LOCATION(RC_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_1, logic->CanBreakPots()), LOCATION(RC_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_2, logic->CanBreakPots()), @@ -307,47 +366,75 @@ void RegionTable_Init_FireTemple() { LOCATION(RC_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_4, logic->CanBreakPots()), }, { //Exits - Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_ROOM, []{return false;}), - Entrance(RR_FIRE_TEMPLE_WEST_CENTRAL_LOWER, []{return true;}), - Entrance(RR_FIRE_TEMPLE_UPPER_FLARE_DANCER, []{return logic->HasExplosives();}), + Entrance(RR_FIRE_TEMPLE_3F_FLARE_DANCER, []{return logic->HasExplosives();}), }); - areaTable[RR_FIRE_TEMPLE_UPPER_FLARE_DANCER] = Region("Fire Temple Upper Flare Dancer", SCENE_FIRE_TEMPLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_3F_FLARE_DANCER] = Region("Fire Temple 3F Flare Dancer", SCENE_FIRE_TEMPLE, {}, {}, { //Exits - Entrance(RR_FIRE_TEMPLE_LATE_FIRE_MAZE, []{return AnyAgeTime([]{return logic->CanKillEnemy(RE_FLARE_DANCER);});}), - Entrance(RR_FIRE_TEMPLE_WEST_CLIMB, []{return AnyAgeTime([]{return logic->CanKillEnemy(RE_FLARE_DANCER);});}), + Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_PAST_WALL, []{return AnyAgeTime([]{return logic->CanKillEnemy(RE_FLARE_DANCER);});}), + Entrance(RR_FIRE_TEMPLE_ABOVE_3F_FLARE_DANCER, []{return AnyAgeTime([]{return logic->CanKillEnemy(RE_FLARE_DANCER);});}), }); - areaTable[RR_FIRE_TEMPLE_WEST_CLIMB] = Region("Fire Temple West Climb", SCENE_FIRE_TEMPLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_ABOVE_3F_FLARE_DANCER] = Region("Fire Temple Above 3F Flare Dancer", SCENE_FIRE_TEMPLE, {}, {}, { //Exits - Entrance(RR_FIRE_TEMPLE_UPPER_FLARE_DANCER, []{return true;}), - Entrance(RR_FIRE_TEMPLE_WEST_PEAK, []{return logic->CanUseProjectile();}), + Entrance(RR_FIRE_TEMPLE_3F_FLARE_DANCER, []{return true;}), + Entrance(RR_FIRE_TEMPLE_SWITCH_CLIMB, []{return true;}), }); - areaTable[RR_FIRE_TEMPLE_WEST_PEAK] = Region("Fire Temple West Peak", SCENE_FIRE_TEMPLE, {}, { + areaTable[RR_FIRE_TEMPLE_SWITCH_CLIMB] = Region("Fire Temple Switch Climb", SCENE_FIRE_TEMPLE, {}, {}, { + //Exits + Entrance(RR_FIRE_TEMPLE_ABOVE_3F_FLARE_DANCER, []{return true;}), + Entrance(RR_FIRE_TEMPLE_NARROW_STAIRS, []{return logic->CanHitSwitch(ED_BOMB_THROW)/* && CanUse(RG_CLIMB)*/;}), + }); + + areaTable[RR_FIRE_TEMPLE_NARROW_STAIRS] = Region("Fire Temple Narrow Stairs", SCENE_FIRE_TEMPLE, {}, { //Locations LOCATION(RC_FIRE_TEMPLE_MEGATON_HAMMER_CHEST, true), }, { //Exits - Entrance(RR_FIRE_TEMPLE_WEST_CENTRAL_UPPER, []{return logic->TakeDamage();}), - Entrance(RR_FIRE_TEMPLE_WEST_CLIMB, []{return true;}), - Entrance(RR_FIRE_TEMPLE_HAMMER_RETURN_PATH, []{return logic->CanUse(RG_MEGATON_HAMMER);}), + Entrance(RR_FIRE_TEMPLE_SOT_CAGE_UPPER_DOOR, []{return logic->TakeDamage();}), + Entrance(RR_FIRE_TEMPLE_SOT_CAGE_SWITCH, []{return logic->TakeDamage();}), + Entrance(RR_FIRE_TEMPLE_SWITCH_CLIMB, []{return true;}), + Entrance(RR_FIRE_TEMPLE_NARROW_STAIRS_4F, []{return AnyAgeTime([]{return logic->CanUse(RG_MEGATON_HAMMER);});}), }); - areaTable[RR_FIRE_TEMPLE_HAMMER_RETURN_PATH] = Region("Fire Temple Hammer Return Path", SCENE_FIRE_TEMPLE, {}, { - // Locations + areaTable[RR_FIRE_TEMPLE_NARROW_STAIRS_4F] = Region("Fire Temple Narrow Stairs 4F", SCENE_FIRE_TEMPLE, {}, {}, { + //Exits + Entrance(RR_FIRE_TEMPLE_TOP_OF_COLLAPSING_STAIRS, []{return AnyAgeTime([]{return logic->CanUse(RG_MEGATON_HAMMER);});}), + //this return path is blocked by a hammer peg that is a perm flag, if a way up is ever added, LOGIC_FIRE_MQ_HIT_SCARECROW_ROOM_PLATFORM should be reworked + Entrance(RR_FIRE_TEMPLE_NARROW_STAIRS, []{return false;}), + }); + + areaTable[RR_FIRE_TEMPLE_TOP_OF_COLLAPSING_STAIRS] = Region("Fire Temple Top of Collapsing Stairs", SCENE_FIRE_TEMPLE, { + //Events + EventAccess(LOGIC_FIRE_HIT_STAIRS, []{return logic->CanUse(RG_MEGATON_HAMMER);}), + EventAccess(LOGIC_FIRE_CHILD_AT_TOP_OF_STAIRS, []{return logic->IsChild;}), + }, { + //Locations LOCATION(RC_FIRE_TEMPLE_AFTER_HAMMER_SMALL_CRATE_1, logic->CanBreakSmallCrates()), LOCATION(RC_FIRE_TEMPLE_AFTER_HAMMER_SMALL_CRATE_2, logic->CanBreakSmallCrates()), - }, - { + }, { //Exits - Entrance(RR_FIRE_TEMPLE_ABOVE_FIRE_MAZE, []{return logic->CanUse(RG_MEGATON_HAMMER);}), + Entrance(RR_FIRE_TEMPLE_NARROW_STAIRS_4F, []{return true;}), + Entrance(RR_FIRE_TEMPLE_BASE_OF_COLLAPSING_STAIRS, []{return logic->Get(LOGIC_FIRE_HIT_STAIRS);}), }); - areaTable[RR_FIRE_TEMPLE_ABOVE_FIRE_MAZE] = Region("Fire Temple Above Fire Maze", SCENE_FIRE_TEMPLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_BASE_OF_COLLAPSING_STAIRS] = Region("Fire Temple Base of Collapsing Stairs", SCENE_FIRE_TEMPLE, {}, {}, { //Exits - Entrance(RR_FIRE_TEMPLE_HAMMER_RETURN_PATH, []{return true;}), - Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_UPPER, []{return logic->CanUse(RG_MEGATON_HAMMER);}), + Entrance(RR_FIRE_TEMPLE_TOP_OF_COLLAPSING_STAIRS, []{return logic->Get(LOGIC_FIRE_HIT_STAIRS) && logic->IsAdult;}), + // this is here to maintain 1:1 door entrances between regions + Entrance(RR_FIRE_TEMPLE_ABOVE_FIRE_MAZE, []{return logic->Get(LOGIC_FIRE_HIT_STAIRS) && (logic->IsAdult || logic->Get(LOGIC_FIRE_CHILD_AT_TOP_OF_STAIRS))/* && str0*/;}), + }); + + areaTable[RR_FIRE_TEMPLE_ABOVE_FIRE_MAZE] = Region("Fire Temple Above Fire Maze", SCENE_FIRE_TEMPLE, { + //Events + EventAccess(LOGIC_FIRE_HIT_ABOVE_MAZE_PLATFORM, []{return logic->CanUse(RG_MEGATON_HAMMER);}), + }, {}, { + //Exits + Entrance(RR_FIRE_TEMPLE_BASE_OF_COLLAPSING_STAIRS, []{return true;}), + Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_MAIN, []{return logic->Get(LOGIC_FIRE_HIT_ABOVE_MAZE_PLATFORM);}), + //it's possible to land directly on the upper platform as child and even avoid fall damage, but it's not intuitive (you have to ledge grab, drop down and then air drift with enough momentum to roll) + Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_PLATFORMS, []{return logic->Get(LOGIC_FIRE_HIT_ABOVE_MAZE_PLATFORM) && logic->CanJumpslash() && logic->TakeDamage();}), }); #pragma endregion @@ -355,44 +442,45 @@ void RegionTable_Init_FireTemple() { #pragma region MQ //potentially dangerous temp flag on the first room's torches, should be made permanent if possible - areaTable[RR_FIRE_TEMPLE_MQ_FIRST_ROOM_LOWER] = Region("Fire Temple MQ First Room Lower", SCENE_FIRE_TEMPLE, {}, { + areaTable[RR_FIRE_TEMPLE_MQ_FOYER_LOWER] = Region("Fire Temple MQ Foyer Lower", SCENE_FIRE_TEMPLE, {}, { //Locations LOCATION(RC_FIRE_TEMPLE_MQ_ENTRANCE_POT_1, logic->CanBreakPots()), LOCATION(RC_FIRE_TEMPLE_MQ_ENTRANCE_POT_2, logic->CanBreakPots()), }, { //Exits - Entrance(RR_FIRE_TEMPLE_ENTRYWAY, []{return true;}), - Entrance(RR_FIRE_TEMPLE_MQ_MAP_ROOM_SOUTH, []{return true;}), - Entrance(RR_FIRE_TEMPLE_MQ_FIRST_ROOM_UPPER, []{return logic->IsAdult || logic->CanUse(RG_HOOKSHOT) || ctx->GetTrickOption(RT_FIRE_SKIP_FLAME_WALLS);}), - Entrance(RR_FIRE_TEMPLE_MQ_STALFOS_ROOM, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 5);}), + Entrance(RR_FIRE_TEMPLE_ENTRYWAY, []{return true;}), + Entrance(RR_FIRE_TEMPLE_MQ_LOOP_CAGE_FOYER_SIDE, []{return true;}), + //child can easilly pass the flame wall with a well timed sidehop, but that's a generic version of RT_FIRE_FLAME_MAZE + Entrance(RR_FIRE_TEMPLE_MQ_FOYER_UPPER, []{return logic->IsAdult || logic->CanUse(RG_HOOKSHOT) || ctx->GetTrickOption(RT_FIRE_SKIP_FLAME_WALLS);}), + Entrance(RR_FIRE_TEMPLE_MQ_LOOP_HEXAGON_ROOM, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 5);}), }); - areaTable[RR_FIRE_TEMPLE_MQ_FIRST_ROOM_UPPER] = Region("Fire Temple MQ First Room Upper", SCENE_FIRE_TEMPLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_MQ_FOYER_UPPER] = Region("Fire Temple MQ Foyer Upper", SCENE_FIRE_TEMPLE, {}, {}, { //Exits - Entrance(RR_FIRE_TEMPLE_MQ_FIRST_ROOM_LOWER, []{return true;}), - Entrance(RR_FIRE_TEMPLE_MQ_NEAR_BOSS_ROOM, []{return logic->HasFireSource();}), - Entrance(RR_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM, []{return AnyAgeTime([]{return logic->CanUse(RG_MEGATON_HAMMER);});}), + Entrance(RR_FIRE_TEMPLE_MQ_FOYER_LOWER, []{return true;}), + Entrance(RR_FIRE_TEMPLE_MQ_NEAR_BOSS_ROOM, []{return logic->HasFireSource();}), + Entrance(RR_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM, []{return AnyAgeTime([]{return logic->CanUse(RG_MEGATON_HAMMER);});}), }); - areaTable[RR_FIRE_TEMPLE_MQ_MAP_ROOM_SOUTH] = Region("Fire Temple MQ Map Room South", SCENE_FIRE_TEMPLE, {}, { + areaTable[RR_FIRE_TEMPLE_MQ_LOOP_CAGE_FOYER_SIDE] = Region("Fire Temple MQ Loop Cage Foyer Side", SCENE_FIRE_TEMPLE, {}, { //Locations LOCATION(RC_FIRE_TEMPLE_MQ_MAP_ROOM_SIDE_CHEST, logic->CanKillEnemy(RE_LIKE_LIKE)), }, { //Exits - Entrance(RR_FIRE_TEMPLE_MQ_FIRST_ROOM_LOWER, []{return AnyAgeTime([]{return logic->CanKillEnemy(RE_LIKE_LIKE);});}), - Entrance(RR_FIRE_TEMPLE_MQ_MAP_ROOM_CAGE, []{return logic->Get(LOGIC_FIRE_OPENED_LOWEST_GORON_CAGE);}), + Entrance(RR_FIRE_TEMPLE_MQ_FOYER_LOWER, []{return AnyAgeTime([]{return logic->CanKillEnemy(RE_LIKE_LIKE);});}), + Entrance(RR_FIRE_TEMPLE_MQ_LOOP_GORON_CAGE, []{return logic->Get(LOGIC_FIRE_OPENED_LOWEST_GORON_CAGE);}), }); - areaTable[RR_FIRE_TEMPLE_MQ_STALFOS_ROOM] = Region("Fire Temple MQ Stalfos Room", SCENE_FIRE_TEMPLE, {}, { + areaTable[RR_FIRE_TEMPLE_MQ_LOOP_HEXAGON_ROOM] = Region("Fire Temple MQ Loop Hexagon Room", SCENE_FIRE_TEMPLE, {}, { //Locations LOCATION(RC_FIRE_TEMPLE_MQ_LOOP_STALFOS_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)), }, { //Exits - Entrance(RR_FIRE_TEMPLE_MQ_FIRST_ROOM_LOWER, []{return true;}), - Entrance(RR_FIRE_TEMPLE_MQ_IRON_KNUCKLE_ROOM, []{return AnyAgeTime([]{return logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2);});}), + Entrance(RR_FIRE_TEMPLE_MQ_FOYER_LOWER, []{return true;}), + Entrance(RR_FIRE_TEMPLE_MQ_LOOP_5_TILE_ROOM, []{return AnyAgeTime([]{return logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2);});}), }); - areaTable[RR_FIRE_TEMPLE_MQ_IRON_KNUCKLE_ROOM] = Region("Fire Temple MQ Iron Knuckle Room", SCENE_FIRE_TEMPLE, { + areaTable[RR_FIRE_TEMPLE_MQ_LOOP_5_TILE_ROOM] = Region("Fire Temple MQ Loop 5 Tile Room", SCENE_FIRE_TEMPLE, { //Events EventAccess(LOGIC_FAIRY_ACCESS, []{return logic->CanBreakPots();}), }, { @@ -408,92 +496,126 @@ void RegionTable_Init_FireTemple() { LOCATION(RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_8, logic->CanBreakPots()), }, { //Exits - Entrance(RR_FIRE_TEMPLE_MQ_STALFOS_ROOM, []{return true;}), - Entrance(RR_FIRE_TEMPLE_MQ_LOWER_FLARE_DANCER, []{return AnyAgeTime([]{return logic->CanKillEnemy(RE_IRON_KNUCKLE);});}), + Entrance(RR_FIRE_TEMPLE_MQ_LOOP_HEXAGON_ROOM, []{return true;}), + Entrance(RR_FIRE_TEMPLE_MQ_LOOP_FLARE_DANCER, []{return AnyAgeTime([]{return logic->CanKillEnemy(RE_IRON_KNUCKLE);});}), }); - areaTable[RR_FIRE_TEMPLE_MQ_LOWER_FLARE_DANCER] = Region("Fire Temple MQ Lower Flare Dancer", SCENE_FIRE_TEMPLE, {}, { + areaTable[RR_FIRE_TEMPLE_MQ_LOOP_FLARE_DANCER] = Region("Fire Temple MQ Loop Flare Dancer", SCENE_FIRE_TEMPLE, {}, { //Locations - LOCATION(RC_FIRE_TEMPLE_MQ_MEGATON_HAMMER_CHEST, (logic->IsAdult || logic->CanUse(RG_HOOKSHOT)) && AnyAgeTime([]{return logic->CanKillEnemy(RE_FLARE_DANCER);})), + LOCATION(RC_FIRE_TEMPLE_MQ_MEGATON_HAMMER_CHEST, (logic->IsAdult || logic->CanUse(RG_HOOKSHOT) || logic->CanGroundJump()) && AnyAgeTime([]{return logic->CanKillEnemy(RE_FLARE_DANCER);})), }, { //Exits - Entrance(RR_FIRE_TEMPLE_MQ_IRON_KNUCKLE_ROOM, []{return true;}), - Entrance(RR_FIRE_TEMPLE_MQ_MAP_ROOM_NORTH, []{return AnyAgeTime([]{return logic->CanKillEnemy(RE_FLARE_DANCER);});}), + Entrance(RR_FIRE_TEMPLE_MQ_LOOP_5_TILE_ROOM, []{return true;}), + Entrance(RR_FIRE_TEMPLE_MQ_LOOP_CAGE_SWITCH, []{return AnyAgeTime([]{return logic->CanKillEnemy(RE_FLARE_DANCER);});}), }); - areaTable[RR_FIRE_TEMPLE_MQ_MAP_ROOM_NORTH] = Region("Fire Temple MQ Map Room North", SCENE_FIRE_TEMPLE, { + areaTable[RR_FIRE_TEMPLE_MQ_LOOP_CAGE_SWITCH] = Region("Fire Temple MQ Loop Cage Switch", SCENE_FIRE_TEMPLE, { //Events EventAccess(LOGIC_FIRE_OPENED_LOWEST_GORON_CAGE, []{return logic->CanUse(RG_MEGATON_HAMMER);}), }, {}, { //Exits - Entrance(RR_FIRE_TEMPLE_MQ_LOWER_FLARE_DANCER, []{return true;}), - Entrance(RR_FIRE_TEMPLE_MQ_MAP_ROOM_CAGE, []{return logic->Get(LOGIC_FIRE_OPENED_LOWEST_GORON_CAGE);}), + Entrance(RR_FIRE_TEMPLE_MQ_LOOP_FLARE_DANCER, []{return true;}), + Entrance(RR_FIRE_TEMPLE_MQ_LOOP_GORON_CAGE, []{return logic->Get(LOGIC_FIRE_OPENED_LOWEST_GORON_CAGE);}), }); - areaTable[RR_FIRE_TEMPLE_MQ_MAP_ROOM_CAGE] = Region("Fire Temple MQ Map Room Cage", SCENE_FIRE_TEMPLE, {}, { + areaTable[RR_FIRE_TEMPLE_MQ_LOOP_GORON_CAGE] = Region("Fire Temple MQ Loop Goron Cage", SCENE_FIRE_TEMPLE, {}, { //Locations LOCATION(RC_FIRE_TEMPLE_MQ_MAP_CHEST, true), }, { //Exits - Entrance(RR_FIRE_TEMPLE_MQ_MAP_ROOM_NORTH, []{return logic->Get(LOGIC_FIRE_OPENED_LOWEST_GORON_CAGE);}), - Entrance(RR_FIRE_TEMPLE_MQ_MAP_ROOM_SOUTH, []{return logic->Get(LOGIC_FIRE_OPENED_LOWEST_GORON_CAGE);}), + Entrance(RR_FIRE_TEMPLE_MQ_LOOP_CAGE_SWITCH, []{return logic->Get(LOGIC_FIRE_OPENED_LOWEST_GORON_CAGE);}), + Entrance(RR_FIRE_TEMPLE_MQ_LOOP_CAGE_FOYER_SIDE, []{return logic->Get(LOGIC_FIRE_OPENED_LOWEST_GORON_CAGE);}), }); areaTable[RR_FIRE_TEMPLE_MQ_NEAR_BOSS_ROOM] = Region("Fire Temple MQ Near Boss Room", SCENE_FIRE_TEMPLE, {}, { //Locations //If we're using the south torch as the initial torch, or using FAs, we either have to cross to the north to remove the crate, or use a trick to ignore it - LOCATION(RC_FIRE_TEMPLE_MQ_NEAR_BOSS_CHEST, logic->FireTimer() > 25 && ctx->GetTrickOption(RT_FIRE_MQ_NEAR_BOSS) && (logic->CanUse(RG_FIRE_ARROWS) || (logic->IsAdult && logic->CanUse(RG_DINS_FIRE) && logic->CanUse(RG_FAIRY_BOW)))), - LOCATION(RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_1, logic->FireTimer() > 25 && logic->CanBreakCrates()), - LOCATION(RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_2, logic->FireTimer() > 25 && logic->CanBreakCrates()), + LOCATION(RC_FIRE_TEMPLE_MQ_NEAR_BOSS_CHEST, logic->FireTimer() >= 24 && ctx->GetTrickOption(RT_FIRE_MQ_NEAR_BOSS) && (logic->CanUse(RG_FIRE_ARROWS) || (logic->IsAdult && logic->CanUse(RG_DINS_FIRE) && logic->CanUse(RG_FAIRY_BOW)))), + LOCATION(RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_1, logic->FireTimer() >= 24 && logic->CanBreakCrates()), + LOCATION(RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_2, logic->FireTimer() >= 24 && logic->CanBreakCrates()), }, { //Exits - Entrance(RR_FIRE_TEMPLE_MQ_FIRST_ROOM_UPPER, []{return true;}), - //Child cannot make it to the north side torches without a hook without specifically bunny hood speed + hover boots - Entrance(RR_FIRE_TEMPLE_MQ_NEAR_BOSS_ROOM_NORTH, []{return logic->FireTimer() > 32 && (logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)));}), - Entrance(RR_FIRE_TEMPLE_BOSS_ENTRYWAY, []{return logic->FireTimer() >= 15 && ((logic->IsAdult && (ctx->GetTrickOption(RT_FIRE_BOSS_DOOR_JUMP) || logic->CanUse(RG_HOVER_BOOTS))) || (logic->Get(LOGIC_FIRE_HIT_PLATFORM) && (logic->IsAdult || logic->CanUse(RG_HOVER_BOOTS))));}), + Entrance(RR_FIRE_TEMPLE_MQ_FOYER_UPPER, []{return (logic->IsAdult || logic->CanUse(RG_HOVER_BOOTS)) && (logic->FireTimer() >= 16 || (logic->Get(LOGIC_FIRE_HIT_PLATFORM) && logic->FireTimer() >= 8));}), + Entrance(RR_FIRE_TEMPLE_MQ_NEAR_BOSS_TARGET, []{return logic->FireTimer() >= 32 && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS));}), + Entrance(RR_FIRE_TEMPLE_BOSS_ENTRYWAY, []{return logic->FireTimer() >= 16 && (logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && (ctx->GetTrickOption(RT_FIRE_BOSS_DOOR_JUMP) || logic->Get(LOGIC_FIRE_HIT_PLATFORM))));}), }); - //This room assumes tunic logic is handled on entry. - //Covers the upper section too, as all methods to reach this can climb up somehow - areaTable[RR_FIRE_TEMPLE_MQ_NEAR_BOSS_ROOM_NORTH] = Region("Fire Temple MQ Near Boss Room North", SCENE_FIRE_TEMPLE, {}, { + //This region assumes tunic logic is handled on entry. + areaTable[RR_FIRE_TEMPLE_MQ_NEAR_BOSS_TARGET] = Region("Fire Temple MQ Near Boss Target", SCENE_FIRE_TEMPLE, {}, { //Locations - //If we have FAs, we can just remove the crate and use those to light the torches. - //otherwise, with Dins, we first light them with dins and then either use a bow shot or to cross back over to light the other torch - //Valid ways across are adult+hovers, bunny+hovers, longshot or running through the lava and then climbing back up as adult (child can't reach the ledge). + //With Dins, we first light them with dins and then either use a bow shot or to cross back over to light the other torch. + //Only adult is tall enough to use a bow shot without climbing to UPPER + //Logical ways to cross are hovers, longshot or running through the lava and then climbing back up as adult (child can't reach the ledge). //The Damage logic here is for jumping down and running across the lava to get in dins range of the south torch //Fairies cannot be used for this as it is time sensetive, and NL is only useful with sticks as it disables other magic while in use, so it's tunic or raw damage taking ability. //testing tells me you take 3 ticks of lava damage, which is 12 internal damage or 3/4 of a heart at x1 damage multiplier, performing this run //logic->EffectiveHealth() works in half hearts for whatever reason, meaning this needs a deeper refactor to be perfect, but it should be good enough for now - LOCATION(RC_FIRE_TEMPLE_MQ_NEAR_BOSS_CHEST, logic->CanUse(RG_FIRE_ARROWS) || (logic->CanUse(RG_DINS_FIRE) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_LONGSHOT) || (logic->IsAdult && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_GORON_TUNIC) || logic->EffectiveHealth() >= 2 || (logic->CanUse(RG_NAYRUS_LOVE) && logic->CanUse(RG_STICKS))))))), + LOCATION(RC_FIRE_TEMPLE_MQ_NEAR_BOSS_CHEST, logic->CanUse(RG_DINS_FIRE) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_LONGSHOT) || (logic->IsAdult && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_GORON_TUNIC) || logic->EffectiveHealth() >= 2 || (logic->CanUse(RG_NAYRUS_LOVE) && logic->CanUse(RG_STICKS)))))), LOCATION(RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_1, logic->CanBreakPots()), LOCATION(RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_2, logic->CanBreakPots()), - LOCATION(RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_1, logic->FireTimer() > 25 && logic->CanBreakCrates()), - LOCATION(RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_2, logic->FireTimer() > 25 && logic->CanBreakCrates()), - LOCATION(RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_3, logic->CanBreakCrates()), - LOCATION(RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_4, logic->CanBreakCrates()), LOCATION(RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_5, logic->CanBreakCrates()), LOCATION(RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_6, logic->CanBreakCrates()), }, { //Exits - Entrance(RR_FIRE_TEMPLE_NEAR_BOSS_ROOM, []{return true;}), + Entrance(RR_FIRE_TEMPLE_NEAR_BOSS_ROOM, []{return true;}), + Entrance(RR_FIRE_TEMPLE_MQ_NEAR_BOSS_ROOM_UPPER, []{return logic->IsAdult || logic->CanUse(RG_HOOKSHOT);}), + }); + + //This region assumes tunic logic is handled on entry. + areaTable[RR_FIRE_TEMPLE_MQ_NEAR_BOSS_ROOM_UPPER] = Region("Fire Temple MQ Near Boss Room Upper", SCENE_FIRE_TEMPLE, {}, { + //Locations + //If we have FAs, we can just remove the crate and use those to light the torches. + //otherwise, with Dins, we first light them with dins and then use a bow shot + LOCATION(RC_FIRE_TEMPLE_MQ_NEAR_BOSS_CHEST, logic->CanUse(RG_FIRE_ARROWS) || (logic->CanUse(RG_DINS_FIRE) && logic->CanUse(RG_FAIRY_BOW))), + LOCATION(RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_3, logic->CanBreakCrates()), + LOCATION(RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_4, logic->CanBreakCrates()), + }, { + //Exits + Entrance(RR_FIRE_TEMPLE_MQ_NEAR_BOSS_TARGET, []{return true;}), }); areaTable[RR_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM] = Region("Fire Temple MQ Big Lava Room", SCENE_FIRE_TEMPLE, {}, { //Locations //I'm currently assuming the oversight version of RT_FIRE_MQ_BK_CHEST for the fire timer logic - LOCATION(RC_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST, logic->FireTimer() >= 40 && logic->HasFireSource() && logic->HasExplosives() && (logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && ctx->GetTrickOption(RT_FIRE_MQ_BLOCKED_CHEST)))), - //implies CanGetEnemyDrop(RE_GOLD_SKULLTULA) - LOCATION(RC_FIRE_TEMPLE_MQ_GS_BIG_LAVA_ROOM_OPEN_DOOR, logic->FireTimer() >= 20 && logic->CanUse(RG_MEGATON_HAMMER)), - LOCATION(RC_FIRE_TEMPLE_MQ_LAVA_ROOM_NORTH_POT, logic->CanBreakPots()), - LOCATION(RC_FIRE_TEMPLE_MQ_LAVA_ROOM_HIGH_POT, logic->CanBreakPots()), - LOCATION(RC_FIRE_TEMPLE_MQ_LAVA_ROOM_SOUTH_POT, logic->FireTimer() >= 40 && (logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_FIRE_MQ_BLOCKED_CHEST) && ((logic->IsAdult && logic->CanBreakPots()) || logic->CanUse(RG_BOOMERANG))))), + LOCATION(RC_FIRE_TEMPLE_MQ_LAVA_ROOM_NORTH_POT, logic->CanBreakPots()), + LOCATION(RC_FIRE_TEMPLE_MQ_LAVA_ROOM_HIGH_POT, logic->CanBreakPots()), + LOCATION(RC_FIRE_TEMPLE_MQ_LAVA_ROOM_SOUTH_POT, logic->FireTimer() >= 40 && (logic->CanUse(RG_HOOKSHOT) || ctx->GetTrickOption(RT_FIRE_MQ_BLOCKED_CHEST)) && logic->CanUse(RG_BOOMERANG)), }, { //Exits + Entrance(RR_FIRE_TEMPLE_MQ_FOYER_UPPER, []{return logic->FireTimer() >= 32;}), + Entrance(RR_FIRE_TEMPLE_MQ_GS_GORON_CAGE, []{return logic->FireTimer() >= 32;}), + Entrance(RR_FIRE_TEMPLE_MQ_BIG_LAVA_BLOCKED_DOOR, []{return logic->FireTimer() >= 48 && (logic->CanUse(RG_HOOKSHOT) || ((logic->IsAdult || logic->CanGroundJump()) && ctx->GetTrickOption(RT_FIRE_MQ_BLOCKED_CHEST)));}), // Fewer tunic requirements ends here - Entrance(RR_FIRE_TEMPLE_MQ_FIRST_ROOM_UPPER, []{return logic->FireTimer() >= 20;}), - Entrance(RR_FIRE_TEMPLE_MQ_ELEVATOR_ROOM, []{return logic->CanUse(RG_GORON_TUNIC) && logic->SmallKeys(SCENE_FIRE_TEMPLE, 2);}), - Entrance(RR_FIRE_TEMPLE_MQ_TORCH_FIREWALL_ROOM, []{return logic->HasFireSource() && ((logic->CanUse(RG_FAIRY_BOW) && logic->FireTimer() >= 25) || (ctx->GetTrickOption(RT_FIRE_MQ_BK_CHEST) && logic->FireTimer() >= 50)) && (logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && ctx->GetTrickOption(RT_FIRE_SOT)));}), + Entrance(RR_FIRE_TEMPLE_MQ_LAVA_GEYSER_1F, []{return logic->CanUse(RG_GORON_TUNIC) && logic->SmallKeys(SCENE_FIRE_TEMPLE, 2);}), + Entrance(RR_FIRE_TEMPLE_MQ_TORCH_FIREWALL_ROOM, []{return logic->HasFireSource() && ((logic->CanUse(RG_FAIRY_BOW) && logic->FireTimer() >= 32) || (ctx->GetTrickOption(RT_FIRE_MQ_BK_CHEST) && logic->FireTimer() >= 56)) && (logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && ctx->GetTrickOption(RT_FIRE_SOT)));}), + }); + + //Tunic timers from other doors are handled on entry from RR_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM + //Specifically the tiled platform, not the ground underneath + areaTable[RR_FIRE_TEMPLE_MQ_BIG_LAVA_BLOCKED_DOOR] = Region("Fire Temple MQ Big Lava Blocked Door", SCENE_FIRE_TEMPLE, {}, { + //Locations + LOCATION(RC_FIRE_TEMPLE_MQ_LAVA_ROOM_SOUTH_POT, logic->CanBreakPots() && logic->FireTimer() >= 8), + }, { + //Exits + Entrance(RR_FIRE_TEMPLE_MQ_TORCH_LOCKED_CAGE, []{return logic->HasExplosives();}), + }); + + areaTable[RR_FIRE_TEMPLE_MQ_GS_GORON_CAGE] = Region("Fire Temple MQ GS Goron Cage", SCENE_FIRE_TEMPLE, {}, { + //Locations + //implies CanGetEnemyDrop(RE_GOLD_SKULLTULA) + LOCATION(RC_FIRE_TEMPLE_MQ_GS_BIG_LAVA_ROOM_OPEN_DOOR, logic->CanUse(RG_MEGATON_HAMMER)), + }, { + //Exits + Entrance(RR_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM, []{return true;}), + }); + + areaTable[RR_FIRE_TEMPLE_MQ_TORCH_LOCKED_CAGE] = Region("Fire Temple MQ Torch Locked Cage", SCENE_FIRE_TEMPLE, {}, { + //Locations + LOCATION(RC_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST, logic->HasFireSource()), + }, { + //Exits + Entrance(RR_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM, []{return true;}), }); areaTable[RR_FIRE_TEMPLE_MQ_TORCH_FIREWALL_ROOM] = Region("Fire Temple MQ Torch Firewall Room", SCENE_FIRE_TEMPLE, { @@ -509,39 +631,100 @@ void RegionTable_Init_FireTemple() { Entrance(RR_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM, []{return true;}), }); - //This room assumes Goron Tunic until looser tunic requirements tricks are made - areaTable[RR_FIRE_TEMPLE_MQ_ELEVATOR_ROOM] = Region("Fire Temple MQ Elevator Room", SCENE_FIRE_TEMPLE, {}, { + areaTable[RR_FIRE_TEMPLE_MQ_LAVA_GEYSER_1F] = Region("Fire Temple MQ Lava Geyser 1F", SCENE_FIRE_TEMPLE, {}, { //Locations LOCATION(RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_LEFT_HEART, true), LOCATION(RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_RIGHT_HEART, true), LOCATION(RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_LOWER_HEART, true), }, { //Exits - Entrance(RR_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM, []{return true;}), - Entrance(RR_FIRE_TEMPLE_MQ_BIG_TORCH_ROOM, []{return true;}), + Entrance(RR_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM, []{return true;}), + Entrance(RR_FIRE_TEMPLE_MQ_LAVA_GEYSER_GRATE, []{return logic->FireTimer() >= 40/* && CanClimbHigh()*/;}), + //this technically only reaches torch pillar, but the heart pillar can be reached from there with longshot + Entrance(RR_FIRE_TEMPLE_MQ_LAVA_GEYSER_PILLARS, []{return logic->FireTimer() >= 40 && logic->CanUse(RG_LONGSHOT);}), }); - - areaTable[RR_FIRE_TEMPLE_MQ_BIG_TORCH_ROOM] = Region("Fire Temple MQ Big Torch Room", SCENE_FIRE_TEMPLE, {}, {}, { - //Exits - Entrance(RR_FIRE_TEMPLE_MQ_LOWER_MAZE, []{return (logic->HasFireSource() && logic->CanUse(RG_HOOKSHOT)) || (ctx->GetTrickOption(RT_FIRE_MQ_CLIMB) && logic->CanUse(RG_HOVER_BOOTS));}), - Entrance(RR_FIRE_TEMPLE_MQ_ELEVATOR_ROOM, []{return logic->CanUse(RG_GORON_TUNIC);}), - Entrance(RR_FIRE_TEMPLE_MQ_MAZE_SHORTCUT_CAGE, []{return logic->Get(LOGIC_FIRE_OPENED_UPPER_SHORTCUT);}), - }); - - areaTable[RR_FIRE_TEMPLE_MQ_LOWER_MAZE] = Region("Fire Temple MQ Lower Maze", SCENE_FIRE_TEMPLE, {}, { + + //tunic logic handled on entry + areaTable[RR_FIRE_TEMPLE_MQ_LAVA_GEYSER_GRATE] = Region("Fire Temple MQ Lava Geyser Grate", SCENE_FIRE_TEMPLE, {}, { //Locations - //Check handled on both floors - LOCATION(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_SIDE_ROOM_CHEST, logic->HasExplosives() && ctx->GetTrickOption(RT_FIRE_MQ_MAZE_SIDE_ROOM)), - }, { + LOCATION(RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_LEFT_HEART, true), + LOCATION(RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_RIGHT_HEART, true), + }, { //Exits - Entrance(RR_FIRE_TEMPLE_MQ_BIG_TORCH_ROOM, []{return true;}), - //Explosives can also reach this room. Chus is relatively simple, they need to detonate on the first horizontal bar up from the floor while horizontally near the switch, but bombs are much harder - Entrance(RR_FIRE_TEMPLE_MQ_LOWER_MAZE_CRATE_CAGE, []{return AnyAgeTime([]{return logic->CanJumpslash();});}), - //it's possible to make the RT_FIRE_MQ_MAZE_HOVERS as child using bunny hood jumps, but not adult as adult bonks - Entrance(RR_FIRE_TEMPLE_MQ_UPPER_MAZE, []{return logic->HasExplosives() && logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_HOOKSHOT);}), + Entrance(RR_FIRE_TEMPLE_MQ_LAVA_GEYSER_1F, []{return true;}), + Entrance(RR_FIRE_TEMPLE_MQ_LAVA_GEYSER_PILLARS, []{return true;}), }); - areaTable[RR_FIRE_TEMPLE_MQ_LOWER_MAZE_CRATE_CAGE] = Region("Fire Temple MQ Lower Maze Crate Cage", SCENE_FIRE_TEMPLE, {}, { + //tunic logic handled on entry + areaTable[RR_FIRE_TEMPLE_MQ_LAVA_GEYSER_PILLARS] = Region("Fire Temple MQ Lava Geyser Pillars", SCENE_FIRE_TEMPLE, {}, { + //Locations + //rang can get the other 2 hearts from here but it's an awkward shot so a trick + LOCATION(RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_LOWER_HEART, true), + }, { + //Exits + Entrance(RR_FIRE_TEMPLE_MQ_LAVA_GEYSER_1F, []{return true;}), + Entrance(RR_FIRE_TEMPLE_MQ_LAVA_GEYSER_GRATE, []{return logic->CanUse(RG_HOOKSHOT);}), + Entrance(RR_FIRE_TEMPLE_MQ_LAVA_GEYSER_2F, []{return true;}), + }); + + areaTable[RR_FIRE_TEMPLE_MQ_LAVA_GEYSER_2F] = Region("Fire Temple MQ Lava Geyser 2F", SCENE_FIRE_TEMPLE, {}, { + }, { + //Exits + //the block lift does some janky stuff that makes leave sideways while on it difficult, so you can't avoid fall damage if you want to land on pillars. + //you can still move "backwards" into the door though and with a roll jump onto the grate, which avoids damage + Entrance(RR_FIRE_TEMPLE_MQ_LAVA_GEYSER_1F, []{return logic->FireTimer() >= 24;}), + Entrance(RR_FIRE_TEMPLE_MQ_LAVA_GEYSER_PILLARS, []{return logic->TakeDamage() && logic->FireTimer() >= 24;}), + Entrance(RR_FIRE_TEMPLE_MQ_SHORTCUT_ROOM_LOWER, []{return true;}), + }); + + areaTable[RR_FIRE_TEMPLE_MQ_SHORTCUT_ROOM_LOWER] = Region("Fire Temple MQ Shortcut Room Lower", SCENE_FIRE_TEMPLE, {}, {}, { + //Exits + Entrance(RR_FIRE_TEMPLE_MQ_SHORTCUT_ROOM_MID, []{return (logic->HasFireSource() && (logic->IsAdult || (logic->CanUse(RG_HOOKSHOT)/* && (CanUse(RG_CLIMB)*/))) || + (ctx->GetTrickOption(RT_FIRE_MQ_CLIMB) && logic->CanUse(RG_HOVER_BOOTS)/*&& CanUse(RG_CLIMB)*/);}), + Entrance(RR_FIRE_TEMPLE_MQ_LAVA_GEYSER_2F, []{return true;}), + Entrance(RR_FIRE_TEMPLE_MQ_SHORTCUT_CAGE, []{return logic->Get(LOGIC_FIRE_OPENED_UPPER_SHORTCUT);}), + }); + + //specifically the foot of the final grate, where the lizalfos spawns + areaTable[RR_FIRE_TEMPLE_MQ_SHORTCUT_ROOM_MID] = Region("Fire Temple MQ Shortcut Room Middle", SCENE_FIRE_TEMPLE, {}, {}, { + //Exits + Entrance(RR_FIRE_TEMPLE_MQ_SHORTCUT_ROOM_LOWER, []{return true;}), + Entrance(RR_FIRE_TEMPLE_MQ_SHORTCUT_ROOM_3F, []{return true/*(logic->CanUse(RG_HOOKSHOT) || (CanUse(RG_CLIMB))*/;}), + }); + + areaTable[RR_FIRE_TEMPLE_MQ_SHORTCUT_ROOM_3F] = Region("Fire Temple MQ Shortcut Room 3F", SCENE_FIRE_TEMPLE, {}, {}, { + //Exits + Entrance(RR_FIRE_TEMPLE_MQ_SHORTCUT_ROOM_MID, []{return true;}), + Entrance(RR_FIRE_TEMPLE_MQ_LOWER_LIZALFOS_MAZE, []{return true;}), + }); + + areaTable[RR_FIRE_TEMPLE_MQ_LOWER_LIZALFOS_MAZE] = Region("Fire Temple MQ Lower Lizalfos Maze", SCENE_FIRE_TEMPLE, {}, {}, { + //Exits + Entrance(RR_FIRE_TEMPLE_MQ_SHORTCUT_ROOM_LOWER, []{return true;}), + //Explosives can also reach this room. Chus is relatively simple, they need to detonate on the first horizontal bar up from the floor while horizontally near the switch, but bombs are much harder + Entrance(RR_FIRE_TEMPLE_MQ_MAZE_CRATE_CAGE, []{return AnyAgeTime([]{return logic->CanJumpslash();});}), + //it's possible to make the RT_FIRE_MQ_MAZE_HOVERS as child using bunny hood jumps, but not adult as adult bonks + Entrance(RR_FIRE_TEMPLE_MQ_UPPER_LIZALFOS_MAZE, []{return (logic->HasExplosives() || ctx->GetTrickOption(RT_RUSTED_SWITCHES)) && logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_HOOKSHOT);}), + Entrance(RR_FIRE_TEMPLE_MQ_MAZE_SWITCH_DOOR, []{return logic->HasExplosives() && ctx->GetTrickOption(RT_FIRE_MQ_MAZE_SIDE_ROOM);}), + Entrance(RR_FIRE_TEMPLE_MQ_NARROW_PATH_ROOM, []{return false;}), + }); + + areaTable[RR_FIRE_TEMPLE_MQ_MAZE_SWITCH_DOOR] = Region("Fire Temple MQ Maze Switch Door", SCENE_FIRE_TEMPLE, {}, {}, { + //Exits + //This exists to join upper/lower access in a way compatible with door shuffle + Entrance(RR_FIRE_TEMPLE_MQ_LOWER_LIZALFOS_MAZE, []{return true;}), + Entrance(RR_FIRE_TEMPLE_MQ_3F_CURVED_CAGE, []{return true;}), + }); + + areaTable[RR_FIRE_TEMPLE_MQ_3F_CURVED_CAGE] = Region("Fire Temple MQ 3F Curved Cage", SCENE_FIRE_TEMPLE, {}, { + //Locations + LOCATION(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_SIDE_ROOM_CHEST, true), + }, { + //Exits + Entrance(RR_FIRE_TEMPLE_MQ_MAZE_SWITCH_DOOR, []{return true;}), + }); + + areaTable[RR_FIRE_TEMPLE_MQ_MAZE_CRATE_CAGE] = Region("Fire Temple MQ Maze Crate Cage", SCENE_FIRE_TEMPLE, {}, { //Locations LOCATION(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CHEST, true), LOCATION(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CRATE_1, logic->CanBreakCrates()), @@ -549,24 +732,24 @@ void RegionTable_Init_FireTemple() { LOCATION(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CRATE_3, logic->CanBreakCrates()), }, { //Exits - Entrance(RR_FIRE_TEMPLE_MQ_LOWER_MAZE, []{return true;}), + Entrance(RR_FIRE_TEMPLE_MQ_LOWER_LIZALFOS_MAZE, []{return true;}), //it's possible to make the RT_FIRE_MQ_MAZE_HOVERS as child using bunny hood jumps, but not adult as adult bonks - Entrance(RR_FIRE_TEMPLE_MQ_UPPER_MAZE, []{return logic->IsAdult && ((ctx->GetTrickOption(RT_FIRE_MQ_MAZE_HOVERS) && logic->CanUse(RG_HOVER_BOOTS)) || ctx->GetTrickOption(RT_FIRE_MQ_MAZE_JUMP));}), + Entrance(RR_FIRE_TEMPLE_MQ_UPPER_LIZALFOS_MAZE, []{return logic->IsAdult && ((ctx->GetTrickOption(RT_FIRE_MQ_MAZE_HOVERS) && logic->CanUse(RG_HOVER_BOOTS)) || ctx->GetTrickOption(RT_FIRE_MQ_MAZE_JUMP));}), }); - areaTable[RR_FIRE_TEMPLE_MQ_UPPER_MAZE] = Region("Fire Temple MQ Upper Maze", SCENE_FIRE_TEMPLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_MQ_UPPER_LIZALFOS_MAZE] = Region("Fire Temple MQ Upper Lizalfos Maze", SCENE_FIRE_TEMPLE, {}, {}, { //Exits - Entrance(RR_FIRE_TEMPLE_MQ_LOWER_MAZE, []{return true;}), + Entrance(RR_FIRE_TEMPLE_MQ_LOWER_LIZALFOS_MAZE, []{return true;}), //this cage is much more lenient than the lower cage as the switch is close to the front. sling, rang and bow all hit the switch easily, though might be too unintuitive for default logic //This shouldn't come up in most cases anyway as most methods to get here need either a melee weapon or explosives - Entrance(RR_FIRE_TEMPLE_MQ_UPPER_MAZE_BOX_CAGE, []{return AnyAgeTime([]{return logic->CanJumpslash() || logic->HasExplosives();});}), - Entrance(RR_FIRE_TEMPLE_MQ_MAZE_SHORTCUT, []{return logic->HasExplosives();}), - //Implies RR_FIRE_TEMPLE_MQ_LOWER_MAZE access - Entrance(RR_FIRE_TEMPLE_MQ_BURNING_BLOCK_CLIMB, []{return logic->HasExplosives() && logic->CanUse(RG_MEGATON_HAMMER) && (logic->CanUse(RG_LONGSHOT) || (logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_SONG_OF_TIME)));}), + Entrance(RR_FIRE_TEMPLE_MQ_MAZE_BOX_CAGE, []{return AnyAgeTime([]{return logic->CanJumpslash() || logic->HasExplosives();});}), + Entrance(RR_FIRE_TEMPLE_MQ_SHORTCUT_CLIMB, []{return logic->HasExplosives();}), + //Implies RR_FIRE_TEMPLE_MQ_LOWER_LIZALFOS_MAZE access + Entrance(RR_FIRE_TEMPLE_MQ_ABOVE_MAZE, []{return logic->HasExplosives() && logic->CanUse(RG_MEGATON_HAMMER) && (logic->CanUse(RG_LONGSHOT) || (logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_SONG_OF_TIME)));}), Entrance(RR_FIRE_TEMPLE_MQ_HIGH_TORCH_ROOM, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 3) && logic->CanUse(RG_GORON_TUNIC);}), }); - areaTable[RR_FIRE_TEMPLE_MQ_UPPER_MAZE_BOX_CAGE] = Region("Fire Temple MQ Upper Maze Box Cage", SCENE_FIRE_TEMPLE, {}, { + areaTable[RR_FIRE_TEMPLE_MQ_MAZE_BOX_CAGE] = Region("Fire Temple MQ Maze Box Cage", SCENE_FIRE_TEMPLE, {}, { //Locations LOCATION(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CHEST, true), LOCATION(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CRATE_1, logic->CanBreakCrates()), @@ -574,49 +757,62 @@ void RegionTable_Init_FireTemple() { LOCATION(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CRATE_3, logic->CanBreakCrates()), LOCATION(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_SMALL_CRATE_1, logic->CanBreakSmallCrates()), LOCATION(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_SMALL_CRATE_2, logic->CanBreakSmallCrates()), + }, { + //Exits + Entrance(RR_FIRE_TEMPLE_MQ_UPPER_LIZALFOS_MAZE, []{return true;}), //Assumes maze access - LOCATION(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_SIDE_ROOM_CHEST, logic->HasExplosives()), - }, { - //Exits - Entrance(RR_FIRE_TEMPLE_MQ_UPPER_MAZE, []{return true;}), + Entrance(RR_FIRE_TEMPLE_MQ_MAZE_SWITCH_DOOR, []{return logic->HasExplosives()/* && str0*/;}), }); - areaTable[RR_FIRE_TEMPLE_MQ_MAZE_SHORTCUT] = Region("Fire Temple MQ Maze Shortcut", SCENE_FIRE_TEMPLE, { + areaTable[RR_FIRE_TEMPLE_MQ_ABOVE_MAZE] = Region("Fire Temple MQ Above Maze", SCENE_FIRE_TEMPLE, {}, {}, { + //Exits + Entrance(RR_FIRE_TEMPLE_MQ_UPPER_LIZALFOS_MAZE, []{return true;}), + Entrance(RR_FIRE_TEMPLE_MQ_TORCH_SLUG_CLIMB, []{return true;}), + }); + + areaTable[RR_FIRE_TEMPLE_MQ_SHORTCUT_CLIMB] = Region("Fire Temple MQ Shortcut Climb", SCENE_FIRE_TEMPLE, { //Events - EventAccess(LOGIC_FIRE_OPENED_UPPER_SHORTCUT, []{return logic->CanUse(RG_MEGATON_HAMMER);}), - }, {}, { - //Exits - Entrance(RR_FIRE_TEMPLE_MQ_UPPER_MAZE, []{return true;}), - Entrance(RR_FIRE_TEMPLE_MQ_MAZE_SHORTCUT_CAGE, []{return logic->Get(LOGIC_FIRE_OPENED_UPPER_SHORTCUT);}), - }); - - areaTable[RR_FIRE_TEMPLE_MQ_MAZE_SHORTCUT_CAGE] = Region("Fire Temple MQ Maze Shortcut Cage", SCENE_FIRE_TEMPLE, {}, { + EventAccess(LOGIC_FIRE_OPENED_UPPER_SHORTCUT, []{return logic->CanUse(RG_MEGATON_HAMMER);}), + }, { //Locations - LOCATION(RC_FIRE_TEMPLE_MQ_COMPASS_CHEST, logic->Get(LOGIC_FIRE_OPENED_UPPER_SHORTCUT);), - LOCATION(RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_1, logic->Get(LOGIC_FIRE_OPENED_UPPER_SHORTCUT) && logic->CanBreakCrates()), - LOCATION(RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_2, logic->Get(LOGIC_FIRE_OPENED_UPPER_SHORTCUT) && logic->CanBreakCrates()), - LOCATION(RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_3, logic->Get(LOGIC_FIRE_OPENED_UPPER_SHORTCUT) && logic->CanBreakCrates()), - LOCATION(RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_4, logic->Get(LOGIC_FIRE_OPENED_UPPER_SHORTCUT) && logic->CanBreakCrates()), - LOCATION(RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_5, logic->Get(LOGIC_FIRE_OPENED_UPPER_SHORTCUT) && logic->CanBreakCrates()), - LOCATION(RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_6, logic->Get(LOGIC_FIRE_OPENED_UPPER_SHORTCUT) && logic->CanBreakCrates()), + LOCATION(RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_1, logic->CanBreakCrates()), + LOCATION(RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_2, logic->CanBreakCrates()), + LOCATION(RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_3, logic->CanBreakCrates()), + LOCATION(RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_4, logic->CanBreakCrates()), + LOCATION(RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_5, logic->CanBreakCrates()), + LOCATION(RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_6, logic->CanBreakCrates()), }, { //Exits - Entrance(RR_FIRE_TEMPLE_MQ_MAZE_SHORTCUT, []{return logic->Get(LOGIC_FIRE_OPENED_UPPER_SHORTCUT);}), - Entrance(RR_FIRE_TEMPLE_MQ_BIG_TORCH_ROOM, []{return logic->Get(LOGIC_FIRE_OPENED_UPPER_SHORTCUT);}), + Entrance(RR_FIRE_TEMPLE_MQ_UPPER_LIZALFOS_MAZE, []{return true/*CanUse(RG_CLIMB)*/;}), + Entrance(RR_FIRE_TEMPLE_MQ_SHORTCUT_CAGE, []{return logic->Get(LOGIC_FIRE_OPENED_UPPER_SHORTCUT);}), }); + areaTable[RR_FIRE_TEMPLE_MQ_SHORTCUT_CAGE] = Region("Fire Temple MQ Shortcut Cage", SCENE_FIRE_TEMPLE, {}, { + //Locations + LOCATION(RC_FIRE_TEMPLE_MQ_COMPASS_CHEST, true), + }, { + //Exits + Entrance(RR_FIRE_TEMPLE_MQ_SHORTCUT_CLIMB, []{return logic->Get(LOGIC_FIRE_OPENED_UPPER_SHORTCUT);}), + Entrance(RR_FIRE_TEMPLE_MQ_SHORTCUT_ROOM_LOWER, []{return logic->Get(LOGIC_FIRE_OPENED_UPPER_SHORTCUT);}), + }); - areaTable[RR_FIRE_TEMPLE_MQ_BURNING_BLOCK_CLIMB] = Region("Fire Temple MQ Burning Block Climb", SCENE_FIRE_TEMPLE, { + areaTable[RR_FIRE_TEMPLE_MQ_TORCH_SLUG_CLIMB] = Region("Fire Temple MQ Torch Slug Climb", SCENE_FIRE_TEMPLE, { //Events EventAccess(LOGIC_FAIRY_ACCESS, []{return logic->CanUse(RG_HOOKSHOT);}), - }, { + }, {}, { + //Exits + Entrance(RR_FIRE_TEMPLE_MQ_ABOVE_MAZE, []{return true;}), + Entrance(RR_FIRE_TEMPLE_MQ_BURNING_BLOCK, []{return logic->CanUse(RG_HOOKSHOT)/*&& CanUse(RG_CLIMB)*/;}), + }); + + areaTable[RR_FIRE_TEMPLE_MQ_BURNING_BLOCK] = Region("Fire Temple MQ Burning Block", SCENE_FIRE_TEMPLE, {}, { //Locations //There's definitely ways to do this hammerless, but with one points on it's a trick - LOCATION(RC_FIRE_TEMPLE_MQ_GS_SKULL_ON_FIRE, logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_FIRE_TEMPLE_MQ_GS_SKULL_ON_FIRE, logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_HOOKSHOT)/* && (str0 || ctx->GetTrickOption(RT_HOOKSHOT_EXTENSION))*/), }, { //Exits - Entrance(RR_FIRE_TEMPLE_MQ_UPPER_MAZE, []{return true;}), - Entrance(RR_FIRE_TEMPLE_MQ_NARROW_PATH_ROOM, []{return logic->TakeDamage();}), + Entrance(RR_FIRE_TEMPLE_MQ_TORCH_SLUG_CLIMB, []{return true;}), + Entrance(RR_FIRE_TEMPLE_MQ_NARROW_PATH_ROOM, []{return logic->TakeDamage();}), }); areaTable[RR_FIRE_TEMPLE_MQ_NARROW_PATH_ROOM] = Region("Fire Temple MQ Narrow Path Room", SCENE_FIRE_TEMPLE, { @@ -629,33 +825,71 @@ void RegionTable_Init_FireTemple() { LOCATION(RC_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_3, logic->CanBreakPots()), }, { //Exits - Entrance(RR_FIRE_TEMPLE_MQ_LOWER_MAZE, []{return true;}), - Entrance(RR_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM, []{return logic->TakeDamage();}), + Entrance(RR_FIRE_TEMPLE_MQ_LOWER_LIZALFOS_MAZE, []{return true;}), + Entrance(RR_FIRE_TEMPLE_MQ_HIGH_TORCH_ROOM, []{return false;}), + Entrance(RR_FIRE_TEMPLE_MQ_HIGH_TORCH_ROOM_CAGE, []{return false;}), + Entrance(RR_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM, []{return logic->TakeDamage();}), }); - areaTable[RR_FIRE_TEMPLE_MQ_HIGH_TORCH_ROOM] = Region("Fire Temple MQ High Torch Room", SCENE_FIRE_TEMPLE, {}, { + areaTable[RR_FIRE_TEMPLE_MQ_HIGH_TORCH_ROOM] = Region("Fire Temple MQ High Torch Room", SCENE_FIRE_TEMPLE, { + //Events + EventAccess(LOGIC_FIRE_MQ_HIGH_TORCH_LIT, []{return (logic->CanUse(RG_FIRE_ARROWS) && logic->FireTimer() >= 24);}), + }, { //Locations - LOCATION(RC_FIRE_TEMPLE_MQ_FLAME_WALL_POT_1, logic->CanBreakPots()), - LOCATION(RC_FIRE_TEMPLE_MQ_FLAME_WALL_POT_2, logic->CanBreakPots()), - LOCATION(RC_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_1, logic->CanBreakCrates()), - LOCATION(RC_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_2, logic->CanBreakCrates()), - LOCATION(RC_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_3, logic->CanBreakCrates()), - LOCATION(RC_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_4, logic->CanBreakCrates()), - LOCATION(RC_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_5, logic->CanBreakCrates()), - LOCATION(RC_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_1, logic->CanBreakSmallCrates()), - LOCATION(RC_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_2, logic->CanBreakSmallCrates()), - LOCATION(RC_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_3, logic->CanBreakSmallCrates()), - LOCATION(RC_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_4, logic->CanBreakSmallCrates()), - LOCATION(RC_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_5, logic->CanBreakSmallCrates()), + LOCATION(RC_FIRE_TEMPLE_MQ_FLAME_WALL_POT_1, logic->CanBreakPots() && logic->FireTimer() >= 24), + LOCATION(RC_FIRE_TEMPLE_MQ_FLAME_WALL_POT_2, logic->CanBreakPots() && logic->FireTimer() >= 24), + LOCATION(RC_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_1, logic->CanBreakCrates() && logic->FireTimer() >= 24), + LOCATION(RC_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_3, logic->CanBreakCrates() && logic->FireTimer() >= 24), + LOCATION(RC_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_4, logic->CanBreakCrates() && logic->FireTimer() >= 16), + LOCATION(RC_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_2, logic->CanBreakSmallCrates() && logic->FireTimer() >= 24), + LOCATION(RC_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_3, logic->CanBreakSmallCrates() && logic->FireTimer() >= 16), }, { //Exits - Entrance(RR_FIRE_TEMPLE_MQ_UPPER_MAZE, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 3);}), - Entrance(RR_FIRE_TEMPLE_MQ_NARROW_PATH_ROOM, []{return true;}), + Entrance(RR_FIRE_TEMPLE_MQ_HIGH_TORCH_ROOM_ABOVE_CAGE, []{return (logic->IsAdult || logic->CanUse(RG_HOOKSHOT)) && logic->FireTimer() >= 24;}), + Entrance(RR_FIRE_TEMPLE_MQ_UPPER_LIZALFOS_MAZE, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 3) && logic->FireTimer() >= 24;}), + Entrance(RR_FIRE_TEMPLE_MQ_NARROW_PATH_ROOM, []{return logic->FireTimer() >= 24;}), //Child has issues navigating the higher points of this room without an equip swapped hookshot - Entrance(RR_FIRE_TEMPLE_MQ_SOUTH_FIRE_MAZE, []{return AnyAgeTime([]{return logic->CanUse(RG_FIRE_ARROWS) || (logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_HOOKSHOT));}) && (logic->IsAdult || logic->CanUse(RG_HOOKSHOT));}), + Entrance(RR_FIRE_TEMPLE_MQ_CORRIDOR, []{return logic->Get(LOGIC_FIRE_MQ_HIGH_TORCH_LIT) && (logic->IsAdult || logic->CanUse(RG_HOOKSHOT)) && logic->FireTimer() >= 16;}), }); - areaTable[RR_FIRE_TEMPLE_MQ_SOUTH_FIRE_MAZE] = Region("Fire Temple MQ South Fire Maze", SCENE_FIRE_TEMPLE, {}, { + areaTable[RR_FIRE_TEMPLE_MQ_HIGH_TORCH_ROOM_BARRED_DOOR] = Region("Fire Temple MQ High Torch Barred Door", SCENE_FIRE_TEMPLE, {}, { + //Locations + LOCATION(RC_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_2, logic->CanBreakCrates() && logic->FireTimer() >= 8), + LOCATION(RC_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_1, logic->CanBreakSmallCrates() && logic->FireTimer() >= 8), + }, { + //Exits + Entrance(RR_FIRE_TEMPLE_MQ_HIGH_TORCH_ROOM, []{return true;}), + Entrance(RR_FIRE_TEMPLE_MQ_CORRIDOR, []{return logic->Get(LOGIC_FIRE_MQ_HIGH_TORCH_LIT);}), + }); + + areaTable[RR_FIRE_TEMPLE_MQ_HIGH_TORCH_ROOM_ABOVE_CAGE] = Region("Fire Temple MQ High Torch Room Above Cage", SCENE_FIRE_TEMPLE, { + //Events + EventAccess(LOGIC_FIRE_MQ_HIGH_TORCH_LIT, []{return ((logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_HOOKSHOT)/*&& str0*/) && logic->FireTimer() >= 48);}), + }, { + //Locations + //Tunic logic for these checks is handled on entry + LOCATION(RC_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_5, logic->CanBreakCrates()), + LOCATION(RC_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_4, logic->CanBreakSmallCrates()), + LOCATION(RC_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_5, logic->CanBreakSmallCrates()), + }, { + //Exits + Entrance(RR_FIRE_TEMPLE_MQ_HIGH_TORCH_ROOM, []{return true;}), + Entrance(RR_FIRE_TEMPLE_MQ_HIGH_TORCH_ROOM_CAGE, []{return true;}), + }); + + areaTable[RR_FIRE_TEMPLE_MQ_HIGH_TORCH_ROOM_CAGE] = Region("Fire Temple MQ High Torch Room Cage", SCENE_FIRE_TEMPLE, {}, {}, { + //Exits + Entrance(RR_FIRE_TEMPLE_MQ_HIGH_TORCH_ROOM_ABOVE_CAGE, []{return logic->CanUse(RG_HOOKSHOT) && logic->FireTimer() >= 8;}), + Entrance(RR_FIRE_TEMPLE_MQ_NARROW_PATH_ROOM, []{return true;}), + }); + + areaTable[RR_FIRE_TEMPLE_MQ_CORRIDOR] = Region("Fire Temple Corridor", SCENE_FIRE_TEMPLE, {}, {}, { + //Exits + Entrance(RR_FIRE_TEMPLE_MQ_HIGH_TORCH_ROOM_BARRED_DOOR, []{return true;}), + Entrance(RR_FIRE_TEMPLE_MQ_FIRE_MAZE_MAIN, []{return true;}), + }); + + areaTable[RR_FIRE_TEMPLE_MQ_FIRE_MAZE_MAIN] = Region("Fire Temple MQ Fire Maze Main", SCENE_FIRE_TEMPLE, {}, { //Locations LOCATION(RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_CENTER, logic->HasExplosives()), LOCATION(RC_FIRE_TEMPLE_MQ_SOUTH_FIRE_MAZE_WEST_POT, logic->CanBreakPots()), @@ -663,80 +897,157 @@ void RegionTable_Init_FireTemple() { }, { //Exits Entrance(RR_FIRE_TEMPLE_MQ_NEAR_BOSS_ROOM, []{return logic->Get(LOGIC_FIRE_HIT_PLATFORM);}), - Entrance(RR_FIRE_TEMPLE_MQ_HIGH_TORCH_ROOM, []{return true;}), + Entrance(RR_FIRE_TEMPLE_MQ_CORRIDOR, []{return true;}), Entrance(RR_FIRE_TEMPLE_MQ_FIRE_MAZE_PLATFORMS, []{return logic->IsAdult || logic->CanUse(RG_SONG_OF_TIME) || logic->CanUse(RG_HOVER_BOOTS);}), //Hover boots get there via the platforms - Entrance(RR_FIRE_TEMPLE_MQ_NORTH_FIRE_MAZE, []{return (bool)ctx->GetTrickOption(RT_FIRE_SKIP_FLAME_WALLS);}), - Entrance(RR_FIRE_TEMPLE_MQ_WEST_FIRE_MAZE, []{return logic->Get(LOGIC_FIRE_MQ_OPENED_FIRE_MAZE_DOOR);}), + Entrance(RR_FIRE_TEMPLE_MQ_FIRE_MAZE_MIDDLE, []{return (bool)ctx->GetTrickOption(RT_FIRE_SKIP_FLAME_WALLS);}), + Entrance(RR_FIRE_TEMPLE_MQ_2_FIRE_WALLS_LOWER, []{return true;}), }); areaTable[RR_FIRE_TEMPLE_MQ_FIRE_MAZE_PLATFORMS] = Region("Fire Temple MQ Fire Maze Platforms", SCENE_FIRE_TEMPLE, { //Events - EventAccess(LOGIC_FIRE_HIT_PLATFORM, []{return logic->CanUse(RG_MEGATON_HAMMER);}), - EventAccess(LOGIC_FIRE_MQ_OPENED_FIRE_MAZE_DOOR, []{return logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_HOOKSHOT);}), + EventAccess(LOGIC_FIRE_HIT_PLATFORM, []{return logic->CanUse(RG_MEGATON_HAMMER);}), }, {}, { - Entrance(RR_FIRE_TEMPLE_MQ_SOUTH_FIRE_MAZE, []{return true;}), - Entrance(RR_FIRE_TEMPLE_MQ_NORTH_FIRE_MAZE, []{return logic->CanUse(RG_SONG_OF_TIME) || logic->CanUse(RG_HOVER_BOOTS);}), - //trick to get to RR_FIRE_TEMPLE_MQ_WEST_FIRE_MAZE with hovers + taking damage is plausible + //Exits + Entrance(RR_FIRE_TEMPLE_MQ_FIRE_MAZE_MAIN, []{return true;}), + Entrance(RR_FIRE_TEMPLE_MQ_FIRE_MAZE_MIDDLE, []{return logic->CanUse(RG_SONG_OF_TIME) || logic->CanUse(RG_HOVER_BOOTS);}), + Entrance(RR_FIRE_TEMPLE_MQ_2_FIRE_WALLS_UPPER_DOOR, []{return true;}), + //This one might be a bit too hard for base logic, but is only relevent in doorsanity or with RT_FIRE_MQ_MAZE_HOVERS + Entrance(RR_FIRE_TEMPLE_MQ_FIRE_MAZE_SWITCH, []{return logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_HOVER_BOOTS) && (logic->TakeDamage() || logic->CanJumpslash());}), }); - areaTable[RR_FIRE_TEMPLE_MQ_NORTH_FIRE_MAZE] = Region("Fire Temple MQ North Fire Maze", SCENE_FIRE_TEMPLE, {}, { + areaTable[RR_FIRE_TEMPLE_MQ_2_FIRE_WALLS_UPPER_DOOR] = Region("Fire Temple MQ 2 Fire Walls Upper Door", SCENE_FIRE_TEMPLE, {}, {}, { + //Exits + Entrance(RR_FIRE_TEMPLE_MQ_FIRE_MAZE_PLATFORMS, []{return true;}), + Entrance(RR_FIRE_TEMPLE_MQ_2_FIRE_WALLS_SWITCH, []{return logic->CanUse(RG_HOOKSHOT);}), + Entrance(RR_FIRE_TEMPLE_MQ_2_FIRE_WALLS_LOWER, []{return false;}), + }); + + areaTable[RR_FIRE_TEMPLE_MQ_2_FIRE_WALLS_SWITCH] = Region("Fire Temple MQ 2 Fire Walls Switch", SCENE_FIRE_TEMPLE, { + //Events + EventAccess(LOGIC_FIRE_MQ_OPENED_FIRE_MAZE_DOOR, []{return logic->CanUse(RG_MEGATON_HAMMER);}), + }, {}, { + //Exits + Entrance(RR_FIRE_TEMPLE_MQ_2_FIRE_WALLS_UPPER_DOOR, []{return logic->CanUse(RG_HOOKSHOT);}), + Entrance(RR_FIRE_TEMPLE_MQ_2_FIRE_WALLS_LOWER, []{return false;}), + }); + + areaTable[RR_FIRE_TEMPLE_MQ_2_FIRE_WALLS_LOWER] = Region("Fire Temple MQ 2 Fire Walls Lower", SCENE_FIRE_TEMPLE, {}, { //Locations - LOCATION(RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_SIDE_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)), - LOCATION(RC_FIRE_TEMPLE_MQ_PAST_FIRE_MAZE_SOUTH_POT, logic->CanUse(RG_BOOMERANG)), - LOCATION(RC_FIRE_TEMPLE_MQ_FIRE_MAZE_NORTHMOST_POT, logic->CanBreakPots()), - LOCATION(RC_FIRE_TEMPLE_MQ_FIRE_MAZE_NORTHWEST_POT, logic->CanBreakPots()), + LOCATION(RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_CENTER, logic->HasExplosives() && (logic->IsAdult || logic->CanGroundJump())), }, { //Exits - Entrance(RR_FIRE_TEMPLE_MQ_SOUTH_FIRE_MAZE, []{return logic->IsAdult || ctx->GetTrickOption(RT_FIRE_SKIP_FLAME_WALLS);}), - Entrance(RR_FIRE_TEMPLE_MQ_WEST_FIRE_MAZE, []{return (bool)ctx->GetTrickOption(RT_FIRE_SKIP_FLAME_WALLS);}), + Entrance(RR_FIRE_TEMPLE_MQ_FIRE_MAZE_MAIN, []{return true;}), + Entrance(RR_FIRE_TEMPLE_MQ_FIRE_MAZE_SWITCH, []{return logic->Get(LOGIC_FIRE_MQ_OPENED_FIRE_MAZE_DOOR);}), }); - areaTable[RR_FIRE_TEMPLE_MQ_WEST_FIRE_MAZE] = Region("Fire Temple MQ West Fire Maze", SCENE_FIRE_TEMPLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_MQ_FIRE_MAZE_MIDDLE] = Region("Fire Temple MQ Fire Maze Middle", SCENE_FIRE_TEMPLE, {}, { + //Locations + LOCATION(RC_FIRE_TEMPLE_MQ_PAST_FIRE_MAZE_SOUTH_POT, logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_FIRE_TEMPLE_MQ_FIRE_MAZE_NORTHMOST_POT, logic->CanBreakPots()), + LOCATION(RC_FIRE_TEMPLE_MQ_FIRE_MAZE_NORTHWEST_POT, logic->CanBreakPots()), + }, { + //Exits + Entrance(RR_FIRE_TEMPLE_MQ_GS_LIZALFOS_ROOM, []{return true;}), + Entrance(RR_FIRE_TEMPLE_MQ_FIRE_MAZE_MAIN, []{return logic->IsAdult || ctx->GetTrickOption(RT_FIRE_SKIP_FLAME_WALLS);}), + Entrance(RR_FIRE_TEMPLE_MQ_FIRE_MAZE_SWITCH, []{return (bool)ctx->GetTrickOption(RT_FIRE_SKIP_FLAME_WALLS);}), + }); + + areaTable[RR_FIRE_TEMPLE_MQ_FIRE_MAZE_SWITCH] = Region("Fire Temple MQ Fire Maze Switch", SCENE_FIRE_TEMPLE, {}, {}, { + //Exits Entrance(RR_FIRE_TEMPLE_MQ_FIRE_MAZE_PAST_WALL, []{return true;}), - Entrance(RR_FIRE_TEMPLE_MQ_NORTH_FIRE_MAZE, []{return (bool)ctx->GetTrickOption(RT_FIRE_SKIP_FLAME_WALLS);}), + Entrance(RR_FIRE_TEMPLE_MQ_FIRE_MAZE_MIDDLE, []{return (bool)ctx->GetTrickOption(RT_FIRE_SKIP_FLAME_WALLS);}), + Entrance(RR_FIRE_TEMPLE_MQ_2_FIRE_WALLS_LOWER, []{return true;}), + }); + + areaTable[RR_FIRE_TEMPLE_MQ_GS_LIZALFOS_ROOM] = Region("Fire Temple MQ GS Lizalfos Room", SCENE_FIRE_TEMPLE, {}, { + //Locations + LOCATION(RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_SIDE_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)), + }, { + //Exits + Entrance(RR_FIRE_TEMPLE_MQ_FIRE_MAZE_MIDDLE, []{return true;}), }); - //this area exists for the pots in case we void warp to the top of fire somehow, because there's no way to get back the way we came areaTable[RR_FIRE_TEMPLE_MQ_FIRE_MAZE_PAST_WALL] = Region("Fire Temple MQ Fire Maze Past Wall", SCENE_FIRE_TEMPLE, {}, { //Locations LOCATION(RC_FIRE_TEMPLE_MQ_PAST_FIRE_MAZE_SOUTH_POT, logic->CanBreakPots()), LOCATION(RC_FIRE_TEMPLE_MQ_PAST_FIRE_MAZE_NORTH_POT, logic->CanBreakPots()), LOCATION(RC_FIRE_TEMPLE_MQ_FIRE_MAZE_NORTHWEST_POT, logic->CanUse(RG_BOOMERANG)), }, { - Entrance(RR_FIRE_TEMPLE_MQ_UPPER_FLARE_DANCER, []{return true;}), + //Exits + Entrance(RR_FIRE_TEMPLE_MQ_3F_FLARE_DANCER, []{return true;}), }); - areaTable[RR_FIRE_TEMPLE_MQ_UPPER_FLARE_DANCER] = Region("Fire Temple MQ North Fire Maze", SCENE_FIRE_TEMPLE, {}, { + areaTable[RR_FIRE_TEMPLE_MQ_3F_FLARE_DANCER] = Region("Fire Temple MQ 3F Flare Dancer", SCENE_FIRE_TEMPLE, {}, { //Locations LOCATION(RC_FIRE_TEMPLE_MQ_FREESTANDING_KEY, logic->CanKillEnemy(RE_FLARE_DANCER)), }, { - Entrance(RR_FIRE_TEMPLE_MQ_FIRE_MAZE_PAST_WALL, []{return logic->CanKillEnemy(RE_FLARE_DANCER);}), - Entrance(RR_FIRE_TEMPLE_MQ_SCARECROW_ROOM, []{return logic->CanKillEnemy(RE_FLARE_DANCER) && logic->SmallKeys(SCENE_FIRE_TEMPLE, 4);}), + //Exits + Entrance(RR_FIRE_TEMPLE_MQ_FIRE_MAZE_PAST_WALL, []{return AnyAgeTime([]{return logic->CanKillEnemy(RE_FLARE_DANCER);});}), + Entrance(RR_FIRE_TEMPLE_MQ_ABOVE_3F_FLARE_DANCER, []{return AnyAgeTime([]{return logic->CanKillEnemy(RE_FLARE_DANCER);});}), }); - areaTable[RR_FIRE_TEMPLE_MQ_SCARECROW_ROOM] = Region("Fire Temple MQ Scarecrow Room", SCENE_FIRE_TEMPLE, {}, { + areaTable[RR_FIRE_TEMPLE_MQ_ABOVE_3F_FLARE_DANCER] = Region("Fire Temple MQ Above 3F Flare Dancer", SCENE_FIRE_TEMPLE, {}, {}, { + //Exits + Entrance(RR_FIRE_TEMPLE_MQ_3F_FLARE_DANCER, []{return true;}), + Entrance(RR_FIRE_TEMPLE_MQ_LOCKED_CLIMB, []{return true;}), + }); + + areaTable[RR_FIRE_TEMPLE_MQ_LOCKED_CLIMB] = Region("Fire Temple MQ Locked Climb", SCENE_FIRE_TEMPLE, {}, {}, { + //Exits + Entrance(RR_FIRE_TEMPLE_MQ_3F_FLARE_DANCER, []{return true;}), + Entrance(RR_FIRE_TEMPLE_MQ_NARROW_STAIRS_ROOM, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 4)/* && CanUse(RG_CLIMB)*/;}), + }); + + areaTable[RR_FIRE_TEMPLE_MQ_NARROW_STAIRS_ROOM] = Region("Fire Temple MQ Narrow Stairs Room", SCENE_FIRE_TEMPLE, { + //Events + EventAccess(LOGIC_FIRE_MQ_HIT_SCARECROW_ROOM_PLATFORM, []{return logic->CanUse(RG_MEGATON_HAMMER);}), + }, { //Locations //This requires nothing in N64 logic, but is tight enough to need rollspam with the one-point on which is stricter than I would normally consider in logic //Child basically needs the scarecrow or a bunny hood though due to a worse ledge grab. LOCATION(RC_FIRE_TEMPLE_MQ_CHEST_ON_FIRE, logic->IsAdult || logic->CanUse(RG_SCARECROW)), }, { - //The dropdown here is unusual in that it hits 1 of 3 locations: RR_FIRE_TEMPLE_MQ_SOUTH_FIRE_MAZE, RR_FIRE_TEMPLE_MQ_FIRE_MAZE_PLATFORMS and the section of RR_FIRE_TEMPLE_MQ_FIRE_MAZE_PLATFORMS with the hammer switch + //Exits + //The dropdown here is unusual in that it hits 1 of 3 locations: RR_FIRE_TEMPLE_MQ_2_FIRE_WALLS_LOWER, RR_FIRE_TEMPLE_MQ_2_FIRE_WALLS_UPPER_DOOR, and RR_FIRE_TEMPLE_MQ_2_FIRE_WALLS_SWITCH //Using this dropdown is in N64 logic elsewhere, but not here, probably because it requires good foreknowlege to determine where to land - //This would be a logical method to reach the hammer switch without hookshot, but it practically requires access to the area that switch unlocks already. It could also be first child access to PLATFORMS if tricks ever enable that - //If a practical use for this drop is found, it should be made a trick - Entrance(RR_FIRE_TEMPLE_MQ_UPPER_FLARE_DANCER, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 4);}), - Entrance(RR_FIRE_TEMPLE_MQ_COLLAPSED_STAIRS, []{return AnyAgeTime([]{return logic->CanUse(RG_MEGATON_HAMMER);}) && logic->SmallKeys(SCENE_FIRE_TEMPLE, 5);}), + Entrance(RR_FIRE_TEMPLE_MQ_2_FIRE_WALLS_LOWER, []{return logic->TakeDamage();}), + Entrance(RR_FIRE_TEMPLE_MQ_2_FIRE_WALLS_UPPER_DOOR, []{return logic->TakeDamage();}), + Entrance(RR_FIRE_TEMPLE_MQ_2_FIRE_WALLS_SWITCH, []{return logic->TakeDamage();}), + Entrance(RR_FIRE_TEMPLE_MQ_3F_FLARE_DANCER, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 4);}), + Entrance(RR_FIRE_TEMPLE_MQ_NARROW_STAIRS_4F, []{return logic->Get(LOGIC_FIRE_MQ_HIT_SCARECROW_ROOM_PLATFORM);}), }); - //The peg knocked down from here could have logical implications for child in the fire maze if tricks to gain height like bomb jumps exist - areaTable[RR_FIRE_TEMPLE_MQ_COLLAPSED_STAIRS] = Region("Fire Temple MQ Collapsed Stairs", SCENE_FIRE_TEMPLE, {}, { + areaTable[RR_FIRE_TEMPLE_MQ_NARROW_STAIRS_4F] = Region("Fire Temple MQ Narrow Stairs 4F", SCENE_FIRE_TEMPLE, {}, {}, { + //Exits + Entrance(RR_FIRE_TEMPLE_MQ_NARROW_STAIRS_ROOM, []{return logic->Get(LOGIC_FIRE_MQ_HIT_SCARECROW_ROOM_PLATFORM) && logic->CanUse(RG_HOOKSHOT);}), + Entrance(RR_FIRE_TEMPLE_MQ_TOP_OF_COLLAPSING_STAIRS, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 5);}), + }); + + areaTable[RR_FIRE_TEMPLE_MQ_TOP_OF_COLLAPSING_STAIRS] = Region("Fire Temple MQ Top of Collapsing Stairs", SCENE_FIRE_TEMPLE, { + //Events + EventAccess(LOGIC_FIRE_HIT_STAIRS, []{return logic->CanUse(RG_MEGATON_HAMMER);}), + }, {}, { + //Exits + Entrance(RR_FIRE_TEMPLE_MQ_BASE_OF_COLLAPSING_STAIRS, []{return logic->Get(LOGIC_FIRE_HIT_STAIRS);}), + Entrance(RR_FIRE_TEMPLE_MQ_NARROW_STAIRS_4F, []{return logic->SmallKeys(SCENE_FIRE_TEMPLE, 5);}), + }); + + areaTable[RR_FIRE_TEMPLE_MQ_BASE_OF_COLLAPSING_STAIRS] = Region("Fire Temple MQ Base of Collapsing Stairs", SCENE_FIRE_TEMPLE, {}, {}, { + //Exits + Entrance(RR_FIRE_TEMPLE_MQ_TOP_OF_COLLAPSING_STAIRS, []{return logic->Get(LOGIC_FIRE_HIT_STAIRS) && logic->IsAdult;}), + Entrance(RR_FIRE_TEMPLE_MQ_ABOVE_FIRE_MAZE, []{return logic->CanUse(RG_HOOKSHOT);}), + }); + + areaTable[RR_FIRE_TEMPLE_MQ_ABOVE_FIRE_MAZE] = Region("Fire Temple MQ Above Fire Maze", SCENE_FIRE_TEMPLE, {}, { //Locations - //If someone manages to make a trick to get here from fire maze, this needs to be in a separate room as the door back is barred - LOCATION(RC_FIRE_TEMPLE_MQ_GS_ABOVE_FIRE_MAZE, logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_FIRE_TEMPLE_MQ_GS_ABOVE_FIRE_MAZE, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)), }, { - Entrance(RR_FIRE_TEMPLE_MQ_FIRE_MAZE_PLATFORMS, []{return logic->CanUse(RG_HOOKSHOT) && AnyAgeTime([]{return logic->CanUse(RG_MEGATON_HAMMER);});}), - Entrance(RR_FIRE_TEMPLE_MQ_SCARECROW_ROOM, []{return logic->IsAdult && logic->CanUse(RG_HOOKSHOT);}), + //Exits + Entrance(RR_FIRE_TEMPLE_MQ_FIRE_MAZE_MAIN, []{return AnyAgeTime([]{return logic->CanUse(RG_MEGATON_HAMMER);});}), + //it's possible to land directly on the upper platform as child and even avoid fall damage, but it's not intuitive (you have to ledge grab, drop down and then air drift with enough momentum to roll) + Entrance(RR_FIRE_TEMPLE_MQ_FIRE_MAZE_PLATFORMS, []{return AnyAgeTime([]{return logic->CanUse(RG_MEGATON_HAMMER);}) && logic->CanJumpslash() && logic->TakeDamage();}), + Entrance(RR_FIRE_TEMPLE_MQ_BASE_OF_COLLAPSING_STAIRS, []{return false;}), }); #pragma endregion diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index 939fac070..d4d1faa71 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -458,6 +458,11 @@ bool Logic::CanGroundJump(bool hasBombflower) { (CanUse(RG_BOMB_BAG) || (hasBombflower && HasItem(RG_GORONS_BRACELET))); } +bool Logic::CanGroundJumpJumpSlash(bool hasBombflower) { + return ctx->GetTrickOption(RT_GROUND_JUMP_HARD) && CanStandingShield() && CanJumpslash() && + (CanUse(RG_BOMB_BAG) || (hasBombflower && HasItem(RG_GORONS_BRACELET))); +} + bool Logic::CanOpenUnderwaterChest() { return ctx->GetTrickOption(RT_OPEN_UNDERWATER_CHEST) && CanUse(RG_IRON_BOOTS) && CanUse(RG_HOOKSHOT); } diff --git a/soh/soh/Enhancements/randomizer/logic.h b/soh/soh/Enhancements/randomizer/logic.h index 858e2e580..d3c5f046d 100644 --- a/soh/soh/Enhancements/randomizer/logic.h +++ b/soh/soh/Enhancements/randomizer/logic.h @@ -45,6 +45,7 @@ class Logic { bool CanOpenOverworldDoor(RandomizerGet itemName); bool SmallKeys(s16 scene, uint8_t requiredAmount); bool CanGroundJump(bool hasBombflower = false); + bool CanGroundJumpJumpSlash(bool hasBombflower = false); bool CanOpenUnderwaterChest(); bool CanDoGlitch(GlitchType glitch); bool CanEquipSwap(RandomizerGet itemName); diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 2e27b69e7..f922f11c7 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -288,7 +288,12 @@ typedef enum { LOGIC_FIRE_OPENED_LOWEST_GORON_CAGE, LOGIC_FIRE_OPENED_UPPER_SHORTCUT, LOGIC_FIRE_HIT_PLATFORM, + LOGIC_FIRE_HIT_STAIRS, + LOGIC_FIRE_CHILD_AT_TOP_OF_STAIRS, + LOGIC_FIRE_HIT_ABOVE_MAZE_PLATFORM, LOGIC_FIRE_MQ_OPENED_FIRE_MAZE_DOOR, + LOGIC_FIRE_MQ_HIT_SCARECROW_ROOM_PLATFORM, + LOGIC_FIRE_MQ_HIGH_TORCH_LIT, LOGIC_WATER_LOW_FROM_HIGH, LOGIC_WATER_LOW_FROM_MID, LOGIC_WATER_MIDDLE, @@ -922,73 +927,109 @@ typedef enum { RR_FOREST_TEMPLE_BOSS_ENTRYWAY, RR_FOREST_TEMPLE_BOSS_ROOM, - RR_FIRE_TEMPLE_FIRST_ROOM, + RR_FIRE_TEMPLE_FOYER, RR_FIRE_TEMPLE_NEAR_BOSS_ROOM, - RR_FIRE_TEMPLE_LOOP_ENEMIES, - RR_FIRE_TEMPLE_LOOP_TILES, + RR_FIRE_TEMPLE_NEAR_BOSS_UPPER, + RR_FIRE_TEMPLE_LOOP_HEXAGON_ROOM, + RR_FIRE_TEMPLE_LOOP_5_TILE_ROOM, RR_FIRE_TEMPLE_LOOP_FLARE_DANCER, - RR_FIRE_TEMPLE_LOOP_HAMMER_SWITCH, - RR_FIRE_TEMPLE_LOOP_GORON_ROOM, - RR_FIRE_TEMPLE_LOOP_EXIT, + RR_FIRE_TEMPLE_LOOP_CAGE_SWITCH, + RR_FIRE_TEMPLE_LOOP_GORON_CAGE, + RR_FIRE_TEMPLE_LOOP_CAGE_FOYER_SIDE, RR_FIRE_TEMPLE_BIG_LAVA_ROOM, - RR_FIRE_TEMPLE_BIG_LAVA_ROOM_NORTH_GORON, - RR_FIRE_TEMPLE_BIG_LAVA_ROOM_NORTH_TILES, - RR_FIRE_TEMPLE_BIG_LAVA_ROOM_SOUTH_GORON, - RR_FIRE_TEMPLE_FIRE_PILLAR_ROOM, + RR_FIRE_TEMPLE_1F_CURVED_CAGE, + RR_FIRE_TEMPLE_8_TILE_ROOM, + RR_FIRE_TEMPLE_STRAIGHTFORWARD_CAGE, + RR_FIRE_TEMPLE_LAVA_GEYSER_1F, + RR_FIRE_TEMPLE_LAVA_GEYSER_GRATE, + RR_FIRE_TEMPLE_LAVA_GEYSER_TORCH, + RR_FIRE_TEMPLE_LAVA_GEYSER_2F, RR_FIRE_TEMPLE_SHORTCUT_ROOM, RR_FIRE_TEMPLE_SHORTCUT_CLIMB, RR_FIRE_TEMPLE_BOULDER_MAZE_LOWER, - RR_FIRE_TEMPLE_BOULDER_MAZE_LOWER_SIDE_ROOM, - RR_FIRE_TEMPLE_EAST_CENTRAL_ROOM, + RR_FIRE_TEMPLE_3F_CURVED_CAGE, + RR_FIRE_TEMPLE_NARROW_PATH_ROOM, RR_FIRE_TEMPLE_FIRE_WALL_CHASE, - RR_FIRE_TEMPLE_MAP_AREA, + RR_FIRE_TEMPLE_FIRE_WALL_CAGE, RR_FIRE_TEMPLE_BOULDER_MAZE_UPPER, - RR_FIRE_TEMPLE_SCARECROW_ROOM, - RR_FIRE_TEMPLE_EAST_PEAK, + RR_FIRE_TEMPLE_GS_CLIMB_4F, + RR_FIRE_TEMPLE_GS_CLIMB_5F, + RR_FIRE_TEMPLE_5F_RUINS, RR_FIRE_TEMPLE_CORRIDOR, - RR_FIRE_TEMPLE_FIRE_MAZE_ROOM, - RR_FIRE_TEMPLE_FIRE_MAZE_UPPER, - RR_FIRE_TEMPLE_FIRE_MAZE_SIDE_ROOM, - RR_FIRE_TEMPLE_WEST_CENTRAL_LOWER, - RR_FIRE_TEMPLE_WEST_CENTRAL_UPPER, - RR_FIRE_TEMPLE_LATE_FIRE_MAZE, - RR_FIRE_TEMPLE_UPPER_FLARE_DANCER, - RR_FIRE_TEMPLE_WEST_CLIMB, - RR_FIRE_TEMPLE_WEST_PEAK, - RR_FIRE_TEMPLE_HAMMER_RETURN_PATH, + RR_FIRE_TEMPLE_FIRE_MAZE_MAIN, + RR_FIRE_TEMPLE_FIRE_MAZE_PLATFORMS, + RR_FIRE_TEMPLE_CAGELESS_CHEST_ROOM, + RR_FIRE_TEMPLE_SOT_CAGE_LOWER, + RR_FIRE_TEMPLE_SOT_CAGE_UPPER_DOOR, + RR_FIRE_TEMPLE_SOT_CAGE_SWITCH, + RR_FIRE_TEMPLE_FIRE_MAZE_SWITCH, + RR_FIRE_TEMPLE_FIRE_MAZE_PAST_WALL, + RR_FIRE_TEMPLE_3F_FLARE_DANCER, + RR_FIRE_TEMPLE_ABOVE_3F_FLARE_DANCER, + RR_FIRE_TEMPLE_SWITCH_CLIMB, + RR_FIRE_TEMPLE_NARROW_STAIRS, + RR_FIRE_TEMPLE_NARROW_STAIRS_4F, + RR_FIRE_TEMPLE_TOP_OF_COLLAPSING_STAIRS, + RR_FIRE_TEMPLE_BASE_OF_COLLAPSING_STAIRS, RR_FIRE_TEMPLE_ABOVE_FIRE_MAZE, - RR_FIRE_TEMPLE_MQ_FIRST_ROOM_LOWER, - RR_FIRE_TEMPLE_MQ_FIRST_ROOM_UPPER, - RR_FIRE_TEMPLE_MQ_MAP_ROOM_SOUTH, - RR_FIRE_TEMPLE_MQ_STALFOS_ROOM, - RR_FIRE_TEMPLE_MQ_IRON_KNUCKLE_ROOM, - RR_FIRE_TEMPLE_MQ_LOWER_FLARE_DANCER, - RR_FIRE_TEMPLE_MQ_MAP_ROOM_NORTH, - RR_FIRE_TEMPLE_MQ_MAP_ROOM_CAGE, + RR_FIRE_TEMPLE_MQ_FOYER_LOWER, + RR_FIRE_TEMPLE_MQ_FOYER_UPPER, + RR_FIRE_TEMPLE_MQ_LOOP_CAGE_FOYER_SIDE, + RR_FIRE_TEMPLE_MQ_LOOP_HEXAGON_ROOM, + RR_FIRE_TEMPLE_MQ_LOOP_5_TILE_ROOM, + RR_FIRE_TEMPLE_MQ_LOOP_FLARE_DANCER, + RR_FIRE_TEMPLE_MQ_LOOP_CAGE_SWITCH, + RR_FIRE_TEMPLE_MQ_LOOP_GORON_CAGE, RR_FIRE_TEMPLE_MQ_NEAR_BOSS_ROOM, - RR_FIRE_TEMPLE_MQ_NEAR_BOSS_ROOM_NORTH, + RR_FIRE_TEMPLE_MQ_NEAR_BOSS_TARGET, + RR_FIRE_TEMPLE_MQ_NEAR_BOSS_ROOM_UPPER, RR_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM, + RR_FIRE_TEMPLE_MQ_BIG_LAVA_BLOCKED_DOOR, + RR_FIRE_TEMPLE_MQ_GS_GORON_CAGE, + RR_FIRE_TEMPLE_MQ_TORCH_LOCKED_CAGE, RR_FIRE_TEMPLE_MQ_TORCH_FIREWALL_ROOM, - RR_FIRE_TEMPLE_MQ_ELEVATOR_ROOM, - RR_FIRE_TEMPLE_MQ_BIG_TORCH_ROOM, - RR_FIRE_TEMPLE_MQ_LOWER_MAZE, - RR_FIRE_TEMPLE_MQ_LOWER_MAZE_CRATE_CAGE, - RR_FIRE_TEMPLE_MQ_UPPER_MAZE, - RR_FIRE_TEMPLE_MQ_UPPER_MAZE_BOX_CAGE, - RR_FIRE_TEMPLE_MQ_MAZE_SHORTCUT, - RR_FIRE_TEMPLE_MQ_MAZE_SHORTCUT_CAGE, - RR_FIRE_TEMPLE_MQ_BURNING_BLOCK_CLIMB, + RR_FIRE_TEMPLE_MQ_LAVA_GEYSER_1F, + RR_FIRE_TEMPLE_MQ_LAVA_GEYSER_GRATE, + RR_FIRE_TEMPLE_MQ_LAVA_GEYSER_PILLARS, + RR_FIRE_TEMPLE_MQ_LAVA_GEYSER_2F, + RR_FIRE_TEMPLE_MQ_SHORTCUT_ROOM_LOWER, + RR_FIRE_TEMPLE_MQ_SHORTCUT_ROOM_MID, + RR_FIRE_TEMPLE_MQ_SHORTCUT_ROOM_3F, + RR_FIRE_TEMPLE_MQ_LOWER_LIZALFOS_MAZE, + RR_FIRE_TEMPLE_MQ_MAZE_SWITCH_DOOR, + RR_FIRE_TEMPLE_MQ_3F_CURVED_CAGE, + RR_FIRE_TEMPLE_MQ_MAZE_CRATE_CAGE, + RR_FIRE_TEMPLE_MQ_UPPER_LIZALFOS_MAZE, + RR_FIRE_TEMPLE_MQ_MAZE_BOX_CAGE, + RR_FIRE_TEMPLE_MQ_ABOVE_MAZE, + RR_FIRE_TEMPLE_MQ_SHORTCUT_CLIMB, + RR_FIRE_TEMPLE_MQ_SHORTCUT_CAGE, + RR_FIRE_TEMPLE_MQ_TORCH_SLUG_CLIMB, + RR_FIRE_TEMPLE_MQ_BURNING_BLOCK, RR_FIRE_TEMPLE_MQ_NARROW_PATH_ROOM, RR_FIRE_TEMPLE_MQ_HIGH_TORCH_ROOM, - RR_FIRE_TEMPLE_MQ_SOUTH_FIRE_MAZE, + RR_FIRE_TEMPLE_MQ_HIGH_TORCH_ROOM_ABOVE_CAGE, + RR_FIRE_TEMPLE_MQ_HIGH_TORCH_ROOM_CAGE, + RR_FIRE_TEMPLE_MQ_HIGH_TORCH_ROOM_BARRED_DOOR, + RR_FIRE_TEMPLE_MQ_CORRIDOR, + RR_FIRE_TEMPLE_MQ_FIRE_MAZE_MAIN, RR_FIRE_TEMPLE_MQ_FIRE_MAZE_PLATFORMS, - RR_FIRE_TEMPLE_MQ_NORTH_FIRE_MAZE, - RR_FIRE_TEMPLE_MQ_WEST_FIRE_MAZE, + RR_FIRE_TEMPLE_MQ_2_FIRE_WALLS_UPPER_DOOR, + RR_FIRE_TEMPLE_MQ_2_FIRE_WALLS_SWITCH, + RR_FIRE_TEMPLE_MQ_2_FIRE_WALLS_LOWER, + RR_FIRE_TEMPLE_MQ_FIRE_MAZE_MIDDLE, + RR_FIRE_TEMPLE_MQ_FIRE_MAZE_SWITCH, + RR_FIRE_TEMPLE_MQ_GS_LIZALFOS_ROOM, RR_FIRE_TEMPLE_MQ_FIRE_MAZE_PAST_WALL, - RR_FIRE_TEMPLE_MQ_UPPER_FLARE_DANCER, - RR_FIRE_TEMPLE_MQ_SCARECROW_ROOM, - RR_FIRE_TEMPLE_MQ_COLLAPSED_STAIRS, + RR_FIRE_TEMPLE_MQ_3F_FLARE_DANCER, + RR_FIRE_TEMPLE_MQ_ABOVE_3F_FLARE_DANCER, + RR_FIRE_TEMPLE_MQ_LOCKED_CLIMB, + RR_FIRE_TEMPLE_MQ_NARROW_STAIRS_ROOM, + RR_FIRE_TEMPLE_MQ_NARROW_STAIRS_4F, + RR_FIRE_TEMPLE_MQ_TOP_OF_COLLAPSING_STAIRS, + RR_FIRE_TEMPLE_MQ_BASE_OF_COLLAPSING_STAIRS, + RR_FIRE_TEMPLE_MQ_ABOVE_FIRE_MAZE, RR_FIRE_TEMPLE_BOSS_ENTRYWAY, RR_FIRE_TEMPLE_BOSS_ROOM,