mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2024-12-22 08:08:53 -05:00
Rewrite MQ spirit logic (#4534)
* rewrite MQ spirit logic * fix oversights
This commit is contained in:
parent
c8815a26f7
commit
2603b97366
@ -211,6 +211,14 @@ bool Here(const RandomizerRegion region, ConditionFn condition) {
|
|||||||
return areaTable[region].Here(condition);
|
return areaTable[region].Here(condition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MQSpiritSharedStatueRoom(const RandomizerRegion region, ConditionFn condition, bool anyAge) {
|
||||||
|
return areaTable[region].MQSpiritShared(condition, false, anyAge);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MQSpiritSharedBrokenWallRoom(const RandomizerRegion region, ConditionFn condition, bool anyAge) {
|
||||||
|
return areaTable[region].MQSpiritShared(condition, true, anyAge);
|
||||||
|
}
|
||||||
|
|
||||||
bool CanPlantBean(const RandomizerRegion region) {
|
bool CanPlantBean(const RandomizerRegion region) {
|
||||||
return areaTable[region].CanPlantBeanCheck();
|
return areaTable[region].CanPlantBeanCheck();
|
||||||
}
|
}
|
||||||
@ -256,7 +264,7 @@ void RegionTable_Init() {
|
|||||||
LOCATION(RC_SARIA_SONG_HINT, logic->CanUse(RG_SARIAS_SONG)),
|
LOCATION(RC_SARIA_SONG_HINT, logic->CanUse(RG_SARIAS_SONG)),
|
||||||
}, {
|
}, {
|
||||||
//Exits
|
//Exits
|
||||||
Entrance(RR_ROOT_EXITS, {[]{return true;}})
|
Entrance(RR_ROOT_EXITS, {[]{return true;}}),
|
||||||
});
|
});
|
||||||
|
|
||||||
areaTable[RR_ROOT_EXITS] = Region("Root Exits", "", {RA_LINKS_POCKET}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
areaTable[RR_ROOT_EXITS] = Region("Root Exits", "", {RA_LINKS_POCKET}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||||
|
@ -205,7 +205,7 @@ public:
|
|||||||
return areas;
|
return areas;
|
||||||
}
|
}
|
||||||
|
|
||||||
RandomizerArea GetFirstArea() const{
|
RandomizerArea GetFirstArea() const{
|
||||||
if (areas.empty()){
|
if (areas.empty()){
|
||||||
assert(false);
|
assert(false);
|
||||||
return RA_NONE;
|
return RA_NONE;
|
||||||
@ -253,12 +253,84 @@ public:
|
|||||||
"Adult Day: " + std::to_string(adultDay) + "\t"
|
"Adult Day: " + std::to_string(adultDay) + "\t"
|
||||||
"Adult Night: " + std::to_string(adultNight);
|
"Adult Night: " + std::to_string(adultNight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*This logic covers checks that exist in the shared areas of MQ spirit from a glitchless standpoint.
|
||||||
|
This room has Quantum logic that I am currently handling with this function, however this is NOT suitable for glitch logic as it relies on specific ages
|
||||||
|
In this chunk there are 3 possibilities for passing a check, but first I have to talk about parallel universes.
|
||||||
|
|
||||||
|
In MQ Spirit key logic, we mostly care about 2 possibilities for how the player can spend keys, creating 2 Parralel universes
|
||||||
|
In the first universe, the player did not enter spirit as adult until after climbing as child, thus child spends keys linearly, only needing 2 to reach statue room.
|
||||||
|
In the second universe, the player went in as adult, possibly out of logic, and started wasting the keys to lock child out.
|
||||||
|
These Universes converge when the player has 7 keys (meaning adult can no longer lock child out) and adult is known to be able to reach Statue room. This creates "Certain Access", which is tracked seperatly for each age.
|
||||||
|
Child Certain Access is simple, if we have 7 keys and child access, it's Certain Access.
|
||||||
|
Adult Certain Access is also simple, adult is not key locked, so if they make it to a location, it's Certain Access.
|
||||||
|
Things get complicated when we handle the overlap of the 2 universes,
|
||||||
|
though an important detail is that if we have Certain Access as either age, we don't need to checked the overlap because overlap logic is strictly stricter than either Certain Access.
|
||||||
|
|
||||||
|
In order to track the first universe, the logic allows technical child access with the minimum number of keys, and then checks in this function for if we have 7 keys to determine if that is Certain or not.
|
||||||
|
This is for technical reasons, as areas with no access at all will simply not be checked.
|
||||||
|
Normally we would need to do similar shenanigans to track the second universe, however adult must have go through statue room to waste keys,
|
||||||
|
so can go back there and get new keys for Child to use if they do, and the navigation logic for shared MQ spirit from Statue Room is very simple for Adult.
|
||||||
|
Additionally, we don't need to know if adult can actually reach spirit temple or climb to statue room, because if the player can't do that, then universe 2 can't happen anyway,
|
||||||
|
and if the player does so out of logic, they can do it again, as the only consumable used sets a permanent flag.
|
||||||
|
|
||||||
|
The Adult Navigation logic is as such:
|
||||||
|
- Broken Wall room is 6 key locked, because if the player tries to spend 6 keys in a way that would block adults access, they would have to give child access instead.
|
||||||
|
- The child side hammer switch for the time travelling chest is 7 key locked for adult
|
||||||
|
- Reaching gauntlets hand is 7 key locked
|
||||||
|
- Going back into big block room is complex, but the only check there is child only so not a concern
|
||||||
|
- Everything else is possible with basic adult movement, or is impossible for child to reach glitchlessly
|
||||||
|
Anything 7 key locked does not need to be checked as shared, as all child access is Certain and because of this workaround we don't need to fake Adult access, meaning that is also Certain.
|
||||||
|
All of this combined means that when checking if adult can reach a location in universe 2, we only have to ask if it is a 6 key locked location or not.
|
||||||
|
|
||||||
|
Knowing all of this this, we can confirm things are logical in 3 different ways:
|
||||||
|
- If we have Adult Access, we know it is Certain Access, so they can get checks alone.
|
||||||
|
- If we have 7 keys, child has Certain Access as we know they cannot be locked out, so can get checks alone, otherwise we check the logical overlap
|
||||||
|
- If Child and Adult can get the check (ignoring actual adult access to the location), and the location is either not 6 key locked or we have 6 keys, we can get the check with the overlap*/
|
||||||
|
bool MQSpiritShared(ConditionFn condition, bool IsBrokenWall, bool anyAge = false) {
|
||||||
|
//if we have Certain Access as child, we can check anyAge and if true, resolve a condition with Here as if adult is here it's also Certain Access
|
||||||
|
if (logic->SmallKeys(RR_SPIRIT_TEMPLE, 7)){
|
||||||
|
if (anyAge){
|
||||||
|
return Here(condition);
|
||||||
|
}
|
||||||
|
return condition();
|
||||||
|
//else, if we are here as adult, we have Certain Access from that and don't need special handling for checking adult
|
||||||
|
} else if (Adult() && logic->IsAdult){
|
||||||
|
return condition();
|
||||||
|
//if we do not have Certain Access, we need to check the overlap by seeing if we are both here as child and meet the adult universe's access condition
|
||||||
|
//We only need to do it as child, as only child access matters for this check, as adult access is assumed based on keys
|
||||||
|
} else if (Child() && logic->IsChild && (!IsBrokenWall || logic->SmallKeys(RR_SPIRIT_TEMPLE, 6))) {
|
||||||
|
bool result = false;
|
||||||
|
//store current age variables
|
||||||
|
bool pastAdult = logic->IsAdult;
|
||||||
|
bool pastChild = logic->IsChild;
|
||||||
|
|
||||||
|
//First check if the check is possible as child
|
||||||
|
logic->IsChild = true;
|
||||||
|
logic->IsAdult = false;
|
||||||
|
result = condition();
|
||||||
|
//If so, check again as adult. both have to be true for result to be true
|
||||||
|
if (result) {
|
||||||
|
logic->IsChild = false;
|
||||||
|
logic->IsAdult = true;
|
||||||
|
result = condition();
|
||||||
|
}
|
||||||
|
|
||||||
|
//set back age variables
|
||||||
|
logic->IsChild = pastChild;
|
||||||
|
logic->IsAdult = pastAdult;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
extern std::array<Region, RR_MAX> areaTable;
|
extern std::array<Region, RR_MAX> areaTable;
|
||||||
extern std::vector<EventAccess> grottoEvents;
|
extern std::vector<EventAccess> grottoEvents;
|
||||||
|
|
||||||
bool Here(const RandomizerRegion region, ConditionFn condition); //RANDOTODO make a less stupid way to check own at either age than self referncing with this
|
bool Here(const RandomizerRegion region, ConditionFn condition); //RANDOTODO make a less stupid way to check own at either age than self referncing with this
|
||||||
|
bool MQSpiritSharedStatueRoom(const RandomizerRegion region, ConditionFn condition, bool anyAge = false);
|
||||||
|
bool MQSpiritSharedBrokenWallRoom(const RandomizerRegion region, ConditionFn condition, bool anyAge = false);
|
||||||
bool CanPlantBean(const RandomizerRegion region);
|
bool CanPlantBean(const RandomizerRegion region);
|
||||||
bool BothAges(const RandomizerRegion region);
|
bool BothAges(const RandomizerRegion region);
|
||||||
bool ChildCanAccess(const RandomizerRegion region);
|
bool ChildCanAccess(const RandomizerRegion region);
|
||||||
|
@ -220,7 +220,7 @@ void RegionTable_Init_GerudoTrainingGrounds() {
|
|||||||
//Locations
|
//Locations
|
||||||
//implies logic->CanKillEnemy(RE_TORCH_SLUG)
|
//implies logic->CanKillEnemy(RE_TORCH_SLUG)
|
||||||
LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_SECOND_IRON_KNUCKLE_CHEST, logic->CanKillEnemy(RE_IRON_KNUCKLE)),
|
LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_SECOND_IRON_KNUCKLE_CHEST, logic->CanKillEnemy(RE_IRON_KNUCKLE)),
|
||||||
LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_FLAME_CIRCLE_CHEST, logic->CanHitSwitch(ED_BOOMERANG)),
|
LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_FLAME_CIRCLE_CHEST, logic->CanHitSwitch(ED_BOMB_THROW)),
|
||||||
}, {
|
}, {
|
||||||
//Exits
|
//Exits
|
||||||
Entrance(RR_GERUDO_TRAINING_GROUNDS_MQ_STATUE_ROOM, {[]{return Here(RR_GERUDO_TRAINING_GROUNDS_MQ_TORCH_SLUG_ROOM, []{return logic->CanKillEnemy(RE_IRON_KNUCKLE);});}}),
|
Entrance(RR_GERUDO_TRAINING_GROUNDS_MQ_STATUE_ROOM, {[]{return Here(RR_GERUDO_TRAINING_GROUNDS_MQ_TORCH_SLUG_ROOM, []{return logic->CanKillEnemy(RE_IRON_KNUCKLE);});}}),
|
||||||
|
@ -138,101 +138,339 @@ void RegionTable_Init_SpiritTemple() {
|
|||||||
areaTable[RR_SPIRIT_TEMPLE_MQ_LOBBY] = Region("Spirit Temple MQ Lobby", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
areaTable[RR_SPIRIT_TEMPLE_MQ_LOBBY] = Region("Spirit Temple MQ Lobby", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||||
//Locations
|
//Locations
|
||||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_LEFT_CHEST, true),
|
LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_LEFT_CHEST, true),
|
||||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_LEFT_CHEST, Here(RR_SPIRIT_TEMPLE_MQ_LOBBY, []{return logic->BlastOrSmash();}) && ((logic->IsChild && logic->CanUse(RG_FAIRY_SLINGSHOT)) || (logic->IsAdult && logic->CanUse(RG_FAIRY_BOW)))),
|
LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_LEFT_CHEST, Here(RR_SPIRIT_TEMPLE_MQ_LOBBY, []{return logic->BlastOrSmash();}) && logic->CanHitEyeTargets()),
|
||||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_RIGHT_CHEST, logic->CanUse(RG_BOMBCHU_5) || (logic->IsAdult && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT))) || (logic->IsChild && (logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG)))),
|
LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_RIGHT_CHEST, logic->CanHitSwitch(ED_BOOMERANG)),
|
||||||
|
LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_RIGHT_CHEST, logic->Spirit1FSilverRupees),
|
||||||
}, {
|
}, {
|
||||||
//Exits
|
//Exits
|
||||||
Entrance(RR_SPIRIT_TEMPLE_ENTRYWAY, {[]{return true;}}),
|
Entrance(RR_SPIRIT_TEMPLE_ENTRYWAY, {[]{return true;}}),
|
||||||
Entrance(RR_SPIRIT_TEMPLE_MQ_CHILD, {[]{return logic->IsChild;}}),
|
Entrance(RR_SPIRIT_TEMPLE_MQ_1F_WEST, {[]{return logic->IsChild;}}),
|
||||||
Entrance(RR_SPIRIT_TEMPLE_MQ_ADULT, {[]{return logic->CanUse(RG_BOMBCHU_5) && logic->IsAdult && logic->CanUse(RG_LONGSHOT) && logic->CanUse(RG_SILVER_GAUNTLETS);}}),
|
Entrance(RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_SOUTH, {[]{return logic->CanUse(RG_LONGSHOT) && logic->CanUse(RG_BOMBCHU_5);}}),
|
||||||
});
|
});
|
||||||
|
|
||||||
areaTable[RR_SPIRIT_TEMPLE_MQ_CHILD] = Region("Spirit Temple MQ Child", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
areaTable[RR_SPIRIT_TEMPLE_MQ_1F_WEST] = Region("Spirit Temple MQ 1F West", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||||
//Events
|
//Events
|
||||||
EventAccess(&logic->FairyPot, {[]{return logic->FairyPot || (logic->CanUse(RG_KOKIRI_SWORD) && logic->CanUse(RG_BOMBCHU_5) && logic->CanUse(RG_FAIRY_SLINGSHOT));}}),
|
//not technically a rusted switch, but a boulder through a wall, but is part of the same trick on N64
|
||||||
|
EventAccess(&logic->MQSpiritCrawlBoulder, {[]{return logic->CanUse(RG_BOMBCHU_5) || (ctx->GetTrickOption(RT_RUSTED_SWITCHES) && logic->CanUse(RG_MEGATON_HAMMER));}}),
|
||||||
}, {
|
}, {
|
||||||
//Locations
|
//Locations
|
||||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_HAMMER_SWITCH_CHEST, Here(RR_SPIRIT_TEMPLE_MQ_ADULT, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && logic->CanUse(RG_MEGATON_HAMMER);})),
|
LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_HAMMER_SWITCH_CHEST, logic->MQSpiritTimeTravelChest),
|
||||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_MAP_ROOM_ENEMY_CHEST, logic->CanUse(RG_KOKIRI_SWORD) && logic->CanUse(RG_BOMBCHU_5) && logic->CanUse(RG_FAIRY_SLINGSHOT) && logic->CanUse(RG_DINS_FIRE)),
|
|
||||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_MAP_CHEST, logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_BOMB_BAG)),
|
|
||||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_SILVER_BLOCK_HALLWAY_CHEST, logic->CanUse(RG_BOMBCHU_5) && logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && logic->CanUse(RG_FAIRY_SLINGSHOT) && (logic->CanUse(RG_DINS_FIRE) || (Here(RR_SPIRIT_TEMPLE_MQ_ADULT, []{return logic->IsAdult && (logic->CanUse(RG_FIRE_ARROWS) || (ctx->GetTrickOption(RT_SPIRIT_MQ_FROZEN_EYE) && logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_SONG_OF_TIME)));})))),
|
|
||||||
//Trick: logic->CanUse(RG_BOMBCHU_5) && logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && logic->CanUse(RG_FAIRY_SLINGSHOT) && (logic->CanUse(RG_DINS_FIRE) || (SPIRIT_TEMPLE_MQ_ADULT.Adult() && logic->IsAdult && (logic->CanUse(RG_FIRE_ARROWS) || (LogicSpiritMQFrozenEye && logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_SONG_OF_TIME)))))
|
|
||||||
}, {
|
}, {
|
||||||
//Exits
|
//Exits
|
||||||
Entrance(RR_SPIRIT_TEMPLE_MQ_SHARED, {[]{return logic->CanUse(RG_BOMBCHU_5) && logic->SmallKeys(RR_SPIRIT_TEMPLE, 2);}}),
|
Entrance(RR_SPIRIT_TEMPLE_MQ_1F_GIBDO_ROOM_SOUTH, {[]{return Here(RR_SPIRIT_TEMPLE_MQ_1F_WEST, []{return logic->CanKillEnemy(RE_TORCH_SLUG);});}}),
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_MAP_ROOM_SOUTH, {[]{return Here(RR_SPIRIT_TEMPLE_MQ_1F_WEST, []{return logic->CanKillEnemy(RE_TORCH_SLUG);});}}),
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_WEST_1F_RUSTED_SWITCH, {[]{return logic->IsChild && logic->MQSpiritCrawlBoulder;}}),
|
||||||
});
|
});
|
||||||
|
|
||||||
areaTable[RR_SPIRIT_TEMPLE_MQ_ADULT] = Region("Spirit Temple MQ Adult", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
areaTable[RR_SPIRIT_TEMPLE_MQ_1F_GIBDO_ROOM_SOUTH] = Region("Spirit Temple MQ 1F Gibdo Room South", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||||
|
//Exits
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_1F_WEST, {[]{return true;}}),
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_1F_GIBDO_ROOM_NORTH, {[]{return logic->CanUse(RG_BOMBCHU_5) && logic->CanHitEyeTargets();}}),
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_TURNTABLE_ROOM, {[]{return logic->CanUse(RG_BOMBCHU_5) && logic->CanHitEyeTargets() && logic->CanKillEnemy(RE_GIBDO);}}),
|
||||||
|
});
|
||||||
|
|
||||||
|
// Room to store the 2 pots in to handle glitch logic going backwards around the loop later
|
||||||
|
areaTable[RR_SPIRIT_TEMPLE_MQ_1F_GIBDO_ROOM_NORTH] = Region("Spirit Temple MQ Gibdo Room North", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {});
|
||||||
|
|
||||||
|
areaTable[RR_SPIRIT_TEMPLE_MQ_TURNTABLE_ROOM] = Region("Spirit Temple Turntable Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||||
|
//Events
|
||||||
|
//For non-fairy pot items, you can also get them with rang without killing the stalfos
|
||||||
|
EventAccess(&logic->FairyPot, {[]{return Here(RR_SPIRIT_TEMPLE_MQ_TURNTABLE_ROOM, []{return logic->CanKillEnemy(RE_STALFOS);});}}),
|
||||||
|
}, {}, {
|
||||||
|
//Exits
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_1F_GIBDO_ROOM_NORTH, {[]{return true;}}),
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_MAP_ROOM_NORTH, {[]{return Here(RR_SPIRIT_TEMPLE_MQ_TURNTABLE_ROOM, []{return logic->CanKillEnemy(RE_STALFOS);});}}),
|
||||||
|
});
|
||||||
|
|
||||||
|
areaTable[RR_SPIRIT_TEMPLE_MQ_MAP_ROOM_NORTH] = Region("Spirit Temple MQ Map Room North", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||||
|
//Events
|
||||||
|
EventAccess(&logic->MQSpiritMapRoomEnemies, {[]{return logic->CanKillEnemy(RE_ANUBIS) && logic->CanKillEnemy(RE_KEESE);}}),
|
||||||
|
}, {
|
||||||
//Locations
|
//Locations
|
||||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_SOUTH_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 7)),
|
LOCATION(RC_SPIRIT_TEMPLE_MQ_MAP_ROOM_ENEMY_CHEST, logic->MQSpiritMapRoomEnemies),
|
||||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_ROOM_LULLABY_CHEST, logic->CanUse(RG_ZELDAS_LULLABY) && (logic->CanJumpslashExceptHammer() || logic->CanUse(RG_HOVER_BOOTS))),
|
|
||||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_ROOM_INVISIBLE_CHEST, (ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH))),
|
|
||||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_BEAMOS_ROOM_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 5)),
|
|
||||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_CHEST_SWITCH_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->CanUse(RG_SONG_OF_TIME)),
|
|
||||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_BOSS_KEY_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->CanUse(RG_SONG_OF_TIME) && (logic->CanUse(RG_MIRROR_SHIELD) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)))),
|
|
||||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_WEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 7)),
|
|
||||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_NORTH, logic->SmallKeys(RR_SPIRIT_TEMPLE, 7)),
|
|
||||||
}, {
|
}, {
|
||||||
//Exits
|
//Exits
|
||||||
Entrance(RR_SPIRIT_TEMPLE_MQ_LOWER_ADULT, {[]{return logic->CanUse(RG_MIRROR_SHIELD) && logic->IsAdult && (logic->CanUse(RG_FIRE_ARROWS) || (ctx->GetTrickOption(RT_SPIRIT_MQ_LOWER_ADULT) && logic->CanUse(RG_DINS_FIRE) && logic->CanUse(RG_FAIRY_BOW)));}}),
|
//Stalfos room blocks you in with fire until you kill the stalfos, which won't spawn from behind the fire
|
||||||
//Trick: logic->CanUse(RG_MIRROR_SHIELD) && logic->IsAdult && (logic->CanUse(RG_FIRE_ARROWS) || (LogicSpiritMQLowerAdult && logic->CanUse(RG_DINS_FIRE) && logic->CanUse(RG_FAIRY_BOW)))
|
Entrance(RR_SPIRIT_TEMPLE_MQ_MAP_ROOM_SOUTH, {[]{return true;}}),
|
||||||
Entrance(RR_SPIRIT_TEMPLE_MQ_SHARED, {[]{return true;}}),
|
|
||||||
Entrance(RR_SPIRIT_TEMPLE_MQ_BOSS_AREA, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 6) && logic->CanUse(RG_ZELDAS_LULLABY) && logic->CanUse(RG_MEGATON_HAMMER);}}),
|
|
||||||
Entrance(RR_SPIRIT_TEMPLE_MQ_MIRROR_SHIELD_HAND, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->CanUse(RG_SONG_OF_TIME) && logic->CanJumpslashExceptHammer() && (ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH));}}),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
areaTable[RR_SPIRIT_TEMPLE_MQ_SHARED] = Region("Spirit Temple MQ Shared", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
areaTable[RR_SPIRIT_TEMPLE_MQ_MAP_ROOM_SOUTH] = Region("Spirit Temple MQ Map Room South", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||||
|
//Events
|
||||||
|
//You can lure the keese over by aggroing them with dins if you use it as close to the torch keese as possible, but it's a trick as it's not intuitive and basically never comes up
|
||||||
|
EventAccess(&logic->MQSpiritMapRoomEnemies, {[]{return logic->CanKillEnemy(RE_ANUBIS) && logic->CanKillEnemy(RE_KEESE, ED_BOOMERANG);}}),
|
||||||
|
}, {
|
||||||
//Locations
|
//Locations
|
||||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_NORTH_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 6)),
|
LOCATION(RC_SPIRIT_TEMPLE_MQ_MAP_CHEST, true),
|
||||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_COMPASS_CHEST, (logic->IsChild && logic->CanUse(RG_FAIRY_SLINGSHOT) && logic->SmallKeys(RR_SPIRIT_TEMPLE, 7)) || (logic->IsAdult && logic->CanUse(RG_FAIRY_BOW)) || (logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_FAIRY_SLINGSHOT))),
|
|
||||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM_CHEST, logic->CanUse(RG_SONG_OF_TIME) || ctx->GetTrickOption(RT_SPIRIT_MQ_SUN_BLOCK_SOT) || logic->IsAdult),
|
|
||||||
//Trick: logic->CanUse(RG_SONG_OF_TIME) || LogicSpiritMQSunBlockSoT || logic->IsAdult
|
|
||||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_SUN_BLOCK_ROOM, (ctx->GetTrickOption(RT_SPIRIT_MQ_SUN_BLOCK_GS) && logic->CanUse(RG_BOOMERANG) && (logic->CanUse(RG_SONG_OF_TIME) || ctx->GetTrickOption(RT_SPIRIT_MQ_SUN_BLOCK_SOT))) || logic->IsAdult),
|
|
||||||
//Trick: (LogicSpiritMQSunBlockGS && logic->CanUse(RG_BOOMERANG) && (logic->CanUse(RG_SONG_OF_TIME) || LogicSpiritMQSunBlockSoT)) || logic->IsAdult
|
|
||||||
}, {
|
}, {
|
||||||
//Exits
|
//Exits
|
||||||
Entrance(RR_SPIRIT_TEMPLE_MQ_SILVER_GAUNTLETS_HAND, {[]{return (logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && (logic->CanUse(RG_SONG_OF_TIME) || ctx->GetTrickOption(RT_SPIRIT_MQ_SUN_BLOCK_SOT) || logic->IsAdult)) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 4) && logic->CanUse(RG_SONG_OF_TIME) && logic->CanJumpslashExceptHammer() && (ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)));}}),
|
//The bridge is a temp flag, so not a way to cross south to north in logic
|
||||||
//Trick: (logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && (logic->CanUse(RG_SONG_OF_TIME) || LogicSpiritMQSunBlockSoT || logic->IsAdult)) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 4) && logic->CanUse(RG_SONG_OF_TIME) && (LogicLensSpiritMQ || logic->CanUse(RG_LENS_OF_TRUTH)))
|
Entrance(RR_SPIRIT_TEMPLE_MQ_MAP_ROOM_NORTH, {[]{return logic->CanUse(RG_HOOKSHOT);}}),
|
||||||
Entrance(RR_DESERT_COLOSSUS, {[]{return (logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && (logic->CanUse(RG_SONG_OF_TIME) || ctx->GetTrickOption(RT_SPIRIT_MQ_SUN_BLOCK_SOT) || logic->IsAdult)) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 4) && logic->CanUse(RG_SONG_OF_TIME) && logic->CanJumpslashExceptHammer() && (ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->IsAdult);}}),
|
Entrance(RR_SPIRIT_TEMPLE_MQ_1F_WEST, {[]{return true;}}),
|
||||||
//Trick: (logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && (logic->CanUse(RG_SONG_OF_TIME) || LogicSpiritMQSunBlockSoT || logic->IsAdult)) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 4) && logic->CanUse(RG_SONG_OF_TIME) && (LogicLensSpiritMQ || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->IsAdult)
|
|
||||||
});
|
});
|
||||||
|
|
||||||
areaTable[RR_SPIRIT_TEMPLE_MQ_LOWER_ADULT] = Region("Spirit Temple MQ Lower Adult", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
areaTable[RR_SPIRIT_TEMPLE_MQ_WEST_1F_RUSTED_SWITCH] = Region("Spirit Temple MQ West 1F Rusted Switch", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||||
//Locations
|
//Events
|
||||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_LEEVER_ROOM_CHEST, true),
|
EventAccess(&logic->MQSpiritTimeTravelChest, {[]{return logic->CanUse(RG_MEGATON_HAMMER);}}),
|
||||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_EPONAS_SONG) && logic->CanUse(RG_SUNS_SONG)
|
EventAccess(&logic->MQSpiritCrawlBoulder, {[]{return logic->CanUse(RG_BOMBCHU_5) || (ctx->GetTrickOption(RT_RUSTED_SWITCHES) && logic->CanUse(RG_MEGATON_HAMMER));}}),
|
||||||
&& logic->CanUse(RG_SONG_OF_STORMS) && logic->CanUse(RG_ZELDAS_LULLABY)),
|
}, {}, {
|
||||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_RIGHT_CHEST, logic->CanUse(RG_MEGATON_HAMMER)),
|
//Exits
|
||||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_LEEVER_ROOM, true),
|
Entrance(RR_SPIRIT_TEMPLE_MQ_1F_WEST, {[]{return logic->IsChild && logic->MQSpiritCrawlBoulder;}}),
|
||||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_SYMPHONY_ROOM, logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_EPONAS_SONG) && logic->CanUse(RG_SUNS_SONG)
|
//This tracks possible child access, if adult has not entered STATUE_ROOM. Certain Child Access is checked for separately as 7 Keys
|
||||||
&& logic->CanUse(RG_SONG_OF_STORMS) && logic->CanUse(RG_ZELDAS_LULLABY)),
|
Entrance(RR_SPIRIT_TEMPLE_MQ_UNDER_LIKE_LIKE, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 1);}}),
|
||||||
}, {});
|
});
|
||||||
|
|
||||||
areaTable[RR_SPIRIT_TEMPLE_MQ_BOSS_AREA] = Region("Spirit Temple MQ Boss Region", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
//THIS REGION NEEDS MQSpiritSharedBrokenWallRoom WHEN ADDING THE POT
|
||||||
|
areaTable[RR_SPIRIT_TEMPLE_MQ_UNDER_LIKE_LIKE] = Region("Spirit Temple MQ Under Like Like", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||||
|
//Exits
|
||||||
|
//This covers adult access only, as child arrives here from the other side of this door
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_WEST_1F_RUSTED_SWITCH, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 7);}}),
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_BROKEN_WALL_ROOM, {[]{return logic->CanHitSwitch();}}),
|
||||||
|
});
|
||||||
|
|
||||||
|
areaTable[RR_SPIRIT_TEMPLE_MQ_BROKEN_WALL_ROOM] = Region("Spirit Temple MQ Broken Wall Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||||
//Locations
|
//Locations
|
||||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_MIRROR_PUZZLE_INVISIBLE_CHEST, ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)),
|
//Implies CanKillEnemy(RE_LIKE_LIKE)
|
||||||
|
LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_NORTH_CHEST, MQSpiritSharedBrokenWallRoom(RR_SPIRIT_TEMPLE_MQ_BROKEN_WALL_ROOM, []{return logic->CanKillEnemy(RE_BEAMOS);})),
|
||||||
|
//Sunlights only temp spawn this chest, which is unintuitive/a bug.
|
||||||
|
//chest is only reachable as adult glitchlessly, so we can skip the shared in favour of IsAdult as adult access is always Certain
|
||||||
|
LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_SOUTH_CHEST, logic->IsAdult && logic->HasExplosives() && (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)) && logic->CanUse(RG_HOOKSHOT)),
|
||||||
}, {
|
}, {
|
||||||
//Exits
|
//Exits
|
||||||
Entrance(RR_SPIRIT_TEMPLE_MQ_INSIDE_STATUE_HEAD, {[]{return logic->CanUse(RG_MIRROR_SHIELD) && logic->CanUse(RG_HOOKSHOT);}}),
|
Entrance(RR_SPIRIT_TEMPLE_MQ_UNDER_LIKE_LIKE, {[]{return logic->CanHitSwitch();}}),
|
||||||
|
//This exit only governs child possible access, adult access starts on the other side so never checks this
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 2);}}),
|
||||||
});
|
});
|
||||||
|
|
||||||
areaTable[RR_SPIRIT_TEMPLE_MQ_INSIDE_STATUE_HEAD] =
|
areaTable[RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM] = Region("Spirit Temple MQ Statue Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||||
Region("Spirit Temple MQ Inside Statue Head", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {},
|
//Locations
|
||||||
{
|
LOCATION(RC_SPIRIT_TEMPLE_MQ_COMPASS_CHEST, MQSpiritSharedStatueRoom(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return logic->CanHitEyeTargets();})),
|
||||||
// Exits
|
}, {
|
||||||
Entrance(RR_SPIRIT_TEMPLE_MQ_SHARED, { [] { return true; } }),
|
//Exits
|
||||||
Entrance(RR_SPIRIT_TEMPLE_BOSS_ENTRYWAY, { [] { return logic->HasItem(RG_SPIRIT_TEMPLE_BOSS_KEY); } }),
|
//we check possible adult access directly in MQSpiritSharedBrokenWallRoom, so this exit only covers Certain Access
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_BROKEN_WALL_ROOM, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 7);}}),
|
||||||
|
//We can use Here instead of Shared here because adult will never need to rely on child access to reach this room, and adult access is Certain
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_NORTH, {[]{return Here(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return logic->HasFireSource() || (ctx->GetTrickOption(RT_SPIRIT_MQ_FROZEN_EYE) && logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_SONG_OF_TIME));});}}),
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM, {[]{return logic->IsAdult || ctx->GetTrickOption(RT_SPIRIT_MQ_SUN_BLOCK_SOT) || logic->CanUse(RG_SONG_OF_TIME);}}),
|
||||||
|
//explicit adult check here is a precaution against possible child logic leaking, child with a hookshot can do this
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM_EAST, {[]{return logic->IsAdult && logic->CanUse(RG_HOOKSHOT);}}),
|
||||||
|
});
|
||||||
|
|
||||||
|
areaTable[RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM] = Region("Spirit Temple MQ Sun Block Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||||
|
//Locations
|
||||||
|
//We don't need Shared here because If we are checking as child, universe 2 adult access needs nothing so it always passes, and if we are checking as adult, it is Certain Access
|
||||||
|
LOCATION(RC_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM_CHEST, true),
|
||||||
|
LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_SUN_BLOCK_ROOM, MQSpiritSharedStatueRoom(RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM, []{return logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_SPIRIT_MQ_SUN_BLOCK_GS) && logic->CanUse(RG_BOOMERANG));})),
|
||||||
|
}, {
|
||||||
|
//Exits
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, {[]{return true;}}),
|
||||||
|
//This door causes the Universes to merge as it requires 7 keys for both ages
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_WEST_IRON_KNUCKLE, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 7);}}),
|
||||||
|
});
|
||||||
|
|
||||||
|
areaTable[RR_SPIRIT_TEMPLE_MQ_WEST_IRON_KNUCKLE] = Region("Spirit Temple MQ East Iron Knuckle", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||||
|
//Exits
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 7);}}),
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_SILVER_GAUNTLETS_HAND, {[]{return logic->CanKillEnemy(RE_IRON_KNUCKLE);}}),
|
||||||
|
});
|
||||||
|
|
||||||
|
areaTable[RR_SPIRIT_TEMPLE_MQ_SILVER_GAUNTLETS_HAND] = Region("Spirit Temple MQ Silver Gauntlets Hand", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||||
|
//Locations
|
||||||
|
LOCATION(RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST, true),
|
||||||
|
}, {
|
||||||
|
//Exits
|
||||||
|
//If it is ever relevent for 1 age to spawn the mirror shield chest for the other can longshot across, it needs an eventAccess
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_WEST_IRON_KNUCKLE, {[]{return true;}}),
|
||||||
|
Entrance(RR_DESERT_COLOSSUS, {[]{return true;}}),
|
||||||
|
});
|
||||||
|
|
||||||
|
areaTable[RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_SOUTH] = Region("Spirit Temple MQ Block Room South", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||||
|
//Exits
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_LOBBY, {[]{return true;}}),
|
||||||
|
//The block here is unusual in that it is a permanent flag, but reset anyway as child. This is because there's a check that would be blocked off by pushing them otherwise
|
||||||
|
//It may be worth considering making this always temp in future so adult doesn't have the same issue
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_NORTH, {[]{return logic->IsChild ? logic->CanUse(RG_SILVER_GAUNTLETS) : Here(RR_SPIRIT_TEMPLE_MQ_LOBBY, []{return logic->CanUse(RG_SILVER_GAUNTLETS);});}}),
|
||||||
|
});
|
||||||
|
|
||||||
|
areaTable[RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_NORTH] = Region("Spirit Temple MQ Block Room North", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||||
|
//Locations
|
||||||
|
//Does not need to be shared as it's hard child locked, because adult pushing the block is a permanent flag that blocks the eye target and cannot be undone
|
||||||
|
LOCATION(RC_SPIRIT_TEMPLE_MQ_SILVER_BLOCK_HALLWAY_CHEST, logic->IsChild && logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && logic->CanHitEyeTargets()),
|
||||||
|
}, {
|
||||||
|
//Exits
|
||||||
|
//if going to RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_SOUTH from here is ever relevant, there needs to be an event to handle the block
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, {[]{return true;}}),
|
||||||
|
});
|
||||||
|
|
||||||
|
areaTable[RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM_EAST] = Region("Spirit Temple MQ Statue Room East", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||||
|
//Locations
|
||||||
|
LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_ROOM_LULLABY_CHEST, logic->CanUse(RG_HOOKSHOT) & logic->CanUse(RG_ZELDAS_LULLABY) && (logic->CanJumpslash() || logic->CanUse(RG_HOVER_BOOTS))),
|
||||||
|
LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_ROOM_INVISIBLE_CHEST, (ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS))),
|
||||||
|
}, {
|
||||||
|
//Exits
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, {[]{return true;}}),
|
||||||
|
//!QUANTUM LOGIC!
|
||||||
|
//We only need 4 keys, access to Shield hand and longshot to reach Gauntlets hand, as if we waste the 5th key we have given ourselves Gauntlets hand access through child climb
|
||||||
|
//This exit handles that possibility as cleanly as possible without quantum logic, but will not survive glitch logic
|
||||||
|
//logic->CanKillEnemy(RE_FLOORMASTER) is implied
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_SILVER_GAUNTLETS_HAND, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 4) &&
|
||||||
|
logic->CanAvoidEnemy(RE_BEAMOS, true, 4) && logic->CanUse(RG_SONG_OF_TIME) &&
|
||||||
|
logic->CanJumpslash() &&
|
||||||
|
(ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) &&
|
||||||
|
logic->CanKillEnemy(RE_IRON_KNUCKLE) &&
|
||||||
|
logic->CanUse(RG_LONGSHOT);}}),
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_FOUR_BEAMOS_ROOM, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->CanUse(RG_HOOKSHOT);}}),
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_THREE_SUNS_ROOM_2F, {[]{return logic->CanUse(RG_FIRE_ARROWS) || (ctx->GetTrickOption(RT_SPIRIT_MQ_LOWER_ADULT) && logic->CanUse(RG_DINS_FIRE));}}),
|
||||||
|
});
|
||||||
|
|
||||||
|
areaTable[RR_SPIRIT_TEMPLE_MQ_THREE_SUNS_ROOM_2F] = Region("Spirit Temple MQ Three Suns Room 2F", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||||
|
//Events
|
||||||
|
//implies logic->CanKillEnemy(RE_WALLMASTER). If we have lights, we can kill stalfos and wallmasters with bow
|
||||||
|
EventAccess(&logic->MQSpirit3SunsEnemies, {[]{return (logic->CanUse(RG_MIRROR_SHIELD) && logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2)) ||
|
||||||
|
(ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS));}}),
|
||||||
|
}, {}, {
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM_EAST, {[]{return true;}}),
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_THREE_SUNS_ROOM_1F, {[]{return logic->MQSpirit3SunsEnemies;}}),
|
||||||
|
});
|
||||||
|
|
||||||
|
areaTable[RR_SPIRIT_TEMPLE_MQ_THREE_SUNS_ROOM_1F] = Region("Spirit Temple MQ Three Suns Room 1F", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_THREE_SUNS_ROOM_2F, {[]{return logic->MQSpirit3SunsEnemies;}}),
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_1F_EAST, {[]{return true;}}),
|
||||||
|
});
|
||||||
|
|
||||||
|
areaTable[RR_SPIRIT_TEMPLE_MQ_1F_EAST] = Region("Spirit Temple MQ 1F East", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||||
|
//Events
|
||||||
|
//Assumes RR_SPIRIT_TEMPLE_MQ_LOBBY access
|
||||||
|
EventAccess(&logic->Spirit1FSilverRupees, {[]{return logic->CanUse(RG_MEGATON_HAMMER);}}),
|
||||||
|
}, {}, {
|
||||||
|
//Exits
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_LOBBY, {[]{return logic->CanUse(RG_MEGATON_HAMMER);}}),
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_THREE_SUNS_ROOM_1F, {[]{return true;}}),
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_LEEVER_ROOM, {[]{return true;}}),
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 7);}}),
|
||||||
|
});
|
||||||
|
|
||||||
|
areaTable[RR_SPIRIT_TEMPLE_MQ_LEEVER_ROOM] = Region("Spirit Temple MQ Leever Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||||
|
//Locations
|
||||||
|
LOCATION(RC_SPIRIT_TEMPLE_MQ_LEEVER_ROOM_CHEST, logic->CanKillEnemy(RE_PURPLE_LEEVER) && logic->CanUse(RG_HOOKSHOT)),
|
||||||
|
LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_LEEVER_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)),
|
||||||
|
}, {
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_1F_EAST, {[]{return logic->CanUse(RG_ZELDAS_LULLABY);}}),
|
||||||
|
});
|
||||||
|
|
||||||
|
areaTable[RR_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM] = Region("Spirit Temple MQ Symphony Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||||
|
//Exits
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_1F_EAST, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 7);}}),
|
||||||
|
//Implies CanPassEnemy(RE_MOBLIN_CHIEF)
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_AFTER_SYMPHONY_ROOM, {[]{return logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_EPONAS_SONG) &&
|
||||||
|
logic->CanUse(RG_SUNS_SONG) && logic->CanUse(RG_SONG_OF_STORMS) && logic->CanUse(RG_ZELDAS_LULLABY);}}),
|
||||||
|
});
|
||||||
|
|
||||||
|
areaTable[RR_SPIRIT_TEMPLE_MQ_AFTER_SYMPHONY_ROOM] = Region("Spirit Temple MQ After Symphony Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||||
|
//Locations
|
||||||
|
LOCATION(RC_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM_CHEST, logic->CanPassEnemy(RE_BIG_SKULLTULA)),
|
||||||
|
LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_SYMPHONY_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)),
|
||||||
|
}, {
|
||||||
|
//Exits
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM, {[]{return true;}}),
|
||||||
|
});
|
||||||
|
|
||||||
|
areaTable[RR_SPIRIT_TEMPLE_MQ_FOUR_BEAMOS_ROOM] = Region("Spirit Temple MQ Four Beamos Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||||
|
//Locations
|
||||||
|
LOCATION(RC_SPIRIT_TEMPLE_MQ_BEAMOS_ROOM_CHEST, logic->CanKillEnemy(RE_BEAMOS)),
|
||||||
|
}, {
|
||||||
|
//Exits
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM_EAST, {[]{return logic->CanAvoidEnemy(RE_BEAMOS, true, 4) && logic->CanUse(RG_SONG_OF_TIME) && logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->CanUse(RG_HOOKSHOT);}}),
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_SOT_SUN_ROOM, {[]{return logic->CanAvoidEnemy(RE_BEAMOS, true, 4) && logic->CanUse(RG_SONG_OF_TIME);}}),
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_BIG_WALL, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 6);}}),
|
||||||
|
});
|
||||||
|
|
||||||
|
areaTable[RR_SPIRIT_TEMPLE_MQ_SOT_SUN_ROOM] = Region("Spirit Temple MQ SoT Sun Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||||
|
//Locations
|
||||||
|
LOCATION(RC_SPIRIT_TEMPLE_MQ_CHEST_SWITCH_CHEST, true),
|
||||||
|
}, {
|
||||||
|
//Exits
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_FOUR_BEAMOS_ROOM, {[]{return true;}}),
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_EAST_STAIRS_TO_HAND, {[]{return logic->CanJumpslash();}}),
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_3F_GIBDO_ROOM, {[]{return Here(RR_SPIRIT_TEMPLE_MQ_SOT_SUN_ROOM, []{return (logic->IsAdult || logic->CanUse(RG_SONG_OF_TIME)) && logic->CanUse(RG_MIRROR_SHIELD);});}}),
|
||||||
|
});
|
||||||
|
|
||||||
|
areaTable[RR_SPIRIT_TEMPLE_MQ_EAST_STAIRS_TO_HAND] = Region("Spirit Temple MQ East Stairs to Hand", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||||
|
//Exits
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_SOT_SUN_ROOM, {[]{return true;}}),
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_EAST_IRON_KNUCKLE, {[]{return (ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) &&
|
||||||
|
Here(RR_SPIRIT_TEMPLE_MQ_EAST_STAIRS_TO_HAND, []{return logic->CanKillEnemy(RE_FLOORMASTER);});}}),
|
||||||
|
});
|
||||||
|
|
||||||
|
areaTable[RR_SPIRIT_TEMPLE_MQ_EAST_IRON_KNUCKLE] = Region("Spirit Temple MQ East Iron Knuckle", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||||
|
//Exits
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_EAST_STAIRS_TO_HAND, {[]{return true;}}),
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_MIRROR_SHIELD_HAND, {[]{return Here(RR_SPIRIT_TEMPLE_MQ_EAST_STAIRS_TO_HAND, []{return logic->CanKillEnemy(RE_IRON_KNUCKLE);});}}),
|
||||||
});
|
});
|
||||||
|
|
||||||
areaTable[RR_SPIRIT_TEMPLE_MQ_MIRROR_SHIELD_HAND] = Region("Spirit Temple MQ Mirror Shield Hand", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
areaTable[RR_SPIRIT_TEMPLE_MQ_MIRROR_SHIELD_HAND] = Region("Spirit Temple MQ Mirror Shield Hand", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||||
//Locations
|
//Locations
|
||||||
LOCATION(RC_SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST, true),
|
LOCATION(RC_SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST, true),
|
||||||
}, {});
|
}, {
|
||||||
|
//Exits
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_SILVER_GAUNTLETS_HAND, {[]{return logic->CanUse(RG_LONGSHOT);}}),
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_EAST_IRON_KNUCKLE, {[]{return true;}}),
|
||||||
|
Entrance(RR_DESERT_COLOSSUS, {[]{return true;}}),
|
||||||
|
});
|
||||||
|
|
||||||
areaTable[RR_SPIRIT_TEMPLE_MQ_SILVER_GAUNTLETS_HAND] = Region("Spirit Temple MQ Silver Gauntlets Hand", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
areaTable[RR_SPIRIT_TEMPLE_MQ_3F_GIBDO_ROOM] = Region("Spirit Temple MQ 3F Gibdo Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||||
//Locations
|
//Locations
|
||||||
LOCATION(RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST, true),
|
LOCATION(RC_SPIRIT_TEMPLE_MQ_BOSS_KEY_CHEST, true),
|
||||||
}, {});
|
}, {
|
||||||
|
//Exits
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_SOT_SUN_ROOM, {[]{return true;}}),
|
||||||
|
});
|
||||||
|
|
||||||
|
areaTable[RR_SPIRIT_TEMPLE_MQ_BIG_WALL] = Region("Spirit Temple MQ Big Wall", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||||
|
//Exits
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_FOUR_BEAMOS_ROOM, {[]{return true;}}),
|
||||||
|
//technically we only need to avoid them, but the sheer height and the moving walls makes getting to the top after only stunning them very difficult/impossible
|
||||||
|
//The silver rupees are irrelevant without silver shuffle
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_4F_CENTRAL, {[]{return logic->CanKillEnemy(RE_KEESE);}}),
|
||||||
|
});
|
||||||
|
|
||||||
|
areaTable[RR_SPIRIT_TEMPLE_MQ_4F_CENTRAL] = Region("Spirit Temple MQ 4F Central", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||||
|
//Exits
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_BIG_WALL, {[]{return true;}}),
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_NINE_CHAIRS_ROOM, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 7);}}),
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_BIG_MIRROR_ROOM, {[]{return logic->CanUse(RG_ZELDAS_LULLABY);}}),
|
||||||
|
});
|
||||||
|
|
||||||
|
areaTable[RR_SPIRIT_TEMPLE_MQ_NINE_CHAIRS_ROOM] = Region("Spirit Temple MQ Nine Chairs Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||||
|
//Locations
|
||||||
|
//These skulls rely on the iron knuckle existing without a trick to shoot through the chairs
|
||||||
|
LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_WEST, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)),
|
||||||
|
LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_NORTH, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)),
|
||||||
|
}, {
|
||||||
|
//Exits
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_4F_CENTRAL, {[]{return true;}}),
|
||||||
|
});
|
||||||
|
|
||||||
|
areaTable[RR_SPIRIT_TEMPLE_MQ_BIG_MIRROR_ROOM] = Region("Spirit Temple MQ Big Mirror Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||||
|
//Exits
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_4F_CENTRAL, {[]{return true;}}),
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CAVE, {[]{return Here(RR_SPIRIT_TEMPLE_MQ_BIG_MIRROR_ROOM, []{return logic->CanUse(RG_MEGATON_HAMMER);});}}),
|
||||||
|
});
|
||||||
|
|
||||||
|
areaTable[RR_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CAVE] = Region("Spirit Temple MQ Big Mirror Cave", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||||
|
//Locations
|
||||||
|
LOCATION(RC_SPIRIT_TEMPLE_MQ_MIRROR_PUZZLE_INVISIBLE_CHEST, ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)),
|
||||||
|
}, {
|
||||||
|
//Exits
|
||||||
|
//If it's ever relevant to longshot into head from lobby, this needs to be an event access
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_INSIDE_STATUE_HEAD, {[]{return Here(RR_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CAVE, []{return logic->CanUse(RG_MIRROR_SHIELD);}) && logic->CanUse(RG_HOOKSHOT);}}),
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, {[]{return Here(RR_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CAVE, []{return logic->CanUse(RG_MIRROR_SHIELD);});}}),
|
||||||
|
});
|
||||||
|
|
||||||
|
areaTable[RR_SPIRIT_TEMPLE_MQ_INSIDE_STATUE_HEAD] = Region("Spirit Temple MQ Inside Statue Head", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||||
|
// Exits
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_LOBBY, {[]{return true;} }),
|
||||||
|
Entrance(RR_SPIRIT_TEMPLE_BOSS_ENTRYWAY, {[]{return logic->HasItem(RG_SPIRIT_TEMPLE_BOSS_KEY);}}),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------
|
/*---------------------------
|
||||||
|
@ -475,7 +475,7 @@ void RegionTable_Init_WaterTemple() {
|
|||||||
areaTable[RR_WATER_TEMPLE_MQ_STALFOS_PIT] = Region("Water Temple MQ Stalfos Pit", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
areaTable[RR_WATER_TEMPLE_MQ_STALFOS_PIT] = Region("Water Temple MQ Stalfos Pit", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||||
//Events
|
//Events
|
||||||
EventAccess(&logic->MQWaterStalfosPit, {[]{return ((logic->IsAdult && logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 3, false, true)) ||
|
EventAccess(&logic->MQWaterStalfosPit, {[]{return ((logic->IsAdult && logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 3, false, true)) ||
|
||||||
(logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT) && logic->CanKillEnemy(RE_STALFOS, ED_BOOMERANG, true, 3, false, true)));}}),
|
(logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT) && logic->CanKillEnemy(RE_STALFOS, ED_BOMB_THROW, true, 3, false, true)));}}),
|
||||||
}, {}, {
|
}, {}, {
|
||||||
//Exits
|
//Exits
|
||||||
Entrance(RR_WATER_TEMPLE_MQ_WATERFALL, {[]{return logic->MQWaterStalfosPit && logic->CanUse(RG_HOOKSHOT) && (logic->IsAdult || logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8);}}),
|
Entrance(RR_WATER_TEMPLE_MQ_WATERFALL, {[]{return logic->MQWaterStalfosPit && logic->CanUse(RG_HOOKSHOT) && (logic->IsAdult || logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8);}}),
|
||||||
@ -577,7 +577,7 @@ void RegionTable_Init_WaterTemple() {
|
|||||||
LOCATION(RC_WATER_TEMPLE_MQ_BOSS_KEY_CHEST, true),
|
LOCATION(RC_WATER_TEMPLE_MQ_BOSS_KEY_CHEST, true),
|
||||||
}, {
|
}, {
|
||||||
//Exits
|
//Exits
|
||||||
Entrance(RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_SWITCH, {[]{return logic->CanHitSwitch(ED_BOOMERANG) || logic->CanUse(RG_HOVER_BOOTS);}}),
|
Entrance(RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_SWITCH, {[]{return logic->CanHitSwitch(ED_BOMB_THROW) || logic->CanUse(RG_HOVER_BOOTS);}}),
|
||||||
Entrance(RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_PIT, {[]{return true;}}),
|
Entrance(RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_PIT, {[]{return true;}}),
|
||||||
Entrance(RR_WATER_TEMPLE_MQ_B1_GATE_SWITCH, {[]{return logic->HasItem(RG_SILVER_SCALE) || (logic->CanUse(RG_IRON_BOOTS) && (logic->HasItem(RG_BRONZE_SCALE) || (logic->WaterTimer() >= 24 && logic->CanUse(RG_LONGSHOT))));}}),
|
Entrance(RR_WATER_TEMPLE_MQ_B1_GATE_SWITCH, {[]{return logic->HasItem(RG_SILVER_SCALE) || (logic->CanUse(RG_IRON_BOOTS) && (logic->HasItem(RG_BRONZE_SCALE) || (logic->WaterTimer() >= 24 && logic->CanUse(RG_LONGSHOT))));}}),
|
||||||
});
|
});
|
||||||
|
@ -434,12 +434,15 @@ namespace Rando {
|
|||||||
case ED_LONG_JUMPSLASH:
|
case ED_LONG_JUMPSLASH:
|
||||||
killed = killed || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_STICKS);
|
killed = killed || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_STICKS);
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
|
case ED_BOMB_THROW:
|
||||||
|
killed = killed || CanUse(RG_BOMB_BAG);
|
||||||
|
[[fallthrough]];
|
||||||
case ED_BOOMERANG:
|
case ED_BOOMERANG:
|
||||||
//RANDOTODO test dins, bomb and chu range in a practical example
|
//RANDOTODO test dins and chu range in a practical example
|
||||||
killed = killed || CanUse(RG_BOMB_BAG) || CanUse(RG_DINS_FIRE);
|
killed = killed || CanUse(RG_DINS_FIRE);
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
case ED_HOOKSHOT:
|
case ED_HOOKSHOT:
|
||||||
//RANDOTODO test dins, bomb and chu range in a practical example
|
//RANDOTODO test dins and chu range in a practical example
|
||||||
killed = killed || CanUse(RG_HOOKSHOT) || (wallOrFloor && CanUse(RG_BOMBCHU_5));
|
killed = killed || CanUse(RG_HOOKSHOT) || (wallOrFloor && CanUse(RG_BOMBCHU_5));
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
case ED_LONGSHOT:
|
case ED_LONGSHOT:
|
||||||
@ -467,9 +470,13 @@ namespace Rando {
|
|||||||
case ED_LONG_JUMPSLASH:
|
case ED_LONG_JUMPSLASH:
|
||||||
killed = killed || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_STICKS);
|
killed = killed || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_STICKS);
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
|
case ED_BOMB_THROW:
|
||||||
|
//RANDOTODO test dins and chu range in a practical example
|
||||||
|
killed = killed || (!inWater && CanUse(RG_BOMB_BAG));
|
||||||
|
[[fallthrough]];
|
||||||
case ED_BOOMERANG:
|
case ED_BOOMERANG:
|
||||||
//RANDOTODO test dins, bomb and chu range in a practical example
|
//RANDOTODO test dins and chu range in a practical example
|
||||||
killed = killed || CanUse(RG_BOOMERANG) || (!inWater && CanUse(RG_BOMB_BAG));
|
killed = killed || CanUse(RG_BOOMERANG);
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
case ED_HOOKSHOT:
|
case ED_HOOKSHOT:
|
||||||
//RANDOTODO test dins, bomb and chu range in a practical example
|
//RANDOTODO test dins, bomb and chu range in a practical example
|
||||||
@ -508,12 +515,12 @@ namespace Rando {
|
|||||||
case ED_LONG_JUMPSLASH:
|
case ED_LONG_JUMPSLASH:
|
||||||
killed = killed || CanUse(RG_BIGGORON_SWORD) || (quantity <= 1 && CanUse(RG_STICKS));
|
killed = killed || CanUse(RG_BIGGORON_SWORD) || (quantity <= 1 && CanUse(RG_STICKS));
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
case ED_BOOMERANG:
|
case ED_BOMB_THROW:
|
||||||
//RANDOTODO test dins, bomb and chu range in a practical example
|
|
||||||
killed = killed || (quantity <= 2 && !timer && !inWater && (CanUse(RG_NUTS) || HookshotOrBoomerang()) && CanUse(RG_BOMB_BAG));
|
killed = killed || (quantity <= 2 && !timer && !inWater && (CanUse(RG_NUTS) || HookshotOrBoomerang()) && CanUse(RG_BOMB_BAG));
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
|
case ED_BOOMERANG:
|
||||||
case ED_HOOKSHOT:
|
case ED_HOOKSHOT:
|
||||||
//RANDOTODO test dins, bomb and chu range in a practical example
|
//RANDOTODO test dins and chu range in a practical example
|
||||||
killed = killed || (wallOrFloor && CanUse(RG_BOMBCHU_5));
|
killed = killed || (wallOrFloor && CanUse(RG_BOMBCHU_5));
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
case ED_LONGSHOT:
|
case ED_LONGSHOT:
|
||||||
@ -535,6 +542,7 @@ namespace Rando {
|
|||||||
return CanUse(RG_MEGATON_HAMMER) || CanUse(RG_HOOKSHOT) || (HasExplosives() && (CanJumpslashExceptHammer() || CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_BOOMERANG)));
|
return CanUse(RG_MEGATON_HAMMER) || CanUse(RG_HOOKSHOT) || (HasExplosives() && (CanJumpslashExceptHammer() || CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_BOOMERANG)));
|
||||||
case RE_WOLFOS:
|
case RE_WOLFOS:
|
||||||
case RE_WHITE_WOLFOS:
|
case RE_WHITE_WOLFOS:
|
||||||
|
case RE_WALLMASTER:
|
||||||
return CanJumpslash() || CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_BOMBCHU_5) || CanUse(RG_DINS_FIRE) || (CanUse(RG_BOMB_BAG) && (CanUse(RG_NUTS) || CanUse(RG_HOOKSHOT) || CanUse(RG_BOOMERANG)));
|
return CanJumpslash() || CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_BOMBCHU_5) || CanUse(RG_DINS_FIRE) || (CanUse(RG_BOMB_BAG) && (CanUse(RG_NUTS) || CanUse(RG_HOOKSHOT) || CanUse(RG_BOOMERANG)));
|
||||||
case RE_GIBDO:
|
case RE_GIBDO:
|
||||||
case RE_REDEAD:
|
case RE_REDEAD:
|
||||||
@ -568,10 +576,11 @@ namespace Rando {
|
|||||||
case ED_LONG_JUMPSLASH:
|
case ED_LONG_JUMPSLASH:
|
||||||
killed = killed || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_STICKS);
|
killed = killed || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_STICKS);
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
case ED_BOOMERANG:
|
case ED_BOMB_THROW:
|
||||||
//RANDOTODO test dins, bomb and chu range in a practical example
|
//RANDOTODO test dins and chu range in a practical example
|
||||||
killed = killed || (!inWater && CanUse(RG_BOMB_BAG));
|
killed = killed || (!inWater && CanUse(RG_BOMB_BAG));
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
|
case ED_BOOMERANG:
|
||||||
case ED_HOOKSHOT:
|
case ED_HOOKSHOT:
|
||||||
//RANDOTODO test dins, bomb and chu range in a practical example
|
//RANDOTODO test dins, bomb and chu range in a practical example
|
||||||
killed = killed || CanUse(RG_HOOKSHOT) || (wallOrFloor && CanUse(RG_BOMBCHU_5));
|
killed = killed || CanUse(RG_HOOKSHOT) || (wallOrFloor && CanUse(RG_BOMBCHU_5));
|
||||||
@ -601,6 +610,16 @@ namespace Rando {
|
|||||||
case RE_DARK_LINK:
|
case RE_DARK_LINK:
|
||||||
//RANDOTODO Dark link is buggy right now, retest when he is not
|
//RANDOTODO Dark link is buggy right now, retest when he is not
|
||||||
return CanJumpslash() || CanUse(RG_FAIRY_BOW);
|
return CanJumpslash() || CanUse(RG_FAIRY_BOW);
|
||||||
|
case RE_ANUBIS:
|
||||||
|
//there's a restoration that allows beating them with mirror shield + some way to trigger thier attack
|
||||||
|
return HasFireSource();
|
||||||
|
case RE_BEAMOS:
|
||||||
|
return HasExplosives();
|
||||||
|
case RE_PURPLE_LEEVER:
|
||||||
|
//dies on it's own, so this is the conditions to spawn it (killing 10 normal leevers)
|
||||||
|
//Sticks and Ice arrows work but will need ammo capacity logic
|
||||||
|
//other mothods can damage them but not kill them, and they run when hit, making them impractical
|
||||||
|
return CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD);
|
||||||
default:
|
default:
|
||||||
SPDLOG_ERROR("CanKillEnemy reached `default`.");
|
SPDLOG_ERROR("CanKillEnemy reached `default`.");
|
||||||
assert(false);
|
assert(false);
|
||||||
@ -637,6 +656,9 @@ namespace Rando {
|
|||||||
case RE_FREEZARD:
|
case RE_FREEZARD:
|
||||||
case RE_SPIKE:
|
case RE_SPIKE:
|
||||||
case RE_DARK_LINK:
|
case RE_DARK_LINK:
|
||||||
|
case RE_ANUBIS:
|
||||||
|
case RE_WALLMASTER:
|
||||||
|
case RE_PURPLE_LEEVER:
|
||||||
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
|
||||||
@ -660,15 +682,17 @@ namespace Rando {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Can we avoid this enemy while climbing up a wall, or doing a difficult platforming challenge?
|
//Can we avoid this enemy while climbing up a wall, or doing a difficult platforming challenge?
|
||||||
bool Logic::CanAvoidEnemy(RandomizerEnemy enemy) {
|
//use grounded if the challenge is such that the enemy interfears even if it cannot hit link out of the air
|
||||||
if (CanKillEnemy(enemy)){
|
bool Logic::CanAvoidEnemy(RandomizerEnemy enemy, bool grounded, uint8_t quantity) {
|
||||||
|
//DISTANCE AND WALL ASSUMED, add more arguments later if needed
|
||||||
|
if (CanKillEnemy(enemy, ED_CLOSE, true, quantity)){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
switch(enemy) {
|
switch(enemy) {
|
||||||
case RE_GOLD_SKULLTULA:
|
case RE_GOLD_SKULLTULA:
|
||||||
case RE_GOHMA_LARVA:
|
case RE_GOHMA_LARVA:
|
||||||
case RE_LIZALFOS:
|
case RE_LIZALFOS:
|
||||||
case RE_DODONGO: //RANDOTODO do dodongos block the way in tight corridors?
|
case RE_DODONGO:
|
||||||
case RE_BIG_SKULLTULA:
|
case RE_BIG_SKULLTULA:
|
||||||
case RE_DEAD_HAND:
|
case RE_DEAD_HAND:
|
||||||
case RE_DEKU_BABA:
|
case RE_DEKU_BABA:
|
||||||
@ -689,14 +713,20 @@ namespace Rando {
|
|||||||
case RE_BIG_OCTO:
|
case RE_BIG_OCTO:
|
||||||
case RE_GIBDO:
|
case RE_GIBDO:
|
||||||
case RE_DARK_LINK:
|
case RE_DARK_LINK:
|
||||||
|
case RE_WALLMASTER:
|
||||||
|
case RE_ANUBIS:
|
||||||
|
case RE_PURPLE_LEEVER:
|
||||||
return true;
|
return true;
|
||||||
|
case RE_BEAMOS:
|
||||||
|
return !grounded || CanUse(RG_NUTS) || (quantity == 1 && (CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT)));
|
||||||
case RE_MAD_SCRUB:
|
case RE_MAD_SCRUB:
|
||||||
|
return !grounded || CanUse(RG_NUTS);
|
||||||
case RE_KEESE:
|
case RE_KEESE:
|
||||||
case RE_FIRE_KEESE:
|
case RE_FIRE_KEESE:
|
||||||
return CanUse(RG_NUTS);
|
return CanUse(RG_NUTS);
|
||||||
case RE_BLUE_BUBBLE:
|
case RE_BLUE_BUBBLE:
|
||||||
//RANDOTODO Trick to use shield hylian shield as child to stun these guys
|
//RANDOTODO Trick to use shield hylian shield as child to stun these guys
|
||||||
return CanUse(RG_NUTS) || HookshotOrBoomerang() || CanStandingShield();
|
return !grounded || CanUse(RG_NUTS) || HookshotOrBoomerang() || CanStandingShield();
|
||||||
default:
|
default:
|
||||||
SPDLOG_ERROR("CanPassEnemy reached `default`.");
|
SPDLOG_ERROR("CanPassEnemy reached `default`.");
|
||||||
assert(false);
|
assert(false);
|
||||||
@ -719,6 +749,7 @@ namespace Rando {
|
|||||||
case ED_SHORT_JUMPSLASH:
|
case ED_SHORT_JUMPSLASH:
|
||||||
case ED_MASTER_SWORD_JUMPSLASH:
|
case ED_MASTER_SWORD_JUMPSLASH:
|
||||||
case ED_LONG_JUMPSLASH:
|
case ED_LONG_JUMPSLASH:
|
||||||
|
case ED_BOMB_THROW:
|
||||||
case ED_BOOMERANG:
|
case ED_BOOMERANG:
|
||||||
drop = drop || CanUse(RG_BOOMERANG);
|
drop = drop || CanUse(RG_BOOMERANG);
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
@ -729,9 +760,10 @@ namespace Rando {
|
|||||||
drop = drop || CanUse(RG_LONGSHOT);
|
drop = drop || CanUse(RG_LONGSHOT);
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
case ED_FAR:
|
case ED_FAR:
|
||||||
return drop;
|
break;
|
||||||
//RANDOTODO double check all jumpslash kills that might be out of jump/backflip range
|
//RANDOTODO double check all jumpslash kills that might be out of jump/backflip range
|
||||||
}
|
}
|
||||||
|
return drop;
|
||||||
break;
|
break;
|
||||||
case RE_KEESE:
|
case RE_KEESE:
|
||||||
case RE_FIRE_KEESE:
|
case RE_FIRE_KEESE:
|
||||||
@ -843,12 +875,14 @@ namespace Rando {
|
|||||||
case ED_LONG_JUMPSLASH:
|
case ED_LONG_JUMPSLASH:
|
||||||
hit = hit || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_STICKS);
|
hit = hit || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_STICKS);
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
|
case ED_BOMB_THROW:
|
||||||
|
hit = hit || (!inWater && CanUse(RG_BOMB_BAG));
|
||||||
|
[[fallthrough]];
|
||||||
case ED_BOOMERANG:
|
case ED_BOOMERANG:
|
||||||
//RANDOTODO test bomb and chu range in a practical example
|
hit = hit || CanUse(RG_BOOMERANG);
|
||||||
hit = hit || CanUse(RG_BOOMERANG) || (!inWater && CanUse(RG_BOMB_BAG)) ;
|
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
case ED_HOOKSHOT:
|
case ED_HOOKSHOT:
|
||||||
//RANDOTODO test bomb and chu range in a practical example
|
//RANDOTODO test chu range in a practical example
|
||||||
hit = hit || CanUse(RG_HOOKSHOT) || CanUse(RG_BOMBCHU_5) ;
|
hit = hit || CanUse(RG_HOOKSHOT) || CanUse(RG_BOMBCHU_5) ;
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
case ED_LONGSHOT:
|
case ED_LONGSHOT:
|
||||||
@ -2121,6 +2155,9 @@ namespace Rando {
|
|||||||
MQWaterB1Switch = false;
|
MQWaterB1Switch = false;
|
||||||
//MQWaterPillarSoTBlock = false;
|
//MQWaterPillarSoTBlock = false;
|
||||||
MQWaterOpenedPillarB1 = false;
|
MQWaterOpenedPillarB1 = false;
|
||||||
|
MQSpiritCrawlBoulder = false;
|
||||||
|
MQSpiritMapRoomEnemies = false;
|
||||||
|
MQSpirit3SunsEnemies = false;
|
||||||
|
|
||||||
StopPerformanceTimer(PT_LOGIC_RESET);
|
StopPerformanceTimer(PT_LOGIC_RESET);
|
||||||
}
|
}
|
||||||
|
@ -166,6 +166,11 @@ class Logic {
|
|||||||
bool MQWaterB1Switch = false;
|
bool MQWaterB1Switch = false;
|
||||||
//bool MQWaterPillarSoTBlock = false; should be irrelevant. SHOULD.
|
//bool MQWaterPillarSoTBlock = false; should be irrelevant. SHOULD.
|
||||||
bool MQWaterOpenedPillarB1 = false;
|
bool MQWaterOpenedPillarB1 = false;
|
||||||
|
bool MQSpiritCrawlBoulder = false;
|
||||||
|
bool MQSpiritMapRoomEnemies = false;
|
||||||
|
bool MQSpiritTimeTravelChest = false;
|
||||||
|
bool MQSpirit3SunsEnemies = false;
|
||||||
|
bool Spirit1FSilverRupees = false;
|
||||||
|
|
||||||
/* --- END OF HELPERS AND LOCATION ACCESS --- */
|
/* --- END OF HELPERS AND LOCATION ACCESS --- */
|
||||||
|
|
||||||
@ -181,7 +186,7 @@ class Logic {
|
|||||||
bool CanEquipSwap(RandomizerGet itemName);
|
bool CanEquipSwap(RandomizerGet itemName);
|
||||||
bool CanKillEnemy(RandomizerEnemy enemy, EnemyDistance distance = ED_CLOSE, bool wallOrFloor = true, uint8_t quantity = 1, bool timer = false, bool inWater = false);
|
bool CanKillEnemy(RandomizerEnemy enemy, EnemyDistance distance = ED_CLOSE, bool wallOrFloor = true, uint8_t quantity = 1, bool timer = false, bool inWater = false);
|
||||||
bool CanPassEnemy(RandomizerEnemy enemy, EnemyDistance distance = ED_CLOSE, bool wallOrFloor = true);
|
bool CanPassEnemy(RandomizerEnemy enemy, EnemyDistance distance = ED_CLOSE, bool wallOrFloor = true);
|
||||||
bool CanAvoidEnemy(RandomizerEnemy enemy);
|
bool CanAvoidEnemy(RandomizerEnemy enemy, bool grounded = false, uint8_t quantity = 1);
|
||||||
bool CanGetEnemyDrop(RandomizerEnemy enemy, EnemyDistance distance = ED_CLOSE, bool aboveLink = false);
|
bool CanGetEnemyDrop(RandomizerEnemy enemy, EnemyDistance distance = ED_CLOSE, bool aboveLink = false);
|
||||||
bool CanBreakMudWalls();
|
bool CanBreakMudWalls();
|
||||||
bool CanGetDekuBabaSticks();
|
bool CanGetDekuBabaSticks();
|
||||||
|
@ -808,13 +808,39 @@ typedef enum {
|
|||||||
RR_SPIRIT_TEMPLE_INSIDE_STATUE_HEAD,
|
RR_SPIRIT_TEMPLE_INSIDE_STATUE_HEAD,
|
||||||
|
|
||||||
RR_SPIRIT_TEMPLE_MQ_LOBBY,
|
RR_SPIRIT_TEMPLE_MQ_LOBBY,
|
||||||
RR_SPIRIT_TEMPLE_MQ_CHILD,
|
RR_SPIRIT_TEMPLE_MQ_1F_WEST,
|
||||||
RR_SPIRIT_TEMPLE_MQ_ADULT,
|
RR_SPIRIT_TEMPLE_MQ_1F_GIBDO_ROOM_NORTH,
|
||||||
RR_SPIRIT_TEMPLE_MQ_SHARED,
|
RR_SPIRIT_TEMPLE_MQ_1F_GIBDO_ROOM_SOUTH,
|
||||||
RR_SPIRIT_TEMPLE_MQ_LOWER_ADULT,
|
RR_SPIRIT_TEMPLE_MQ_TURNTABLE_ROOM,
|
||||||
RR_SPIRIT_TEMPLE_MQ_BOSS_AREA,
|
RR_SPIRIT_TEMPLE_MQ_MAP_ROOM_NORTH,
|
||||||
RR_SPIRIT_TEMPLE_MQ_MIRROR_SHIELD_HAND,
|
RR_SPIRIT_TEMPLE_MQ_MAP_ROOM_SOUTH,
|
||||||
|
RR_SPIRIT_TEMPLE_MQ_WEST_1F_RUSTED_SWITCH,
|
||||||
|
RR_SPIRIT_TEMPLE_MQ_UNDER_LIKE_LIKE,
|
||||||
|
RR_SPIRIT_TEMPLE_MQ_BROKEN_WALL_ROOM,
|
||||||
|
RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM,
|
||||||
|
RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM,
|
||||||
|
RR_SPIRIT_TEMPLE_MQ_WEST_IRON_KNUCKLE,
|
||||||
RR_SPIRIT_TEMPLE_MQ_SILVER_GAUNTLETS_HAND,
|
RR_SPIRIT_TEMPLE_MQ_SILVER_GAUNTLETS_HAND,
|
||||||
|
RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_SOUTH,
|
||||||
|
RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_NORTH,
|
||||||
|
RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM_EAST,
|
||||||
|
RR_SPIRIT_TEMPLE_MQ_THREE_SUNS_ROOM_2F,
|
||||||
|
RR_SPIRIT_TEMPLE_MQ_THREE_SUNS_ROOM_1F,
|
||||||
|
RR_SPIRIT_TEMPLE_MQ_1F_EAST,
|
||||||
|
RR_SPIRIT_TEMPLE_MQ_LEEVER_ROOM,
|
||||||
|
RR_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM,
|
||||||
|
RR_SPIRIT_TEMPLE_MQ_AFTER_SYMPHONY_ROOM,
|
||||||
|
RR_SPIRIT_TEMPLE_MQ_FOUR_BEAMOS_ROOM,
|
||||||
|
RR_SPIRIT_TEMPLE_MQ_SOT_SUN_ROOM,
|
||||||
|
RR_SPIRIT_TEMPLE_MQ_EAST_STAIRS_TO_HAND,
|
||||||
|
RR_SPIRIT_TEMPLE_MQ_EAST_IRON_KNUCKLE,
|
||||||
|
RR_SPIRIT_TEMPLE_MQ_MIRROR_SHIELD_HAND,
|
||||||
|
RR_SPIRIT_TEMPLE_MQ_3F_GIBDO_ROOM,
|
||||||
|
RR_SPIRIT_TEMPLE_MQ_BIG_WALL,
|
||||||
|
RR_SPIRIT_TEMPLE_MQ_4F_CENTRAL,
|
||||||
|
RR_SPIRIT_TEMPLE_MQ_NINE_CHAIRS_ROOM,
|
||||||
|
RR_SPIRIT_TEMPLE_MQ_BIG_MIRROR_ROOM,
|
||||||
|
RR_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CAVE,
|
||||||
RR_SPIRIT_TEMPLE_MQ_INSIDE_STATUE_HEAD,
|
RR_SPIRIT_TEMPLE_MQ_INSIDE_STATUE_HEAD,
|
||||||
|
|
||||||
RR_SPIRIT_TEMPLE_BOSS_ENTRYWAY,
|
RR_SPIRIT_TEMPLE_BOSS_ENTRYWAY,
|
||||||
@ -4571,6 +4597,10 @@ typedef enum {
|
|||||||
RE_GANONDORF,
|
RE_GANONDORF,
|
||||||
RE_GANON,
|
RE_GANON,
|
||||||
RE_DARK_LINK,
|
RE_DARK_LINK,
|
||||||
|
RE_ANUBIS,
|
||||||
|
RE_BEAMOS,
|
||||||
|
RE_WALLMASTER,
|
||||||
|
RE_PURPLE_LEEVER,
|
||||||
} RandomizerEnemy;
|
} RandomizerEnemy;
|
||||||
|
|
||||||
//RANDOTODO compare child long jumpslash range with adult short
|
//RANDOTODO compare child long jumpslash range with adult short
|
||||||
@ -4581,6 +4611,7 @@ typedef enum {
|
|||||||
ED_MASTER_SWORD_JUMPSLASH,
|
ED_MASTER_SWORD_JUMPSLASH,
|
||||||
//sticks or BGS
|
//sticks or BGS
|
||||||
ED_LONG_JUMPSLASH,
|
ED_LONG_JUMPSLASH,
|
||||||
|
ED_BOMB_THROW,
|
||||||
ED_BOOMERANG,
|
ED_BOOMERANG,
|
||||||
ED_HOOKSHOT,
|
ED_HOOKSHOT,
|
||||||
ED_LONGSHOT,
|
ED_LONGSHOT,
|
||||||
|
@ -445,7 +445,7 @@ void Settings::CreateOptions() {
|
|||||||
mTrickOptions[RT_WATER_BK_REGION] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::INTERMEDIATE}, false, "Water Temple Boss Key Region with Hover Boots", "With precise Hover Boots movement it is possible to reach the boss key chest's region without needing the Longshot. It is not necessary to take damage from the spikes. The Gold Skulltula Token in the following room can also be obtained with just the Hover Boots.");
|
mTrickOptions[RT_WATER_BK_REGION] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::INTERMEDIATE}, false, "Water Temple Boss Key Region with Hover Boots", "With precise Hover Boots movement it is possible to reach the boss key chest's region without needing the Longshot. It is not necessary to take damage from the spikes. The Gold Skulltula Token in the following room can also be obtained with just the Hover Boots.");
|
||||||
mTrickOptions[RT_WATER_NORTH_BASEMENT_LEDGE_JUMP] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_WATER_TEMPLE, {Tricks::Tag::INTERMEDIATE}, false, "Water Temple North Basement Ledge with Precise Jump", "In the northern basement there's a ledge from where, in vanilla Water Temple, boulders roll out into the room. Normally to jump directly to this ledge logically requires the Hover Boots, but with precise jump, it can be done without them. This trick applies to both Vanilla and Master Quest.");
|
mTrickOptions[RT_WATER_NORTH_BASEMENT_LEDGE_JUMP] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_WATER_TEMPLE, {Tricks::Tag::INTERMEDIATE}, false, "Water Temple North Basement Ledge with Precise Jump", "In the northern basement there's a ledge from where, in vanilla Water Temple, boulders roll out into the room. Normally to jump directly to this ledge logically requires the Hover Boots, but with precise jump, it can be done without them. This trick applies to both Vanilla and Master Quest.");
|
||||||
mTrickOptions[RT_WATER_BK_JUMP_DIVE] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::NOVICE}, false, "Water Temple Boss Key Jump Dive", "Stand on the very edge of the raised corridor leading from the push block room to the rolling boulder corridor. Face the gold skulltula on the waterfall and jump over the boulder corridor floor into the pool of water, swimming right once underwater. This allows access to the boss key room without Iron boots.");
|
mTrickOptions[RT_WATER_BK_JUMP_DIVE] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::NOVICE}, false, "Water Temple Boss Key Jump Dive", "Stand on the very edge of the raised corridor leading from the push block room to the rolling boulder corridor. Face the gold skulltula on the waterfall and jump over the boulder corridor floor into the pool of water, swimming right once underwater. This allows access to the boss key room without Iron boots.");
|
||||||
//Also used in MQ logic, but won't be relevent unl;ess a way to enter tower without irons exists (likely a clip + swim)
|
//Also used in MQ logic, but won't be relevent unless a way to enter tower without irons exists (likely a clip + swim)
|
||||||
mTrickOptions[RT_WATER_FW_CENTRAL_GS] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::NOVICE}, false, "Water Temple Central Pillar GS with Farore\'s Wind", "If you set Farore's Wind inside the central pillar and then return to that warp point after raising the water to the highest level, you can obtain this Skulltula Token with Hookshot or Boomerang.");
|
mTrickOptions[RT_WATER_FW_CENTRAL_GS] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::NOVICE}, false, "Water Temple Central Pillar GS with Farore\'s Wind", "If you set Farore's Wind inside the central pillar and then return to that warp point after raising the water to the highest level, you can obtain this Skulltula Token with Hookshot or Boomerang.");
|
||||||
mTrickOptions[RT_WATER_IRONS_CENTRAL_GS] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::NOVICE}, false, "Water Temple Central Pillar GS with Iron Boots", "After opening the middle water level door into the central pillar, the door will stay unbarred so long as you do not leave the room -- even if you were to raise the water up to the highest level. With the Iron Boots to go through the door after the water has been raised, you can obtain the Skulltula Token with the Hookshot.");
|
mTrickOptions[RT_WATER_IRONS_CENTRAL_GS] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::NOVICE}, false, "Water Temple Central Pillar GS with Iron Boots", "After opening the middle water level door into the central pillar, the door will stay unbarred so long as you do not leave the room -- even if you were to raise the water up to the highest level. With the Iron Boots to go through the door after the water has been raised, you can obtain the Skulltula Token with the Hookshot.");
|
||||||
mTrickOptions[RT_WATER_CENTRAL_BOW] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::ADVANCED}, false, "Water Temple Central Bow Target without Longshot or Hover Boots", "A very precise Bow shot can hit the eye switch from the floor above. Then, you can jump down into the hallway and make through it before the gate closes. It can also be done as child, using the Slingshot instead of the Bow.");
|
mTrickOptions[RT_WATER_CENTRAL_BOW] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::ADVANCED}, false, "Water Temple Central Bow Target without Longshot or Hover Boots", "A very precise Bow shot can hit the eye switch from the floor above. Then, you can jump down into the hallway and make through it before the gate closes. It can also be done as child, using the Slingshot instead of the Bow.");
|
||||||
|
Loading…
Reference in New Issue
Block a user