mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-08-22 14:23:44 -07:00
WIP
This commit is contained in:
parent
d90f7267c3
commit
01800f74c6
7 changed files with 617 additions and 364 deletions
|
@ -210,33 +210,129 @@ bool Here(const RandomizerRegion region, ConditionFn condition) {
|
|||
return areaTable[region].Here(condition);
|
||||
}
|
||||
|
||||
bool SpiritExplosiveLogic() {
|
||||
return logic->HasExplosives() ? 1 : ctx->GetOption(RSK_BOMBCHU_BAG) && logic->BombchuRefill() ? 2 : 3;
|
||||
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.
|
||||
bool SpiritSharedStatueRoom(ConditionFn condition, bool anyAge) {
|
||||
return areaTable[RR_SPIRIT_TEMPLE_STATUE_ROOM].SpiritShared(
|
||||
condition, [] { return logic->HasExplosives(); }, [] { return true; }, 5, 3, SpiritExplosiveLogic(), anyAge);
|
||||
}
|
||||
|
||||
bool SpiritSharedSunBlockRoom(ConditionFn condition, bool anyAge) {
|
||||
return areaTable[RR_SPIRIT_TEMPLE_BLOCK_PUZZLE].SpiritShared(
|
||||
condition, [] { return logic->HasExplosives(); }, [] { return true; }, 5, 3, SpiritExplosiveLogic(), anyAge);
|
||||
}
|
||||
// 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
|
||||
|
||||
bool SpiritSharedBrokenWallRoom(ConditionFn condition, bool anyAge) {
|
||||
return areaTable[RR_SPIRIT_TEMPLE_CHILD_CLIMB].SpiritShared(
|
||||
condition, [] { return true; }, [] { return true; }, 5, 3, 1, anyAge);
|
||||
}
|
||||
|
||||
bool MQSpiritSharedStatueRoom(const RandomizerRegion region, ConditionFn condition, bool anyAge) {
|
||||
return areaTable[region].SpiritShared(
|
||||
condition, [] { return true; }, [] { return true; }, 7, 0, 0, anyAge);
|
||||
}
|
||||
/*
|
||||
* This logic covers checks that exist in the shared areas of Spirit from a glitchless standpoint.
|
||||
* 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
|
||||
|
||||
bool MQSpiritSharedBrokenWallRoom(const RandomizerRegion region, ConditionFn condition, bool anyAge) {
|
||||
return areaTable[region].SpiritShared(
|
||||
condition, [] { return true; }, [] { return true; }, 7, 7, 6, anyAge);
|
||||
* There are 4 possibilities for passing a check, 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
|
||||
* 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
|
||||
|
||||
* 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.
|
||||
|
||||
* 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
|
||||
*/
|
||||
|
||||
|
||||
bool SpiritShared(RandomizerRegion region, ConditionFn condition, bool anyAge, RandomizerRegion otherRegion, ConditionFn otherCondition){
|
||||
SpiritLogicData curRegionData = Region::spiritLogicData[region];
|
||||
uint8_t childKeys = logic->ReverseSpiritChild ? 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;
|
||||
|
||||
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()) ||
|
||||
(otherRegion != RR_NONE &&
|
||||
(otherRegionData.adultAccess && (!logic->IsReverseAccessPossible() || otherRegionData.reverseAccess) && otherCondition()));
|
||||
|
||||
logic->IsChild = pastChild;
|
||||
logic->IsAdult = pastAdult;
|
||||
|
||||
return result;
|
||||
}
|
||||
} else if (areaTable[region].Adult() && logic->IsAdult) {
|
||||
bool 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;
|
||||
|
||||
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()) ||
|
||||
(otherRegion != RR_NONE &&
|
||||
(otherRegionData.childAccess && (!logic->IsReverseAccessPossible() || otherRegionData.reverseAccess) && otherCondition()));
|
||||
|
||||
logic->IsChild = pastChild;
|
||||
logic->IsAdult = pastAdult;
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BeanPlanted(const RandomizerRegion region) {
|
||||
|
|
|
@ -111,6 +111,25 @@ class Entrance;
|
|||
enum class EntranceType;
|
||||
} // namespace Rando
|
||||
|
||||
struct SpiritLogicData {
|
||||
uint8_t childKeys; //the number of keys that guarantees Child can reach this region
|
||||
//The number of keys that guarantees Child can reach this region if they have reverse access
|
||||
//This changes for MQ broken wall room as the first child lock can only be opened by Child
|
||||
//guaranteeing access with 6 keys
|
||||
uint8_t childReverseKeys;
|
||||
uint8_t adultKeys; //the number of keys that guarantees Adult can reach this region
|
||||
//The area access condition to reach this region as Child, from the first lock,
|
||||
//including the minimum number of keys for ambiguous access
|
||||
// 1 key is always assumed to be required
|
||||
ConditionFn childAccess;
|
||||
//The area access condition to reach this region as Adult, from the first lock
|
||||
//including the minimum number of keys for ambiguous access
|
||||
//1 key is always assumed to be required on vanilla
|
||||
ConditionFn adultAccess;
|
||||
//The area access condition to reach this region from the boss door,
|
||||
ConditionFn reverseAccess;
|
||||
};
|
||||
|
||||
class Region {
|
||||
public:
|
||||
Region();
|
||||
|
@ -231,85 +250,11 @@ class Region {
|
|||
"Adult Night: " +
|
||||
std::to_string(adultNight);
|
||||
}
|
||||
|
||||
/*
|
||||
* This logic covers checks that exist in the shared areas of Spirit from a glitchless standpoint.
|
||||
* 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 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
|
||||
* 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
|
||||
|
||||
* 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.
|
||||
|
||||
* 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
|
||||
*/
|
||||
|
||||
bool SpiritShared(ConditionFn condition, ConditionFn childAccess, ConditionFn adultAccess, uint8_t childKeys,
|
||||
uint8_t adultKeys, uint8_t eitherKeys, bool anyAge = false) {
|
||||
// If we have all of the keys, we know that access is Certain Access
|
||||
if (ctx->GetDungeon(Rando::SPIRIT_TEMPLE)->IsMQ() ? logic->SmallKeys(RR_SPIRIT_TEMPLE, 7)
|
||||
: logic->SmallKeys(RR_SPIRIT_TEMPLE, 5)) {
|
||||
if (anyAge) {
|
||||
return Here(condition);
|
||||
}
|
||||
return condition();
|
||||
// otherwise, we have to check the current age and...
|
||||
} else if (Child() && logic->IsChild) {
|
||||
bool result = condition();
|
||||
// if we have enough keys to have Certain Access, we just run the condition
|
||||
if (logic->SmallKeys(RR_SPIRIT_TEMPLE, childKeys)) {
|
||||
return result;
|
||||
// otherwise we need to check both ages if we have enough keys that either can get there
|
||||
} else if (result && logic->SmallKeys(RR_SPIRIT_TEMPLE, eitherKeys) && adultAccess) {
|
||||
// store current age variables
|
||||
bool pastAdult = logic->IsAdult;
|
||||
bool pastChild = logic->IsChild;
|
||||
|
||||
logic->IsChild = false;
|
||||
logic->IsAdult = true;
|
||||
|
||||
result = condition();
|
||||
|
||||
logic->IsChild = pastChild;
|
||||
logic->IsAdult = pastAdult;
|
||||
|
||||
return result;
|
||||
}
|
||||
} else if (Adult() && logic->IsAdult) {
|
||||
bool result = condition();
|
||||
// if we have enough keys to have Certain Access, we just run the condition
|
||||
if (logic->SmallKeys(RR_SPIRIT_TEMPLE, adultKeys)) {
|
||||
return result;
|
||||
// otherwise we need to check both ages
|
||||
} else if (result && logic->SmallKeys(RR_SPIRIT_TEMPLE, eitherKeys) && childAccess) {
|
||||
// store current age variables
|
||||
bool pastAdult = logic->IsAdult;
|
||||
bool pastChild = logic->IsChild;
|
||||
|
||||
logic->IsChild = true;
|
||||
logic->IsAdult = false;
|
||||
|
||||
result = condition();
|
||||
|
||||
logic->IsChild = pastChild;
|
||||
logic->IsAdult = pastAdult;
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -318,11 +263,8 @@ extern std::vector<EventAccess> grottoEvents;
|
|||
bool Here(const RandomizerRegion region,
|
||||
ConditionFn
|
||||
condition); // RANDOTODO make a less stupid way to check own at either age than self referencing with this
|
||||
bool SpiritSharedBrokenWallRoom(ConditionFn condition, bool anyAge = false);
|
||||
bool SpiritSharedStatueRoom(ConditionFn condition, bool anyAge = false);
|
||||
bool SpiritSharedSunBlockRoom(ConditionFn condition, bool anyAge = false);
|
||||
bool MQSpiritSharedStatueRoom(const RandomizerRegion region, ConditionFn condition, bool anyAge = false);
|
||||
bool MQSpiritSharedBrokenWallRoom(const RandomizerRegion region, ConditionFn condition, bool anyAge = false);
|
||||
bool SpiritShared(RandomizerRegion region, ConditionFn condition, bool anyAge = false,
|
||||
RandomizerRegion otherRegion = RR_NONE, ConditionFn otherCondition = []{return false;});
|
||||
bool CanPlantBean(const RandomizerRegion region);
|
||||
bool BothAges(const RandomizerRegion region);
|
||||
bool ChildCanAccess(const RandomizerRegion region);
|
||||
|
|
|
@ -22,44 +22,45 @@ void RegionTable_Init_SpiritTemple() {
|
|||
LOCATION(RC_SPIRIT_TEMPLE_LOBBY_POT_2, logic->CanBreakPots()),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_ENTRYWAY, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_CHILD_LOBBY, []{return logic->IsChild;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_ADULT_LOBBY, []{return logic->CanUse(RG_SILVER_GAUNTLETS);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_ENTRYWAY, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_1F_WEST, []{return logic->IsChild;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_1F_EAST, []{return logic->CanUse(RG_SILVER_GAUNTLETS);}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_CHILD_LOBBY] = Region("Child Spirit Temple", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_1F_WEST] = Region("Spirit Temple 1F West", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->NutCrate, []{return true;}),
|
||||
}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_LOBBY, []{return logic->IsChild;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_CHILD_BEFORE_CLIMB, []{return logic->IsChild;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_CHILD_STALFOS, []{return logic->CanKillEnemy(RE_ARMOS) && logic->CanKillEnemy(RE_KEESE);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_CHILD_TORCHES, []{return logic->CanKillEnemy(RE_ARMOS) && logic->CanKillEnemy(RE_KEESE);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_LOBBY, []{return logic->IsChild;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_1F_BOXES, []{return logic->IsChild;}),
|
||||
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_CHILD_STALFOS] = Region("Child Spirit Temple Stalfos", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_SWITCH_BRIDGE_SOUTH] = Region("Spirit Temple Switch Bridge South", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->SpiritChildStalfosBridge, []{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));}),
|
||||
//RANDOTODO a version od 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
|
||||
Entrance(RR_SPIRIT_TEMPLE_CHILD_LOBBY, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_CHILD_STALFOS_ACROSS_BRIDGE, []{return (logic->SpiritChildStalfosBridge && logic->CanPassEnemy(RE_GREEN_BUBBLE, ED_CLOSE, false)) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_LONGSHOT);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_1F_WEST, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_SWITCH_BRIDGE_NORTH, []{return (logic->SpiritChildSwitchBridge && logic->CanPassEnemy(RE_GREEN_BUBBLE, ED_CLOSE, false)) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_LONGSHOT);}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_CHILD_STALFOS_ACROSS_BRIDGE] = Region("Child Spirit Temple Stalfos Across Bridge", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_SWITCH_BRIDGE_NORTH] = Region("Spirit Temple Switch Bridge North", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->SpiritChildStalfosBridge, []{return logic->CanHitSwitch();}),
|
||||
EventAccess(&logic->SpiritChildSwitchBridge, []{return logic->CanHitSwitch();}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_CHILD_BRIDGE_CHEST, true),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_CHILD_STALFOS, []{return logic->CanUse(RG_HOVER_BOOTS) || (logic->SpiritChildStalfosBridge && logic->CanPassEnemy(RE_GREEN_BUBBLE, ED_CLOSE, false));}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_CHILD_ANUBIS, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_SWITCH_BRIDGE_SOUTH, []{return logic->CanUse(RG_HOVER_BOOTS) || (logic->SpiritChildSwitchBridge && logic->CanPassEnemy(RE_GREEN_BUBBLE, ED_CLOSE, false));}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_1F_ANUBIS, []{return true;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_CHILD_ANUBIS] = Region("Child Spirit Temple Anubis", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_1F_ANUBIS] = Region("Spirit Temple 1F Anubis", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_ANUBIS_POT_1, true),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_ANUBIS_POT_2, true),
|
||||
|
@ -67,214 +68,297 @@ void RegionTable_Init_SpiritTemple() {
|
|||
LOCATION(RC_SPIRIT_TEMPLE_ANUBIS_POT_4, true),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_CHILD_STALFOS_ACROSS_BRIDGE, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_CHILD_TORCHES_ACROSS_BRIDGE, []{return logic->CanHitSwitch() || logic->CanKillEnemy(RE_ANUBIS);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_SWITCH_BRIDGE_NORTH, []{return Here(RR_SPIRIT_TEMPLE_1F_ANUBIS, []{return logic->CanHitSwitch() || logic->CanKillEnemy(RE_ANUBIS);});}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_RUPEE_BRIDGE_NORTH, []{return Here(RR_SPIRIT_TEMPLE_1F_ANUBIS, []{return logic->CanHitSwitch() || logic->CanKillEnemy(RE_ANUBIS);});}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_CHILD_TORCHES_ACROSS_BRIDGE] = Region("Child Spirit Temple Torches", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
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->SpiritChildTorchesBridge, []{return true;}),
|
||||
EventAccess(&logic->SpiritRupeeBridge, []{return true;}),
|
||||
}, {
|
||||
//Locations
|
||||
// these assume SpiritChildTorchesBridge, silver rupee shuffle & shuffle climb will want to adjust
|
||||
// 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)),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_CHILD_TORCHES, []{return logic->SpiritChildTorchesBridge;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_CHILD_ANUBIS, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_RUPEE_BRIDGE_SOUTH, []{return logic->SpiritRupeeBridge;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_1F_ANUBIS, []{return true;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_CHILD_TORCHES] = Region("Child Spirit Temple Torches", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_RUPEE_BRIDGE_SOUTH] = Region("Spirit Temple Rupee Bridge South", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_GS_METAL_FENCE, logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_BOOMERANG)),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_GS_METAL_FENCE, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_CHILD_LOBBY, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_CHILD_TORCHES_ACROSS_BRIDGE, []{return logic->SpiritChildTorchesBridge;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_1F_WEST, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_RUPEE_BRIDGE_NORTH, []{return logic->SpiritRupeeBridge;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_CHILD_BEFORE_CLIMB] = Region("Child Spirit Temple Before Climb", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_1F_BOXES] = Region("Child Spirit Temple Before Climb", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_BEFORE_CHILD_CLIMB_SMALL_CRATE_1, logic->CanBreakSmallCrates()),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_BEFORE_CHILD_CLIMB_SMALL_CRATE_2, logic->CanBreakSmallCrates()),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_CHILD_LOBBY, []{return logic->IsChild;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_CHILD_CLIMB, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 1);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_1F_WEST, []{return logic->IsChild;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_BROKEN_WALL, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 1);}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_CHILD_CLIMB] = Region("Child Spirit Temple Climb", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_WEST_CLIMB_BASE] = Region("Spirit Temple Child Climb Base", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_CHILD_CLIMB_NORTH_CHEST, SpiritSharedBrokenWallRoom([]{return logic->CanHitSwitch(ED_BOMB_THROW);})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_CHILD_CLIMB_EAST_CHEST, SpiritSharedBrokenWallRoom([]{return logic->CanHitSwitch(ED_BOMB_THROW);})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_GS_SUN_ON_FLOOR_ROOM, SpiritSharedBrokenWallRoom([]{return logic->CanKillEnemy(RE_GOLD_SKULLTULA, logic->TakeDamage() ? ED_SHORT_JUMPSLASH : ED_BOMB_THROW);})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_CHILD_CLIMB_POT_1, logic->CanBreakPots()),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_GS_SUN_ON_FLOOR_ROOM, SpiritShared(RR_SPIRIT_TEMPLE_WEST_CLIMB_BASE, []{return logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG);})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_CHILD_CLIMB_POT_1, SpiritShared(RR_SPIRIT_TEMPLE_WEST_CLIMB_BASE, []{return logic->CanBreakPots();})),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_CHILD_BEFORE_CLIMB, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 5);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_STATUE_ROOM, []{return logic->HasExplosives() || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS));}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_1F_BOXES, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 5);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_BROKEN_WALL, []{return true;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_ADULT_LOBBY] = Region("Adult Spirit Temple Lobby", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->SpiritAdultLobbySwitch, []{return logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_BOMBCHU_5) || (logic->CanUse(RG_BOMB_BAG) && logic->IsAdult && ctx->GetTrickOption(RT_SPIRIT_LOWER_ADULT_SWITCH));}),
|
||||
}, {}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_BROKEN_WALL] = Region("Spirit Temple Broken Wall", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_CHILD_CLIMB_NORTH_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_BROKEN_WALL, []{return logic->CanHitSwitch(ED_BOMB_THROW);})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_CHILD_CLIMB_EAST_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_BROKEN_WALL, []{return logic->CanHitSwitch(ED_BOMB_THROW);})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_GS_SUN_ON_FLOOR_ROOM, SpiritShared(RR_SPIRIT_TEMPLE_BROKEN_WALL, []{return logic->CanKillEnemy(RE_GOLD_SKULLTULA, logic->TakeDamage() ? ED_SHORT_JUMPSLASH : ED_BOMB_THROW);})),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_LOBBY, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_ADULT_SAND_PIT, []{return logic->SpiritAdultLobbySwitch;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_ADULT_BOULDERS, []{return logic->SpiritAdultLobbySwitch;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_ADULT_CLIMB, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 3);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_WEST_CLIMB_BASE, []{return true;}),
|
||||
///*CanClimbHigh() &&*/ (HasExplosives() || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && CanUse(RG_LIGHT_ARROWS)))
|
||||
Entrance(RR_SPIRIT_TEMPLE_STATUE_ROOM, []{return logic->SpiritBrokenWallToStatue();}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_ADULT_SAND_PIT] = Region("Adult Spirit Temple Sand Pit", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_1F_EAST] = Region("Adult Spirit Temple Lobby", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_LOBBY, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_SAND_PIT, []{return Here(RR_SPIRIT_TEMPLE_1F_EAST, []{return logic->CanHitSwitch(logic->IsAdult && ctx->GetTrickOption(RT_SPIRIT_LOWER_ADULT_SWITCH) ? ED_BOMB_THROW : ED_BOOMERANG);});}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_BOULDERS, []{return Here(RR_SPIRIT_TEMPLE_1F_EAST, []{return logic->CanHitSwitch(logic->IsAdult && ctx->GetTrickOption(RT_SPIRIT_LOWER_ADULT_SWITCH) ? ED_BOMB_THROW : ED_BOOMERANG);});}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_EAST_CLIMB_BASE, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 1);}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_SAND_PIT] = Region("Spirit Temple Sand Pit", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_COMPASS_CHEST, logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_ZELDAS_LULLABY)),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_ADULT_LOBBY, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_1F_EAST, []{return true;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_ADULT_BOULDERS] = Region("Adult Spirit Temple Boulders", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_ABOVE_BOULDERS] = Region("Spirit Temple Above Boulders", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
//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
|
||||
EventAccess(&logic->SpiritBouldersSilvers, []{return logic->CanUse(RG_HOVER_BOOTS) || logic->CanJumpslash() || logic->CanUse(RG_LONGSHOT);}),
|
||||
}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_1F_EAST, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_BOULDERS, []{return true;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_BOULDERS] = Region("Spirit Temple Boulders", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_GS_BOULDER_ROOM, logic->CanUse(RG_SONG_OF_TIME) && logic->CanKillEnemy(RE_GOLD_SKULLTULA)),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_ADULT_LOBBY, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_ADULT_PAST_BOULDERS, []{return logic->CanUse(RG_HOVER_BOOTS) || logic->CanJumpslash() || logic->CanUse(RG_LONGSHOT);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_ABOVE_BOULDERS, []{return true;}),
|
||||
//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;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_ADULT_PAST_BOULDERS] = Region("Adult Spirit Temple Past Boulders", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_PAST_BOULDERS] = Region("Spirit Temple Past Boulders", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_EARLY_ADULT_RIGHT_CHEST, true),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_ADULT_BOULDERS, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_BOULDERS, []{return true;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_ADULT_CLIMB] = Region("Adult Spirit Temple Climb", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
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;}),
|
||||
});
|
||||
|
||||
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, true),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_FIRST_MIRROR_RIGHT_CHEST, true),
|
||||
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;})),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_ADULT_LOBBY, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 3);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_EAST_CLIMB_BASE, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_STATUE_ROOM_EAST, []{return true;}),
|
||||
});
|
||||
|
||||
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);})),
|
||||
}, {
|
||||
//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();}),
|
||||
// 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;}),
|
||||
//!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);}),
|
||||
});
|
||||
|
||||
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);})),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_STATUE_ROOM_WEST, []{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, SpiritSharedStatueRoom([]{return logic->HasFireSourceWithTorch() || (ctx->GetTrickOption(RT_SPIRIT_MAP_CHEST) && logic->CanUse(RG_FAIRY_BOW));})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_GS_LOBBY, SpiritSharedStatueRoom([]{return logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA,
|
||||
(ctx->GetTrickOption(RT_SPIRIT_LOBBY_JUMP) || logic->CanUse(RG_HOVER_BOOTS)) ? ED_CLOSE : ctx->GetTrickOption(RT_SPIRIT_LOBBY_GS) ? ED_BOOMERANG : ED_HOOKSHOT);})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_1, logic->CanBreakPots()),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_2, logic->CanBreakPots()),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_3, logic->CanBreakPots()),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_4, logic->CanBreakPots()),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_5, logic->CanBreakPots()),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_6, logic->CanBreakPots()),
|
||||
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();})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_3, SpiritShared(RR_SPIRIT_TEMPLE_STATUE_ROOM, []{return logic->CanBreakPots();})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_4, SpiritShared(RR_SPIRIT_TEMPLE_STATUE_ROOM, []{return logic->CanBreakPots();})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_5, SpiritShared(RR_SPIRIT_TEMPLE_STATUE_ROOM, []{return logic->CanBreakPots();})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_6, SpiritShared(RR_SPIRIT_TEMPLE_STATUE_ROOM, []{return logic->CanBreakPots();})),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_CHILD_CLIMB, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_STATUE_ROOM_WEST, []{return true;}),
|
||||
// RT_SPIRIT_PLATFORM_HOOKSHOT is currently disabled
|
||||
Entrance(RR_SPIRIT_TEMPLE_INSIDE_STATUE_HEAD, []{return ctx->GetTrickOption(RT_SPIRIT_PLATFORM_HOOKSHOT) && logic->CanUse(RG_HOOKSHOT);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_PLATFORM, []{return logic->SpiritPlatformLowered &&
|
||||
(logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_SPIRIT_PLATFORM_HOOKSHOT) && logic->CanUse(RG_HOOKSHOT)));}),
|
||||
//explicit adult check here is a precaution against possible child logic leaking, child with a hookshot can do this
|
||||
Entrance(RR_SPIRIT_TEMPLE_STATUE_ROOM_EAST, []{return logic->IsAdult && logic->CanUse(RG_HOOKSHOT);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_STAIRS_TO_BLOCK_PUZZLE, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_STATUE_ROOM_EAST, []{return logic->IsAdult && logic->CanUse(RG_HOOKSHOT);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_SHORTCUT, []{return logic->SpiritStatueRoomSouthDoor;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_STAIRS_TO_BLOCK_PUZZLE] = Region("Spirit Temple Stairs to Block Puzzle", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_EMPTY_STAIRS] = Region("Spirit Temple Empty Stairs", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_STATUE_ROOM, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_BLOCK_PUZZLE, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_STATUE_ROOM, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_SUN_BLOCK_ROOM, []{return true;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_BLOCK_PUZZLE] = Region("Spirit Temple Block Puzzle", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->SpiritSunBlockTorch, []{return SpiritSharedSunBlockRoom([]{return logic->IsAdult || logic->CanKillEnemy(RE_BEAMOS);});}),
|
||||
}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_SUN_BLOCK_ROOM] = Region("Spirit Temple Sun Block Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
//Child can push blocks to get to the chest without killing the beamos, but it's likely a trick for similar reasons to armos push, and is not relevant without doorsanity
|
||||
LOCATION(RC_SPIRIT_TEMPLE_SUN_BLOCK_ROOM_CHEST, SpiritSharedSunBlockRoom([]{return (logic->HasFireSource() ||
|
||||
(logic->SpiritSunBlockTorch && (logic->CanUse(RG_STICKS) || (ctx->GetTrickOption(RT_SPIRIT_SUN_CHEST) && logic->CanUse(RG_FAIRY_BOW))))) &&
|
||||
(logic->IsAdult || logic->CanKillEnemy(RE_BEAMOS) || logic->CanUse(RG_HOOKSHOT));})),
|
||||
//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));})),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_STAIRS_TO_BLOCK_PUZZLE, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_WEST_STAIRS_TO_HAND, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_EMPTY_STAIRS, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_SKULLTULA_STAIRS, []{return true;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_WEST_STAIRS_TO_HAND] = Region("Spirit Temple West Stairs to Hand", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_SKULLTULA_STAIRS] = Region("Spirit Temple Skulltula Stairs", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_GS_HALL_AFTER_SUN_BLOCK_ROOM, (logic->HasExplosives() && logic->CanUse(RG_BOOMERANG) && logic->CanUse(RG_HOOKSHOT)) ||
|
||||
(logic->CanUse(RG_BOOMERANG) && logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->HasExplosives()) ||
|
||||
(logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_SILVER_GAUNTLETS) && (logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) &&
|
||||
logic->CanUse(RG_BOOMERANG) && ctx->GetOption(RSK_BOMBCHU_BAG) && logic->BombchuRefill() && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))))),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_1, logic->CanBreakPots() && (logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && ctx->GetOption(RSK_BOMBCHU_BAG) && logic->BombchuRefill() && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF)))),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_2, logic->CanBreakPots() && (logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && ctx->GetOption(RSK_BOMBCHU_BAG) && logic->BombchuRefill() && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF)))),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_GS_HALL_AFTER_SUN_BLOCK_ROOM, SpiritShared(RR_SPIRIT_TEMPLE_SKULLTULA_STAIRS, []{return logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG);})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_1, SpiritShared(RR_SPIRIT_TEMPLE_SKULLTULA_STAIRS, []{return logic->CanBreakPots();})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_2, SpiritShared(RR_SPIRIT_TEMPLE_SKULLTULA_STAIRS, []{return logic->CanBreakPots();})),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_BLOCK_PUZZLE, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_WEST_IRON_KNUCKLE, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 5);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_SUN_BLOCK_ROOM, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_WEST_THRONE, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 5);}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_WEST_IRON_KNUCKLE] = Region("Spirit Temple East Stairs to Iron Knuckle", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_WEST_THRONE] = Region("Spirit Temple West Throne", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_WEST_STAIRS_TO_HAND, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 5);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_EXIT_TO_SILVER_GAUNTLETS_HAND, []{return Here(RR_SPIRIT_TEMPLE_WEST_IRON_KNUCKLE, []{return logic->CanKillEnemy(RE_IRON_KNUCKLE);});}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_SKULLTULA_STAIRS, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 5);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_WEST_HAND_EXIT, []{return Here(RR_SPIRIT_TEMPLE_WEST_THRONE, []{return logic->CanKillEnemy(RE_IRON_KNUCKLE);});}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_EXIT_TO_SILVER_GAUNTLETS_HAND] = Region("Spirit Temple Exit to Mirror Shield Hand", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
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_IRON_KNUCKLE, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_SILVER_GAUNTLETS_HAND, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_WEST_THRONE, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_WEST_HAND, []{return true;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_SILVER_GAUNTLETS_HAND] = Region("Spirit Temple Mirror Shield Hand", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_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),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_EXIT_TO_SILVER_GAUNTLETS_HAND, []{return true;}),
|
||||
Entrance(RR_DESERT_COLOSSUS, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_WEST_HAND_EXIT, []{return true;}),
|
||||
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
|
||||
LOCATION(RC_SPIRIT_TEMPLE_STATUE_ROOM_HAND_CHEST, logic->CanUse(RG_ZELDAS_LULLABY)),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_STATUE_ROOM_NORTHEAST_CHEST, logic->CanUse(RG_ZELDAS_LULLABY) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_SPIRIT_LOBBY_JUMP))),
|
||||
//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)),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_ADULT_CLIMB, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_STATUE_ROOM, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_STAIRS_TO_BEAMOS_PITS, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 4);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_SHORTCUT, []{return logic->CanUse(RG_MEGATON_HAMMER) && (ctx->GetTrickOption(RT_SPIRIT_LOBBY_JUMP) || logic->CanUse(RG_HOVER_BOOTS) || (logic->CanUse(RG_ZELDAS_LULLABY) && logic->CanUse(RG_HOOKSHOT)));}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_2F_MIRROR, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_STATUE_ROOM, []{return true;}),
|
||||
//(IsAdult && ctx->GetTrickOption(RT_SPIRIT_LOBBY_JUMP)) || CanUse(RG_HOVER_BOOTS) || (CanUse(RG_ZELDAS_LULLABY) && CanUse(RG_HOOKSHOT));
|
||||
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
|
||||
//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);}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_STAIRS_TO_BEAMOS_PITS] = Region("Spirit Temple Stairs to Beamos Pits", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_SHORTCUT_SWITCH] = Region("Spirit Temple Shortcut Switch", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
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)),
|
||||
}, {
|
||||
//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
|
||||
//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, {}, {
|
||||
LOCATION(RC_SPIRIT_TEMPLE_BEAMOS_HALL_POT_1, logic->CanBreakPots()),
|
||||
}, {
|
||||
Entrance(RR_SPIRIT_TEMPLE_STATUE_ROOM_EAST, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 4);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_BEAMOS_PITS, []{return true;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_BEAMOS_PITS] = Region("Spirit Temple Beamos Pits", "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_ARMOS_ROOM_SUN_FAIRY, logic->HasExplosives() && logic->CanUse(RG_SUNS_SONG)),
|
||||
}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_BEAMOS_PITS] = Region("Spirit Temple Beamos Pits", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_STAIRS_TO_BEAMOS_PITS, []{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);}),
|
||||
//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);}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_FOUR_ARMOS] = Region("Spirit Temple Four Armos", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
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_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_EAST_STAIRS_TO_HAND, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_CHEST_STAIRS, []{return true;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_FOUR_ARMOS_SIDE_ROOM] = Region("Spirit Temple Four Armos Side Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
|
@ -285,46 +369,47 @@ void RegionTable_Init_SpiritTemple() {
|
|||
Entrance(RR_SPIRIT_TEMPLE_FOUR_ARMOS, []{return true;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_EAST_STAIRS_TO_HAND] = Region("Spirit Temple East Stairs to Iron Knuckle", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_CHEST_STAIRS] = Region("Spirit Temple Chest Stairs", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_HALLWAY_LEFT_INVISIBLE_CHEST, ctx->GetTrickOption(RT_LENS_SPIRIT) || logic->CanUse(RG_LENS_OF_TRUTH)),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_HALLWAY_RIGHT_INVISIBLE_CHEST, ctx->GetTrickOption(RT_LENS_SPIRIT) || logic->CanUse(RG_LENS_OF_TRUTH)),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_FOUR_ARMOS, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_EAST_IRON_KNUCKLE, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_FOUR_ARMOS, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_EAST_THRONE, []{return true;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_EAST_IRON_KNUCKLE] = Region("Spirit Temple East Stairs to Iron Knuckle", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_EAST_THRONE] = Region("Spirit Temple East Throne", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_EAST_STAIRS_TO_HAND, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_EXIT_TO_MIRROR_SHIELD_HAND, []{return Here(RR_SPIRIT_TEMPLE_EAST_IRON_KNUCKLE, []{return logic->CanKillEnemy(RE_IRON_KNUCKLE);});}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_CHEST_STAIRS, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_EAST_HAND_EXIT, []{return Here(RR_SPIRIT_TEMPLE_EAST_THRONE, []{return logic->CanKillEnemy(RE_IRON_KNUCKLE);});}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_EXIT_TO_MIRROR_SHIELD_HAND] = Region("Spirit Temple Exit to Mirror Shield Hand", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
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_IRON_KNUCKLE, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MIRROR_SHIELD_HAND, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_EAST_THRONE, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_EAST_HAND, []{return true;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MIRROR_SHIELD_HAND] = Region("Spirit Temple Mirror Shield Hand", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_EAST_HAND] = Region("Spirit Temple 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_EXIT_TO_MIRROR_SHIELD_HAND, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_SILVER_GAUNTLETS_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_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, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_BEAMOS_PITS, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_BIG_WALL_UPPER, []{return ctx->GetTrickOption(RT_SPIRIT_WALL) || logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_BOMBCHU_5) || (logic->CanAvoidEnemy(RE_BEAMOS, true, 2) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_MEGATON_HAMMER)));}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_BIG_WALL_UPPER, []{return ctx->GetTrickOption(RT_SPIRIT_WALL) || (logic->CanAvoidEnemy(RE_BEAMOS, true, 2) && logic->CanPassEnemy(RE_WALLTULA));}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_BIG_WALL_UPPER] = Region("Spirit Temple Big Wall Upper", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
//Grabbing these with rang is possible, but requires a blind shot aimed high
|
||||
LOCATION(RC_SPIRIT_TEMPLE_ADULT_CLIMB_LEFT_HEART, logic->CanUse(RG_HOOKSHOT)),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_ADULT_CLIMB_RIGHT_HEART, logic->CanUse(RG_HOOKSHOT)),
|
||||
}, {
|
||||
|
@ -336,41 +421,69 @@ void RegionTable_Init_SpiritTemple() {
|
|||
areaTable[RR_SPIRIT_TEMPLE_4F_CENTRAL] = Region("Spirit Temple 4F Central", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_BIG_WALL_UPPER, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_BOSS_KEY_ROOM, []{return logic->CanUse(RG_ZELDAS_LULLABY);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_FAKE_DOORS_ROOM, []{return logic->CanUse(RG_ZELDAS_LULLABY);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_BIG_MIRROR_ROOM, []{return true;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_BOSS_KEY_ROOM] = Region("Spirit Temple Boss Key Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_FAKE_DOORS_ROOM] = Region("Spirit Temple Fake Doors Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_BOSS_KEY_CHEST, (logic->TakeDamage() && ctx->GetTrickOption(RT_FLAMING_CHESTS)) || (logic->CanHitEyeTargets() && logic->CanUse(RG_HOOKSHOT))),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_BOSS_KEY_CHEST, (logic->TakeDamage() && ctx->GetTrickOption(RT_FLAMING_CHESTS)) ||
|
||||
(Here(RR_SPIRIT_TEMPLE_FAKE_DOORS_ROOM, []{return logic->CanHitEyeTargets() && logic->CanAvoidEnemy(RE_TORCH_SLUG, true, 4);})
|
||||
&& logic->CanUse(RG_HOOKSHOT))),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_4F_CENTRAL, []{return true;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_BIG_MIRROR_ROOM] = Region("Spirit Temple Big Mirror Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_BIG_MIRROR_ROOM] = Region("Spirit Temple Big Mirror Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//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));}),
|
||||
|
||||
}, {}, {
|
||||
Entrance(RR_SPIRIT_TEMPLE_4F_CENTRAL, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_BIG_MIRROR_CAVE, []{return logic->CanJumpslash() || logic->HasExplosives();}),
|
||||
//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));}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_BIG_MIRROR_CAVE] = Region("Spirit Temple Big Mirror Cave", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
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();}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_TOPMOST_CHEST, 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)) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS))),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_BIG_MIRROR_ROOM, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_INSIDE_STATUE_HEAD, []{return logic->CanUse(RG_MIRROR_SHIELD) && logic->HasExplosives() && logic->CanUse(RG_HOOKSHOT);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_BIG_MIRROR_ROOM, []{return true;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_SHORTCUT] = Region("Spirit Temple Shortcut", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
Entrance(RR_SPIRIT_TEMPLE_STATUE_ROOM, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_LOBBY, []{return logic->CanUse(RG_SILVER_GAUNTLETS) && logic->CanUse(RG_MEGATON_HAMMER);}),
|
||||
//Assumes a SpiritPlatformLowered check on entry
|
||||
areaTable[RR_SPIRIT_TEMPLE_PLATFORM] = Region("Spirit Temple Lowered Platform", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_STATUE_ROOM, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_STATUE_ROOM_WEST, []{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);}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_INSIDE_STATUE_HEAD] = Region("Spirit Temple Inside Statue Head", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_STATUE_HEAD] = Region("Spirit Temple Statue Head", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
//WARNING these events are not glitchproofed and assume you need all keys to reach from the front
|
||||
EventAccess(&logic->ReverseSpiritChild, []{return logic->IsChild;}),
|
||||
EventAccess(&logic->ReverseSpiritAdult, []{return logic->IsAdult;}),
|
||||
}, {}, {
|
||||
// Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_STATUE_ROOM, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_BOSS_ENTRYWAY, []{return logic->HasItem(RG_SPIRIT_TEMPLE_BOSS_KEY);}),
|
||||
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_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
|
||||
|
@ -432,7 +545,6 @@ void RegionTable_Init_SpiritTemple() {
|
|||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_TURNTABLE_ROOM] = Region("Spirit Temple Turntable Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
//For non-fairy pot items, you can also get them with rang without killing the stalfos
|
||||
EventAccess(&logic->FairyPot, []{return Here(RR_SPIRIT_TEMPLE_MQ_TURNTABLE_ROOM, []{return logic->CanKillEnemy(RE_STALFOS);});}),
|
||||
}, {
|
||||
//Locations
|
||||
|
@ -470,7 +582,7 @@ void RegionTable_Init_SpiritTemple() {
|
|||
}, {
|
||||
//Exits
|
||||
//The bridge is a temp flag, so not a way to cross south to north in logic
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_MAP_ROOM_NORTH, []{return logic->CanUse(RG_HOOKSHOT);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_MAP_ROOM_NORTH, []{return logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_1F_WEST, []{return true;}),
|
||||
});
|
||||
|
||||
|
@ -487,7 +599,7 @@ void RegionTable_Init_SpiritTemple() {
|
|||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_UNDER_LIKE_LIKE] = Region("Spirit Temple MQ Under Like Like", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_LIKE_LIKE_POT, MQSpiritSharedBrokenWallRoom(RR_SPIRIT_TEMPLE_MQ_UNDER_LIKE_LIKE, []{return logic->CanBreakPots();})),
|
||||
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
|
||||
|
@ -498,10 +610,9 @@ void RegionTable_Init_SpiritTemple() {
|
|||
areaTable[RR_SPIRIT_TEMPLE_MQ_BROKEN_WALL_ROOM] = Region("Spirit Temple MQ Broken Wall Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
//Implies CanKillEnemy(RE_LIKE_LIKE)
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_NORTH_CHEST, MQSpiritSharedBrokenWallRoom(RR_SPIRIT_TEMPLE_MQ_BROKEN_WALL_ROOM, []{return logic->CanKillEnemy(RE_BEAMOS);})),
|
||||
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.
|
||||
//chest is only reachable as adult glitchlessly, so we can skip the shared in favour of IsAdult as adult access is always Certain
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_SOUTH_CHEST, logic->IsAdult && (logic->HasExplosives() || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS))) && logic->CanUse(RG_HOOKSHOT)),
|
||||
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);})),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_UNDER_LIKE_LIKE, []{return logic->CanHitSwitch();}),
|
||||
|
@ -509,28 +620,48 @@ void RegionTable_Init_SpiritTemple() {
|
|||
Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 2);}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM] = Region("Spirit Temple MQ Statue Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
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);});}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_COMPASS_CHEST, MQSpiritSharedStatueRoom(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return logic->CanHitEyeTargets();})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_3F_EAST_POT, MQSpiritSharedStatueRoom(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{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, MQSpiritSharedStatueRoom(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return (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_2F_CENTER_EAST_POT, MQSpiritSharedStatueRoom(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return logic->CanBreakPots();})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_2F_WEST_POT, MQSpiritSharedStatueRoom(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return logic->CanBreakPots();})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_2F_EASTMOST_POT, MQSpiritSharedStatueRoom(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return logic->CanBreakPots();})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_CRATE_1, MQSpiritSharedStatueRoom(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return logic->CanBreakCrates();})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_CRATE_2, MQSpiritSharedStatueRoom(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return logic->CanBreakCrates();})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_SMALL_CRATE, MQSpiritSharedStatueRoom(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return logic->CanBreakSmallCrates();})),
|
||||
|
||||
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
|
||||
//we check possible adult access directly in MQSpiritSharedBrokenWallRoom, so this exit only covers Certain Access
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_BROKEN_WALL_ROOM, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 7);}),
|
||||
//We can use Here instead of Shared here because adult will never need to rely on child access to reach this room, and adult access is Certain
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_NORTH, []{return Here(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return logic->HasFireSource() || (ctx->GetTrickOption(RT_SPIRIT_MQ_FROZEN_EYE) && logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_SONG_OF_TIME));});}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_FLAMETHROWER_STAIRS, []{return logic->IsAdult || ctx->GetTrickOption(RT_SPIRIT_MQ_SUN_BLOCK_SOT) || logic->CanUse(RG_SONG_OF_TIME);}),
|
||||
//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();}),
|
||||
//explicit adult check here is a precaution against possible child logic leaking, child with a hookshot can do this
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM_EAST, []{return logic->IsAdult && logic->CanUse(RG_HOOKSHOT);}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_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();});}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_COMPASS_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return logic->CanHitEyeTargets();})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_2F_CENTER_EAST_POT, SpiritShared(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return logic->CanBreakPots();})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_2F_WEST_POT, SpiritShared(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return logic->CanBreakPots();})),
|
||||
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
|
||||
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());})),
|
||||
}, {
|
||||
//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
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM_EAST, []{return logic->IsAdult && logic->CanUse(RG_SCARECROW);}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_FLAMETHROWER_STAIRS] = Region("Spirit Temple MQ Flamethrower Stairs", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
|
@ -541,43 +672,43 @@ 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, true),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_SUN_BLOCK_ROOM, MQSpiritSharedStatueRoom(RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM, []{return logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_SPIRIT_MQ_SUN_BLOCK_GS) && logic->CanUse(RG_BOOMERANG));})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_1, MQSpiritSharedStatueRoom(RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM, []{return logic->CanBreakPots();})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_2, MQSpiritSharedStatueRoom(RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM, []{return logic->CanBreakPots();})),
|
||||
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();})),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_FLAMETHROWER_STAIRS, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_FLAMETHROWER_STAIRS, []{return true/*str0*/;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_SKULLTULA_STAIRS, []{return true/*str0*/;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_SKULLTULA_STAIRS] = Region("Spirit Temple MQ Skulltula Stairs", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM, []{return true;}),
|
||||
//This door causes the Universes to merge as it requires 7 keys for both ages
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_WEST_STAIRS_TO_HAND, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_WEST_THRONE, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 7);}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_WEST_STAIRS_TO_HAND] = Region("Spirit Temple MQ West Stairs to Hand", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_WEST_THRONE] = Region("Spirit Temple MQ West Throne", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_WEST_IRON_KNUCKLE, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 7);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_SKULLTULA_STAIRS, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 7);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_WEST_HAND_EXIT, []{return Here(RR_SPIRIT_TEMPLE_MQ_WEST_THRONE, []{return logic->CanKillEnemy(RE_IRON_KNUCKLE);});}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_WEST_IRON_KNUCKLE] = Region("Spirit Temple MQ East Iron Knuckle", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
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_STAIRS_TO_HAND, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 7);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_EXIT_TO_SILVER_GAUNTLETS_HAND, []{return Here(RR_SPIRIT_TEMPLE_MQ_WEST_IRON_KNUCKLE, []{return logic->CanKillEnemy(RE_IRON_KNUCKLE);});}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_WEST_THRONE, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_WEST_HAND, []{return true;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_EXIT_TO_SILVER_GAUNTLETS_HAND] = Region("Spirit Temple MQ Exit to Silver Gauntlets Hand", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_WEST_IRON_KNUCKLE, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_SILVER_GAUNTLETS_HAND, []{return true;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_SILVER_GAUNTLETS_HAND] = Region("Spirit Temple MQ Silver Gauntlets Hand", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_WEST_HAND] = Region("Spirit Temple MQ West Hand", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST, true),
|
||||
}, {
|
||||
//Exits
|
||||
//If it is ever relevent for 1 age to spawn the mirror shield chest for the other can longshot across, it needs an eventAccess
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_EXIT_TO_SILVER_GAUNTLETS_HAND, []{return true;}),
|
||||
Entrance(RR_DESERT_COLOSSUS, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_WEST_HAND_EXIT, []{return true;}),
|
||||
Entrance(RR_DESERT_COLOSSUS, []{return true;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_SOUTH] = Region("Spirit Temple MQ Block Room South", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
|
@ -590,8 +721,8 @@ void RegionTable_Init_SpiritTemple() {
|
|||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_NORTH] = Region("Spirit Temple MQ Block Room North", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
//Does not need to be shared as it's hard child locked, because adult pushing the block is a permanent flag that blocks the eye target and cannot be undone
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_SILVER_BLOCK_HALLWAY_CHEST, logic->IsChild && logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && logic->CanHitEyeTargets()),
|
||||
//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();})),
|
||||
}, {
|
||||
//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
|
||||
|
@ -609,7 +740,7 @@ void RegionTable_Init_SpiritTemple() {
|
|||
//We only need 4 keys, access to Shield hand and longshot to reach Gauntlets hand, as if we waste the 5th key we have given ourselves Gauntlets hand access through child climb
|
||||
//This exit handles that possibility as cleanly as possible without quantum logic, but will not survive glitch logic
|
||||
//logic->CanKillEnemy(RE_FLOORMASTER) is implied
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_SILVER_GAUNTLETS_HAND, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 4) &&
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_WEST_HAND, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 4) &&
|
||||
logic->CanAvoidEnemy(RE_BEAMOS, true, 4) && logic->CanUse(RG_SONG_OF_TIME) &&
|
||||
logic->CanJumpslash() &&
|
||||
(ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) &&
|
||||
|
@ -647,11 +778,11 @@ void RegionTable_Init_SpiritTemple() {
|
|||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_LOBBY, []{return logic->CanUse(RG_MEGATON_HAMMER);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_THREE_SUNS_ROOM_1F, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_LEEVER_ROOM, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_SAND_PIT, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 7);}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_LEEVER_ROOM] = Region("Spirit Temple MQ Leever Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_SAND_PIT] = Region("Spirit Temple MQ Sand Pit", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_LEEVER_ROOM_CHEST, logic->CanKillEnemy(RE_PURPLE_LEEVER) && logic->CanUse(RG_HOOKSHOT)),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_LEEVER_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)),
|
||||
|
@ -732,7 +863,7 @@ void RegionTable_Init_SpiritTemple() {
|
|||
LOCATION(RC_SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST, true),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_SILVER_GAUNTLETS_HAND, []{return logic->CanUse(RG_LONGSHOT);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_WEST_HAND, []{return logic->CanUse(RG_LONGSHOT);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_EAST_IRON_KNUCKLE, []{return true;}),
|
||||
Entrance(RR_DESERT_COLOSSUS, []{return true;}),
|
||||
});
|
||||
|
@ -810,11 +941,16 @@ void RegionTable_Init_SpiritTemple() {
|
|||
//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_INSIDE_STATUE_HEAD, []{return Here(RR_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CAVE, []{return logic->CanUse(RG_MIRROR_SHIELD);}) && logic->CanUse(RG_HOOKSHOT);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_HEAD, []{return Here(RR_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CAVE, []{return logic->CanUse(RG_MIRROR_SHIELD);}) && logic->CanUse(RG_HOOKSHOT);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return Here(RR_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CAVE, []{return logic->CanUse(RG_MIRROR_SHIELD);});}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_INSIDE_STATUE_HEAD] = Region("Spirit Temple MQ Inside Statue Head", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_STATUE_HEAD] = Region("Spirit Temple MQ Statue Head", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
//WARNING these events are not glitchproofed and assume you need all keys to reach from the front
|
||||
EventAccess(&logic->ReverseSpiritChild, []{return logic->IsChild;}),
|
||||
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);}),
|
||||
|
@ -825,9 +961,9 @@ void RegionTable_Init_SpiritTemple() {
|
|||
// Boss Room
|
||||
areaTable[RR_SPIRIT_TEMPLE_BOSS_ENTRYWAY] = Region("Spirit Temple Boss Entryway", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
// Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_INSIDE_STATUE_HEAD, []{return ctx->GetDungeon(SPIRIT_TEMPLE)->IsVanilla() && false;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_INSIDE_STATUE_HEAD, []{return ctx->GetDungeon(SPIRIT_TEMPLE)->IsMQ() && false;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_BOSS_ROOM, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_STATUE_HEAD, []{return ctx->GetDungeon(SPIRIT_TEMPLE)->IsVanilla() && false;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_HEAD, []{return ctx->GetDungeon(SPIRIT_TEMPLE)->IsMQ() && false;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_BOSS_ROOM, []{return true;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_BOSS_ROOM] = Region("Spirit Temple Boss Room", "Spirit Temple", {}, NO_DAY_NIGHT_CYCLE, {
|
||||
|
|
|
@ -539,14 +539,11 @@ bool Logic::CanKillEnemy(RandomizerEnemy enemy, EnemyDistance distance, bool wal
|
|||
killed = killed || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_STICKS);
|
||||
[[fallthrough]];
|
||||
case ED_BOMB_THROW:
|
||||
killed = killed || CanUse(RG_BOMB_BAG);
|
||||
killed = killed || CanUse(RG_BOMB_BAG) || CanUse(RG_DINS_FIRE);
|
||||
[[fallthrough]];
|
||||
case ED_BOOMERANG:
|
||||
// RANDOTODO test dins and chu range in a practical example
|
||||
killed = killed || CanUse(RG_DINS_FIRE);
|
||||
[[fallthrough]];
|
||||
case ED_HOOKSHOT:
|
||||
// RANDOTODO test dins and chu range in a practical example
|
||||
// RANDOTODO test chu range in a practical example
|
||||
killed = killed || CanUse(RG_HOOKSHOT) || (wallOrFloor && CanUse(RG_BOMBCHU_5));
|
||||
[[fallthrough]];
|
||||
case ED_LONGSHOT:
|
||||
|
@ -576,15 +573,15 @@ bool Logic::CanKillEnemy(RandomizerEnemy enemy, EnemyDistance distance, bool wal
|
|||
killed = killed || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_STICKS);
|
||||
[[fallthrough]];
|
||||
case ED_BOMB_THROW:
|
||||
// RANDOTODO test dins and chu range in a practical example
|
||||
// RANDOTODO test chu range in a practical example
|
||||
killed = killed || (!inWater && CanUse(RG_BOMB_BAG));
|
||||
[[fallthrough]];
|
||||
case ED_BOOMERANG:
|
||||
// RANDOTODO test dins and chu range in a practical example
|
||||
// RANDOTODO test chu range in a practical example
|
||||
killed = killed || CanUse(RG_BOOMERANG);
|
||||
[[fallthrough]];
|
||||
case ED_HOOKSHOT:
|
||||
// RANDOTODO test dins, bomb and chu range in a practical example
|
||||
// RANDOTODO test chu range in a practical example
|
||||
killed = killed || CanUse(RG_HOOKSHOT) || (wallOrFloor && CanUse(RG_BOMBCHU_5));
|
||||
[[fallthrough]];
|
||||
case ED_LONGSHOT:
|
||||
|
@ -629,7 +626,7 @@ bool Logic::CanKillEnemy(RandomizerEnemy enemy, EnemyDistance distance, bool wal
|
|||
[[fallthrough]];
|
||||
case ED_BOOMERANG:
|
||||
case ED_HOOKSHOT:
|
||||
// RANDOTODO test dins and chu range in a practical example
|
||||
// RANDOTODO test chu range in a practical example
|
||||
killed = killed || (wallOrFloor && CanUse(RG_BOMBCHU_5));
|
||||
[[fallthrough]];
|
||||
case ED_LONGSHOT:
|
||||
|
@ -710,12 +707,11 @@ bool Logic::CanKillEnemy(RandomizerEnemy enemy, EnemyDistance distance, bool wal
|
|||
killed = killed || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_STICKS);
|
||||
[[fallthrough]];
|
||||
case ED_BOMB_THROW:
|
||||
// RANDOTODO test dins and chu range in a practical example
|
||||
killed = killed || (!inWater && CanUse(RG_BOMB_BAG));
|
||||
[[fallthrough]];
|
||||
case ED_BOOMERANG:
|
||||
case ED_HOOKSHOT:
|
||||
// RANDOTODO test dins, bomb and chu range in a practical example
|
||||
// RANDOTODO test chu range in a practical example
|
||||
killed = killed || CanUse(RG_HOOKSHOT) || (wallOrFloor && CanUse(RG_BOMBCHU_5));
|
||||
[[fallthrough]];
|
||||
case ED_LONGSHOT:
|
||||
|
@ -789,6 +785,33 @@ bool Logic::CanKillEnemy(RandomizerEnemy enemy, EnemyDistance distance, bool wal
|
|||
case RE_OCTOROK:
|
||||
return CanReflectNuts() || HookshotOrBoomerang() || CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT) ||
|
||||
CanUse(RG_BOMB_BAG) || (wallOrFloor && CanUse(RG_BOMBCHU_5));
|
||||
case RE_WALLTULA:
|
||||
switch (distance) {
|
||||
case ED_CLOSE:
|
||||
case ED_SHORT_JUMPSLASH:
|
||||
killed = CanUse(RG_KOKIRI_SWORD);
|
||||
[[fallthrough]];
|
||||
case ED_MASTER_SWORD_JUMPSLASH:
|
||||
killed = killed || CanUse(RG_MASTER_SWORD);
|
||||
[[fallthrough]];
|
||||
case ED_LONG_JUMPSLASH:
|
||||
killed = killed || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_STICKS);
|
||||
[[fallthrough]];
|
||||
case ED_BOMB_THROW:
|
||||
killed = killed || (!inWater && CanUse(RG_BOMB_BAG)) || CanUse(RG_DINS_FIRE);
|
||||
[[fallthrough]];
|
||||
case ED_BOOMERANG:
|
||||
case ED_HOOKSHOT:
|
||||
killed = killed || CanUse(RG_HOOKSHOT) || CanUse(RG_BOMBCHU_5) || CanUse(RG_MEGATON_HAMMER);
|
||||
[[fallthrough]];
|
||||
case ED_LONGSHOT:
|
||||
killed = killed || CanUse(RG_LONGSHOT);
|
||||
[[fallthrough]];
|
||||
case ED_FAR:
|
||||
killed = killed || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_FAIRY_BOW);
|
||||
break;
|
||||
}
|
||||
return killed;
|
||||
default:
|
||||
SPDLOG_ERROR("CanKillEnemy reached `default`.");
|
||||
assert(false);
|
||||
|
@ -841,6 +864,7 @@ bool Logic::CanPassEnemy(RandomizerEnemy enemy, EnemyDistance distance, bool wal
|
|||
return CanUse(RG_HOOKSHOT) || CanUse(RG_SUNS_SONG);
|
||||
case RE_IRON_KNUCKLE:
|
||||
case RE_BIG_OCTO:
|
||||
case RE_WALLTULA: //consistent with RT_SPIRIT_WALL
|
||||
return false;
|
||||
case RE_GREEN_BUBBLE:
|
||||
return TakeDamage() || CanUse(RG_NUTS) || CanUse(RG_BOOMERANG) || CanUse(RG_HOOKSHOT);
|
||||
|
@ -887,6 +911,7 @@ bool Logic::CanAvoidEnemy(RandomizerEnemy enemy, bool grounded, uint8_t quantity
|
|||
case RE_WALLMASTER:
|
||||
case RE_ANUBIS:
|
||||
case RE_PURPLE_LEEVER:
|
||||
case RE_WALLTULA:
|
||||
return true;
|
||||
case RE_BEAMOS:
|
||||
return !grounded || CanUse(RG_NUTS) || CanUse(RG_DINS_FIRE) ||
|
||||
|
@ -899,6 +924,8 @@ bool Logic::CanAvoidEnemy(RandomizerEnemy enemy, bool grounded, uint8_t quantity
|
|||
case RE_BLUE_BUBBLE:
|
||||
// RANDOTODO Trick to use shield hylian shield as child to stun these guys
|
||||
return !grounded || CanUse(RG_NUTS) || HookshotOrBoomerang() || CanStandingShield();
|
||||
case RE_TORCH_SLUG:
|
||||
return !grounded || CanUse(RG_NUTS) || CanUse(RG_HOOKSHOT) || CanUse(RG_DINS_FIRE);
|
||||
default:
|
||||
SPDLOG_ERROR("CanPassEnemy reached `default`.");
|
||||
assert(false);
|
||||
|
@ -2331,6 +2358,32 @@ void Logic::SetInLogic(LogicVal logicVal, bool value) {
|
|||
inLogic[logicVal] = value;
|
||||
}
|
||||
|
||||
bool Logic::IsReverseAccessPossible(){
|
||||
return ctx->GetOption(RSK_SHUFFLE_BOSS_ENTRANCES) &&
|
||||
(ctx->GetOption(RSK_DECOUPLED_ENTRANCES) ||
|
||||
ctx->GetOption(RSK_MIX_BOSS_ENTRANCES));
|
||||
}
|
||||
|
||||
bool Logic::SpiritBrokenWallToStatue() {
|
||||
return /*CanClimbHigh() &&*/ (HasExplosives() || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && CanUse(RG_LIGHT_ARROWS)));
|
||||
}
|
||||
|
||||
bool Logic::SpiritEastToSwitch() {
|
||||
return (IsAdult && ctx->GetTrickOption(RT_SPIRIT_LOBBY_JUMP)) || CanUse(RG_HOVER_BOOTS) || (CanUse(RG_ZELDAS_LULLABY) && CanUse(RG_HOOKSHOT));
|
||||
}
|
||||
|
||||
bool Logic::SpiritWestToSkull() {
|
||||
return (IsAdult && ctx->GetTrickOption(RT_SPIRIT_LOBBY_JUMP)) || CanUse(RG_HOVER_BOOTS) || CanUse(RG_SCARECROW);
|
||||
}
|
||||
|
||||
bool Logic::MQSpiritStatueToSunBlock() {
|
||||
return IsAdult || ctx->GetTrickOption(RT_SPIRIT_MQ_SUN_BLOCK_SOT) || CanUse(RG_SONG_OF_TIME);
|
||||
}
|
||||
|
||||
bool Logic::MQSpiritStatueSouthDoor() {
|
||||
return HasFireSource() || (ctx->GetTrickOption(RT_SPIRIT_MQ_FROZEN_EYE) && CanUse(RG_FAIRY_BOW) && CanUse(RG_SONG_OF_TIME)/* && CanClimb()*/);
|
||||
}
|
||||
|
||||
void Logic::Reset() {
|
||||
NewSaveContext();
|
||||
StartPerformanceTimer(PT_LOGIC_RESET);
|
||||
|
@ -2520,11 +2573,15 @@ void Logic::Reset() {
|
|||
MQSpirit3SunsEnemies = false;
|
||||
MQSpiritOpenedBigMirrorCave = false;
|
||||
Spirit1FSilverRupees = false;
|
||||
SpiritChildStalfosBridge = false;
|
||||
SpiritChildTorchesBridge = false;
|
||||
SpiritSunBlockTorch = false;
|
||||
SpiritAdultLobbySwitch = false;
|
||||
SpiritChildSwitchBridge = false;
|
||||
SpiritRupeeBridge = false;
|
||||
SpiritBouldersSilvers = false;
|
||||
SpiritPlatformLowered = false;
|
||||
Spirit4FSwitch = false;
|
||||
ReverseSpiritChild = false;
|
||||
ReverseSpiritAdult = false;
|
||||
|
||||
StopPerformanceTimer(PT_LOGIC_RESET);
|
||||
}
|
||||
|
||||
} // namespace Rando
|
||||
|
|
|
@ -26,6 +26,7 @@ enum class GlitchDifficulty {
|
|||
HERO,
|
||||
};
|
||||
|
||||
|
||||
class Logic {
|
||||
public:
|
||||
bool noVariable = false;
|
||||
|
@ -182,10 +183,14 @@ class Logic {
|
|||
bool MQSpirit3SunsEnemies = false;
|
||||
bool MQSpiritOpenedBigMirrorCave = false;
|
||||
bool Spirit1FSilverRupees = false;
|
||||
bool SpiritChildStalfosBridge = false;
|
||||
bool SpiritChildTorchesBridge = false;
|
||||
bool SpiritSunBlockTorch = false;
|
||||
bool SpiritAdultLobbySwitch = false;
|
||||
bool SpiritChildSwitchBridge = false;
|
||||
bool SpiritRupeeBridge = false;
|
||||
bool SpiritBouldersSilvers = false;
|
||||
bool SpiritStatueRoomSouthDoor = false;
|
||||
bool SpiritPlatformLowered = false;
|
||||
bool Spirit4FSwitch = false;
|
||||
bool ReverseSpiritChild = false;
|
||||
bool ReverseSpiritAdult = true;
|
||||
|
||||
/* --- END OF HELPERS AND LOCATION ACCESS --- */
|
||||
|
||||
|
@ -294,6 +299,12 @@ 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();
|
||||
|
||||
private:
|
||||
std::shared_ptr<Context> ctx;
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
#define TWO_ACTOR_PARAMS(a, b) ((((a)&0xFFFF) << 16) | ((b)&0xFFFF))
|
||||
|
||||
typedef bool (*ConditionFn)();
|
||||
|
||||
// This should probably go in a less rando-specific location
|
||||
// but the best location will probably be in the modding engine
|
||||
// which doesn't exist yet.
|
||||
|
@ -844,43 +846,50 @@ typedef enum {
|
|||
RR_WATER_TEMPLE_BOSS_ROOM,
|
||||
|
||||
RR_SPIRIT_TEMPLE_LOBBY,
|
||||
RR_SPIRIT_TEMPLE_CHILD_LOBBY,
|
||||
RR_SPIRIT_TEMPLE_CHILD_STALFOS,
|
||||
RR_SPIRIT_TEMPLE_CHILD_STALFOS_ACROSS_BRIDGE,
|
||||
RR_SPIRIT_TEMPLE_CHILD_ANUBIS,
|
||||
RR_SPIRIT_TEMPLE_CHILD_TORCHES,
|
||||
RR_SPIRIT_TEMPLE_CHILD_TORCHES_ACROSS_BRIDGE,
|
||||
RR_SPIRIT_TEMPLE_CHILD_BEFORE_CLIMB,
|
||||
RR_SPIRIT_TEMPLE_CHILD_CLIMB,
|
||||
RR_SPIRIT_TEMPLE_ADULT_LOBBY,
|
||||
RR_SPIRIT_TEMPLE_ADULT_SAND_PIT,
|
||||
RR_SPIRIT_TEMPLE_ADULT_BOULDERS,
|
||||
RR_SPIRIT_TEMPLE_ADULT_PAST_BOULDERS,
|
||||
RR_SPIRIT_TEMPLE_ADULT_CLIMB,
|
||||
RR_SPIRIT_TEMPLE_1F_WEST,
|
||||
RR_SPIRIT_TEMPLE_SWITCH_BRIDGE_SOUTH,
|
||||
RR_SPIRIT_TEMPLE_SWITCH_BRIDGE_NORTH,
|
||||
RR_SPIRIT_TEMPLE_1F_ANUBIS,
|
||||
RR_SPIRIT_TEMPLE_RUPEE_BRIDGE_SOUTH,
|
||||
RR_SPIRIT_TEMPLE_RUPEE_BRIDGE_NORTH,
|
||||
RR_SPIRIT_TEMPLE_1F_BOXES,
|
||||
RR_SPIRIT_TEMPLE_WEST_CLIMB_BASE,
|
||||
RR_SPIRIT_TEMPLE_BROKEN_WALL,
|
||||
RR_SPIRIT_TEMPLE_1F_EAST,
|
||||
RR_SPIRIT_TEMPLE_SAND_PIT,
|
||||
RR_SPIRIT_TEMPLE_BOULDERS,
|
||||
RR_SPIRIT_TEMPLE_ABOVE_BOULDERS,
|
||||
RR_SPIRIT_TEMPLE_PAST_BOULDERS,
|
||||
RR_SPIRIT_TEMPLE_EAST_CLIMB_BASE,
|
||||
RR_SPIRIT_TEMPLE_2F_MIRROR,
|
||||
RR_SPIRIT_TEMPLE_STATUE_ROOM,
|
||||
RR_SPIRIT_TEMPLE_STATUE_ROOM_WEST,
|
||||
RR_SPIRIT_TEMPLE_GS_LEDGE,
|
||||
RR_SPIRIT_TEMPLE_STATUE_ROOM_EAST,
|
||||
RR_SPIRIT_TEMPLE_STAIRS_TO_BLOCK_PUZZLE,
|
||||
RR_SPIRIT_TEMPLE_BLOCK_PUZZLE,
|
||||
RR_SPIRIT_TEMPLE_WEST_STAIRS_TO_HAND,
|
||||
RR_SPIRIT_TEMPLE_WEST_IRON_KNUCKLE,
|
||||
RR_SPIRIT_TEMPLE_EXIT_TO_SILVER_GAUNTLETS_HAND,
|
||||
RR_SPIRIT_TEMPLE_SILVER_GAUNTLETS_HAND,
|
||||
RR_SPIRIT_TEMPLE_STAIRS_TO_BEAMOS_PITS,
|
||||
RR_SPIRIT_TEMPLE_SHORTCUT_SWITCH,
|
||||
RR_SPIRIT_TEMPLE_SHORTCUT,
|
||||
RR_SPIRIT_TEMPLE_EMPTY_STAIRS,
|
||||
RR_SPIRIT_TEMPLE_SUN_BLOCK_ROOM,
|
||||
RR_SPIRIT_TEMPLE_SKULLTULA_STAIRS,
|
||||
RR_SPIRIT_TEMPLE_WEST_THRONE,
|
||||
RR_SPIRIT_TEMPLE_WEST_HAND_EXIT,
|
||||
RR_SPIRIT_TEMPLE_WEST_HAND,
|
||||
RR_SPIRIT_TEMPLE_POT_STAIRS,
|
||||
RR_SPIRIT_TEMPLE_BEAMOS_PITS,
|
||||
RR_SPIRIT_TEMPLE_FOUR_ARMOS,
|
||||
RR_SPIRIT_TEMPLE_FOUR_ARMOS_SIDE_ROOM,
|
||||
RR_SPIRIT_TEMPLE_EAST_STAIRS_TO_HAND,
|
||||
RR_SPIRIT_TEMPLE_EAST_IRON_KNUCKLE,
|
||||
RR_SPIRIT_TEMPLE_EXIT_TO_MIRROR_SHIELD_HAND,
|
||||
RR_SPIRIT_TEMPLE_MIRROR_SHIELD_HAND,
|
||||
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_BIG_WALL_UPPER,
|
||||
RR_SPIRIT_TEMPLE_4F_CENTRAL,
|
||||
RR_SPIRIT_TEMPLE_BOSS_KEY_ROOM,
|
||||
RR_SPIRIT_TEMPLE_FAKE_DOORS_ROOM,
|
||||
RR_SPIRIT_TEMPLE_BIG_MIRROR_ROOM,
|
||||
RR_SPIRIT_TEMPLE_BIG_MIRROR_CAVE,
|
||||
RR_SPIRIT_TEMPLE_SHORTCUT,
|
||||
RR_SPIRIT_TEMPLE_INSIDE_STATUE_HEAD,
|
||||
RR_SPIRIT_TEMPLE_PLATFORM,
|
||||
RR_SPIRIT_TEMPLE_STATUE_HEAD,
|
||||
|
||||
RR_SPIRIT_TEMPLE_MQ_LOBBY,
|
||||
RR_SPIRIT_TEMPLE_MQ_1F_WEST,
|
||||
|
@ -893,19 +902,20 @@ typedef enum {
|
|||
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_FLAMETHROWER_STAIRS,
|
||||
RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM,
|
||||
RR_SPIRIT_TEMPLE_MQ_WEST_STAIRS_TO_HAND,
|
||||
RR_SPIRIT_TEMPLE_MQ_WEST_IRON_KNUCKLE,
|
||||
RR_SPIRIT_TEMPLE_MQ_EXIT_TO_SILVER_GAUNTLETS_HAND,
|
||||
RR_SPIRIT_TEMPLE_MQ_SILVER_GAUNTLETS_HAND,
|
||||
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_BIG_BLOCK_ROOM_SOUTH,
|
||||
RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_NORTH,
|
||||
RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM_EAST,
|
||||
RR_SPIRIT_TEMPLE_MQ_THREE_SUNS_ROOM_2F,
|
||||
RR_SPIRIT_TEMPLE_MQ_THREE_SUNS_ROOM_1F,
|
||||
RR_SPIRIT_TEMPLE_MQ_1F_EAST,
|
||||
RR_SPIRIT_TEMPLE_MQ_LEEVER_ROOM,
|
||||
RR_SPIRIT_TEMPLE_MQ_SAND_PIT,
|
||||
RR_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM,
|
||||
RR_SPIRIT_TEMPLE_MQ_AFTER_SYMPHONY_ROOM,
|
||||
RR_SPIRIT_TEMPLE_MQ_FIRE_WALL_STAIRS_LOWER,
|
||||
|
@ -923,7 +933,7 @@ typedef enum {
|
|||
RR_SPIRIT_TEMPLE_MQ_NINE_CHAIRS_ROOM,
|
||||
RR_SPIRIT_TEMPLE_MQ_BIG_MIRROR_ROOM,
|
||||
RR_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CAVE,
|
||||
RR_SPIRIT_TEMPLE_MQ_INSIDE_STATUE_HEAD,
|
||||
RR_SPIRIT_TEMPLE_MQ_STATUE_HEAD,
|
||||
|
||||
RR_SPIRIT_TEMPLE_BOSS_ENTRYWAY,
|
||||
RR_SPIRIT_TEMPLE_BOSS_ROOM,
|
||||
|
@ -3665,7 +3675,7 @@ typedef enum {
|
|||
RT_SHADOW_MQ_WINDY_WALKWAY,
|
||||
RT_LENS_SPIRIT,
|
||||
RT_SPIRIT_CHILD_CHU,
|
||||
RT_SPIRIT_LOBBY_GS,
|
||||
RT_SPIRIT_WEST_LEDGE,
|
||||
RT_SPIRIT_LOWER_ADULT_SWITCH,
|
||||
RT_SPIRIT_LOBBY_JUMP,
|
||||
RT_SPIRIT_PLATFORM_HOOKSHOT,
|
||||
|
@ -6481,6 +6491,7 @@ typedef enum {
|
|||
RE_BARI,
|
||||
RE_SHABOM,
|
||||
RE_OCTOROK,
|
||||
RE_WALLTULA,
|
||||
} RandomizerEnemy;
|
||||
|
||||
// RANDOTODO compare child long jumpslash range with adult short
|
||||
|
|
|
@ -1006,11 +1006,11 @@ void Settings::CreateOptions() {
|
|||
"Removes the requirements for the Lens of Truth in Spirit Temple.");
|
||||
OPT_TRICK(RT_SPIRIT_CHILD_CHU, RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, { Tricks::Tag::NOVICE },
|
||||
"Spirit Temple Child Side Bridge with Bombchu", "A carefully-timed Bombchu can hit the switch.");
|
||||
OPT_TRICK(RT_SPIRIT_LOBBY_GS, RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, { Tricks::Tag::NOVICE },
|
||||
"Spirit Temple Main Room GS with Boomerang",
|
||||
"Standing on the highest part of the arm of the statue, a precise Boomerang throw can kill and obtain "
|
||||
"this Gold Skulltula. You must throw the Boomerang slightly off to the side so that it curves into the "
|
||||
"Skulltula, as aiming directly at it will clank off of the wall in front.");
|
||||
OPT_TRICK(RT_SPIRIT_WEST_LEDGE, RCQUEST_BOTH, RA_SPIRIT_TEMPLE, { Tricks::Tag::NOVICE },
|
||||
"Spirit Temple Statue Room West Ledge Checks with Boomerang",
|
||||
"By carefully walking onto the upper arm of the statue, it's possible to get a good angle on the "
|
||||
"Gold Skulltula (In Vanilla) and the farthest pot (In MQ) to collect the checks with Boomerang. "
|
||||
"The nearest pot in MQ can be reached from the forearm and is always in logic.");
|
||||
OPT_TRICK(RT_SPIRIT_LOWER_ADULT_SWITCH, RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, { Tricks::Tag::ADVANCED },
|
||||
"Spirit Temple Lower Adult Switch with Bombs",
|
||||
"A bomb can be used to hit the switch on the ceiling, but it must be thrown from a particular distance "
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue