mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-04-28 13:17:58 +03:00
v0 complete
This commit is contained in:
parent
01800f74c6
commit
5b42fb1e4e
6 changed files with 537 additions and 290 deletions
|
@ -213,126 +213,176 @@ bool Here(const RandomizerRegion region, ConditionFn condition) {
|
|||
uint8_t SpiritExplosiveLogic() {
|
||||
return logic->SpiritBrokenWallToStatue() ? 1 : ctx->GetOption(RSK_BOMBCHU_BAG) && logic->BombchuRefill() ? 2 : 3;
|
||||
}
|
||||
// RANDOTODO basically every condition here will need climb or longshot.
|
||||
|
||||
// clang-format off
|
||||
std::map<RandomizerRegion, SpiritLogicData> Region::spiritLogicData = {
|
||||
{RR_SPIRIT_TEMPLE_WEST_CLIMB_BASE, SpiritLogicData(5, 5, 3, []{return true;} , []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, SpiritExplosiveLogic())/* && logic->CanClimbHigh() && str0*/;}, []{return true/*logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS)*/;})},
|
||||
{RR_SPIRIT_TEMPLE_BROKEN_WALL, SpiritLogicData(5, 5, 3, []{return true /*logic->CanClimbHigh()*/;} , []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, SpiritExplosiveLogic())/* && logic->CanClimbHigh() && str0*/;}, []{return true/*logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS)*/;})},
|
||||
{RR_SPIRIT_TEMPLE_2F_MIRROR, SpiritLogicData(5, 5, 3, []{return logic->CanUse(RG_HOOKSHOT) && logic->SpiritBrokenWallToStatue();} , []{return true/*logic->CanClimbHigh()*/;} , []{return logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS);})},
|
||||
{RR_SPIRIT_TEMPLE_STATUE_ROOM_WEST, SpiritLogicData(5, 5, 3, []{return logic->SpiritBrokenWallToStatue();} , []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, SpiritExplosiveLogic())/* && logic->CanClimbHigh() && str0*/;}, []{return true/*logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS)*/;})},
|
||||
{RR_SPIRIT_TEMPLE_GS_LEDGE, SpiritLogicData(5, 5, 3, []{return logic->SpiritBrokenWallToStatue() && logic->SpiritWestToSkull();} , []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, SpiritExplosiveLogic()) && logic->SpiritWestToSkull()
|
||||
/* && logic->CanClimbHigh() && str0*/;} , []{return logic->SpiritWestToSkull()/* && (logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS))*/;})},
|
||||
{RR_SPIRIT_TEMPLE_STATUE_ROOM, SpiritLogicData(5, 5, 3, []{return logic->SpiritBrokenWallToStatue();} , []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, SpiritExplosiveLogic())/* && logic->CanClimbHigh() && str0*/;}, []{return true;})},
|
||||
{RR_SPIRIT_TEMPLE_SUN_BLOCK_ROOM, SpiritLogicData(5, 5, 3, []{return logic->SpiritBrokenWallToStatue()/* && str0*/;} , []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, SpiritExplosiveLogic())/* && logic->CanClimbHigh() && str0*/;}, []{return true/*(logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS)) && str0*/;})},
|
||||
{RR_SPIRIT_TEMPLE_SKULLTULA_STAIRS, SpiritLogicData(5, 5, 3, []{return logic->SpiritBrokenWallToStatue()/* && str0*/;} , []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, SpiritExplosiveLogic())/* && logic->CanClimbHigh() && str0*/;}, []{return true/*(logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS)) && str0*/;})},
|
||||
{RR_SPIRIT_TEMPLE_STATUE_ROOM_EAST, SpiritLogicData(5, 5, 3, []{return logic->CanUse(RG_HOOKSHOT) && logic->SpiritBrokenWallToStatue();} , []{return true/*logic->CanClimbHigh() && str0*/;} , []{return logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS);})},
|
||||
{RR_SPIRIT_TEMPLE_SHORTCUT_SWITCH, SpiritLogicData(5, 5, 3, []{return logic->CanUse(RG_HOOKSHOT) && logic->SpiritBrokenWallToStatue() && logic->SpiritEastToSwitch();}, []{return logic->SpiritEastToSwitch()/* && logic->CanClimbHigh() && str0*/;} , []{return logic->SpiritEastToSwitch() && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS));})},
|
||||
{RR_SPIRIT_TEMPLE_MQ_UNDER_LIKE_LIKE, SpiritLogicData(7, 6, 7, []{return true;} , []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 6) && logic->CanHitSwitch()/* && logic->Climb*/;} , []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 6) && logic->CanHitSwitch()/* && (logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS))*/;})},
|
||||
{RR_SPIRIT_TEMPLE_MQ_BROKEN_WALL_ROOM, SpiritLogicData(7, 6, 7, []{return logic->CanHitSwitch()/* && logic->CanClimbHigh()*/;} , []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 6)/* && logic->Climb*/;} , []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 6)/* && (logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS))*/;})},
|
||||
{RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM_WEST, SpiritLogicData(7, 7, 0, []{return logic->CanHitSwitch()/* && logic->CanClimbHigh()*/;} , []{return true/*logic->Climb*/;} , []{return true/*logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS)*/;})},
|
||||
{RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, SpiritLogicData(7, 7, 0, []{return logic->CanHitSwitch()/* && logic->CanClimbHigh()*/;} , []{return true;} , []{return true;})},
|
||||
{RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM, SpiritLogicData(7, 7, 0, []{return logic->CanHitSwitch() && logic->MQSpiritStatueToSunBlock()/* && logic->CanClimbHigh()*/;} , []{return logic->MQSpiritStatueToSunBlock()/* && logic->Climb*/;} , []{return logic->MQSpiritStatueToSunBlock()/* && (logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS))*/;})},
|
||||
{RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_NORTH, SpiritLogicData(7, 7, 0, []{return logic->CanHitSwitch() &&
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_NORTH].Here([]{return logic->MQSpiritStatueSouthDoor();})
|
||||
/* && logic->CanClimbHigh()*/;} , []{return false;} , []{return areaTable[RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_NORTH].Here([]{return logic->MQSpiritStatueSouthDoor();});})},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
|
||||
/*
|
||||
* This logic covers checks that exist in the shared areas of Spirit from a glitchless standpoint.
|
||||
* This logic covers checks that exist in the shared areas of Spirit
|
||||
* This code will fail if any glitch allows Adult to go in the Child spirit door first or vice versa as it relies on
|
||||
specific ages
|
||||
|
||||
* There are 4 possibilities for passing a check, but first I have to talk about parallel universes.
|
||||
* In order to pass a check, we must either determine that Access is certain,
|
||||
or that it is always possible to get a check somehow.
|
||||
|
||||
* But first I have to talk about parallel universes.
|
||||
|
||||
* In the first universe, the player enters spirit as child, and spends as many keys as they can to lock adult out
|
||||
* In the second, they enter as adult and spend as many keys as they can to lock child out.
|
||||
|
||||
* When an Age can no longer be kept out by the other age, that age is said to have Certain Access to a region
|
||||
* Additionally, if it is possible to enter spirit in reverse, there are 2 more universes:
|
||||
* In the third universe, adult enters in reverse, and wastes all the keys so noone can enter through the front
|
||||
* In the forth, child manages to do the same, and lock people out of the front
|
||||
* All access from the boss door in shared areas is Certain
|
||||
|
||||
* While other universes exist, such as both ages entering in reverse or
|
||||
child using their key, getting stuck, then coming back to do the dungeon as adult, these
|
||||
are all sub-possibilities of these 4 universes
|
||||
|
||||
* As we do not know which universe we are in until the player chooses one in-game,
|
||||
we must be able to collect the check in both universes
|
||||
|
||||
* When an Age can no longer be kept out by conflicting universes, that age is said to have Certain Access to a region
|
||||
* If both ages have access to a region with a certain number of keys, but there is no Certain Access,
|
||||
* then a check is only in logic if both ages can collect the check independently
|
||||
* then a check is only in logic if all possible universes can collect the check independently
|
||||
|
||||
* If an age has Certain Access then that age can collect checks alone,
|
||||
* and there is no reason to check the other age untile the universes converge.
|
||||
|
||||
* The universes converge when the player has all the keys, giving both ages Certain Access.
|
||||
* The universes converge when the player has all the keys, giving both ages Certain Access everywhere.
|
||||
|
||||
* We must check for these universes manually as we allow technical access with minimum keys for
|
||||
* technical reasons as otherwise the code will never run
|
||||
*/
|
||||
* technical reasons as otherwise the logic code will never run
|
||||
|
||||
* The first and 3rd column list how many keys are needed for each age to have Certain Access
|
||||
* the second column is child keys in case there's Child reverse access, due to an edge case in MQ spirit logic
|
||||
* where the broken wall room can be reached with 6 keys if you can hit switches and have reverse Child access
|
||||
|
||||
* The first condition is the combined conditions needed to move from the 1F child lock to the area being checks
|
||||
* the second condition is the same for adult 1F lock, and the third is the access from the boss door.
|
||||
*/
|
||||
|
||||
// clang-format off
|
||||
std::map<RandomizerRegion, SpiritLogicData> Region::spiritLogicData = {
|
||||
//Vanilla
|
||||
{RR_SPIRIT_TEMPLE_WEST_CLIMB_BASE, SpiritLogicData(5, 5, 3, []{return true;}, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, SpiritExplosiveLogic())/* && logic->CanClimbHigh() && str0*/;}, []{return true/*logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS)*/;})},
|
||||
{RR_SPIRIT_TEMPLE_BROKEN_WALL, SpiritLogicData(5, 5, 3, []{return true /*logic->CanClimbHigh()*/;}, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, SpiritExplosiveLogic())/* && logic->CanClimbHigh() && str0*/;}, []{return true/*logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS)*/;})},
|
||||
{RR_SPIRIT_TEMPLE_2F_MIRROR, SpiritLogicData(5, 5, 3, []{return logic->CanUse(RG_HOOKSHOT) && logic->SpiritBrokenWallToStatue();}, []{return true/*logic->CanClimbHigh()*/;}, []{return logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS);})},
|
||||
{RR_SPIRIT_TEMPLE_STATUE_ROOM_WEST, SpiritLogicData(5, 5, 3, []{return logic->SpiritBrokenWallToStatue()/* && logic->CanClimbHigh()*/;}, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, SpiritExplosiveLogic())/* && logic->CanClimbHigh() && str0*/;}, []{return true/*logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS)*/;})},
|
||||
{RR_SPIRIT_TEMPLE_INNER_WEST_HAND, SpiritLogicData(5, 5, 3, []{return logic->SpiritBrokenWallToStatue()/* && logic->CanClimbHigh()*/;}, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, SpiritExplosiveLogic())/* && logic->CanClimbHigh() && str0*/;}, []{return true/*logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS)*/;})},
|
||||
{RR_SPIRIT_TEMPLE_GS_LEDGE, SpiritLogicData(5, 5, 3, []{return logic->SpiritBrokenWallToStatue() && logic->SpiritWestToSkull()/* && logic->CanClimbHigh()*/;}, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, SpiritExplosiveLogic()) && logic->SpiritWestToSkull()
|
||||
/* && logic->CanClimbHigh() && str0*/;}, []{return logic->SpiritWestToSkull()/* && (logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS))*/;})},
|
||||
{RR_SPIRIT_TEMPLE_STATUE_ROOM, SpiritLogicData(5, 5, 3, []{return logic->SpiritBrokenWallToStatue()/* && logic->CanClimbHigh()*/;}, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, SpiritExplosiveLogic())/* && logic->CanClimbHigh() && str0*/;}, []{return true;})},
|
||||
//Assumes SpiritSunBlockSouthLedge() for all access
|
||||
{RR_SPIRIT_TEMPLE_SUN_BLOCK_SOUTH_LEDGE, SpiritLogicData(5, 5, 3, []{return logic->SpiritBrokenWallToStatue()/* && logic->CanClimbHigh() && str0*/;}, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, SpiritExplosiveLogic())/* && logic->CanClimbHigh() && str0*/;}, []{return true/*(logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS)) && str0*/;})},
|
||||
{RR_SPIRIT_TEMPLE_SKULLTULA_STAIRS, SpiritLogicData(5, 5, 3, []{return logic->SpiritBrokenWallToStatue()/* && logic->CanClimbHigh() && str0*/;}, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, SpiritExplosiveLogic())/* && logic->CanClimbHigh() && str0*/;}, []{return true/*(logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS)) && str0*/;})},
|
||||
{RR_SPIRIT_TEMPLE_STATUE_ROOM_EAST, SpiritLogicData(5, 5, 3, []{return logic->CanUse(RG_HOOKSHOT) && logic->SpiritBrokenWallToStatue()/* && logic->CanClimbHigh()*/;}, []{return true/*logic->CanClimbHigh() && str0*/;}, []{return logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS);})},
|
||||
{RR_SPIRIT_TEMPLE_INNER_EAST_HAND, SpiritLogicData(5, 5, 3, []{return logic->CanUse(RG_HOOKSHOT) && logic->SpiritBrokenWallToStatue()/* && logic->CanClimbHigh()*/;}, []{return true/*logic->CanClimbHigh() && str0*/;}, []{return logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS);})},
|
||||
{RR_SPIRIT_TEMPLE_SHORTCUT_SWITCH, SpiritLogicData(5, 5, 3, []{return logic->CanUse(RG_HOOKSHOT) && logic->SpiritBrokenWallToStatue() && logic->SpiritEastToSwitch();}, []{return logic->SpiritEastToSwitch()/* && logic->CanClimbHigh() && str0*/;}, []{return logic->SpiritEastToSwitch() && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS));})},
|
||||
//MQ /*&& logic->CanClimbHigh()*/
|
||||
{RR_SPIRIT_TEMPLE_MQ_UNDER_LIKE_LIKE, SpiritLogicData(7, 6, 7, []{return true;}, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 6) && logic->CanHitSwitch()/* && logic->Climb*/;}, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 6) && logic->CanHitSwitch()/* && (logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS))*/;})},
|
||||
{RR_SPIRIT_TEMPLE_MQ_BROKEN_WALL_ROOM, SpiritLogicData(7, 6, 7, []{return logic->CanHitSwitch()/* && logic->CanClimbHigh()*/;}, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 6)/* && logic->Climb*/;}, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 6)/* && (logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS))*/;})},
|
||||
{RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM_WEST, SpiritLogicData(7, 7, 0, []{return logic->CanHitSwitch()/* && logic->CanClimbHigh()*/;}, []{return true/*logic->Climb*/;}, []{return true/*logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS)*/;})},
|
||||
{RR_SPIRIT_TEMPLE_MQ_POT_LEDGE, SpiritLogicData(7, 7, 0, []{return logic->CanHitSwitch() && logic->MQSpiritWestToPots()/* && logic->CanClimbHigh()*/;}, []{return logic->MQSpiritWestToPots()/* && logic->Climb*/;}, []{return /*logic->CanUse(RG_HOVER_BOOTS) || (logic->CanClimb() && */logic->MQSpiritWestToPots()/*)*/;})},
|
||||
{RR_SPIRIT_TEMPLE_MQ_INNER_WEST_HAND, SpiritLogicData(7, 7, 0, []{return logic->CanHitSwitch() && logic->MQSpiritWestToPots()/* && logic->CanClimbHigh()*/;}, []{return logic->MQSpiritWestToPots()/* && logic->Climb*/;}, []{return /*logic->CanUse(RG_HOVER_BOOTS) || (logic->CanClimb() && */logic->MQSpiritWestToPots()/*)*/;})},
|
||||
{RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, SpiritLogicData(7, 7, 0, []{return logic->CanHitSwitch()/* && logic->CanClimbHigh()*/;}, []{return true;}, []{return true;})},
|
||||
{RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM, SpiritLogicData(7, 7, 0, []{return logic->CanHitSwitch() && logic->MQSpiritStatueToSunBlock()/* && logic->CanClimbHigh()*/;} , []{return logic->MQSpiritStatueToSunBlock()/* && logic->Climb*/;}, []{return logic->MQSpiritStatueToSunBlock()/* && (logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS))*/;})},
|
||||
{RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_NORTH, SpiritLogicData(7, 7, 0, []{return logic->CanHitSwitch() &&
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_NORTH].Here([]{return logic->MQSpiritStatueSouthDoor();})
|
||||
/* && logic->CanClimbHigh()*/;}, []{return true;}, []{return areaTable[RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_NORTH].Here([]{return logic->MQSpiritStatueSouthDoor();});})},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
bool SpiritShared(RandomizerRegion region, ConditionFn condition, bool anyAge, RandomizerRegion otherRegion, ConditionFn otherCondition){
|
||||
/*
|
||||
* Spirit Shared can take up to 3 regions, this is because checks can exist in many regions at the same time
|
||||
and the logic needs to be able to check the access logic from those regions to check the other universes properly.
|
||||
|
||||
*anyAge is equivalent to a self referencing Here, used for events and any check where that is relevent.
|
||||
*/
|
||||
|
||||
bool SpiritShared(RandomizerRegion region, ConditionFn condition, bool anyAge,
|
||||
RandomizerRegion otherRegion, ConditionFn otherCondition,
|
||||
RandomizerRegion thirdRegion, ConditionFn thirdCondition){
|
||||
SpiritLogicData curRegionData = Region::spiritLogicData[region];
|
||||
uint8_t childKeys = logic->ReverseSpiritChild ? curRegionData.childReverseKeys : curRegionData.childKeys;
|
||||
bool result = false;
|
||||
|
||||
// store current age variables
|
||||
bool pastAdult = logic->IsAdult;
|
||||
bool pastChild = logic->IsChild;
|
||||
// If child enters in reverse, then they have access to Certain Access to Broken Wall room in 6 keys,
|
||||
// the ability to hit switches and the ability to climb because only child can reach the initial child lock
|
||||
// without opening the Statue room to Broken Wall Room lock first
|
||||
logic->IsChild = true;
|
||||
logic->IsAdult = false;
|
||||
uint8_t childKeys = (logic->ReverseSpiritChild && logic->CanHitSwitch()/* && CanClimbHigh()*/) ? curRegionData.childReverseKeys : curRegionData.childKeys;
|
||||
|
||||
// If we have enough keys that an age cannot be kept out, we have Certain Access
|
||||
// otherwise if we have entered in reverse and can reach from the face, we have Certain Access
|
||||
bool ChildCertainAccess = (logic->ReverseSpiritChild && curRegionData.reverseAccess) || logic->SmallKeys(RR_SPIRIT_TEMPLE, childKeys);
|
||||
bool AdultCertainAccess = (logic->ReverseSpiritAdult && curRegionData.reverseAccess) || logic->SmallKeys(RR_SPIRIT_TEMPLE, curRegionData.adultKeys);
|
||||
// If both ages have certain access, we can test with Either age
|
||||
if (ChildCertainAccess && AdultCertainAccess) {
|
||||
if (anyAge) {
|
||||
return areaTable[region].Here(condition);
|
||||
}
|
||||
return condition();
|
||||
// otherwise, we have to check the current age and...
|
||||
} else if (areaTable[region].Child() && logic->IsChild) {
|
||||
bool result = condition();
|
||||
// If we have Certain Access, we just run the condition.
|
||||
if (ChildCertainAccess) {
|
||||
return result;
|
||||
// Otherwise, if we have the keys to know either age can reach, we need to see if we could reach as Adult too
|
||||
} else if (result) {
|
||||
SpiritLogicData otherRegionData = Region::spiritLogicData[otherRegion];
|
||||
// store current age variables
|
||||
bool pastAdult = logic->IsAdult;
|
||||
bool pastChild = logic->IsChild;
|
||||
bool ChildCertainAccess = (logic->ReverseSpiritChild && curRegionData.reverseAccess()) || logic->SmallKeys(RR_SPIRIT_TEMPLE, childKeys);
|
||||
|
||||
//Switch back to adult to check adult access
|
||||
logic->IsChild = false;
|
||||
logic->IsAdult = true;
|
||||
|
||||
bool AdultCertainAccess = (logic->ReverseSpiritAdult && curRegionData.reverseAccess()) || logic->SmallKeys(RR_SPIRIT_TEMPLE, curRegionData.adultKeys);
|
||||
// If we are AnyAge and have any CeratinAccess, then we can check those ages
|
||||
//we don't need to check ambiguity here as if this fails, then 1 of the ages has failed
|
||||
if (anyAge && (ChildCertainAccess || AdultCertainAccess)){
|
||||
// set age access to the Certain Access
|
||||
logic->IsChild = ChildCertainAccess;
|
||||
logic->IsAdult = AdultCertainAccess;
|
||||
|
||||
// check condition as well as having at least child or adult access
|
||||
result = condition();
|
||||
|
||||
// otherwise, we have to check the current age and...
|
||||
} else if (areaTable[region].Child() && pastChild) {
|
||||
//Switch to Child
|
||||
logic->IsChild = true;
|
||||
logic->IsAdult = false;
|
||||
|
||||
result = condition();
|
||||
// If we have Certain Access, we just run the condition.
|
||||
// Otherwise, if we have the keys to know either age can reach, we need to see if we could reach as Adult
|
||||
// and if needed, in reverse
|
||||
if (!ChildCertainAccess && result && (!logic->IsReverseAccessPossible() || Region::spiritLogicData[otherRegion].reverseAccess())) {
|
||||
//Switch to Adult
|
||||
logic->IsChild = false;
|
||||
logic->IsAdult = true;
|
||||
|
||||
// If Adult can get there and get the check, we can get the check in logic
|
||||
// If reverse spirit is also possible, we need to make sure Adult can get it via reverse entry too
|
||||
result = (curRegionData.adultAccess && (!logic->IsReverseAccessPossible() || curRegionData.reverseAccess) && condition()) ||
|
||||
result = (curRegionData.adultAccess() && (!logic->IsReverseAccessPossible() || curRegionData.reverseAccess) && condition()) ||
|
||||
(otherRegion != RR_NONE &&
|
||||
(otherRegionData.adultAccess && (!logic->IsReverseAccessPossible() || otherRegionData.reverseAccess) && otherCondition()));
|
||||
|
||||
logic->IsChild = pastChild;
|
||||
logic->IsAdult = pastAdult;
|
||||
|
||||
return result;
|
||||
(Region::spiritLogicData[otherRegion].adultAccess() &&
|
||||
(!logic->IsReverseAccessPossible() || Region::spiritLogicData[otherRegion].reverseAccess()) &&
|
||||
otherCondition())) ||
|
||||
(thirdRegion != RR_NONE &&
|
||||
(Region::spiritLogicData[thirdRegion].adultAccess() &&
|
||||
(!logic->IsReverseAccessPossible() || Region::spiritLogicData[thirdRegion].reverseAccess()) &&
|
||||
thirdCondition()));
|
||||
}
|
||||
} else if (areaTable[region].Adult() && logic->IsAdult) {
|
||||
bool result = condition();
|
||||
} else if (areaTable[region].Adult() && pastAdult) {
|
||||
result = condition();
|
||||
// if we have enough keys to have Certain Access, we just run the condition
|
||||
// Alternatively, if we have entered in reverse and can reach from the face, we have Certain Access
|
||||
if (AdultCertainAccess) {
|
||||
return result;
|
||||
// Otherwise, if we have the keys to know either age can reach, we need to see if we could reach as Child too
|
||||
} else if (result){
|
||||
SpiritLogicData otherRegionData = Region::spiritLogicData[otherRegion];
|
||||
// store current age variables
|
||||
bool pastAdult = logic->IsAdult;
|
||||
bool pastChild = logic->IsChild;
|
||||
|
||||
// Otherwise, if we have the keys to know either age can reach, we need to see if we could reach as Child
|
||||
// and if needed, in reverse
|
||||
if (!AdultCertainAccess && result && (!logic->IsReverseAccessPossible() || Region::spiritLogicData[otherRegion].reverseAccess)){
|
||||
//Switch to Child
|
||||
logic->IsChild = true;
|
||||
logic->IsAdult = false;
|
||||
|
||||
// If Child can get there and get the check, we can get the check in logic
|
||||
// If reverse spirit is also possible, we need to make sure Child can get it via reverse entry too
|
||||
result = (curRegionData.childAccess && (!logic->IsReverseAccessPossible() || curRegionData.reverseAccess) && condition()) ||
|
||||
result = (curRegionData.childAccess() && (!logic->IsReverseAccessPossible() || curRegionData.reverseAccess()) && condition()) ||
|
||||
(otherRegion != RR_NONE &&
|
||||
(otherRegionData.childAccess && (!logic->IsReverseAccessPossible() || otherRegionData.reverseAccess) && otherCondition()));
|
||||
|
||||
logic->IsChild = pastChild;
|
||||
logic->IsAdult = pastAdult;
|
||||
|
||||
return result;
|
||||
(Region::spiritLogicData[otherRegion].childAccess() &&
|
||||
(!logic->IsReverseAccessPossible() || Region::spiritLogicData[otherRegion].reverseAccess()) &&
|
||||
otherCondition())) ||
|
||||
(thirdRegion != RR_NONE &&
|
||||
(Region::spiritLogicData[thirdRegion].childAccess() &&
|
||||
(!logic->IsReverseAccessPossible() || Region::spiritLogicData[thirdRegion].reverseAccess()) &&
|
||||
thirdCondition()));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
// set back age variables
|
||||
logic->IsChild = pastChild;
|
||||
logic->IsAdult = pastAdult;
|
||||
return result;
|
||||
}
|
||||
|
||||
bool BeanPlanted(const RandomizerRegion region) {
|
||||
|
|
|
@ -252,9 +252,6 @@ class Region {
|
|||
}
|
||||
|
||||
static std::map<RandomizerRegion, SpiritLogicData> spiritLogicData;
|
||||
|
||||
bool SpiritShared(ConditionFn condition, ConditionFn childAccess, ConditionFn adultAccess, ConditionFn ReverseAccess,
|
||||
uint8_t childKeys, uint8_t adultKeys, uint8_t eitherKeys, bool anyAge);
|
||||
};
|
||||
|
||||
extern std::array<Region, RR_MAX> areaTable;
|
||||
|
@ -264,7 +261,8 @@ bool Here(const RandomizerRegion region,
|
|||
ConditionFn
|
||||
condition); // RANDOTODO make a less stupid way to check own at either age than self referencing with this
|
||||
bool SpiritShared(RandomizerRegion region, ConditionFn condition, bool anyAge = false,
|
||||
RandomizerRegion otherRegion = RR_NONE, ConditionFn otherCondition = []{return false;});
|
||||
RandomizerRegion otherRegion = RR_NONE, ConditionFn otherCondition = []{return false;},
|
||||
RandomizerRegion thirdRegion = RR_NONE, ConditionFn thirdCondition = []{return false;});
|
||||
bool CanPlantBean(const RandomizerRegion region);
|
||||
bool BothAges(const RandomizerRegion region);
|
||||
bool ChildCanAccess(const RandomizerRegion region);
|
||||
|
|
|
@ -23,7 +23,7 @@ void RegionTable_Init_SpiritTemple() {
|
|||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_ENTRYWAY, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_1F_WEST, []{return logic->IsChild;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_1F_WEST, []{return logic->IsChild/*CanUse(RG_CRAWL)*/;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_1F_EAST, []{return logic->CanUse(RG_SILVER_GAUNTLETS);}),
|
||||
});
|
||||
|
||||
|
@ -32,15 +32,15 @@ void RegionTable_Init_SpiritTemple() {
|
|||
EventAccess(&logic->NutCrate, []{return true;}),
|
||||
}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_LOBBY, []{return logic->IsChild;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_1F_BOXES, []{return logic->IsChild;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_LOBBY, []{return logic->IsChild/*CanUse(RG_CRAWL)*/;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_1F_BOXES, []{return logic->IsChild/*CanUse(RG_CRAWL)*/;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_SWITCH_BRIDGE_SOUTH, []{return Here(RR_SPIRIT_TEMPLE_1F_WEST, []{return logic->CanKillEnemy(RE_ARMOS) && logic->CanKillEnemy(RE_KEESE);});}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_RUPEE_BRIDGE_SOUTH, []{return Here(RR_SPIRIT_TEMPLE_1F_WEST, []{return logic->CanKillEnemy(RE_ARMOS) && logic->CanKillEnemy(RE_KEESE);});}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_SWITCH_BRIDGE_SOUTH] = Region("Spirit Temple Switch Bridge South", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
//RANDOTODO a version od CanHitSwitch that takes WallOrFloor
|
||||
//RANDOTODO a version of CanHitSwitch that takes WallOrFloor
|
||||
EventAccess(&logic->SpiritChildSwitchBridge, []{return logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_SPIRIT_CHILD_CHU));}),
|
||||
}, {}, {
|
||||
//Exits
|
||||
|
@ -74,13 +74,13 @@ void RegionTable_Init_SpiritTemple() {
|
|||
|
||||
areaTable[RR_SPIRIT_TEMPLE_RUPEE_BRIDGE_NORTH] = Region("Spirit Temple Rupee Bridge North", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->SpiritRupeeBridge, []{return true;}),
|
||||
EventAccess(&logic->SpiritRupeeBridge, []{return true/*CanClimb()*/;}),
|
||||
}, {
|
||||
//Locations
|
||||
// these assume SpiritRupeeBridge, silver rupee shuffle & shuffle climb will want to adjust
|
||||
LOCATION(RC_SPIRIT_TEMPLE_CHILD_EARLY_TORCHES_CHEST, logic->HasFireSourceWithTorch()),
|
||||
// possible to collect without lowering fence, should be a trick
|
||||
LOCATION(RC_SPIRIT_TEMPLE_GS_METAL_FENCE, logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_BOMB_THROW)),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_GS_METAL_FENCE, logic->SpiritRupeeBridge && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_BOMB_THROW)),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_RUPEE_BRIDGE_SOUTH, []{return logic->SpiritRupeeBridge;}),
|
||||
|
@ -102,7 +102,7 @@ void RegionTable_Init_SpiritTemple() {
|
|||
LOCATION(RC_SPIRIT_TEMPLE_BEFORE_CHILD_CLIMB_SMALL_CRATE_2, logic->CanBreakSmallCrates()),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_1F_WEST, []{return logic->IsChild;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_1F_WEST, []{return logic->IsChild/*CanUse(RG_CRAWL)*/;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_BROKEN_WALL, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 1);}),
|
||||
});
|
||||
|
||||
|
@ -113,7 +113,7 @@ void RegionTable_Init_SpiritTemple() {
|
|||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_1F_BOXES, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 5);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_BROKEN_WALL, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_BROKEN_WALL, []{return true/*CanClimbHigh()*/;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_BROKEN_WALL] = Region("Spirit Temple Broken Wall", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
|
@ -160,7 +160,7 @@ void RegionTable_Init_SpiritTemple() {
|
|||
LOCATION(RC_SPIRIT_TEMPLE_GS_BOULDER_ROOM, logic->CanUse(RG_SONG_OF_TIME) && logic->CanKillEnemy(RE_GOLD_SKULLTULA)),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_ABOVE_BOULDERS, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_ABOVE_BOULDERS, []{return true/*CanClimb()*/;}),
|
||||
//Jump slash is possible as child, but pretty tight. Jumpslash as late as you can
|
||||
//A damage boost off the boulder is also possible, but you need
|
||||
Entrance(RR_SPIRIT_TEMPLE_PAST_BOULDERS, []{return logic->SpiritBouldersSilvers;}),
|
||||
|
@ -178,56 +178,71 @@ void RegionTable_Init_SpiritTemple() {
|
|||
areaTable[RR_SPIRIT_TEMPLE_EAST_CLIMB_BASE] = Region("Spirit Temple East Climb Base", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_1F_EAST, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 5);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_2F_MIRROR, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_2F_MIRROR, []{return true/*CanClimbHigh()*/;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_2F_MIRROR] = Region("Spirit Temple 2F Mirror", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_FIRST_MIRROR_LEFT_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_2F_MIRROR, []{return true;})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_FIRST_MIRROR_RIGHT_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_2F_MIRROR, []{return true;})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_FIRST_MIRROR_LEFT_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_2F_MIRROR, []{return true/*str0 || SunlightArrows()*/;})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_FIRST_MIRROR_RIGHT_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_2F_MIRROR, []{return true/*str0 || SunlightArrows()*/;})),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_EAST_CLIMB_BASE, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_STATUE_ROOM_EAST, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_STATUE_ROOM_EAST, []{return true/*str0 || SunlightArrows()*/;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_STATUE_ROOM_WEST] = Region("Spirit Temple Statue Rooom West", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
//Assumes RR_SPIRIT_TEMPLE_STATUE_ROOM access
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MAP_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_STATUE_ROOM_WEST, []{return logic->HasFireSourceWithTorch() || (ctx->GetTrickOption(RT_SPIRIT_MAP_CHEST) && logic->CanUse(RG_FAIRY_BOW));})),
|
||||
//Current and N64 logic doesn't need scarecrow, you can hit the skull with normal hookshot from a specific spot on the forearm
|
||||
//Child can get this with hook by backflipping onto the upper arm and standing in a precise place
|
||||
LOCATION(RC_SPIRIT_TEMPLE_GS_LOBBY, SpiritShared(RR_SPIRIT_TEMPLE_STATUE_ROOM_WEST, []{return logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ctx->GetTrickOption(RT_SPIRIT_WEST_LEDGE) ? ED_BOOMERANG : ED_HOOKSHOT);}, false,
|
||||
RR_SPIRIT_TEMPLE_GS_LEDGE, []{return logic->CanKillEnemy(RE_GOLD_SKULLTULA);})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MAP_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_STATUE_ROOM_WEST, []{return logic->HasFireSourceWithTorch() || (ctx->GetTrickOption(RT_SPIRIT_MAP_CHEST) && logic->CanUse(RG_FAIRY_BOW));}, false,
|
||||
RR_SPIRIT_TEMPLE_STATUE_ROOM, []{return logic->HasFireSource();})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_GS_LOBBY, SpiritShared(RR_SPIRIT_TEMPLE_STATUE_ROOM_WEST, []{return logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_LONGSHOT);}, false,
|
||||
RR_SPIRIT_TEMPLE_INNER_WEST_HAND, []{return logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ctx->GetTrickOption(RT_SPIRIT_WEST_LEDGE) ? ED_BOOMERANG : ED_HOOKSHOT);},
|
||||
RR_SPIRIT_TEMPLE_GS_LEDGE, []{return logic->CanKillEnemy(RE_GOLD_SKULLTULA);})),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_BROKEN_WALL, []{return true;}),
|
||||
//(IsAdult && ctx->GetTrickOption(RT_SPIRIT_LOBBY_JUMP)) || CanUse(RG_HOVER_BOOTS) || CanUse(RG_SCARECROW)
|
||||
Entrance(RR_SPIRIT_TEMPLE_GS_LEDGE, []{return logic->SpiritWestToSkull();}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_BROKEN_WALL, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_INNER_WEST_HAND, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_GS_LEDGE, []{return logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_SCARECROW);}),
|
||||
// RT_SPIRIT_PLATFORM_HOOKSHOT is currently disabled
|
||||
Entrance(RR_SPIRIT_TEMPLE_PLATFORM, []{return logic->SpiritPlatformLowered &&
|
||||
(logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_SPIRIT_PLATFORM_HOOKSHOT) && logic->CanUse(RG_HOOKSHOT)));}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_EMPTY_STAIRS, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_PLATFORM, []{return logic->SpiritPlatformLowered &&
|
||||
(logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_SPIRIT_PLATFORM_HOOKSHOT) && logic->CanUse(RG_HOOKSHOT)));}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_EMPTY_STAIRS, []{return true/*str0*/;}),
|
||||
//!QUANTUM LOGIC!
|
||||
//When child enters spirit in reverse, has 4 keys, and dungeon entrance shuffle is off,
|
||||
//Child cannot lock themselves out of desert colossus access as if they save the west hand lock for last
|
||||
//they will be able to exit the dungeon through the intended entrance and vice versa
|
||||
//for needing to open the west hand lock to block the intended child route
|
||||
Entrance(RR_DESERT_COLOSSUS, []{return ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF) && logic->ReverseSpiritChild &&
|
||||
logic->IsChild && logic->SmallKeys(RR_SPIRIT_TEMPLE, 4) && logic->CanKillEnemy(RE_IRON_KNUCKLE);}),
|
||||
Entrance(RR_DESERT_COLOSSUS, []{return ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF) && logic->ReverseSpiritChild && /*str0 &&*/
|
||||
logic->IsChild/*CanUse(RG_CRAWL)*/ && logic->SmallKeys(RR_SPIRIT_TEMPLE, 4) && logic->CanKillEnemy(RE_IRON_KNUCKLE);}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_INNER_WEST_HAND] = Region("Spirit Temple Inner West Hand", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
//You can hit the skull with normal hookshot from a specific spot on the forearm, which is in logic on N64 and 3DS, pretty questionable though
|
||||
LOCATION(RC_SPIRIT_TEMPLE_GS_LOBBY, SpiritShared(RR_SPIRIT_TEMPLE_INNER_WEST_HAND, []{return logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ctx->GetTrickOption(RT_SPIRIT_WEST_LEDGE) ? ED_BOOMERANG : ED_HOOKSHOT);}, false,
|
||||
RR_SPIRIT_TEMPLE_GS_LEDGE, []{return logic->CanKillEnemy(RE_GOLD_SKULLTULA);},
|
||||
RR_SPIRIT_TEMPLE_STATUE_ROOM_WEST, []{return logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_LONGSHOT);})),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_STATUE_ROOM_WEST, []{return logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_GS_LEDGE, []{return logic->IsAdult && ctx->GetTrickOption(RT_SPIRIT_LOBBY_JUMP);})
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_GS_LEDGE] = Region("Spirit Temple GS ledge", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_GS_LOBBY, SpiritShared(RR_SPIRIT_TEMPLE_GS_LEDGE, []{return logic->CanKillEnemy(RE_GOLD_SKULLTULA);})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_GS_LOBBY, SpiritShared(RR_SPIRIT_TEMPLE_GS_LEDGE, []{return logic->CanKillEnemy(RE_GOLD_SKULLTULA);}, false,
|
||||
RR_SPIRIT_TEMPLE_INNER_WEST_HAND, []{return logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ctx->GetTrickOption(RT_SPIRIT_WEST_LEDGE) ? ED_BOOMERANG : ED_HOOKSHOT);},
|
||||
RR_SPIRIT_TEMPLE_STATUE_ROOM_WEST, []{return logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_LONGSHOT);})),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_STATUE_ROOM_WEST, []{return true;})
|
||||
Entrance(RR_SPIRIT_TEMPLE_STATUE_ROOM_WEST, []{return logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_INNER_WEST_HAND, []{return true;})
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_STATUE_ROOM] = Region("Spirit Temple Statue Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MAP_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_STATUE_ROOM, []{return logic->HasFireSource();}, false,
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MAP_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_STATUE_ROOM, []{return logic->HasFireSource();}, false,
|
||||
RR_SPIRIT_TEMPLE_STATUE_ROOM_WEST, []{return logic->HasFireSourceWithTorch() || (ctx->GetTrickOption(RT_SPIRIT_MAP_CHEST) && logic->CanUse(RG_FAIRY_BOW));})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_1, SpiritShared(RR_SPIRIT_TEMPLE_STATUE_ROOM, []{return logic->CanBreakPots();})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_2, SpiritShared(RR_SPIRIT_TEMPLE_STATUE_ROOM, []{return logic->CanBreakPots();})),
|
||||
|
@ -237,7 +252,7 @@ void RegionTable_Init_SpiritTemple() {
|
|||
LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_6, SpiritShared(RR_SPIRIT_TEMPLE_STATUE_ROOM, []{return logic->CanBreakPots();})),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_STATUE_ROOM_WEST, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_STATUE_ROOM_WEST, []{return true/*CanClimb()*/;}),
|
||||
// RT_SPIRIT_PLATFORM_HOOKSHOT is currently disabled
|
||||
Entrance(RR_SPIRIT_TEMPLE_PLATFORM, []{return logic->SpiritPlatformLowered &&
|
||||
(logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_SPIRIT_PLATFORM_HOOKSHOT) && logic->CanUse(RG_HOOKSHOT)));}),
|
||||
|
@ -252,15 +267,29 @@ void RegionTable_Init_SpiritTemple() {
|
|||
Entrance(RR_SPIRIT_TEMPLE_SUN_BLOCK_ROOM, []{return true;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_SUN_BLOCK_ROOM] = Region("Spirit Temple Sun Block Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_SUN_BLOCK_ROOM] = Region("Spirit Temple Sun Block Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_EMPTY_STAIRS, []{return true/*str0 || SunlightArrows*/;}),
|
||||
//The blocks can be used to get onto this ledge itemless
|
||||
//true/*str0 || IsAdult || CanKillEnemy(RE_BEAMOS) || BunnyHovers() ||
|
||||
//((HasFireSource() || (SpiritSunBlockTorch && (logic->CanUse(STICKS) || (ctx->GetTrickOption(RT_SPIRIT_SUN_CHEST) && logic->CanUse(RG_FAIRY_BOW))))) && CanUse(RG_HOOKSHOT))*/
|
||||
Entrance(RR_SPIRIT_TEMPLE_SUN_BLOCK_SOUTH_LEDGE, []{return logic->SpiritSunBlockSouthLedge();}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_SKULLTULA_STAIRS, []{return true/*str0 || SunlightArrows*/;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_SUN_BLOCK_SOUTH_LEDGE] = Region("Spirit Temple Sun Block South ledge", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
//Assumes RR_SPIRIT_TEMPLE_SUN_BLOCK_ROOM access
|
||||
EventAccess(&logic->SpiritSunBlockTorch, []{return SpiritShared(RR_SPIRIT_TEMPLE_SUN_BLOCK_SOUTH_LEDGE, []{return true;}, true);}),
|
||||
}, {
|
||||
//Locations
|
||||
//the blocks can be used to get all the silver rupees and the chest itemless
|
||||
LOCATION(RC_SPIRIT_TEMPLE_SUN_BLOCK_ROOM_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_SUN_BLOCK_ROOM,
|
||||
[]{return logic->HasFireSourceWithTorch() || (ctx->GetTrickOption(RT_SPIRIT_SUN_CHEST) && logic->CanUse(RG_FAIRY_BOW));})),
|
||||
//Spawning the chest to get here is accounted for in movement logic, so we only need to confirm it can be spawned here
|
||||
LOCATION(RC_SPIRIT_TEMPLE_SUN_BLOCK_ROOM_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_SUN_BLOCK_SOUTH_LEDGE,
|
||||
[]{return logic->HasFireSource() ||
|
||||
(logic->SpiritSunBlockTorch && (logic->CanUse(RG_STICKS) || (ctx->GetTrickOption(RT_SPIRIT_SUN_CHEST) && logic->CanUse(RG_FAIRY_BOW))));})),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_EMPTY_STAIRS, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_SKULLTULA_STAIRS, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_SUN_BLOCK_ROOM, []{return true;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_SKULLTULA_STAIRS] = Region("Spirit Temple Skulltula Stairs", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
|
@ -283,10 +312,10 @@ void RegionTable_Init_SpiritTemple() {
|
|||
areaTable[RR_SPIRIT_TEMPLE_WEST_HAND_EXIT] = Region("Spirit Temple West Hand Exit", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_WEST_THRONE, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_WEST_HAND, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_OUTER_WEST_HAND, []{return true;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_WEST_HAND] = Region("Spirit Temple West Hand", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_OUTER_WEST_HAND] = Region("Spirit Temple West Hand", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST, true),
|
||||
}, {
|
||||
|
@ -295,11 +324,7 @@ void RegionTable_Init_SpiritTemple() {
|
|||
Entrance(RR_DESERT_COLOSSUS, []{return true;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_STATUE_ROOM_EAST] = Region("Spirit Temple Statue Room East", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
//Assumes RR_SPIRIT_TEMPLE_STATUE_ROOM_WEST access. WARNING: ZL spawning chests here is a temp flag
|
||||
LOCATION(RC_SPIRIT_TEMPLE_STATUE_ROOM_HAND_CHEST, logic->CanUse(RG_ZELDAS_LULLABY)),
|
||||
}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_STATUE_ROOM_EAST] = Region("Spirit Temple Statue Room East", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_2F_MIRROR, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_STATUE_ROOM, []{return true;}),
|
||||
|
@ -307,14 +332,40 @@ void RegionTable_Init_SpiritTemple() {
|
|||
Entrance(RR_SPIRIT_TEMPLE_SHORTCUT_SWITCH, []{return logic->SpiritEastToSwitch();}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_POT_STAIRS, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 4);}),
|
||||
//!QUANTUM LOGIC!
|
||||
//With 3 keys, you cannot lock adult out of longshotting to the west hand as you would have to
|
||||
//open the west hand door and then adult could climb through sun block room
|
||||
//With 3 keys, you cannot lock adult out of leaving spirit onto the hands and jumping down, as you would have to
|
||||
//open the west hand door and then adult could climb through sun block room to jump down from there
|
||||
//This requires that adult can complete both routes
|
||||
//Implies CanKillEnemy(RE_IRON_KNUCKLE)
|
||||
Entrance(RR_SPIRIT_TEMPLE_WEST_HAND, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) && logic->CanUse(RG_LONGSHOT) && logic->CanKillEnemy(RE_BEAMOS);}),
|
||||
//Similarly, we can gurantee jumping into desert colossus the same way
|
||||
//except this does not need the longshot as we don't care which hand we jump down from
|
||||
Entrance(RR_DESERT_COLOSSUS, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) && logic->CanKillEnemy(RE_BEAMOS);}),
|
||||
Entrance(RR_DESERT_COLOSSUS, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) && logic->CanKillEnemy(RE_BEAMOS)/* && CanClimb() && str0*/;}),
|
||||
//!QUANTUM LOGIC!
|
||||
//Continuing from above, if you also have the Longshot, then you can always reach the outer west hand, as you can longshot from east hand
|
||||
Entrance(RR_SPIRIT_TEMPLE_OUTER_WEST_HAND, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) && logic->CanUse(RG_LONGSHOT) && logic->CanKillEnemy(RE_BEAMOS)/* && CanClimb() && str0*/;}),
|
||||
//!QUANTUM LOGIC!
|
||||
//A variant of the above, if dungeon entrance randomiser is off, Adult entered spirit in reverse, and they have str 2 to get there from the front,
|
||||
//it is always possible for them to reach 1F_EAST with only 2 keys. This is because you can only waste 1 key (on the first child side lock)
|
||||
//before you either allow you to climb down through 2F mirror room, or give yourself access to a hand to jump down from.
|
||||
//If for whatever reason you can reach east hand but not west hand, this becomes possible with 3 keys instead.
|
||||
//If for whatever reason you can reach west hand but not east hand, this becomes possible with 4 keys instead.
|
||||
Entrance(RR_SPIRIT_TEMPLE_1F_EAST, []{return ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF) &&
|
||||
logic->CanUse(RG_SILVER_GAUNTLETS) &&
|
||||
((logic->CanKillEnemy(RE_BEAMOS) && logic->SmallKeys(RR_SPIRIT_TEMPLE, /*CanClimb() && str0 ?*/ 2 /*: 3*/)) ||
|
||||
(/*CanClimb() && str0 && */logic->CanKillEnemy(RE_IRON_KNUCKLE) && logic->SmallKeys(RR_SPIRIT_TEMPLE, 4)));}),
|
||||
//RT_SPIRIT_PLATFORM_HOOKSHOT is currently disabled
|
||||
Entrance(RR_SPIRIT_TEMPLE_PLATFORM, []{return logic->SpiritPlatformLowered &&
|
||||
(logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_SPIRIT_PLATFORM_HOOKSHOT) && logic->CanUse(RG_HOOKSHOT)));}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_INNER_EAST_HAND] = Region("Spirit Temple Inner East Hand", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
//Assumes RR_SPIRIT_TEMPLE_INNER_WEST_HAND access via RR_SPIRIT_TEMPLE_STATUE_ROOM_WEST and RR_SPIRIT_TEMPLE_STATUE_ROOM.
|
||||
LOCATION(RC_SPIRIT_TEMPLE_STATUE_ROOM_HAND_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_INNER_EAST_HAND, []{return logic->CanUse(RG_ZELDAS_LULLABY)/* && CanClimb()*/;})),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_STATUE_ROOM, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_STATUE_ROOM_EAST, []{return logic->CanUse(RG_HOVER_BOOTS);}),
|
||||
//Assumes RR_SPIRIT_TEMPLE_STATUE_ROOM_EAST access via RR_SPIRIT_TEMPLE_STATUE_ROOM
|
||||
Entrance(RR_SPIRIT_TEMPLE_SHORTCUT_SWITCH, []{return (logic->IsAdult && ctx->GetTrickOption(RT_SPIRIT_LOBBY_JUMP)) ||
|
||||
(logic->CanUse(RG_ZELDAS_LULLABY) && logic->CanUse(RG_HOOKSHOT));}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_SHORTCUT_SWITCH] = Region("Spirit Temple Shortcut Switch", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
|
@ -322,21 +373,21 @@ void RegionTable_Init_SpiritTemple() {
|
|||
EventAccess(&logic->SpiritStatueRoomSouthDoor, []{return SpiritShared(RR_SPIRIT_TEMPLE_SHORTCUT_SWITCH, []{return logic->CanUse(RG_MEGATON_HAMMER);});}),
|
||||
}, {
|
||||
//Locations
|
||||
//Assumes RR_SPIRIT_TEMPLE_STATUE_ROOM_EAST access
|
||||
LOCATION(RC_SPIRIT_TEMPLE_STATUE_ROOM_NORTHEAST_CHEST, logic->CanUse(RG_ZELDAS_LULLABY)),
|
||||
//Assumes RR_SPIRIT_TEMPLE_INNER_EAST_HAND access
|
||||
LOCATION(RC_SPIRIT_TEMPLE_STATUE_ROOM_NORTHEAST_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_SHORTCUT_SWITCH, []{return logic->CanUse(RG_ZELDAS_LULLABY);})),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_STATUE_ROOM_EAST, []{return true;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_SHORTCUT] = Region("Spirit Temple Shortcut", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//If child can ever use silver gauntlets and adult items, there needs to be an event here to account for child entering in reverse
|
||||
//If child can ever use silver gauntlets, there needs to be an event here to account for child entering in reverse
|
||||
//opening the way for adult entering via the front.
|
||||
Entrance(RR_SPIRIT_TEMPLE_STATUE_ROOM, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_LOBBY, []{return logic->CanUse(RG_SILVER_GAUNTLETS) && logic->CanUse(RG_MEGATON_HAMMER);}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_POT_STAIRS] = Region("Spirit Temple Stairs to Beamos Pits", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_POT_STAIRS] = Region("Spirit Temple Pot Stairs", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
LOCATION(RC_SPIRIT_TEMPLE_BEAMOS_HALL_POT_1, logic->CanBreakPots()),
|
||||
}, {
|
||||
Entrance(RR_SPIRIT_TEMPLE_STATUE_ROOM_EAST, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 4);}),
|
||||
|
@ -346,18 +397,18 @@ void RegionTable_Init_SpiritTemple() {
|
|||
areaTable[RR_SPIRIT_TEMPLE_BEAMOS_PITS] = Region("Spirit Temple Beamos Pits", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
//Implies killing the anubis with the fire ring, doing so itemless requires voiding out, which can lock hardcore + OHKO seeds
|
||||
Entrance(RR_SPIRIT_TEMPLE_POT_STAIRS, []{return logic->CanKillEnemy(RE_BEAMOS);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_FOUR_ARMOS, []{return logic->CanKillEnemy(RE_BEAMOS);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_BIG_WALL_LOWER, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 5);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_POT_STAIRS, []{return logic->CanKillEnemy(RE_BEAMOS);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_FOUR_ARMOS, []{return logic->CanKillEnemy(RE_BEAMOS);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_BIG_WALL_BASE, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 5);}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_FOUR_ARMOS] = Region("Spirit Temple Four Armos", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_NEAR_FOUR_ARMOS_CHEST, (logic->CanUse(RG_MIRROR_SHIELD) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS))) && logic->HasExplosives()),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_NEAR_FOUR_ARMOS_CHEST, (logic->CanUse(RG_MIRROR_SHIELD) || logic->SunlightArrows()) && logic->HasExplosives()),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY, logic->HasExplosives() && logic->CanUse(RG_SUNS_SONG)),
|
||||
}, {
|
||||
Entrance(RR_SPIRIT_TEMPLE_BEAMOS_PITS, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_FOUR_ARMOS_SIDE_ROOM, []{return logic->CanUse(RG_MIRROR_SHIELD) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS));}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_FOUR_ARMOS_SIDE_ROOM, []{return logic->CanUse(RG_MIRROR_SHIELD) || logic->SunlightArrows();}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_CHEST_STAIRS, []{return true;}),
|
||||
});
|
||||
|
||||
|
@ -387,24 +438,25 @@ void RegionTable_Init_SpiritTemple() {
|
|||
|
||||
areaTable[RR_SPIRIT_TEMPLE_EAST_HAND_EXIT] = Region("Spirit Temple East hand Exit", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_EAST_THRONE, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_EAST_HAND, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_EAST_THRONE, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_OUTER_EAST_HAND, []{return true;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_EAST_HAND] = Region("Spirit Temple East Hand", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_OUTER_EAST_HAND] = Region("Spirit Temple Outer East Hand", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST, true),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_EAST_HAND_EXIT, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_WEST_HAND, []{return logic->CanUse(RG_LONGSHOT);}),
|
||||
Entrance(RR_DESERT_COLOSSUS, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_EAST_HAND_EXIT, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_OUTER_WEST_HAND, []{return logic->CanUse(RG_LONGSHOT);}),
|
||||
Entrance(RR_DESERT_COLOSSUS, []{return true;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_BIG_WALL_LOWER] = Region("Spirit Temple Big Wall Lower", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_BIG_WALL_BASE] = Region("Spirit Temple Big Wall Base", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_BEAMOS_PITS, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_BIG_WALL_UPPER, []{return ctx->GetTrickOption(RT_SPIRIT_WALL) || (logic->CanAvoidEnemy(RE_BEAMOS, true, 2) && logic->CanPassEnemy(RE_WALLTULA));}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_BIG_WALL_UPPER, []{return (ctx->GetTrickOption(RT_SPIRIT_WALL) || (logic->CanAvoidEnemy(RE_BEAMOS, true, 2) && logic->CanPassEnemy(RE_WALLTULA)))
|
||||
/*&& CanClimbHigh()*/;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_BIG_WALL_UPPER] = Region("Spirit Temple Big Wall Upper", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
|
@ -414,8 +466,8 @@ void RegionTable_Init_SpiritTemple() {
|
|||
LOCATION(RC_SPIRIT_TEMPLE_ADULT_CLIMB_RIGHT_HEART, logic->CanUse(RG_HOOKSHOT)),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_BIG_WALL_LOWER, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_4F_CENTRAL, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_BIG_WALL_BASE, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_4F_CENTRAL, []{return true;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_4F_CENTRAL] = Region("Spirit Temple 4F Central", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
|
@ -439,27 +491,27 @@ void RegionTable_Init_SpiritTemple() {
|
|||
//Events
|
||||
EventAccess(&logic->Spirit4FSwitch, []{return logic->CanJumpslash() || logic->HasExplosives();}),
|
||||
//Needs the mirror in the cave to be a perm flag and event for doorsanity
|
||||
EventAccess(&logic->SpiritPlatformLowered, []{return (Here(RR_SPIRIT_TEMPLE_BIG_MIRROR_ROOM, []{return logic->CanJumpslash() || logic->HasExplosives();}) || logic->CanUse(RG_MIRROR_SHIELD)) ||
|
||||
(ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS));}),
|
||||
EventAccess(&logic->SpiritPlatformLowered, []{return (logic->SpiritPushed4FMirrors && logic->CanUse(RG_MIRROR_SHIELD)) || logic->SunlightArrows();}),
|
||||
|
||||
}, {}, {
|
||||
Entrance(RR_SPIRIT_TEMPLE_4F_CENTRAL, []{return true;}),
|
||||
//Rang can hit the switch on the way back but that's a trick
|
||||
Entrance(RR_SPIRIT_TEMPLE_BIG_MIRROR_CAVE, []{return logic->Spirit4FSwitch;}),
|
||||
//Assumes RR_SPIRIT_TEMPLE_BIG_MIRROR_CAVE access
|
||||
Entrance(RR_SPIRIT_TEMPLE_PLATFORM, []{return (logic->CanUse(RG_MIRROR_SHIELD) && logic->HasExplosives() && logic->Spirit4FSwitch) ||
|
||||
(ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS));}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_PLATFORM, []{return logic->SpiritPlatformLowered;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_BIG_MIRROR_CAVE] = Region("Spirit Temple Big Mirror Cave", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->Spirit4FSwitch, []{return logic->HasExplosives();}),
|
||||
EventAccess(&logic->Spirit4FSwitch, []{return logic->HasExplosives();}),
|
||||
//WARNING: not currently a permanent flag, needs to be one for doorsanity
|
||||
EventAccess(&logic->SpiritPushed4FMirrors, []{return logic->HasExplosives()/*&& str0*/;}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_TOPMOST_CHEST, (logic->IsAdult && logic->CanUse(RG_MIRROR_SHIELD)) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS))),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_TOPMOST_CHEST, (logic->IsAdult && logic->CanUse(RG_MIRROR_SHIELD)) || logic->SunlightArrows()),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_BIG_MIRROR_ROOM, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_BIG_MIRROR_ROOM, []{return true;}),
|
||||
});
|
||||
|
||||
//Assumes a SpiritPlatformLowered check on entry
|
||||
|
@ -467,9 +519,10 @@ void RegionTable_Init_SpiritTemple() {
|
|||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_STATUE_ROOM, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_STATUE_ROOM_WEST, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_INNER_WEST_HAND, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_STATUE_ROOM_EAST, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_STATUE_HEAD, []{return Here(RR_SPIRIT_TEMPLE_STATUE_HEAD, []{return logic->CanUse(RG_MIRROR_SHIELD) && logic->HasExplosives() && logic->Spirit4FSwitch;})
|
||||
&& logic->CanUse(RG_HOOKSHOT);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_INNER_EAST_HAND, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_STATUE_HEAD, []{return logic->SpiritPushed4FMirrors && logic->CanUse(RG_HOOKSHOT);}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_STATUE_HEAD] = Region("Spirit Temple Statue Head", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
|
@ -480,8 +533,8 @@ void RegionTable_Init_SpiritTemple() {
|
|||
}, {}, {
|
||||
// Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_STATUE_ROOM, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_STATUE_ROOM_WEST, []{return logic->CanUse(RG_HOVER_BOOTS);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_STATUE_ROOM_EAST, []{return logic->CanUse(RG_HOVER_BOOTS);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_INNER_WEST_HAND, []{return logic->CanUse(RG_HOVER_BOOTS);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_INNER_EAST_HAND, []{return logic->CanUse(RG_HOVER_BOOTS);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_PLATFORM, []{return logic->SpiritPlatformLowered && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT));}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_BOSS_ENTRYWAY, []{return logic->HasItem(RG_SPIRIT_TEMPLE_BOSS_KEY);}),
|
||||
});
|
||||
|
@ -503,7 +556,7 @@ void RegionTable_Init_SpiritTemple() {
|
|||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_ENTRYWAY, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_1F_WEST, []{return logic->IsChild;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_1F_WEST, []{return logic->IsChild/*logic->CanUse(RG_CRAWL) && logic->HasSoul(RG_NABOORU_SOUL)*/;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_1F_EAST, []{return false;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_SOUTH, []{return logic->CanUse(RG_LONGSHOT) && logic->CanUse(RG_BOMBCHU_5);}),
|
||||
});
|
||||
|
@ -520,9 +573,11 @@ void RegionTable_Init_SpiritTemple() {
|
|||
LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_RIGHT_HEART, logic->CanHitEyeTargets()),
|
||||
}, {
|
||||
//Exits
|
||||
//Nabooru's legs are technically visible one way collision here, but I'm not sure if this counts
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_LOBBY, []{return logic->IsChild/*logic->CanUse(RG_CRAWL)*/;}),
|
||||
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;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_WEST_1F_RUSTED_SWITCH, []{return logic->IsChild/*logic->CanUse(RG_CRAWL)*/ && logic->MQSpiritCrawlBoulder;}),
|
||||
});
|
||||
|
||||
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, {
|
||||
|
@ -531,7 +586,7 @@ void RegionTable_Init_SpiritTemple() {
|
|||
}, {}, {
|
||||
//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_1F_GIBDO_ROOM_NORTH, []{return logic->CanUse(RG_BOMBCHU_5) && logic->CanHitEyeTargets()/* && str0*/;}),
|
||||
});
|
||||
|
||||
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, {}, {
|
||||
|
@ -543,7 +598,7 @@ void RegionTable_Init_SpiritTemple() {
|
|||
Entrance(RR_SPIRIT_TEMPLE_MQ_TURNTABLE_ROOM, []{return logic->MQSpiritGibdosCleared;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_TURNTABLE_ROOM] = Region("Spirit Temple Turntable Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_TURNTABLE_ROOM] = Region("Spirit Temple MQ Turntable Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->FairyPot, []{return Here(RR_SPIRIT_TEMPLE_MQ_TURNTABLE_ROOM, []{return logic->CanKillEnemy(RE_STALFOS);});}),
|
||||
}, {
|
||||
|
@ -561,7 +616,8 @@ void RegionTable_Init_SpiritTemple() {
|
|||
|
||||
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);}),
|
||||
EventAccess(&logic->MQSpiritMapRoomEnemies, []{return /*(*/logic->CanKillEnemy(RE_ANUBIS) && logic->CanKillEnemy(RE_KEESE)/*) && (str0 || CanUse(RG_HOVER_BOOTS) || CanUse(RG_HOOKSHOT)) ||
|
||||
logic->CanKillEnemy(RE_ANUBIS, ED_BOOMERANG) && logic->CanKillEnemy(RE_KEESE, ED_FAR)*/;}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_MAP_ROOM_ENEMY_CHEST, logic->MQSpiritMapRoomEnemies),
|
||||
|
@ -569,7 +625,7 @@ void RegionTable_Init_SpiritTemple() {
|
|||
//Exits
|
||||
//Stalfos room blocks you in with fire until you kill the stalfos, which won't spawn from behind the fire
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_TURNTABLE_ROOM, []{return false;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_MAP_ROOM_SOUTH, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_MAP_ROOM_SOUTH, []{return true/*str0 || CanUse(RG_HOVER_BOOTS) || CanUse(RG_HOOKSHOT)*/;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_MAP_ROOM_SOUTH] = Region("Spirit Temple MQ Map Room South", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
|
@ -592,7 +648,7 @@ void RegionTable_Init_SpiritTemple() {
|
|||
EventAccess(&logic->MQSpiritCrawlBoulder, []{return logic->CanUse(RG_BOMBCHU_5) || (ctx->GetTrickOption(RT_RUSTED_SWITCHES) && logic->CanUse(RG_MEGATON_HAMMER));}),
|
||||
}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_1F_WEST, []{return logic->IsChild && logic->MQSpiritCrawlBoulder;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_1F_WEST, []{return logic->IsChild/*logic->CanUse(RG_CRAWL)*/ && logic->MQSpiritCrawlBoulder;}),
|
||||
//This tracks possible child access, if adult has not entered STATUE_ROOM. Certain Child Access is checked for separately as 7 Keys
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_UNDER_LIKE_LIKE, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 1);}),
|
||||
});
|
||||
|
@ -602,9 +658,9 @@ void RegionTable_Init_SpiritTemple() {
|
|||
LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_LIKE_LIKE_POT, SpiritShared(RR_SPIRIT_TEMPLE_MQ_UNDER_LIKE_LIKE, []{return logic->CanBreakPots();})),
|
||||
}, {
|
||||
//Exits
|
||||
//This covers adult access only, as child arrives here from the other side of this door
|
||||
//This covers adult and reverse access only, as child going forwards 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();}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_BROKEN_WALL_ROOM, []{return logic->CanHitSwitch()/* && CanClimbHigh()*/;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_BROKEN_WALL_ROOM] = Region("Spirit Temple MQ Broken Wall Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
|
@ -612,37 +668,81 @@ void RegionTable_Init_SpiritTemple() {
|
|||
//Implies CanKillEnemy(RE_LIKE_LIKE)
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_NORTH_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_MQ_BROKEN_WALL_ROOM, []{return logic->CanKillEnemy(RE_BEAMOS);})),
|
||||
//Sunlights only temp spawn this chest, which is unintuitive/a bug.
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_SOUTH_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_MQ_BROKEN_WALL_ROOM, []{return (logic->HasExplosives() || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS))) && logic->CanUse(RG_HOOKSHOT);})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_SOUTH_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_MQ_BROKEN_WALL_ROOM, []{return (logic->HasExplosives() || logic->SunlightArrows()) && logic->CanUse(RG_HOOKSHOT);})),
|
||||
}, {
|
||||
//Exits
|
||||
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
|
||||
//This exit only governs child forwards access, adult and reverse 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_STATUE_ROOM_WEST] = Region("Spirit Temple MQ Statue Room West", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->SpiritStatueRoomSouthDoor, []{return SpiritShared(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM_WEST, []{return ctx->GetTrickOption(RT_SPIRIT_MQ_FROZEN_EYE) && logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_SONG_OF_TIME);});}),
|
||||
}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM_WEST] = Region("Spirit Temple MQ Statue Room West", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_3F_EAST_POT, SpiritShared(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM_WEST, []{return ((logic->IsAdult || logic->CanJumpslash()) && logic->CanUse(RG_BOOMERANG)) ||
|
||||
((logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_SONG_OF_TIME) || (logic->IsAdult && ctx->GetTrickOption(RT_SPIRIT_LOBBY_JUMP))) && logic->CanBreakPots());})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_3F_WEST_POT, SpiritShared(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM_WEST, []{return ((logic->IsAdult || logic->CanJumpslash()) && logic->CanUse(RG_BOOMERANG) && ctx->GetTrickOption(RT_SPIRIT_WEST_LEDGE)) ||
|
||||
(logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_SONG_OF_TIME) || (logic->IsAdult && ctx->GetTrickOption(RT_SPIRIT_LOBBY_JUMP)) && logic->CanBreakPots());})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_SMALL_CRATE, SpiritShared(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM_WEST, []{return logic->CanBreakSmallCrates();})),
|
||||
}, {
|
||||
//Exits
|
||||
//Minimal entry, real key logic handled in Shared functions
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_BROKEN_WALL_ROOM, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 6);}),
|
||||
//IsAdult || ctx->GetTrickOption(RT_SPIRIT_MQ_SUN_BLOCK_SOT) || CanUse(RG_SONG_OF_TIME)
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_FLAMETHROWER_STAIRS, []{return logic->MQSpiritStatueToSunBlock();}),
|
||||
//!QUANTUM LOGIC!
|
||||
//If we entered in reverse and dungeon entrances are off, we only need 6 keys, access to Gauntlets Hand and the ability to crawl to reach colossus
|
||||
//This is because with 6 keys it becomes impossible to avoid opening either the west hand lock or the first child side lock
|
||||
//and either direction lets child reach colossus. CanHitSwitch and CanKillEnemy(RE_IRON_KNUCKLE) is implied.
|
||||
//Logic can then allow child back into spirit, putting 1F west in logic with only 6 keys without forwards entry
|
||||
Entrance(RR_DESERT_COLOSSUS, []{return logic->IsChild/*CanUse(RG_CRAWL)*/ && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF) &&
|
||||
logic->ReverseSpiritChild && logic->SmallKeys(RR_SPIRIT_TEMPLE, 6) && /*(str0 || SunlightArrows())&&*/
|
||||
(logic->CanUse(RG_BOMBCHU_5) || (ctx->GetTrickOption(RT_RUSTED_SWITCHES) && logic->CanUse(RG_MEGATON_HAMMER)));}),
|
||||
//!QUANTUM LOGIC!
|
||||
//If we have 6 keys and Child reverse spirit entry, we can gurantee broken wall room access for Child
|
||||
//as long as we can hit a switch and because Adult cannot reach the initial child lock without
|
||||
//first opening the Statue Room to Broken Wall Room lock. The details of this are handled in SpiritShared.
|
||||
//if adult can ever cross crawlspaces this becomes more complicated.
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_BROKEN_WALL_ROOM, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 6);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_POT_LEDGE, []{return logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_SONG_OF_TIME);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_INNER_WEST_HAND, []{return logic->IsAdult || logic->CanJumpslash() || logic->CanUse(RG_HOVER_BOOTS);}),
|
||||
//(IsAdult || ctx->GetTrickOption(RT_SPIRIT_MQ_SUN_BLOCK_SOT) || CanUse(RG_SONG_OF_TIME)) && str0
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_FLAMETHROWER_STAIRS, []{return logic->MQSpiritStatueToSunBlock();}),
|
||||
//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);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM_EAST, []{return logic->IsAdult && logic->CanUse(RG_HOOKSHOT);}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_POT_LEDGE] = Region("Spirit Temple MQ Pot Ledge", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
//This event does not need handling in SpiritShared as it only affects navigation, adult access here is always Certain, and Child has no way through that Adult does not.
|
||||
EventAccess(&logic->SpiritStatueRoomSouthDoor, []{return ctx->GetTrickOption(RT_SPIRIT_MQ_FROZEN_EYE) && logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_SONG_OF_TIME);}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_3F_EAST_POT, SpiritShared(RR_SPIRIT_TEMPLE_MQ_POT_LEDGE , []{return logic->CanBreakPots();}, false,
|
||||
RR_SPIRIT_TEMPLE_MQ_INNER_WEST_HAND , []{return logic->CanUse(RG_BOOMERANG);})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_3F_WEST_POT, SpiritShared(RR_SPIRIT_TEMPLE_MQ_POT_LEDGE , []{return logic->CanBreakPots();}, false,
|
||||
RR_SPIRIT_TEMPLE_MQ_INNER_WEST_HAND , []{return ctx->GetTrickOption(RT_SPIRIT_WEST_LEDGE) && logic->CanUse(RG_BOOMERANG);})),
|
||||
}, {
|
||||
//Exits
|
||||
//This is pretty tight to reach the SoT block, but you can just go via the hand...
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM_WEST, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_INNER_WEST_HAND, []{return true;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_INNER_WEST_HAND] = Region("Spirit Temple MQ Inner West Hand", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_3F_EAST_POT, SpiritShared(RR_SPIRIT_TEMPLE_MQ_INNER_WEST_HAND, []{return logic->CanUse(RG_BOOMERANG);}, false,
|
||||
RR_SPIRIT_TEMPLE_MQ_POT_LEDGE, []{return logic->CanBreakPots();})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_3F_WEST_POT, SpiritShared(RR_SPIRIT_TEMPLE_MQ_INNER_WEST_HAND, []{return logic->CanUse(RG_BOOMERANG) && ctx->GetTrickOption(RT_SPIRIT_WEST_LEDGE);}, false,
|
||||
RR_SPIRIT_TEMPLE_MQ_POT_LEDGE, []{return logic->CanBreakPots();})),
|
||||
}, {
|
||||
//Exits
|
||||
//Land on the SoT block
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM_WEST, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_POT_LEDGE, []{return logic->IsAdult && ctx->GetTrickOption(RT_SPIRIT_LOBBY_JUMP);}),
|
||||
// RT_SPIRIT_PLATFORM_HOOKSHOT is currently disabled
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_PLATFORM, []{return logic->SpiritPlatformLowered &&
|
||||
(logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_SPIRIT_PLATFORM_HOOKSHOT) && logic->CanUse(RG_HOOKSHOT)));}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM] = Region("Spirit Temple MQ Statue Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->SpiritStatueRoomSouthDoor, []{return SpiritShared(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return logic->HasFireSource();});}),
|
||||
//This event does not need handling in SpiritShared as it only affects navigation, Adult access here is always Certain, and Child has no way through that adult does not.
|
||||
EventAccess(&logic->SpiritStatueRoomSouthDoor, []{return logic->HasFireSource();}),
|
||||
//Assuming all higher areas filter down to here for this despite there being many good angles to use FAs
|
||||
EventAccess(&logic->MQSpiritStatueRoomTorches, []{return logic->CanUse(RG_FIRE_ARROWS) || (ctx->GetTrickOption(RT_SPIRIT_MQ_LOWER_ADULT) && logic->CanUse(RG_DINS_FIRE));}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_COMPASS_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return logic->CanHitEyeTargets();})),
|
||||
|
@ -651,15 +751,16 @@ void RegionTable_Init_SpiritTemple() {
|
|||
LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_2F_EASTMOST_POT, SpiritShared(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return logic->CanBreakPots();})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_CRATE_1, SpiritShared(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return logic->CanBreakCrates();})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_CRATE_2, SpiritShared(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return logic->CanBreakCrates();})),
|
||||
//the drop sometimes flies off the block when the crate is blown up, but not always, so I added a rang requirement
|
||||
//a trick to reload for it is plausible
|
||||
//The drop sometimes flies off the block when the crate is blown up, but not always, so I added a rang requirement
|
||||
//A trick to reload for it is plausible
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_SMALL_CRATE, SpiritShared(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return (logic->CanUse(RG_SONG_OF_TIME) && logic->CanBreakSmallCrates()) ||
|
||||
(logic->CanUse(RG_BOOMERANG) && logic->HasExplosives());})),
|
||||
(logic->CanUse(RG_BOOMERANG) && logic->HasExplosives());})),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM_WEST, []{return true/*logic->CanClimb()*/;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_NORTH, []{return logic->SpiritStatueRoomSouthDoor;}),
|
||||
//explicit adult check here is a precaution against possible child logic leaking, child with a hookshot can do this
|
||||
//explicit adult check here is a precaution against possible Child logic leaking, Child with a hookshot can do this
|
||||
//It's possible to climb the legs of the statue to line up a longshot hit, but you can just go via West
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM_EAST, []{return logic->IsAdult && logic->CanUse(RG_SCARECROW);}),
|
||||
});
|
||||
|
||||
|
@ -672,14 +773,14 @@ void RegionTable_Init_SpiritTemple() {
|
|||
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, SpiritMQSharedSunBlockRoom([]{return true/*str0*/;})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_SUN_BLOCK_ROOM, SpiritMQSharedSunBlockRoom([]{return logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_SPIRIT_MQ_SUN_BLOCK_GS) && logic->CanUse(RG_BOOMERANG));})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_1, SpiritMQSharedSunBlockRoom([]{return logic->CanBreakPots();})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_2, SpiritMQSharedSunBlockRoom([]{return logic->CanBreakPots();})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM, []{return true/*str0*/;})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_SUN_BLOCK_ROOM, SpiritShared(RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM, []{return logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_SPIRIT_MQ_SUN_BLOCK_GS) && logic->CanUse(RG_BOOMERANG));})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_1, SpiritShared(RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM, []{return logic->CanBreakPots();})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_2, SpiritShared(RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM, []{return logic->CanBreakPots();})),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_FLAMETHROWER_STAIRS, []{return true/*str0*/;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_SKULLTULA_STAIRS, []{return true/*str0*/;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_FLAMETHROWER_STAIRS, []{return true/*str0 || SunlightArrows()*/;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_SKULLTULA_STAIRS , []{return true/*str0 || SunlightArrows()*/;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_SKULLTULA_STAIRS] = Region("Spirit Temple MQ Skulltula Stairs", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
|
@ -697,11 +798,11 @@ void RegionTable_Init_SpiritTemple() {
|
|||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_WEST_HAND_EXIT] = Region("Spirit Temple MQ West Hand Exit", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_WEST_THRONE, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_WEST_HAND, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_WEST_THRONE , []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_OUTER_WEST_HAND, []{return true;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_WEST_HAND] = Region("Spirit Temple MQ West Hand", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_OUTER_WEST_HAND] = Region("Spirit Temple MQ Outer West Hand", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST, true),
|
||||
}, {
|
||||
|
@ -716,44 +817,77 @@ void RegionTable_Init_SpiritTemple() {
|
|||
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);});}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_NORTH, []{return logic->IsChild ? logic->CanUse(RG_SILVER_GAUNTLETS) : Here(RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_SOUTH, []{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
|
||||
//Dhard 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, SpiritMQSharedBigBlock([]{return logic->IsChild && logic->CanHitEyeTargets();})),
|
||||
//Hard child locked because pushing the block is a permanent flag that blocks the eye target and cannot be undone
|
||||
//but it resets as Child as a rando QoL feature
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_SILVER_BLOCK_HALLWAY_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_NORTH, []{return logic->IsChild && 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))),
|
||||
}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM_EAST] = Region("Spirit Temple MQ Statue Room East", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_INNER_EAST_HAND, []{return logic->IsAdult || logic->CanJumpslash() || logic->CanUse(RG_HOVER_BOOTS);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_CHEST_LEDGE, []{return logic->CanUse(RG_HOVER_BOOTS) ||
|
||||
((ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_LONGSHOT));}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_THREE_SUNS_ROOM_2F, []{return logic->MQSpiritStatueRoomTorches;}),
|
||||
//!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
|
||||
//We only need 4 keys and the ability to reach both hands for adult to logically be able to drop down onto Desert Colossus
|
||||
//This is because there are only 3 keys that can be wasted without opening up either this lock to East hand, or the West Hand lock through Sun Block Room
|
||||
//and both directions allow you to drop onto colossus
|
||||
//logic->CanKillEnemy(RE_FLOORMASTER) is implied
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_WEST_HAND, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 4) &&
|
||||
Entrance(RR_DESERT_COLOSSUS, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 4) &&
|
||||
logic->CanAvoidEnemy(RE_BEAMOS, true, 4) && logic->CanUse(RG_SONG_OF_TIME) &&
|
||||
logic->CanJumpslash() &&
|
||||
logic->CanJumpslash() && /*(str0 || SunlightArrows) &&*/
|
||||
(ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) &&
|
||||
logic->CanKillEnemy(RE_IRON_KNUCKLE) &&
|
||||
logic->CanUse(RG_LONGSHOT);}),
|
||||
logic->CanUse(RG_HOOKSHOT);}),
|
||||
//!QUANTUM LOGIC!
|
||||
//Continuing from above, if we also have a longshot, we can go from the East hand to the West hand, meaning we always have access to East Hand
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_OUTER_WEST_HAND, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 4) &&
|
||||
logic->CanAvoidEnemy(RE_BEAMOS, true, 4) && logic->CanUse(RG_SONG_OF_TIME) &&
|
||||
logic->CanJumpslash() && /*(str0 || SunlightArrows) &&*/
|
||||
(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_FIRE_WALL_STAIRS_LOWER, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 5);}),
|
||||
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));}),
|
||||
// RT_SPIRIT_PLATFORM_HOOKSHOT is currently disabled
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_PLATFORM, []{return logic->SpiritPlatformLowered &&
|
||||
(logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_SPIRIT_PLATFORM_HOOKSHOT) && logic->CanUse(RG_HOOKSHOT)));}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_INNER_EAST_HAND] = Region("Spirit Temple MQ Inner East Hand", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_ROOM_LULLABY_CHEST, logic->CanUse(RG_ZELDAS_LULLABY) && logic->CanBreakCrates()),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM_EAST, []{return logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_CHEST_LEDGE, []{return ((logic->IsAdult || ctx->GetTrickOption(RT_SPIRIT_WEST_LEDGE)) && (ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOOKSHOT))
|
||||
|| (logic->IsAdult && ctx->GetTrickOption(RT_SPIRIT_LOBBY_JUMP));}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_CHEST_LEDGE] = Region("Spirit Temple MQ Chest Ledge", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_ROOM_INVISIBLE_CHEST, ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM_EAST, []{return logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_LONGSHOT);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_INNER_EAST_HAND, []{return true;}),
|
||||
});
|
||||
|
||||
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));}),
|
||||
EventAccess(&logic->MQSpirit3SunsEnemies, []{return (logic->CanUse(RG_MIRROR_SHIELD) && logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2)) || logic->SunlightArrows();}),
|
||||
}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM_EAST, []{return true;}),
|
||||
|
@ -762,7 +896,8 @@ void RegionTable_Init_SpiritTemple() {
|
|||
|
||||
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, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_THREE_SUNS_ROOM_2F, []{return logic->MQSpirit3SunsEnemies;}),
|
||||
//It is possible to clip through here with longshot by aiming high enough
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_THREE_SUNS_ROOM_2F, []{return logic->MQSpirit3SunsEnemies/* && CanClimbHigh()*/;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_1F_EAST, []{return true;}),
|
||||
});
|
||||
|
||||
|
@ -776,10 +911,10 @@ void RegionTable_Init_SpiritTemple() {
|
|||
LOCATION(RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_2, logic->CanBreakPots()),
|
||||
}, {
|
||||
//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_SAND_PIT, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 7);}),
|
||||
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_SAND_PIT, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM_UPPER, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 7);}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_SAND_PIT] = Region("Spirit Temple MQ Sand Pit", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
|
@ -791,11 +926,22 @@ void RegionTable_Init_SpiritTemple() {
|
|||
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, {}, {}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM_UPPER] = Region("Spirit Temple MQ Symphony Room Upper", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->MQSpiritSymphonyRoomDoor, []{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);}),
|
||||
}, {}, {
|
||||
//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);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM_LOWER, []{return true;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM_LOWER] = Region("Spirit Temple MQ Symphony Room Lower", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM_UPPER, []{return true/*CanClimb()*/;}),
|
||||
//Implies CanPassEnemy(RE_MOBLIN_CHIEF)
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_AFTER_SYMPHONY_ROOM, []{return logic->MQSpiritSymphonyRoomDoor;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_AFTER_SYMPHONY_ROOM] = Region("Spirit Temple MQ After Symphony Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
|
@ -804,7 +950,7 @@ void RegionTable_Init_SpiritTemple() {
|
|||
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;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM_UPPER, []{return true;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_FIRE_WALL_STAIRS_LOWER] = Region("Spirit Temple MQ Fire Wall Stairs Lower", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
|
@ -816,17 +962,17 @@ void RegionTable_Init_SpiritTemple() {
|
|||
areaTable[RR_SPIRIT_TEMPLE_MQ_FIRE_WALL_STAIRS_UPPER] = Region("Spirit Temple MQ Fire Wall Stairs Upper", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_FIRE_WALL_STAIRS_LOWER, []{return logic->CanUse(RG_HOOKSHOT);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_FOUR_BEAMOS_ROOM, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_BEAMOS_PITS, []{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, {}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_BEAMOS_PITS] = Region("Spirit Temple MQ Beamos Pits", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_BEAMOS_ROOM_CHEST, logic->CanKillEnemy(RE_BEAMOS)),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_BEAMOS_SMALL_CRATE, logic->CanKillEnemy(RE_BEAMOS) && logic->CanUse(RG_SONG_OF_TIME) && logic->CanBreakSmallCrates()),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_BEAMOS_SMALL_CRATE, logic->CanAvoidEnemy(RE_BEAMOS, true, 4) && logic->CanUse(RG_SONG_OF_TIME) && logic->CanBreakSmallCrates()),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_FIRE_WALL_STAIRS_UPPER, []{return logic->CanAvoidEnemy(RE_BEAMOS, true, 4) && logic->CanUse(RG_SONG_OF_TIME);}),
|
||||
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_FIRE_WALL_STAIRS_UPPER, []{return logic->CanAvoidEnemy(RE_BEAMOS, true, 4) && logic->CanUse(RG_SONG_OF_TIME)/* && str0*/;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_SOT_SUN_ROOM, []{return logic->CanAvoidEnemy(RE_BEAMOS, true, 4) && logic->CanUse(RG_SONG_OF_TIME)/* && str0*/;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_BIG_WALL_LOWER, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 6);}),
|
||||
});
|
||||
|
||||
|
@ -836,36 +982,36 @@ void RegionTable_Init_SpiritTemple() {
|
|||
LOCATION(RC_SPIRIT_TEMPLE_MQ_DINALFOS_ROOM_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)),
|
||||
}, {
|
||||
//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);});}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_BEAMOS_PITS, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_FLOORMASTER_STAIRS, []{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, {}, {}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_FLOORMASTER_STAIRS] = Region("Spirit Temple MQ Floormaster Stairs", "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);});}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_SOT_SUN_ROOM, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_EAST_THRONE, []{return (ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && Here(RR_SPIRIT_TEMPLE_MQ_FLOORMASTER_STAIRS, []{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, {}, {}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_EAST_THRONE] = Region("Spirit Temple MQ East Throne", "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_EXIT_TO_MIRROR_SHIELD_HAND, []{return Here(RR_SPIRIT_TEMPLE_MQ_EAST_IRON_KNUCKLE, []{return logic->CanKillEnemy(RE_IRON_KNUCKLE);});}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_FLOORMASTER_STAIRS, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_EAST_HAND_EXIT, []{return Here(RR_SPIRIT_TEMPLE_MQ_EAST_THRONE, []{return logic->CanKillEnemy(RE_IRON_KNUCKLE);});}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_EXIT_TO_MIRROR_SHIELD_HAND] = Region("Spirit Temple MQ Exit To Mirror Shield Hand", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_EAST_IRON_KNUCKLE, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_MIRROR_SHIELD_HAND, []{return true;}),
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_EAST_HAND_EXIT] = Region("Spirit Temple MQ East Hand Exit", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_EAST_THRONE, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_OUTER_EAST_HAND, []{return true;}),
|
||||
});
|
||||
|
||||
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_OUTER_EAST_HAND] = Region("Spirit Temple MQ Outer East Hand", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST, true),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_WEST_HAND, []{return logic->CanUse(RG_LONGSHOT);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_EAST_IRON_KNUCKLE, []{return true;}),
|
||||
Entrance(RR_DESERT_COLOSSUS, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_OUTER_WEST_HAND, []{return logic->CanUse(RG_LONGSHOT);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_EAST_THRONE, []{return true;}),
|
||||
Entrance(RR_DESERT_COLOSSUS, []{return true;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_3F_GIBDO_ROOM] = Region("Spirit Temple MQ 3F Gibdo Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
|
@ -882,16 +1028,19 @@ void RegionTable_Init_SpiritTemple() {
|
|||
LOCATION(RC_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_2, logic->CanBreakPots()),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_FOUR_BEAMOS_ROOM, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_BEAMOS_PITS, []{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
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_BIG_WALL_UPPER, []{return logic->CanKillEnemy(RE_KEESE);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_BIG_WALL_UPPER, []{return /*(*/logic->CanKillEnemy(RE_KEESE)/*|| CanUse(RG_SKULL_MASK)) && CanClimbHigh()*/;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_BIG_WALL_UPPER] = Region("Spirit Temple MQ Big Wall Upper", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_BIG_WALL_UPPER] = Region("Spirit Temple MQ Big Wall Upper", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
//Getting some of these with just climbing downwards is theoretically possible but definitly a trick
|
||||
EventAccess(&logic->MQSpiritBigWallSilvers, []{return /*(*/logic->CanKillEnemy(RE_KEESE)/*|| CanUse(RG_SKULL_MASK)) && CanClimbHigh()*/;}),
|
||||
}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_BIG_WALL_LOWER, []{return true;}),
|
||||
//The silver rupees are irrelevant without silver shuffle
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_4F_CENTRAL, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_4F_CENTRAL, []{return logic->MQSpiritBigWallSilvers;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_4F_CENTRAL] = Region("Spirit Temple MQ 4F Central", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
|
@ -900,12 +1049,12 @@ void RegionTable_Init_SpiritTemple() {
|
|||
LOCATION(RC_SPIRIT_TEMPLE_MQ_BEFORE_MIRROR_POT_2, logic->CanBreakPots()),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_BIG_WALL_UPPER, []{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);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_BIG_WALL_UPPER, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_NINE_THRONES_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, {}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_NINE_THRONES_ROOM] = Region("Spirit Temple MQ Nine Thrones 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)),
|
||||
|
@ -917,7 +1066,8 @@ void RegionTable_Init_SpiritTemple() {
|
|||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_BIG_MIRROR_ROOM] = Region("Spirit Temple MQ Big Mirror Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->MQSpiritOpenedBigMirrorCave, []{return logic->CanUse(RG_MEGATON_HAMMER);}),
|
||||
//Needs the mirror in the cave to be a perm flag and event for doorsanity
|
||||
EventAccess(&logic->SpiritPlatformLowered, []{return (logic->SpiritPushed4FMirrors && logic->CanUse(RG_MIRROR_SHIELD)) || logic->SunlightArrows();}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_1, logic->CanBreakPots()),
|
||||
|
@ -931,18 +1081,31 @@ void RegionTable_Init_SpiritTemple() {
|
|||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_4F_CENTRAL, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CAVE, []{return logic->MQSpiritOpenedBigMirrorCave;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CAVE, []{return Here(RR_SPIRIT_TEMPLE_MQ_BIG_MIRROR_ROOM, []{return logic->CanUse(RG_MEGATON_HAMMER);});}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_PLATFORM, []{return logic->SpiritPlatformLowered;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CAVE] = Region("Spirit Temple MQ Big Mirror Cave", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CAVE] = Region("Spirit Temple MQ Big Mirror Cave", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
//WARNING: Not currently a permanent flag, needs to be one for doorsanity
|
||||
EventAccess(&logic->SpiritPushed4FMirrors, []{return ((logic->IsAdult && logic->CanUse(RG_MIRROR_SHIELD)) || logic->SunlightArrows())/* && str0*/;}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_MIRROR_PUZZLE_INVISIBLE_CHEST, ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_BIG_MIRROR_ROOM, []{return logic->MQSpiritOpenedBigMirrorCave;}),
|
||||
//If it's ever relevant to longshot into head from lobby, this needs to be an event access
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_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);});}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_BIG_MIRROR_ROOM, []{return true;}),
|
||||
});
|
||||
|
||||
//Assumes SpiritPlatformLowered is checked on entry
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_PLATFORM] = Region("Spirit Temple MQ Platform", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_HEAD, []{return logic->SpiritPushed4FMirrors && logic->CanUse(RG_MIRROR_SHIELD) && logic->CanUse(RG_HOOKSHOT);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM_WEST, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_INNER_WEST_HAND, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM_EAST, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_INNER_EAST_HAND, []{return true;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_STATUE_HEAD] = Region("Spirit Temple MQ Statue Head", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
|
@ -952,8 +1115,11 @@ void RegionTable_Init_SpiritTemple() {
|
|||
EventAccess(&logic->ReverseSpiritAdult, []{return logic->IsAdult;}),
|
||||
}, {}, {
|
||||
// Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_LOBBY, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_BOSS_ENTRYWAY, []{return logic->HasItem(RG_SPIRIT_TEMPLE_BOSS_KEY);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_INNER_WEST_HAND, []{return logic->CanUse(RG_HOVER_BOOTS);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_INNER_EAST_HAND, []{return logic->CanUse(RG_HOVER_BOOTS);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_PLATFORM, []{return logic->SpiritPlatformLowered && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT));}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_BOSS_ENTRYWAY, []{return logic->HasItem(RG_SPIRIT_TEMPLE_BOSS_KEY);}),
|
||||
});
|
||||
|
||||
#pragma endregion
|
||||
|
|
|
@ -1286,6 +1286,10 @@ bool Logic::HasFireSourceWithTorch() {
|
|||
return HasFireSource() || CanUse(RG_STICKS);
|
||||
}
|
||||
|
||||
bool Logic::SunlightArrows() {
|
||||
return ctx->GetOption(RSK_SUNLIGHT_ARROWS) && CanUse(RG_LIGHT_ARROWS);
|
||||
}
|
||||
|
||||
// Is this best off signaling what you have already traded, or what step you are currently on?
|
||||
bool Logic::TradeQuestStep(RandomizerGet rg) {
|
||||
if (ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE)) {
|
||||
|
@ -2376,8 +2380,19 @@ bool Logic::SpiritWestToSkull() {
|
|||
return (IsAdult && ctx->GetTrickOption(RT_SPIRIT_LOBBY_JUMP)) || CanUse(RG_HOVER_BOOTS) || CanUse(RG_SCARECROW);
|
||||
}
|
||||
|
||||
bool Logic::SpiritSunBlockSouthLedge() {
|
||||
return true/*str0 || IsAdult || CanKillEnemy(RE_BEAMOS) || BunnyHovers() ||
|
||||
(CanUse(RG_HOOKSHOT) && (HasFireSource() ||
|
||||
(SpiritSunBlockTorch && (logic->CanUse(STICKS) || (ctx->GetTrickOption(RT_SPIRIT_SUN_CHEST) && logic->CanUse(RG_FAIRY_BOW))))))*/;
|
||||
}
|
||||
|
||||
//Combines crossing the ledge directly and the jump from the hand
|
||||
bool Logic::MQSpiritWestToPots() {
|
||||
return (IsAdult && ctx->GetTrickOption(RT_SPIRIT_LOBBY_JUMP)) || CanUse(RG_HOVER_BOOTS) || CanUse(RG_SONG_OF_TIME);
|
||||
}
|
||||
|
||||
bool Logic::MQSpiritStatueToSunBlock() {
|
||||
return IsAdult || ctx->GetTrickOption(RT_SPIRIT_MQ_SUN_BLOCK_SOT) || CanUse(RG_SONG_OF_TIME);
|
||||
return (IsAdult || ctx->GetTrickOption(RT_SPIRIT_MQ_SUN_BLOCK_SOT) || CanUse(RG_SONG_OF_TIME))/* && str0*/;
|
||||
}
|
||||
|
||||
bool Logic::MQSpiritStatueSouthDoor() {
|
||||
|
@ -2570,18 +2585,20 @@ void Logic::Reset() {
|
|||
MQSpiritCrawlBoulder = false;
|
||||
MQSpiritMapRoomEnemies = false;
|
||||
MQSpiritTimeTravelChest = false;
|
||||
MQSpiritStatueRoomTorches = false;
|
||||
MQSpirit3SunsEnemies = false;
|
||||
MQSpiritOpenedBigMirrorCave = false;
|
||||
MQSpiritSymphonyRoomDoor = false;
|
||||
MQSpiritBigWallSilvers = false;
|
||||
Spirit1FSilverRupees = false;
|
||||
SpiritChildSwitchBridge = false;
|
||||
SpiritRupeeBridge = false;
|
||||
SpiritBouldersSilvers = false;
|
||||
SpiritPlatformLowered = false;
|
||||
Spirit4FSwitch = false;
|
||||
SpiritPushed4FMirrors = false;
|
||||
ReverseSpiritChild = false;
|
||||
ReverseSpiritAdult = false;
|
||||
|
||||
StopPerformanceTimer(PT_LOGIC_RESET);
|
||||
}
|
||||
|
||||
} // namespace Rando
|
||||
|
|
|
@ -180,15 +180,19 @@ class Logic {
|
|||
bool MQSpiritCrawlBoulder = false;
|
||||
bool MQSpiritMapRoomEnemies = false;
|
||||
bool MQSpiritTimeTravelChest = false;
|
||||
bool MQSpiritStatueRoomTorches = false;
|
||||
bool MQSpirit3SunsEnemies = false;
|
||||
bool MQSpiritOpenedBigMirrorCave = false;
|
||||
bool MQSpiritSymphonyRoomDoor = false;
|
||||
bool MQSpiritBigWallSilvers = false;
|
||||
bool Spirit1FSilverRupees = false;
|
||||
bool SpiritChildSwitchBridge = false;
|
||||
bool SpiritRupeeBridge = false;
|
||||
bool SpiritSunBlockTorch = false;
|
||||
bool SpiritBouldersSilvers = false;
|
||||
bool SpiritStatueRoomSouthDoor = false;
|
||||
bool SpiritPlatformLowered = false;
|
||||
bool Spirit4FSwitch = false;
|
||||
bool SpiritPushed4FMirrors = false;
|
||||
bool ReverseSpiritChild = false;
|
||||
bool ReverseSpiritAdult = true;
|
||||
|
||||
|
@ -258,6 +262,7 @@ class Logic {
|
|||
bool CanBreakSmallCrates();
|
||||
bool HasFireSource();
|
||||
bool HasFireSourceWithTorch();
|
||||
bool SunlightArrows();
|
||||
bool TradeQuestStep(RandomizerGet rg);
|
||||
bool CanFinishGerudoFortress();
|
||||
bool CanStandingShield();
|
||||
|
@ -299,12 +304,14 @@ class Logic {
|
|||
static std::map<uint32_t, uint32_t> RandoGetToDungeonScene;
|
||||
static std::map<RandomizerGet, uint32_t> RandoGetToEquipFlag;
|
||||
static std::map<RandomizerGet, uint32_t> RandoGetToRandInf;
|
||||
bool Logic::IsReverseAccessPossible();
|
||||
bool Logic::SpiritBrokenWallToStatue();
|
||||
bool Logic::SpiritEastToSwitch();
|
||||
bool Logic::SpiritWestToSkull();
|
||||
bool Logic::MQSpiritStatueToSunBlock();
|
||||
bool Logic::MQSpiritStatueSouthDoor();
|
||||
bool IsReverseAccessPossible();
|
||||
bool SpiritBrokenWallToStatue();
|
||||
bool SpiritEastToSwitch();
|
||||
bool SpiritWestToSkull();
|
||||
bool SpiritSunBlockSouthLedge();
|
||||
bool MQSpiritWestToPots();
|
||||
bool MQSpiritStatueToSunBlock();
|
||||
bool MQSpiritStatueSouthDoor();
|
||||
|
||||
private:
|
||||
std::shared_ptr<Context> ctx;
|
||||
|
|
|
@ -864,16 +864,19 @@ typedef enum {
|
|||
RR_SPIRIT_TEMPLE_2F_MIRROR,
|
||||
RR_SPIRIT_TEMPLE_STATUE_ROOM,
|
||||
RR_SPIRIT_TEMPLE_STATUE_ROOM_WEST,
|
||||
RR_SPIRIT_TEMPLE_INNER_WEST_HAND,
|
||||
RR_SPIRIT_TEMPLE_GS_LEDGE,
|
||||
RR_SPIRIT_TEMPLE_STATUE_ROOM_EAST,
|
||||
RR_SPIRIT_TEMPLE_INNER_EAST_HAND,
|
||||
RR_SPIRIT_TEMPLE_SHORTCUT_SWITCH,
|
||||
RR_SPIRIT_TEMPLE_SHORTCUT,
|
||||
RR_SPIRIT_TEMPLE_EMPTY_STAIRS,
|
||||
RR_SPIRIT_TEMPLE_SUN_BLOCK_ROOM,
|
||||
RR_SPIRIT_TEMPLE_SUN_BLOCK_SOUTH_LEDGE,
|
||||
RR_SPIRIT_TEMPLE_SKULLTULA_STAIRS,
|
||||
RR_SPIRIT_TEMPLE_WEST_THRONE,
|
||||
RR_SPIRIT_TEMPLE_WEST_HAND_EXIT,
|
||||
RR_SPIRIT_TEMPLE_WEST_HAND,
|
||||
RR_SPIRIT_TEMPLE_OUTER_WEST_HAND,
|
||||
RR_SPIRIT_TEMPLE_POT_STAIRS,
|
||||
RR_SPIRIT_TEMPLE_BEAMOS_PITS,
|
||||
RR_SPIRIT_TEMPLE_FOUR_ARMOS,
|
||||
|
@ -881,8 +884,8 @@ typedef enum {
|
|||
RR_SPIRIT_TEMPLE_CHEST_STAIRS,
|
||||
RR_SPIRIT_TEMPLE_EAST_THRONE,
|
||||
RR_SPIRIT_TEMPLE_EAST_HAND_EXIT,
|
||||
RR_SPIRIT_TEMPLE_EAST_HAND,
|
||||
RR_SPIRIT_TEMPLE_BIG_WALL_LOWER,
|
||||
RR_SPIRIT_TEMPLE_OUTER_EAST_HAND,
|
||||
RR_SPIRIT_TEMPLE_BIG_WALL_BASE,
|
||||
RR_SPIRIT_TEMPLE_BIG_WALL_UPPER,
|
||||
RR_SPIRIT_TEMPLE_4F_CENTRAL,
|
||||
RR_SPIRIT_TEMPLE_FAKE_DOORS_ROOM,
|
||||
|
@ -901,38 +904,44 @@ typedef enum {
|
|||
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_STATUE_ROOM_WEST,
|
||||
RR_SPIRIT_TEMPLE_MQ_INNER_WEST_HAND,
|
||||
RR_SPIRIT_TEMPLE_MQ_POT_LEDGE,
|
||||
RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM,
|
||||
RR_SPIRIT_TEMPLE_MQ_FLAMETHROWER_STAIRS,
|
||||
RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM,
|
||||
RR_SPIRIT_TEMPLE_MQ_SKULLTULA_STAIRS,
|
||||
RR_SPIRIT_TEMPLE_MQ_WEST_THRONE,
|
||||
RR_SPIRIT_TEMPLE_MQ_WEST_HAND_EXIT,
|
||||
RR_SPIRIT_TEMPLE_MQ_WEST_HAND,
|
||||
RR_SPIRIT_TEMPLE_MQ_OUTER_WEST_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_INNER_EAST_HAND,
|
||||
RR_SPIRIT_TEMPLE_MQ_CHEST_LEDGE,
|
||||
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_SAND_PIT,
|
||||
RR_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM,
|
||||
RR_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM_UPPER,
|
||||
RR_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM_LOWER,
|
||||
RR_SPIRIT_TEMPLE_MQ_AFTER_SYMPHONY_ROOM,
|
||||
RR_SPIRIT_TEMPLE_MQ_FIRE_WALL_STAIRS_LOWER,
|
||||
RR_SPIRIT_TEMPLE_MQ_FIRE_WALL_STAIRS_UPPER,
|
||||
RR_SPIRIT_TEMPLE_MQ_FOUR_BEAMOS_ROOM,
|
||||
RR_SPIRIT_TEMPLE_MQ_BEAMOS_PITS,
|
||||
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_EXIT_TO_MIRROR_SHIELD_HAND,
|
||||
RR_SPIRIT_TEMPLE_MQ_MIRROR_SHIELD_HAND,
|
||||
RR_SPIRIT_TEMPLE_MQ_FLOORMASTER_STAIRS,
|
||||
RR_SPIRIT_TEMPLE_MQ_EAST_THRONE,
|
||||
RR_SPIRIT_TEMPLE_MQ_EAST_HAND_EXIT,
|
||||
RR_SPIRIT_TEMPLE_MQ_OUTER_EAST_HAND,
|
||||
RR_SPIRIT_TEMPLE_MQ_3F_GIBDO_ROOM,
|
||||
RR_SPIRIT_TEMPLE_MQ_BIG_WALL_LOWER,
|
||||
RR_SPIRIT_TEMPLE_MQ_BIG_WALL_UPPER,
|
||||
RR_SPIRIT_TEMPLE_MQ_4F_CENTRAL,
|
||||
RR_SPIRIT_TEMPLE_MQ_NINE_CHAIRS_ROOM,
|
||||
RR_SPIRIT_TEMPLE_MQ_NINE_THRONES_ROOM,
|
||||
RR_SPIRIT_TEMPLE_MQ_BIG_MIRROR_ROOM,
|
||||
RR_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CAVE,
|
||||
RR_SPIRIT_TEMPLE_MQ_PLATFORM,
|
||||
RR_SPIRIT_TEMPLE_MQ_STATUE_HEAD,
|
||||
|
||||
RR_SPIRIT_TEMPLE_BOSS_ENTRYWAY,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue