Rewrite MQ fire logic and fix MQ deku logic (#4443)

* commit to merge

* rewrite fire and fix deku
This commit is contained in:
Pepper0ni 2024-10-20 09:00:39 +01:00 committed by GitHub
parent cbd35d0ef5
commit ba38d985b3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 363 additions and 70 deletions

View File

@ -37,7 +37,7 @@ void RegionTable_Init_BottomOfTheWell() {
Entrance(RR_BOTTOM_OF_THE_WELL_BEHIND_FAKE_WALLS, {[]{return ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH);}}), Entrance(RR_BOTTOM_OF_THE_WELL_BEHIND_FAKE_WALLS, {[]{return ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH);}}),
Entrance(RR_BOTTOM_OF_THE_WELL_SOUTHWEST_ROOM, {[]{return ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH);}}), Entrance(RR_BOTTOM_OF_THE_WELL_SOUTHWEST_ROOM, {[]{return ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH);}}),
Entrance(RR_BOTTOM_OF_THE_WELL_KEESE_BEAMOS_ROOM, {[]{return logic->IsChild && logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 3);}}), Entrance(RR_BOTTOM_OF_THE_WELL_KEESE_BEAMOS_ROOM, {[]{return logic->IsChild && logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 3);}}),
Entrance(RR_BOTTOM_OF_THE_WELL_COFFIN_ROOM, {[]{return logic->LoweredWaterInsideBotw || logic->CanUse(RG_BRONZE_SCALE);}}), Entrance(RR_BOTTOM_OF_THE_WELL_COFFIN_ROOM, {[]{return logic->LoweredWaterInsideBotw || logic->HasItem(RG_BRONZE_SCALE);}}),
Entrance(RR_BOTTOM_OF_THE_WELL_DEAD_HAND_ROOM, {[]{return logic->LoweredWaterInsideBotw && logic->IsChild;}}), Entrance(RR_BOTTOM_OF_THE_WELL_DEAD_HAND_ROOM, {[]{return logic->LoweredWaterInsideBotw && logic->IsChild;}}),
//Falling down into basement requires nothing, but falling down somewhere specific requires lens or lens trick //Falling down into basement requires nothing, but falling down somewhere specific requires lens or lens trick
//kinda questionable given several drops are blocked by rocks, but that's how it was handled before and on N64 //kinda questionable given several drops are blocked by rocks, but that's how it was handled before and on N64
@ -108,7 +108,7 @@ void RegionTable_Init_BottomOfTheWell() {
LOCATION(RC_BOTTOM_OF_THE_WELL_FREESTANDING_KEY, logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW)), LOCATION(RC_BOTTOM_OF_THE_WELL_FREESTANDING_KEY, logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW)),
}, { }, {
//Exits //Exits
Entrance(RR_BOTTOM_OF_THE_WELL_PERIMETER, {[]{return logic->LoweredWaterInsideBotw || logic->CanUse(RG_BRONZE_SCALE);}}), Entrance(RR_BOTTOM_OF_THE_WELL_PERIMETER, {[]{return logic->LoweredWaterInsideBotw || logic->HasItem(RG_BRONZE_SCALE);}}),
}); });
areaTable[RR_BOTTOM_OF_THE_WELL_DEAD_HAND_ROOM] = Region("Bottom of the Well Dead Hand Room", "Bottom of the Well", {RA_BOTTOM_OF_THE_WELL}, NO_DAY_NIGHT_CYCLE, {}, { areaTable[RR_BOTTOM_OF_THE_WELL_DEAD_HAND_ROOM] = Region("Bottom of the Well Dead Hand Room", "Bottom of the Well", {RA_BOTTOM_OF_THE_WELL}, NO_DAY_NIGHT_CYCLE, {}, {

View File

@ -256,7 +256,7 @@ void RegionTable_Init_DekuTree() {
areaTable[RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_FRONT] = Region("Deku Tree MQ Basement Water Room Front", "Deku Tree", {RA_DEKU_TREE}, NO_DAY_NIGHT_CYCLE, { areaTable[RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_FRONT] = Region("Deku Tree MQ Basement Water Room Front", "Deku Tree", {RA_DEKU_TREE}, NO_DAY_NIGHT_CYCLE, {
//Events //Events
//It's possible to get this with bow if you have move while in first person and one-point skips on, noticeably harder and jankier as child, but that's a trick //It's possible to get this with bow if you have move while in first person and one-point skips on, noticeably harder and jankier as child, but that's a trick
EventAccess(&logic->MQDekuWaterRoomTorches, {[]{return logic->CanUse(RG_FIRE_ARROWS) || (logic->IsChild && logic->CanUse(RG_STICKS) && logic->CanShield());}}), EventAccess(&logic->MQDekuWaterRoomTorches, {[]{return logic->CanUse(RG_FIRE_ARROWS) || (logic->CanUse(RG_STICKS) && (ctx->GetTrickOption(RT_DEKU_MQ_LOG) || (logic->IsChild && logic->CanShield())));}}),
}, { }, {
//Locations //Locations
LOCATION(RC_DEKU_TREE_MQ_BEFORE_SPINNING_LOG_CHEST, true), LOCATION(RC_DEKU_TREE_MQ_BEFORE_SPINNING_LOG_CHEST, true),
@ -279,7 +279,7 @@ void RegionTable_Init_DekuTree() {
//Exits //Exits
Entrance(RR_DEKU_TREE_MQ_BASEMENT_SOUTHWEST_ROOM, {[]{return logic->MQDekuWaterRoomTorches && logic->CanPassEnemy(RE_BIG_SKULLTULA, logic->CanUse(RG_SONG_OF_TIME) ? ED_CLOSE : ED_HAMMER_JUMPSLASH);}}), Entrance(RR_DEKU_TREE_MQ_BASEMENT_SOUTHWEST_ROOM, {[]{return logic->MQDekuWaterRoomTorches && logic->CanPassEnemy(RE_BIG_SKULLTULA, logic->CanUse(RG_SONG_OF_TIME) ? ED_CLOSE : ED_HAMMER_JUMPSLASH);}}),
Entrance(RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_FRONT, {[]{return ctx->GetTrickOption(RT_DEKU_MQ_LOG) || (logic->IsChild && logic->CanShield()) || Entrance(RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_FRONT, {[]{return ctx->GetTrickOption(RT_DEKU_MQ_LOG) || (logic->IsChild && logic->CanShield()) ||
logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_BRONZE_SCALE) || logic->CanUse(RG_LONGSHOT) || logic->HasItem(RG_BRONZE_SCALE) ||
(logic->CanUse(RG_IRON_BOOTS) && (logic->IsAdult || logic->CanUse(RG_HOOKSHOT)));}}), (logic->CanUse(RG_IRON_BOOTS) && (logic->IsAdult || logic->CanUse(RG_HOOKSHOT)));}}),
}); });
@ -321,19 +321,19 @@ void RegionTable_Init_DekuTree() {
LOCATION(RC_DEKU_TREE_MQ_DEKU_SCRUB, logic->CanStunDeku()), LOCATION(RC_DEKU_TREE_MQ_DEKU_SCRUB, logic->CanStunDeku()),
}, { }, {
//Exits //Exits
Entrance(RR_DEKU_TREE_MQ_BASEMENT_BACK_ROOM, {[]{return logic->IsChild;}}), Entrance(RR_DEKU_TREE_MQ_BASEMENT_GRAVE_ROOM, {[]{return logic->IsChild;}}),
Entrance(RR_DEKU_TREE_MQ_BASEMENT, {[]{return true;}}), Entrance(RR_DEKU_TREE_MQ_BASEMENT, {[]{return true;}}),
//If strength 0 is shuffled, add hovers or block push to the stick check //If strength 0 is shuffled, add hovers or block push to the stick check
//recoiling to skip swim is possible, but would be a trick //recoiling to skip swim is possible, but would be a trick
Entrance(RR_DEKU_TREE_MQ_OUTSIDE_BOSS_ROOM, {[]{return Here(RR_DEKU_TREE_MQ_BASEMENT_LEDGE, []{return logic->HasFireSource() || (/*logic->PushedDekuBasementBlock && */logic->CanUse(RG_STICKS));}) Entrance(RR_DEKU_TREE_MQ_OUTSIDE_BOSS_ROOM, {[]{return Here(RR_DEKU_TREE_MQ_BASEMENT_LEDGE, []{return logic->HasFireSource() || (/*logic->PushedDekuBasementBlock && */logic->CanUse(RG_STICKS));})
&& (logic->CanUse(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS));}}), && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS));}}),
}); });
areaTable[RR_DEKU_TREE_MQ_OUTSIDE_BOSS_ROOM] = areaTable[RR_DEKU_TREE_MQ_OUTSIDE_BOSS_ROOM] =
Region("Deku Tree MQ Outside Boss Room", "Deku Tree", {RA_DEKU_TREE}, NO_DAY_NIGHT_CYCLE, {}, {}, Region("Deku Tree MQ Outside Boss Room", "Deku Tree", {RA_DEKU_TREE}, NO_DAY_NIGHT_CYCLE, {}, {},
{ {
// Exits // Exits
Entrance(RR_DEKU_TREE_MQ_BASEMENT_LEDGE, {[]{return logic->CanUse(RG_BRONZE_SCALE);}}), Entrance(RR_DEKU_TREE_MQ_BASEMENT_LEDGE, {[]{return logic->HasItem(RG_BRONZE_SCALE);}}),
Entrance(RR_DEKU_TREE_BOSS_ENTRYWAY, {[]{return Here(RR_DEKU_TREE_MQ_OUTSIDE_BOSS_ROOM, []{return logic->CanReflectNuts();});}}), Entrance(RR_DEKU_TREE_BOSS_ENTRYWAY, {[]{return Here(RR_DEKU_TREE_MQ_OUTSIDE_BOSS_ROOM, []{return logic->CanReflectNuts();});}}),
}); });
} }

View File

@ -11,7 +11,7 @@ void RegionTable_Init_FireTemple() {
areaTable[RR_FIRE_TEMPLE_ENTRYWAY] = Region("Fire Temple Entryway", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { areaTable[RR_FIRE_TEMPLE_ENTRYWAY] = Region("Fire Temple Entryway", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
//Exits //Exits
Entrance(RR_FIRE_TEMPLE_FIRST_ROOM, {[]{return ctx->GetDungeon(FIRE_TEMPLE)->IsVanilla();}}), Entrance(RR_FIRE_TEMPLE_FIRST_ROOM, {[]{return ctx->GetDungeon(FIRE_TEMPLE)->IsVanilla();}}),
Entrance(RR_FIRE_TEMPLE_MQ_LOWER, {[]{return ctx->GetDungeon(FIRE_TEMPLE)->IsMQ();}}), Entrance(RR_FIRE_TEMPLE_MQ_FIRST_ROOM_LOWER, {[]{return ctx->GetDungeon(FIRE_TEMPLE)->IsMQ();}}),
Entrance(RR_DMC_CENTRAL_LOCAL, {[]{return true;}}), Entrance(RR_DMC_CENTRAL_LOCAL, {[]{return true;}}),
}); });
@ -314,82 +314,309 @@ void RegionTable_Init_FireTemple() {
| MASTER QUEST DUNGEON | | MASTER QUEST DUNGEON |
---------------------------*/ ---------------------------*/
if (ctx->GetDungeon(FIRE_TEMPLE)->IsMQ()) { if (ctx->GetDungeon(FIRE_TEMPLE)->IsMQ()) {
areaTable[RR_FIRE_TEMPLE_MQ_LOWER] = Region("Fire Temple MQ Lower", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { //potentially dangerous temp flag on the first room's torches, should be made parament if possible
//Locations areaTable[RR_FIRE_TEMPLE_MQ_FIRST_ROOM_LOWER] = Region("Fire Temple MQ First Room Lower", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
LOCATION(RC_FIRE_TEMPLE_MQ_MAP_ROOM_SIDE_CHEST, logic->CanJumpslashExceptHammer() || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_BOMB_BAG) || logic->CanUse(RG_DINS_FIRE)),
LOCATION(RC_FIRE_TEMPLE_MQ_NEAR_BOSS_CHEST, logic->IsAdult && (ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS) || logic->CanUse(RG_GORON_TUNIC)) && (((logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_FIRE_MQ_NEAR_BOSS) && logic->CanUse(RG_FAIRY_BOW))) && logic->HasFireSource()) || (logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_FIRE_ARROWS) || (logic->CanUse(RG_DINS_FIRE) && ((ctx->GetOption(RSK_DAMAGE_MULTIPLIER).IsNot(RO_DAMAGE_MULTIPLIER_OHKO) && ctx->GetOption(RSK_DAMAGE_MULTIPLIER).IsNot(RO_DAMAGE_MULTIPLIER_QUADRUPLE) && ctx->GetOption(RSK_DAMAGE_MULTIPLIER).IsNot(RO_DAMAGE_MULTIPLIER_OCTUPLE) && ctx->GetOption(RSK_DAMAGE_MULTIPLIER).IsNot(RO_DAMAGE_MULTIPLIER_SEXDECUPLE)) || logic->CanUse(RG_GORON_TUNIC) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_LONGSHOT)))))),
//Trick: logic->IsAdult && (LogicFewerTunicRequirements || logic->CanUse(RG_GORON_TUNIC)) && (((logic->CanUse(RG_HOVER_BOOTS) || (LogicFireMQNearBoss && logic->CanUse(RG_FAIRY_BOW))) && logic->HasFireSource()) || (logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_FIRE_ARROWS) || (logic->CanUse(RG_DINS_FIRE) && ((DamageMultiplier.IsNot(DAMAGEMULTIPLIER_OHKO) && DamageMultiplier.IsNot(DAMAGEMULTIPLIER_QUADRUPLE) && DamageMultiplier.IsNot(DAMAGEMULTIPLIER_OCTUPLE) && DamageMultiplier.IsNot(DAMAGEMULTIPLIER_SEXDECUPLE)) || logic->CanUse(RG_GORON_TUNIC) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_LONGSHOT)))))
}, {
//Exits //Exits
Entrance(RR_FIRE_TEMPLE_ENTRYWAY, {[]{return true;}}), Entrance(RR_FIRE_TEMPLE_ENTRYWAY, {[]{return true;}}),
Entrance(RR_FIRE_TEMPLE_BOSS_ENTRYWAY, {[]{return logic->IsAdult && logic->CanUse(RG_GORON_TUNIC) && logic->CanUse(RG_MEGATON_HAMMER) && logic->HasItem(RG_FIRE_TEMPLE_BOSS_KEY) && ((logic->HasFireSource() && (ctx->GetTrickOption(RT_FIRE_BOSS_DOOR_JUMP) || logic->CanUse(RG_HOVER_BOOTS))) || HasAccessTo(RR_FIRE_TEMPLE_MQ_UPPER));}}), Entrance(RR_FIRE_TEMPLE_MQ_MAP_ROOM_SOUTH, {[]{return true;}}),
Entrance(RR_FIRE_TEMPLE_MQ_LOWER_LOCKED_DOOR, {[]{return logic->SmallKeys(RR_FIRE_TEMPLE, 5) && (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD));}}), Entrance(RR_FIRE_TEMPLE_MQ_FIRST_ROOM_UPPER, {[]{return logic->IsAdult || logic->CanUse(RG_HOOKSHOT);}}),
Entrance(RR_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM, {[]{return logic->IsAdult && logic->FireTimer() >= 24 && logic->CanUse(RG_MEGATON_HAMMER);}}), Entrance(RR_FIRE_TEMPLE_MQ_STALFOS_ROOM, {[]{return logic->SmallKeys(RR_FIRE_TEMPLE, 5);}}),
}); });
areaTable[RR_FIRE_TEMPLE_MQ_LOWER_LOCKED_DOOR] = Region("Fire Temple MQ Lower Locked Door", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, { areaTable[RR_FIRE_TEMPLE_MQ_FIRST_ROOM_UPPER] = Region("Fire Temple MQ First Room Upper", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
//Events //Exits
EventAccess(&logic->FairyPot, {[]{return true;}}), Entrance(RR_FIRE_TEMPLE_MQ_FIRST_ROOM_LOWER, {[]{return true;}}),
}, { Entrance(RR_FIRE_TEMPLE_NEAR_BOSS_ROOM, {[]{return logic->HasFireSource();}}),
//Locations Entrance(RR_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM, {[]{return Here(RR_FIRE_TEMPLE_MQ_FIRST_ROOM_UPPER, {[]{return logic->CanUse(RG_MEGATON_HAMMER);}});}}),
LOCATION(RC_FIRE_TEMPLE_MQ_MEGATON_HAMMER_CHEST, logic->IsAdult && (logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_HOOKSHOT) || (logic->HasExplosives() && (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG))))), });
LOCATION(RC_FIRE_TEMPLE_MQ_MAP_CHEST, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)),
}, {});
areaTable[RR_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM] = Region("Fire Temple MQ Big Lava Room", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, { areaTable[RR_FIRE_TEMPLE_MQ_MAP_ROOM_SOUTH] = Region("Fire Temple MQ Map Room South", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
//Events
EventAccess(&logic->FairyPot, {[]{return logic->FairyPot || (logic->HasFireSource() && (logic->CanUse(RG_FAIRY_BOW) || ctx->GetTrickOption(RT_FIRE_MQ_BK_CHEST)) && logic->IsAdult && (logic->CanUse(RG_HOOKSHOT) || ctx->GetTrickOption(RT_FIRE_SOT)));}}),
//Trick: logic->HasFireSource() && (logic->CanUse(RG_FAIRY_BOW) || LogicFireMQBKChest) && logic->IsAdult && (logic->CanUse(RG_HOOKSHOT) || LogicFireSongOfTime)
}, {
//Locations //Locations
LOCATION(RC_FIRE_TEMPLE_MQ_BOSS_KEY_CHEST, logic->HasFireSource() && (logic->CanUse(RG_FAIRY_BOW) || ctx->GetTrickOption(RT_FIRE_MQ_BK_CHEST)) && logic->IsAdult && logic->CanUse(RG_HOOKSHOT)), LOCATION(RC_FIRE_TEMPLE_MQ_MAP_ROOM_SIDE_CHEST, logic->CanKillEnemy(RE_LIKE_LIKE)),
//Trick: logic->HasFireSource() && (logic->CanUse(RG_FAIRY_BOW) || LogicFireMQBKChest) && logic->IsAdult && logic->CanUse(RG_HOOKSHOT)
LOCATION(RC_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST, logic->HasFireSource() && logic->HasExplosives() && logic->IsAdult && (logic->CanUse(RG_HOOKSHOT) || ctx->GetTrickOption(RT_FIRE_MQ_BLOCKED_CHEST))),
//Trick: logic->HasFireSource() && logic->HasExplosives() && logic->IsAdult && (logic->CanUse(RG_HOOKSHOT) || LogicFireMQBlockedChest)
LOCATION(RC_FIRE_TEMPLE_MQ_GS_BIG_LAVA_ROOM_OPEN_DOOR, true),
}, { }, {
//Exits //Exits
Entrance(RR_FIRE_TEMPLE_MQ_LOWER_MAZE, {[]{return logic->IsAdult && logic->CanUse(RG_GORON_TUNIC) && logic->SmallKeys(RR_FIRE_TEMPLE, 2) && (logic->HasFireSource() || (ctx->GetTrickOption(RT_FIRE_MQ_CLIMB) && logic->CanUse(RG_HOVER_BOOTS)));}}), Entrance(RR_FIRE_TEMPLE_MQ_FIRST_ROOM_LOWER, {[]{return Here(RR_FIRE_TEMPLE_MQ_FIRST_ROOM_LOWER, {[]{return logic->CanKillEnemy(RE_LIKE_LIKE);}});}}),
//Trick: logic->IsAdult && logic->CanUse(RG_GORON_TUNIC) && logic->SmallKeys(RR_FIRE_TEMPLE, 2) && (logic->HasFireSource() || (LogicFireMQClimb && logic->CanUse(RG_HOVER_BOOTS))) Entrance(RR_FIRE_TEMPLE_MQ_MAP_ROOM_CAGE, {[]{return logic->OpenedLowestGoronCage;}}),
}); });
areaTable[RR_FIRE_TEMPLE_MQ_STALFOS_ROOM] = Region("Fire Temple MQ Stalfos Room", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
//Exits
Entrance(RR_FIRE_TEMPLE_MQ_FIRST_ROOM_LOWER, {[]{return true;}}),
Entrance(RR_FIRE_TEMPLE_MQ_IRON_KNUCKLE_ROOM, {[]{return Here(RR_FIRE_TEMPLE_MQ_FIRST_ROOM_LOWER, {[]{return logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, 2);}});}}),
});
areaTable[RR_FIRE_TEMPLE_MQ_IRON_KNUCKLE_ROOM] = Region("Fire Temple MQ Iron Knuckle Room", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->FairyPot, {[]{return true;}}),
}, {}, {
//Exits
Entrance(RR_FIRE_TEMPLE_MQ_STALFOS_ROOM, {[]{return true;}}),
Entrance(RR_FIRE_TEMPLE_MQ_LOWER_FLARE_DANCER, {[]{return Here(RR_FIRE_TEMPLE_MQ_FIRST_ROOM_LOWER, {[]{return logic->CanKillEnemy(RE_IRON_KNUCKLE);}});}}),
});
areaTable[RR_FIRE_TEMPLE_MQ_LOWER_FLARE_DANCER] = Region("Fire Temple MQ Lower Flare Dancer", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
//Locations
LOCATION(RC_FIRE_TEMPLE_MQ_MEGATON_HAMMER_CHEST, (logic->IsAdult || logic->CanUse(RG_HOOKSHOT)) && Here(RR_FIRE_TEMPLE_MQ_LOWER_FLARE_DANCER, {[]{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 Here(RR_FIRE_TEMPLE_MQ_LOWER_FLARE_DANCER, {[]{return logic->CanKillEnemy(RE_FLARE_DANCER);}});}}),
});
areaTable[RR_FIRE_TEMPLE_MQ_MAP_ROOM_NORTH] = Region("Fire Temple MQ Map Room North", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->OpenedLowestGoronCage, {[]{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->OpenedLowestGoronCage;}}),
});
areaTable[RR_FIRE_TEMPLE_MQ_MAP_ROOM_CAGE] = Region("Fire Temple MQ Map Room Cage", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
//Locations
LOCATION(RC_FIRE_TEMPLE_MQ_MAP_CHEST, true),
}, {
//Exits
Entrance(RR_FIRE_TEMPLE_MQ_MAP_ROOM_NORTH, {[]{return logic->OpenedLowestGoronCage;}}),
Entrance(RR_FIRE_TEMPLE_MQ_MAP_ROOM_SOUTH, {[]{return logic->OpenedLowestGoronCage;}}),
});
areaTable[RR_FIRE_TEMPLE_NEAR_BOSS_ROOM] = Region("Fire Temple MQ Near Boss Room", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
//Locations
//Child cannot make it to the north side torches without a hook without specifically bunny hood speed + hover boots
//The Damage logic here is for crossing to the north torches with hookshot, then using dins there before 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, //Using the south torch as the initial torch, or using FAs, we first have to sort the crate...
//If we don't go out of the way to break the box it's reasonable to do things in ~25 seconds, otherwise it takes about 40
(logic->FireTimer() > (ctx->GetTrickOption(RT_FIRE_MQ_NEAR_BOSS) ? 25 : 40) &&
(ctx->GetTrickOption(RT_FIRE_MQ_NEAR_BOSS) || logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS))) &&
//then use FA's, or dins + bow as adult. Child can only do a torch shot from the north side upper torch so will be handled in the lower case to avoid RT_FIRE_MQ_NEAR_BOSS issues
(logic->CanUse(RG_FIRE_ARROWS) || (logic->IsAdult && logic->CanUse(RG_DINS_FIRE) && logic->CanUse(RG_FAIRY_BOW)))) ||
//If we're starting with the north torches, we need to get across first, and light them
//Pretty much all these methods take ~20-30 seconds
(logic->FireTimer() > 30 &&
(logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS))) && logic->CanUse(RG_DINS_FIRE) &&
//then we need to either use a bow to shoot back across, or somehow get back to use dins again. Alternatively we can use Sticks as adult and NL
(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)))))))
}, {
//Exits
Entrance(RR_FIRE_TEMPLE_MQ_FIRST_ROOM_UPPER, {[]{return true;}}),
Entrance(RR_FIRE_TEMPLE_BOSS_ENTRYWAY, {[]{return logic->HasItem(RG_FIRE_TEMPLE_BOSS_KEY) && logic->FireTimer() >= 15 &&
(logic->IsAdult && (ctx->GetTrickOption(RT_FIRE_BOSS_DOOR_JUMP) || logic->CanUse(RG_HOVER_BOOTS))) ||
(logic->IsAdult && logic->HitFireTemplePlatform) ||
(logic->HitFireTemplePlatform && logic->CanUse(RG_HOVER_BOOTS))
;}}),
});
areaTable[RR_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM] = Region("Fire Temple MQ Big Lava Room", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
//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) || 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)),
}, {
//Exits
// 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(RR_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)));}}),
});
areaTable[RR_FIRE_TEMPLE_MQ_TORCH_FIREWALL_ROOM] = Region("Fire Temple MQ Torch Firewall Room", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->FairyPot, {[]{return logic->CanUse(RG_HOOKSHOT);}}),
}, {
//Locations
LOCATION(RC_FIRE_TEMPLE_MQ_BOSS_KEY_CHEST, logic->CanUse(RG_HOOKSHOT)),
}, {
//Exits
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", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
//Exits
Entrance(RR_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM, {[]{return true;}}),
Entrance(RR_FIRE_TEMPLE_MQ_BIG_TORCH_ROOM, {[]{return true;}}),
});
areaTable[RR_FIRE_TEMPLE_MQ_BIG_TORCH_ROOM] = Region("Fire Temple MQ Big Torch Room", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
//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->OpenedUpperFireShortcut;}}),
});
areaTable[RR_FIRE_TEMPLE_MQ_LOWER_MAZE] = Region("Fire Temple MQ Lower Maze", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { areaTable[RR_FIRE_TEMPLE_MQ_LOWER_MAZE] = Region("Fire Temple MQ Lower Maze", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
//Locations //Locations
LOCATION(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CHEST, logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)), //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) || HasAccessTo(RR_FIRE_TEMPLE_MQ_UPPER_MAZE))), LOCATION(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_SIDE_ROOM_CHEST, logic->HasExplosives() && ctx->GetTrickOption(RT_FIRE_MQ_MAZE_SIDE_ROOM)),
//Trick: logic->HasExplosives() && (LogicFireMQMazeSideRoom || FIRE_TEMPLE_MQ_UPPER_MAZE.Adult())
}, { }, {
//Exits //Exits
Entrance(RR_FIRE_TEMPLE_MQ_UPPER_MAZE, {[]{return (logic->IsAdult && ((logic->HasExplosives() && logic->CanUse(RG_HOOKSHOT)) || (ctx->GetTrickOption(RT_FIRE_MQ_MAZE_HOVERS) && logic->CanUse(RG_HOVER_BOOTS)))) || ctx->GetTrickOption(RT_FIRE_MQ_MAZE_JUMP);}}), Entrance(RR_FIRE_TEMPLE_MQ_BIG_TORCH_ROOM, {[]{return true;}}),
//Trick: (logic->IsAdult && ((logic->HasExplosives() && logic->CanUse(RG_HOOKSHOT)) || (LogicFireMQMazeHovers && logic->CanUse(RG_HOVER_BOOTS)))) || LogicFireMQMazeJump //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 Here(RR_FIRE_TEMPLE_MQ_LOWER_MAZE, {[]{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);}}),
}); });
areaTable[RR_FIRE_TEMPLE_MQ_UPPER_MAZE] = Region("Fire Temple MQ Upper Maze", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, { areaTable[RR_FIRE_TEMPLE_MQ_LOWER_MAZE_CRATE_CAGE] = Region("Fire Temple MQ Lower Maze Crate Cage", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
//Events //Locations
//EventAccess(&WallFairy, {[]{return WallFairy || (logic->IsAdult && (((logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_HOOKSHOT) && logic->HasExplosives()) || logic->CanUse(RG_LONGSHOT))));}}), LOCATION(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CHEST, true),
EventAccess(&logic->FairyPot, {[]{return logic->SmallKeys(RR_FIRE_TEMPLE, 3);}}),
}, { }, {
//Exits
Entrance(RR_FIRE_TEMPLE_MQ_LOWER_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));}}),
});
areaTable[RR_FIRE_TEMPLE_MQ_UPPER_MAZE] = Region("Fire Temple MQ Upper Maze", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
//Exits
Entrance(RR_FIRE_TEMPLE_MQ_LOWER_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 Here(RR_FIRE_TEMPLE_MQ_UPPER_MAZE, {[]{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_HIGH_TORCH_ROOM, {[]{return logic->SmallKeys(RR_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", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
//Locations //Locations
LOCATION(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CHEST, true), LOCATION(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CHEST, true),
LOCATION(RC_FIRE_TEMPLE_MQ_COMPASS_CHEST, logic->HasExplosives()), //Assumes maze access
LOCATION(RC_FIRE_TEMPLE_MQ_GS_SKULL_ON_FIRE, logic->IsAdult && ((logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_HOOKSHOT) && logic->HasExplosives()) || logic->CanUse(RG_LONGSHOT))), LOCATION(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_SIDE_ROOM_CHEST, logic->HasExplosives()),
}, { }, {
//Exits //Exits
Entrance(RR_FIRE_TEMPLE_MQ_UPPER, {[]{return logic->SmallKeys(RR_FIRE_TEMPLE, 3) && logic->IsAdult && ((logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_HOOKSHOT)) || logic->CanUse(RG_FIRE_ARROWS));}}), Entrance(RR_FIRE_TEMPLE_MQ_UPPER_MAZE, {[]{return true;}}),
}); });
areaTable[RR_FIRE_TEMPLE_MQ_UPPER] = Region("Fire Temple MQ Upper", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { areaTable[RR_FIRE_TEMPLE_MQ_MAZE_SHORTCUT] = Region("Fire Temple MQ Maze Shortcut", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->OpenedUpperFireShortcut, {[]{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->OpenedUpperFireShortcut;}}),
});
areaTable[RR_FIRE_TEMPLE_MQ_MAZE_SHORTCUT_CAGE] = Region("Fire Temple MQ Maze Shortcut Cage", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
//Locations
LOCATION(RC_FIRE_TEMPLE_MQ_COMPASS_CHEST, logic->OpenedUpperFireShortcut;),
}, {
//Exits
Entrance(RR_FIRE_TEMPLE_MQ_MAZE_SHORTCUT, {[]{return logic->OpenedUpperFireShortcut;}}),
Entrance(RR_FIRE_TEMPLE_MQ_BIG_TORCH_ROOM, {[]{return logic->OpenedUpperFireShortcut;}}),
});
areaTable[RR_FIRE_TEMPLE_MQ_BURNING_BLOCK_CLIMB] = Region("Fire Temple MQ Burning Block Climb", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
//Events
//EventAccess(&WallFairy, {[]{return logic->CanUse(RG_HOOKSHOT);}}),
}, {
//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)),
}, {
//Exits
Entrance(RR_FIRE_TEMPLE_MQ_UPPER_MAZE, {[]{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", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->FairyPot, {[]{return true;}}),
}, {}, {
//Exits
Entrance(RR_FIRE_TEMPLE_MQ_LOWER_MAZE, {[]{return true;}}),
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", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
//Exits
Entrance(RR_FIRE_TEMPLE_MQ_UPPER_MAZE, {[]{return logic->SmallKeys(RR_FIRE_TEMPLE, 3);}}),
Entrance(RR_FIRE_TEMPLE_MQ_NARROW_PATH_ROOM, {[]{return true;}}),
//Child has issues navigating the higher points of this room without an equip swapped hookshot
Entrance(RR_FIRE_TEMPLE_MQ_SOUTH_FIRE_MAZE, {[]{return Here(RR_FIRE_TEMPLE_MQ_HIGH_TORCH_ROOM, {[]{return logic->CanUse(RG_FIRE_ARROWS) || (logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_HOOKSHOT));}}) &&
(logic->IsAdult || logic->CanUse(RG_HOOKSHOT));}}),
});
areaTable[RR_FIRE_TEMPLE_MQ_SOUTH_FIRE_MAZE] = Region("Fire Temple MQ South Fire Maze", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
//Locations //Locations
LOCATION(RC_FIRE_TEMPLE_MQ_FREESTANDING_KEY, ((logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG)) && logic->CanUse(RG_HOOKSHOT)) || ctx->GetTrickOption(RT_FIRE_MQ_FLAME_MAZE)),
//Trick: (logic->IsAdult && logic->CanUse(RG_HOOKSHOT)) || LogicFireMQFlameMaze
LOCATION(RC_FIRE_TEMPLE_MQ_CHEST_ON_FIRE, ((logic->IsAdult && logic->CanUse(RG_HOOKSHOT)) || ctx->GetTrickOption(RT_FIRE_MQ_FLAME_MAZE)) && logic->SmallKeys(RR_FIRE_TEMPLE, 4)),
//Trick: ((logic->IsAdult && logic->CanUse(RG_HOOKSHOT)) || LogicFireMQFlameMaze) && logic->SmallKeys(RR_FIRE_TEMPLE, 4)
LOCATION(RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_SIDE_ROOM, logic->CanUse(RG_SONG_OF_TIME) || logic->CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_FIRE_MQ_FLAME_MAZE)),
//Trick: logic->CanUse(RG_SONG_OF_TIME) || logic->CanUse(RG_HOVER_BOOTS) || LogicFireMQFlameMaze
LOCATION(RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_CENTER, logic->HasExplosives()), LOCATION(RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_CENTER, logic->HasExplosives()),
LOCATION(RC_FIRE_TEMPLE_MQ_GS_ABOVE_FIRE_WALL_MAZE, (logic->IsAdult && logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(RR_FIRE_TEMPLE, 5)) || (ctx->GetTrickOption(RT_FIRE_MQ_ABOVE_MAZE_GS) && logic->IsAdult && logic->CanUse(RG_LONGSHOT))), }, {
//Trick: (logic->IsAdult && logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(RR_FIRE_TEMPLE, 5)) || (LogicFireMQAboveMazeGS && logic->IsAdult && logic->CanUse(RG_LONGSHOT)) //Exits
}, {}); Entrance(RR_FIRE_TEMPLE_MQ_NEAR_BOSS_DOOR, {[]{return logic->HitFireTemplePlatform;}}),
Entrance(RR_FIRE_TEMPLE_MQ_HIGH_TORCH_ROOM, {[]{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_FIRE_MAZE_SIDE_ROOM, {[]{return (bool)ctx->GetTrickOption(RT_FIRE_MQ_FLAME_MAZE);}}),
Entrance(RR_FIRE_TEMPLE_MQ_NORTH_FIRE_MAZE, {[]{return logic->OpenedFireMQFireMazeDoor;}}),
});
areaTable[RR_FIRE_TEMPLE_MQ_FIRE_MAZE_PLATFORMS] = Region("Fire Temple MQ Fire Maze Platforms", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->HitFireTemplePlatform, {[]{return logic->CanUse(RG_MEGATON_HAMMER);}}),
EventAccess(&logic->OpenedFireMQFireMazeDoor, {[]{return logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_HOOKSHOT);}}),
}, {}, {
Entrance(RR_FIRE_TEMPLE_MQ_SOUTH_FIRE_MAZE, {[]{return true;}}),
Entrance(RR_FIRE_TEMPLE_MQ_FIRE_MAZE_SIDE_ROOM, {[]{return logic->CanUse(RG_SONG_OF_TIME) || logic->CanUse(RG_HOVER_BOOTS);}}),
//trick to get to RR_FIRE_TEMPLE_MQ_NORTH_FIRE_MAZE with hovers + taking damage is plausible
});
areaTable[RR_FIRE_TEMPLE_MQ_FIRE_MAZE_SIDE_ROOM] = Region("Fire Temple MQ Side Room", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
//Locations
LOCATION(RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_SIDE_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)),
}, {
//Exits
Entrance(RR_FIRE_TEMPLE_MQ_SOUTH_FIRE_MAZE, {[]{return logic->IsAdult || ctx->GetTrickOption(RT_FIRE_MQ_FLAME_MAZE);}}),
Entrance(RR_FIRE_TEMPLE_MQ_NORTH_FIRE_MAZE, {[]{return (bool)ctx->GetTrickOption(RT_FIRE_MQ_FLAME_MAZE);}}),
});
areaTable[RR_FIRE_TEMPLE_MQ_NORTH_FIRE_MAZE] = Region("Fire Temple MQ North Fire Maze", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
Entrance(RR_FIRE_TEMPLE_MQ_FIRE_MAZE_PAST_WALL, {[]{return true;}}),
Entrance(RR_FIRE_TEMPLE_MQ_FIRE_MAZE_SIDE_ROOM, {[]{return (bool)ctx->GetTrickOption(RT_FIRE_MQ_FLAME_MAZE);}}),
});
//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", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
Entrance(RR_FIRE_TEMPLE_MQ_UPPER_FLARE_DANCER, {[]{return true;}}),
});
areaTable[RR_FIRE_TEMPLE_MQ_UPPER_FLARE_DANCER] = Region("Fire Temple MQ North Fire Maze", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
//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(RR_FIRE_TEMPLE, 4);}}),
});
areaTable[RR_FIRE_TEMPLE_MQ_SCARECROW_ROOM] = Region("Fire Temple MQ Scarecrow Room", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
//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
//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(RR_FIRE_TEMPLE, 4);}}),
Entrance(RR_FIRE_TEMPLE_MQ_COLLAPSED_STAIRS, {[]{return Here(RR_FIRE_TEMPLE_MQ_SCARECROW_ROOM, {[]{return logic->CanUse(RG_MEGATON_HAMMER);}}) && logic->SmallKeys(RR_FIRE_TEMPLE, 5);}}),
});
//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", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
//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)),
}, {
Entrance(RR_FIRE_TEMPLE_MQ_FIRE_MAZE_PLATFORMS, {[]{return logic->CanUse(RG_HOOKSHOT) && Here(RR_FIRE_TEMPLE_MQ_COLLAPSED_STAIRS, {[]{return logic->CanUse(RG_MEGATON_HAMMER);}});}}),
Entrance(RR_FIRE_TEMPLE_MQ_SCARECROW_ROOM, {[]{return logic->IsAdult && logic->CanUse(RG_HOOKSHOT);}}),
});
} }
/*--------------------------- /*---------------------------
@ -400,7 +627,7 @@ void RegionTable_Init_FireTemple() {
{ {
// Exits // Exits
Entrance(RR_FIRE_TEMPLE_NEAR_BOSS_ROOM, { [] { return ctx->GetDungeon(FIRE_TEMPLE)->IsVanilla() && false; } }), Entrance(RR_FIRE_TEMPLE_NEAR_BOSS_ROOM, { [] { return ctx->GetDungeon(FIRE_TEMPLE)->IsVanilla() && false; } }),
Entrance(RR_FIRE_TEMPLE_MQ_LOWER, { [] { return ctx->GetDungeon(FIRE_TEMPLE)->IsMQ() && false; } }), Entrance(RR_FIRE_TEMPLE_MQ_NEAR_BOSS_DOOR, { [] { return ctx->GetDungeon(FIRE_TEMPLE)->IsMQ() && false; } }),
Entrance(RR_FIRE_TEMPLE_BOSS_ROOM, { [] { return true; } }), Entrance(RR_FIRE_TEMPLE_BOSS_ROOM, { [] { return true; } }),
}); });

View File

@ -368,7 +368,7 @@ Dungeons::Dungeons() {
RC_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST, RC_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST,
RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_SIDE_ROOM_CHEST, RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_SIDE_ROOM_CHEST,
RC_FIRE_TEMPLE_MQ_FREESTANDING_KEY, RC_FIRE_TEMPLE_MQ_FREESTANDING_KEY,
RC_FIRE_TEMPLE_MQ_GS_ABOVE_FIRE_WALL_MAZE, RC_FIRE_TEMPLE_MQ_GS_ABOVE_FIRE_MAZE,
RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_CENTER, RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_CENTER,
RC_FIRE_TEMPLE_MQ_GS_BIG_LAVA_ROOM_OPEN_DOOR, RC_FIRE_TEMPLE_MQ_GS_BIG_LAVA_ROOM_OPEN_DOOR,
RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_SIDE_ROOM, RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_SIDE_ROOM,

View File

@ -687,7 +687,7 @@ void Rando::StaticData::InitLocationTable() { //
locationTable[RC_FIRE_TEMPLE_GS_BOULDER_MAZE] = Location::GSToken(RC_FIRE_TEMPLE_GS_BOULDER_MAZE, RCQUEST_VANILLA, SCENE_FIRE_TEMPLE, 9220, 0x04, "GS Boulder Maze", RHT_FIRE_TEMPLE_GS_BOULDER_MAZE); locationTable[RC_FIRE_TEMPLE_GS_BOULDER_MAZE] = Location::GSToken(RC_FIRE_TEMPLE_GS_BOULDER_MAZE, RCQUEST_VANILLA, SCENE_FIRE_TEMPLE, 9220, 0x04, "GS Boulder Maze", RHT_FIRE_TEMPLE_GS_BOULDER_MAZE);
locationTable[RC_FIRE_TEMPLE_GS_SCARECROW_TOP] = Location::GSToken(RC_FIRE_TEMPLE_GS_SCARECROW_TOP, RCQUEST_VANILLA, SCENE_FIRE_TEMPLE, 9224, 0x08, "GS Scarecrow Top", RHT_FIRE_TEMPLE_GS_SCARECROW_TOP); locationTable[RC_FIRE_TEMPLE_GS_SCARECROW_TOP] = Location::GSToken(RC_FIRE_TEMPLE_GS_SCARECROW_TOP, RCQUEST_VANILLA, SCENE_FIRE_TEMPLE, 9224, 0x08, "GS Scarecrow Top", RHT_FIRE_TEMPLE_GS_SCARECROW_TOP);
locationTable[RC_FIRE_TEMPLE_GS_SCARECROW_CLIMB] = Location::GSToken(RC_FIRE_TEMPLE_GS_SCARECROW_CLIMB, RCQUEST_VANILLA, SCENE_FIRE_TEMPLE, 9232, 0x10, "GS Scarecrow Climb", RHT_FIRE_TEMPLE_GS_SCARECROW_CLIMB); locationTable[RC_FIRE_TEMPLE_GS_SCARECROW_CLIMB] = Location::GSToken(RC_FIRE_TEMPLE_GS_SCARECROW_CLIMB, RCQUEST_VANILLA, SCENE_FIRE_TEMPLE, 9232, 0x10, "GS Scarecrow Climb", RHT_FIRE_TEMPLE_GS_SCARECROW_CLIMB);
locationTable[RC_FIRE_TEMPLE_MQ_GS_ABOVE_FIRE_WALL_MAZE] = Location::GSToken(RC_FIRE_TEMPLE_MQ_GS_ABOVE_FIRE_WALL_MAZE, RCQUEST_MQ, SCENE_FIRE_TEMPLE, 9218, 0x02, "MQ GS Above Fire Wall Maze", RHT_FIRE_TEMPLE_MQ_GS_ABOVE_FIRE_WALL_MAZE); locationTable[RC_FIRE_TEMPLE_MQ_GS_ABOVE_FIRE_MAZE] = Location::GSToken(RC_FIRE_TEMPLE_MQ_GS_ABOVE_FIRE_MAZE, RCQUEST_MQ, SCENE_FIRE_TEMPLE, 9218, 0x02, "MQ GS Above Fire Wall Maze", RHT_FIRE_TEMPLE_MQ_GS_ABOVE_FIRE_WALL_MAZE);
locationTable[RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_CENTER] = Location::GSToken(RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_CENTER, RCQUEST_MQ, SCENE_FIRE_TEMPLE, 9224, 0x08, "MQ GS Fire Wall Maze Center", RHT_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_CENTER); locationTable[RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_CENTER] = Location::GSToken(RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_CENTER, RCQUEST_MQ, SCENE_FIRE_TEMPLE, 9224, 0x08, "MQ GS Fire Wall Maze Center", RHT_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_CENTER);
locationTable[RC_FIRE_TEMPLE_MQ_GS_BIG_LAVA_ROOM_OPEN_DOOR] = Location::GSToken(RC_FIRE_TEMPLE_MQ_GS_BIG_LAVA_ROOM_OPEN_DOOR, RCQUEST_MQ, SCENE_FIRE_TEMPLE, 9217, 0x01, "MQ GS Big Lava Room Open Door", RHT_FIRE_TEMPLE_MQ_GS_BIG_LAVA_ROOM_OPEN_DOOR); locationTable[RC_FIRE_TEMPLE_MQ_GS_BIG_LAVA_ROOM_OPEN_DOOR] = Location::GSToken(RC_FIRE_TEMPLE_MQ_GS_BIG_LAVA_ROOM_OPEN_DOOR, RCQUEST_MQ, SCENE_FIRE_TEMPLE, 9217, 0x01, "MQ GS Big Lava Room Open Door", RHT_FIRE_TEMPLE_MQ_GS_BIG_LAVA_ROOM_OPEN_DOOR);
locationTable[RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_SIDE_ROOM] = Location::GSToken(RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_SIDE_ROOM, RCQUEST_MQ, SCENE_FIRE_TEMPLE, 9232, 0x10, "MQ GS Fire Wall Maze Side Room", RHT_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_SIDE_ROOM); locationTable[RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_SIDE_ROOM] = Location::GSToken(RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_SIDE_ROOM, RCQUEST_MQ, SCENE_FIRE_TEMPLE, 9232, 0x10, "MQ GS Fire Wall Maze Side Room", RHT_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_SIDE_ROOM);

View File

@ -232,6 +232,7 @@ namespace Rando {
} }
//Can the passed in item be used? //Can the passed in item be used?
//RANDOTODO catch magic items explicitly and add an assert on miss.
bool Logic::CanUse(RandomizerGet itemName) { bool Logic::CanUse(RandomizerGet itemName) {
if (!HasItem(itemName)) if (!HasItem(itemName))
return false; return false;
@ -420,7 +421,8 @@ namespace Rando {
return false; return false;
} }
bool Logic::CanKillEnemy(RandomizerEnemy enemy, EnemyDistance distance) { //RANDOTODO quantity is a placeholder for proper ammo use calculation logic. in time will want updating to account for ammo capacity
bool Logic::CanKillEnemy(RandomizerEnemy enemy, EnemyDistance distance, uint8_t quantity) {
bool killed = false; bool killed = false;
switch(enemy) { switch(enemy) {
case RE_GOLD_SKULLTULA: case RE_GOLD_SKULLTULA:
@ -465,6 +467,23 @@ namespace Rando {
return CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD) || (CanUse(RG_STICKS) && ctx->GetTrickOption(RT_BOTW_CHILD_DEADHAND)); return CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD) || (CanUse(RG_STICKS) && ctx->GetTrickOption(RT_BOTW_CHILD_DEADHAND));
case RE_WITHERED_DEKU_BABA: case RE_WITHERED_DEKU_BABA:
return CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_BOOMERANG); return CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_BOOMERANG);
case RE_LIKE_LIKE:
return CanDamage();
case RE_STALFOS:
//RANDOTODO Add trick to kill stalfos with sticks, and a second one for bombs without stunning. Higher ammo logic for bombs is also plausible
return CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_MEGATON_HAMMER) || CanUse(RG_FAIRY_BOW) || CanUse(RG_BOMBCHU_5) ||
(quantity <= 2 && (CanUse(RG_NUTS) || HookshotOrBoomerang()) && CanUse(RG_BOMB_BAG)) || (quantity <= 1 && CanUse(RG_STICKS));
//Needs 16 bombs, but is in default logic in N64, probably because getting the hits is quite easy.
//bow and sling can wake them and damage after they shed their armour, so could reduce ammo requirements for explosives to 10.
//requires 8 sticks to kill so would be a trick unless we apply higher stick bag logic
case RE_IRON_KNUCKLE:
return CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_MEGATON_HAMMER) || HasExplosives();
//To stun flare dancer with chus, you have to hit the flame under it while it is spinning. It should eventually return to spinning after dashing for a while if you miss the window
//it is possible to damage the core with explosives, but difficult to get all 4 hits in even with chus, and if it reconstructs the core heals, so it would be a trick.
//the core takes damage from hookshot even if it doesn't show
//Dins killing isn't hard, but is obscure and tight on single magic, so is a trick
case RE_FLARE_DANCER:
return CanUse(RG_MEGATON_HAMMER) || CanUse(RG_HOOKSHOT) || (HasExplosives() && (CanJumpslashExceptHammer() || CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_BOOMERANG)));
default: default:
SPDLOG_ERROR("CanKillEnemy reached `default`."); SPDLOG_ERROR("CanKillEnemy reached `default`.");
assert(false); assert(false);
@ -490,10 +509,16 @@ namespace Rando {
case RE_DEAD_HAND: case RE_DEAD_HAND:
case RE_DEKU_BABA: case RE_DEKU_BABA:
case RE_WITHERED_DEKU_BABA: case RE_WITHERED_DEKU_BABA:
case RE_STALFOS:
case RE_FLARE_DANCER:
return true; return true;
case RE_BIG_SKULLTULA: case RE_BIG_SKULLTULA:
//hammer jumpslash can pass, but only on flat land where you can kill with hammer swing //hammer jumpslash can pass, but only on flat land where you can kill with hammer swing
return CanUse(RG_NUTS) || CanUse(RG_BOOMERANG); return CanUse(RG_NUTS) || CanUse(RG_BOOMERANG);
case RE_LIKE_LIKE:
return CanUse(RG_HOOKSHOT) || CanUse(RG_BOOMERANG);
case RE_IRON_KNUCKLE:
return false;
default: default:
SPDLOG_ERROR("CanPassEnemy reached `default`."); SPDLOG_ERROR("CanPassEnemy reached `default`.");
assert(false); assert(false);
@ -514,6 +539,10 @@ namespace Rando {
case RE_DEAD_HAND: case RE_DEAD_HAND:
case RE_DEKU_BABA: case RE_DEKU_BABA:
case RE_WITHERED_DEKU_BABA: case RE_WITHERED_DEKU_BABA:
case RE_LIKE_LIKE:
case RE_STALFOS:
case RE_IRON_KNUCKLE:
case RE_FLARE_DANCER:
return true; return true;
case RE_MAD_SCRUB: case RE_MAD_SCRUB:
case RE_KEESE: case RE_KEESE:
@ -1843,6 +1872,10 @@ namespace Rando {
ClearedMQDekuSERoom = false; ClearedMQDekuSERoom = false;
MQDekuWaterRoomTorches = false; MQDekuWaterRoomTorches = false;
PushedDekuBasementBlock = false; PushedDekuBasementBlock = false;
OpenedLowestGoronCage = false;
OpenedUpperFireShortcut = false;
HitFireTemplePlatform = false;
OpenedFireMQFireMazeDoor = false;
StopPerformanceTimer(PT_LOGIC_RESET); StopPerformanceTimer(PT_LOGIC_RESET);
} }

View File

@ -140,6 +140,10 @@ class Logic {
bool ClearedMQDekuSERoom = false; bool ClearedMQDekuSERoom = false;
bool MQDekuWaterRoomTorches = false; bool MQDekuWaterRoomTorches = false;
bool PushedDekuBasementBlock = false; bool PushedDekuBasementBlock = false;
bool OpenedLowestGoronCage = false;
bool OpenedUpperFireShortcut = false;
bool HitFireTemplePlatform = false;
bool OpenedFireMQFireMazeDoor = false;
/* --- END OF HELPERS AND LOCATION ACCESS --- */ /* --- END OF HELPERS AND LOCATION ACCESS --- */
@ -153,7 +157,7 @@ class Logic {
bool SmallKeys(RandomizerRegion dungeon, uint8_t requiredAmountGlitchless, uint8_t requiredAmountGlitched); bool SmallKeys(RandomizerRegion dungeon, uint8_t requiredAmountGlitchless, uint8_t requiredAmountGlitched);
bool CanDoGlitch(GlitchType glitch); bool CanDoGlitch(GlitchType glitch);
bool CanEquipSwap(RandomizerGet itemName); bool CanEquipSwap(RandomizerGet itemName);
bool CanKillEnemy(RandomizerEnemy enemy, EnemyDistance distance = ED_CLOSE); bool CanKillEnemy(RandomizerEnemy enemy, EnemyDistance distance = ED_CLOSE, uint8_t quantity = 1);
bool CanPassEnemy(RandomizerEnemy enemy, EnemyDistance distance = ED_CLOSE); bool CanPassEnemy(RandomizerEnemy enemy, EnemyDistance distance = ED_CLOSE);
bool CanAvoidEnemy(RandomizerEnemy enemy); bool CanAvoidEnemy(RandomizerEnemy enemy);
bool CanGetEnemyDrop(RandomizerEnemy enemy, EnemyDistance distance = ED_CLOSE, bool aboveLink = false); bool CanGetEnemyDrop(RandomizerEnemy enemy, EnemyDistance distance = ED_CLOSE, bool aboveLink = false);

View File

@ -672,12 +672,36 @@ typedef enum {
RR_FIRE_TEMPLE_HAMMER_RETURN_PATH, RR_FIRE_TEMPLE_HAMMER_RETURN_PATH,
RR_FIRE_TEMPLE_ABOVE_FIRE_MAZE, RR_FIRE_TEMPLE_ABOVE_FIRE_MAZE,
RR_FIRE_TEMPLE_MQ_LOWER, RR_FIRE_TEMPLE_MQ_FIRST_ROOM_LOWER,
RR_FIRE_TEMPLE_MQ_LOWER_LOCKED_DOOR, 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_NEAR_BOSS_DOOR,
RR_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM, RR_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM,
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,
RR_FIRE_TEMPLE_MQ_LOWER_MAZE_CRATE_CAGE,
RR_FIRE_TEMPLE_MQ_UPPER_MAZE, RR_FIRE_TEMPLE_MQ_UPPER_MAZE,
RR_FIRE_TEMPLE_MQ_UPPER, 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_NARROW_PATH_ROOM,
RR_FIRE_TEMPLE_MQ_HIGH_TORCH_ROOM,
RR_FIRE_TEMPLE_MQ_SOUTH_FIRE_MAZE,
RR_FIRE_TEMPLE_MQ_FIRE_MAZE_PLATFORMS,
RR_FIRE_TEMPLE_MQ_FIRE_MAZE_SIDE_ROOM,
RR_FIRE_TEMPLE_MQ_NORTH_FIRE_MAZE,
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_BOSS_ENTRYWAY, RR_FIRE_TEMPLE_BOSS_ENTRYWAY,
RR_FIRE_TEMPLE_BOSS_ROOM, RR_FIRE_TEMPLE_BOSS_ROOM,
@ -1371,7 +1395,7 @@ typedef enum {
RC_FIRE_TEMPLE_MQ_GS_SKULL_ON_FIRE, RC_FIRE_TEMPLE_MQ_GS_SKULL_ON_FIRE,
RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_CENTER, RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_CENTER,
RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_SIDE_ROOM, RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_SIDE_ROOM,
RC_FIRE_TEMPLE_MQ_GS_ABOVE_FIRE_WALL_MAZE, RC_FIRE_TEMPLE_MQ_GS_ABOVE_FIRE_MAZE,
RC_FIRE_TEMPLE_VOLVAGIA_HEART, RC_FIRE_TEMPLE_VOLVAGIA_HEART,
RC_WATER_TEMPLE_COMPASS_CHEST, RC_WATER_TEMPLE_COMPASS_CHEST,
RC_WATER_TEMPLE_MAP_CHEST, RC_WATER_TEMPLE_MAP_CHEST,
@ -4419,6 +4443,10 @@ typedef enum {
RE_DEAD_HAND, RE_DEAD_HAND,
RE_DEKU_BABA, RE_DEKU_BABA,
RE_WITHERED_DEKU_BABA, RE_WITHERED_DEKU_BABA,
RE_LIKE_LIKE,
RE_STALFOS,
RE_IRON_KNUCKLE,
RE_FLARE_DANCER,
} RandomizerEnemy; } RandomizerEnemy;
typedef enum { typedef enum {

View File

@ -424,6 +424,7 @@ void Settings::CreateOptions() {
// mTrickOptions[RT_FOREST_MQ_HOOKSHOT_HALLWAY_SWITCH] = TrickOption::LogicTrick(RCQUEST_MQ, RA_FOREST_TEMPLE, {Tricks::Tag::INTERMEDIATE}, false, "Forest Temple MQ Twisted Hallway Switch with Hookshot", "There's a very small gap between the glass block and the wall. Through that gap you can hookshot the target on the ceiling."); // mTrickOptions[RT_FOREST_MQ_HOOKSHOT_HALLWAY_SWITCH] = TrickOption::LogicTrick(RCQUEST_MQ, RA_FOREST_TEMPLE, {Tricks::Tag::INTERMEDIATE}, false, "Forest Temple MQ Twisted Hallway Switch with Hookshot", "There's a very small gap between the glass block and the wall. Through that gap you can hookshot the target on the ceiling.");
mTrickOptions[RT_FOREST_MQ_RANG_HALLWAY_SWITCH] = TrickOption::LogicTrick(RCQUEST_MQ, RA_FOREST_TEMPLE, {Tricks::Tag::INTERMEDIATE}, false, "Forest Temple MQ Twisted Hallway Switch with Boomerang", "The Boomerang can return to Link through walls, allowing child to hit the hallway switch. This can be used to allow adult to pass through later, or in conjuction with \"Forest Temple Outside Backdoor with Jump Slash\"."); mTrickOptions[RT_FOREST_MQ_RANG_HALLWAY_SWITCH] = TrickOption::LogicTrick(RCQUEST_MQ, RA_FOREST_TEMPLE, {Tricks::Tag::INTERMEDIATE}, false, "Forest Temple MQ Twisted Hallway Switch with Boomerang", "The Boomerang can return to Link through walls, allowing child to hit the hallway switch. This can be used to allow adult to pass through later, or in conjuction with \"Forest Temple Outside Backdoor with Jump Slash\".");
mTrickOptions[RT_FIRE_BOSS_DOOR_JUMP] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_FIRE_TEMPLE, {Tricks::Tag::NOVICE}, false, "Fire Temple Boss Door without Hover Boots or Pillar", "The Fire Temple Boss Door can be reached as adult with a precise jump. You must be touching the side wall of the room so that Link will grab the ledge from farther away than is normally possible."); mTrickOptions[RT_FIRE_BOSS_DOOR_JUMP] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_FIRE_TEMPLE, {Tricks::Tag::NOVICE}, false, "Fire Temple Boss Door without Hover Boots or Pillar", "The Fire Temple Boss Door can be reached as adult with a precise jump. You must be touching the side wall of the room so that Link will grab the ledge from farther away than is normally possible.");
//Is also used in MQ logic, but has no practical effect there as of now
mTrickOptions[RT_FIRE_SOT] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_FIRE_TEMPLE, {Tricks::Tag::INTERMEDIATE}, false, "Fire Temple Song of Time Room GS without Song of Time", "A precise jump can be used to reach this room."); mTrickOptions[RT_FIRE_SOT] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_FIRE_TEMPLE, {Tricks::Tag::INTERMEDIATE}, false, "Fire Temple Song of Time Room GS without Song of Time", "A precise jump can be used to reach this room.");
mTrickOptions[RT_FIRE_STRENGTH] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_FIRE_TEMPLE, {Tricks::Tag::INTERMEDIATE}, false, "Fire Temple Climb without Strength", "A precise jump can be used to skip pushing the block."); mTrickOptions[RT_FIRE_STRENGTH] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_FIRE_TEMPLE, {Tricks::Tag::INTERMEDIATE}, false, "Fire Temple Climb without Strength", "A precise jump can be used to skip pushing the block.");
mTrickOptions[RT_FIRE_SCARECROW] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_FIRE_TEMPLE, {Tricks::Tag::EXPERT}, false, "Fire Temple East Tower without Scarecrow\'s Song", "Also known as \"Pixelshot\". The Longshot can reach the target on the elevator itself, allowing you to skip needing to spawn the scarecrow."); mTrickOptions[RT_FIRE_SCARECROW] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_FIRE_TEMPLE, {Tricks::Tag::EXPERT}, false, "Fire Temple East Tower without Scarecrow\'s Song", "Also known as \"Pixelshot\". The Longshot can reach the target on the elevator itself, allowing you to skip needing to spawn the scarecrow.");