mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-08-20 21:33:40 -07:00
finish vanilla
This commit is contained in:
parent
458722d15d
commit
e263acd4a6
7 changed files with 140 additions and 104 deletions
|
@ -600,63 +600,89 @@ bool Here(const RandomizerRegion region, ConditionFn condition) {
|
|||
* the second condition is the same for adult 1F lock, and the third is the access from the boss door.
|
||||
*/
|
||||
|
||||
bool SpiritExplosiveKeyLogic() {
|
||||
return logic->SmallKeys(RR_SPIRIT_TEMPLE, logic->HasExplosives() ? 1
|
||||
: ctx->GetOption(RSK_BOMBCHU_BAG) && logic->BombchuRefill() ? 2
|
||||
: 3);
|
||||
}
|
||||
|
||||
//!QUANTUM LOGIC!
|
||||
//With 3 keys, you cannot lock adult out of leaving spirit onto the hands and jumping down, as you would have to
|
||||
//open the west hand door and then adult could climb through sun block room to jump down from there
|
||||
//This requires that adult can complete both routes
|
||||
//If we have the longshot, we can also guarantee access to the outer west hand as you can longshot from the east hand to the west
|
||||
//Implies CanKillEnemy(RE_IRON_KNUCKLE)
|
||||
bool OuterWestHandLogic(){
|
||||
return logic->HasExplosives()/* && logic->CanClimbHigh() && str0*/ && logic->SmallKeys(RR_SPIRIT_TEMPLE, logic->HasItem(RG_LONGSHOT) ? 3 : 5);
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
std::map<RandomizerRegion, SpiritLogicData> Region::spiritLogicData = {
|
||||
//Vanilla
|
||||
{RR_SPIRIT_TEMPLE_WEST_CLIMB_BASE, {5, 5, 9, []{return true;}, []{return true/* && logic->CanClimbHigh() && str0*/;}, []{return true/*logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS)*/;}}},
|
||||
{RR_SPIRIT_TEMPLE_BROKEN_WALL, {5, 5, 9, []{return true /*logic->CanClimbHigh()*/;}, []{return true/* && logic->CanClimbHigh() && str0*/;}, []{return true/*logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS)*/;}}},
|
||||
{RR_SPIRIT_TEMPLE_2F_MIRROR, {5, 5, 9, []{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, {5, 5, 9, []{return true/*logic->CanClimbHigh()*/;}, []{return true/*logic->CanClimbHigh() && str0*/;}, []{return true/*logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS)*/;}}},
|
||||
{RR_SPIRIT_TEMPLE_INNER_WEST_HAND, {5, 5, 9, []{return true/*logic->CanClimbHigh()*/;}, []{return true/*logic->CanClimbHigh() && str0*/;}, []{return true/*logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS)*/;}}},
|
||||
{RR_SPIRIT_TEMPLE_GS_LEDGE, {5, 5, 9, []{return true && logic->SpiritWestToSkull()/* && logic->CanClimbHigh()*/;}, []{return logic->SpiritWestToSkull()/* && logic->CanClimbHigh() && str0*/;}, []{return logic->SpiritWestToSkull()/* && (logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS))*/;}}},
|
||||
{RR_SPIRIT_TEMPLE_STATUE_ROOM, {5, 5, 9, []{return true;}, []{return true/*logic->CanClimbHigh() && str0*/;}, []{return true;}}},
|
||||
//Vanilla Child uses ExplosiveKeyLogic here because they need to exist for shared adult checks
|
||||
{RR_SPIRIT_TEMPLE_WEST_CLIMB_BASE, {5, 0, 3, 0, []{return true;}, []{return SpiritExplosiveKeyLogic()/* && logic->CanClimbHigh() && str0*/;}, []{return true/*logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS)*/;}}},
|
||||
{RR_SPIRIT_TEMPLE_SUN_ON_FLOOR, {5, 0, 3, 0, []{return true/*logic->CanClimbHigh()*/;}, []{return SpiritExplosiveKeyLogic()/* && logic->CanClimbHigh() && str0*/;}, []{return true/*logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS)*/;}}},
|
||||
{RR_SPIRIT_TEMPLE_2F_MIRROR, {5, 0, 3, 0, []{return logic->CanUse(RG_HOOKSHOT) && logic->SpiritSunOnFloorToStatue();}, []{return true/*logic->CanClimbHigh()*/;}, []{return logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS);}}},
|
||||
{RR_SPIRIT_TEMPLE_STATUE_ROOM_WEST, {5, 0, 3, 0, []{return SpiritExplosiveKeyLogic()/* && logic->CanClimbHigh()*/;}, []{return SpiritExplosiveKeyLogic()/* && logic->CanClimbHigh() && str0*/;}, []{return true/*logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS)*/;}}},
|
||||
{RR_SPIRIT_TEMPLE_INNER_WEST_HAND, {5, 0, 3, 0, []{return SpiritExplosiveKeyLogic()/* && logic->CanClimbHigh()*/;}, []{return SpiritExplosiveKeyLogic()/* && logic->CanClimbHigh() && str0*/;}, []{return true/*logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS)*/;}}},
|
||||
{RR_SPIRIT_TEMPLE_GS_LEDGE, {5, 0, 3, 0, []{return SpiritExplosiveKeyLogic() && logic->SpiritWestToSkull()/* && logic->CanClimbHigh()*/;}, []{return SpiritExplosiveKeyLogic() && logic->SpiritWestToSkull()/* && logic->CanClimbHigh() && str0*/;}, []{return logic->SpiritWestToSkull()/* && (logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS))*/;}}},
|
||||
{RR_SPIRIT_TEMPLE_STATUE_ROOM, {5, 0, 3, 0, []{return SpiritExplosiveKeyLogic();}, []{return SpiritExplosiveKeyLogic()/* && logic->CanClimbHigh() && str0*/;}, []{return true;}}},
|
||||
//Assumes SpiritSunBlockSouthLedge() for all access
|
||||
{RR_SPIRIT_TEMPLE_SUN_BLOCK_SOUTH_LEDGE, {5, 5, 9, []{return true/*logic->CanClimbHigh() && str0*/;}, []{return true/*logic->CanClimbHigh() && str0*/;}, []{return true/*((logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS)) && str0) || (logic->CanKillEnemy(RE_BEAMOS) && logic->CanUse(RG_LONGSHOT))*/;}}},
|
||||
{RR_SPIRIT_TEMPLE_SKULLTULA_STAIRS, {5, 5, 9, []{return true/*logic->CanClimbHigh() && str0*/;}, []{return true/*logic->CanClimbHigh() && str0*/;}, []{return true/*((logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS)) && str0) || (logic->CanKillEnemy(RE_BEAMOS) && logic->CanUse(RG_LONGSHOT))*/;}}},
|
||||
{RR_SPIRIT_TEMPLE_OUTER_WEST_HAND, {5, 5, 3, []{return logic->CanKillEnemy(RE_IRON_KNUCKLE)/*&& logic->CanClimbHigh() && str0*/;}, //For the purpose of shared, adult needs to get to west side via BOTH possible routes for it to count //Only using HasItem here is intended so this check can pass as child if adult can do their part. This works because this edge case assumes that you can only waste keys on adult side with adult
|
||||
[]{return logic->CanKillEnemy(RE_BEAMOS) && logic->CanUse(RG_LONGSHOT)/* && logic->CanClimbHigh() && str0*/;}, []{return logic->CanKillEnemy(RE_BEAMOS) && logic->HasItem(RG_LONGSHOT)/* && logic->CanClimb() && str0*/;}}},
|
||||
{RR_SPIRIT_TEMPLE_STATUE_ROOM_EAST, {5, 5, 9, []{return logic->CanUse(RG_HOOKSHOT)/* && logic->CanClimbHigh()*/;}, []{return true/*logic->CanClimbHigh() && str0*/;}, []{return logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS);}}},
|
||||
{RR_SPIRIT_TEMPLE_INNER_EAST_HAND, {5, 5, 9, []{return logic->CanUse(RG_HOOKSHOT)/* && logic->CanClimbHigh()*/;}, []{return true/*logic->CanClimbHigh() && str0*/;}, []{return logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS);}}},
|
||||
{RR_SPIRIT_TEMPLE_SHORTCUT_SWITCH, {5, 5, 9, []{return logic->CanUse(RG_HOOKSHOT) && logic->SpiritEastToSwitch();}, []{return logic->SpiritEastToSwitch()/* && logic->CanClimbHigh() && str0*/;}, []{return logic->SpiritEastToSwitch() && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS));}}},
|
||||
{RR_SPIRIT_TEMPLE_SUN_BLOCK_SOUTH_LEDGE, {5, 0, 3, 0, []{return SpiritExplosiveKeyLogic()/* && logic->CanClimbHigh() && str0*/;}, []{return SpiritExplosiveKeyLogic()/* && logic->CanClimbHigh() && str0*/;}, []{return true/*((logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS)) && str0) || (logic->CanKillEnemy(RE_BEAMOS) && logic->CanUse(RG_LONGSHOT))*/;}}},
|
||||
{RR_SPIRIT_TEMPLE_SKULLTULA_STAIRS, {5, 0, 3, 0, []{return SpiritExplosiveKeyLogic()/* && logic->CanClimbHigh() && str0*/;}, []{return SpiritExplosiveKeyLogic()/* && logic->CanClimbHigh() && str0*/;}, []{return true/*((logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS)) && str0) || (logic->CanKillEnemy(RE_BEAMOS) && logic->CanUse(RG_LONGSHOT))*/;}}},
|
||||
{RR_SPIRIT_TEMPLE_OUTER_WEST_HAND, {5, 5, 3, 3, []{return OuterWestHandLogic();}, []{return OuterWestHandLogic();}, []{return OuterWestHandLogic();}}},
|
||||
{RR_SPIRIT_TEMPLE_STATUE_ROOM_EAST, {5, 0, 3, 0, []{return SpiritExplosiveKeyLogic() && logic->CanUse(RG_HOOKSHOT)/* && logic->CanClimbHigh()*/;}, []{return true/*logic->CanClimbHigh() && str0*/;}, []{return logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS);}}},
|
||||
{RR_SPIRIT_TEMPLE_INNER_EAST_HAND, {5, 0, 3, 0, []{return SpiritExplosiveKeyLogic() && logic->CanUse(RG_HOOKSHOT)/* && logic->CanClimbHigh()*/;}, []{return true/*logic->CanClimbHigh() && str0*/;}, []{return logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS);}}},
|
||||
{RR_SPIRIT_TEMPLE_SHORTCUT_SWITCH, {5, 0, 3, 0, []{return SpiritExplosiveKeyLogic() && logic->CanUse(RG_HOOKSHOT) && logic->SpiritEastToSwitch();}, []{return logic->SpiritEastToSwitch()/* && logic->CanClimbHigh() && str0*/;}, []{return logic->SpiritEastToSwitch() && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS));}}},
|
||||
//MQ /*&& logic->CanClimbHigh()*/
|
||||
{RR_SPIRIT_TEMPLE_MQ_UNDER_LIKE_LIKE, {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, {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, {7, 7, 0, []{return logic->CanHitSwitch()/* && logic->CanClimbHigh()*/;}, []{return true/*logic->Climb*/;}, []{return true/*logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS)*/;}}},
|
||||
{RR_SPIRIT_TEMPLE_MQ_POT_LEDGE, {7, 7, 0, []{return logic->CanHitSwitch() && logic->MQSpiritWestToPots()/* && logic->CanClimbHigh()*/;}, []{return logic->MQSpiritWestToPots()/* && logic->Climb*/;}, []{return /*logic->CanUse(RG_HOVER_BOOTS) || (logic->CanClimb() && */logic->MQSpiritWestToPots()/*)*/;}}},
|
||||
{RR_SPIRIT_TEMPLE_MQ_INNER_WEST_HAND, {7, 7, 0, []{return logic->CanHitSwitch() && logic->MQSpiritWestToPots()/* && logic->CanClimbHigh()*/;}, []{return logic->MQSpiritWestToPots()/* && logic->Climb*/;}, []{return /*logic->CanUse(RG_HOVER_BOOTS) || (logic->CanClimb() && */logic->MQSpiritWestToPots()/*)*/;}}},
|
||||
{RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, {7, 7, 0, []{return logic->CanHitSwitch()/* && logic->CanClimbHigh()*/;}, []{return true;}, []{return true;}}},
|
||||
{RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM, {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_OUTER_WEST_HAND, {7, 7, 4, []{return logic->CanHitSwitch() && logic->MQSpiritStatueToSunBlock() //For the purpose of shared, adult needs to get to west side via BOTH possible routes for it to count //Only using HasItem here for adult items so child can pass this check
|
||||
/* && logic->CanClimbHigh() && str0*/;}, []{return logic->MQSpirit4KeyWestHand();}, []{return logic->CouldMQSpirit4KeyWestHand();}}},
|
||||
{RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_NORTH, {7, 7, 0, []{return logic->CanHitSwitch() &&
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_NORTH].Here([]{return logic->MQSpiritStatueSouthDoor();})
|
||||
/* && logic->CanClimbHigh()*/;}, []{return true;}, []{return areaTable[RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_NORTH].Here([]{return logic->MQSpiritStatueSouthDoor();});}}},
|
||||
{RR_SPIRIT_TEMPLE_MQ_UNDER_LIKE_LIKE, {7, 9, 7, 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_SUN_ON_FLOOR, {7, 9, 7, 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, {7, 0, 0, 0, []{return logic->CanHitSwitch()/* && logic->CanClimbHigh()*/;}, []{return true/*logic->Climb*/;}, []{return true/*logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS)*/;}}},
|
||||
{RR_SPIRIT_TEMPLE_MQ_POT_LEDGE, {7, 0, 0, 0, []{return logic->CanHitSwitch() && logic->MQSpiritWestToPots()/* && logic->CanClimbHigh()*/;}, []{return logic->MQSpiritWestToPots()/* && logic->Climb*/;}, []{return /*logic->CanUse(RG_HOVER_BOOTS) || (logic->CanClimb() && */logic->MQSpiritWestToPots()/*)*/;}}},
|
||||
{RR_SPIRIT_TEMPLE_MQ_INNER_WEST_HAND, {7, 0, 0, 0, []{return logic->CanHitSwitch() && logic->MQSpiritWestToPots()/* && logic->CanClimbHigh()*/;}, []{return logic->MQSpiritWestToPots()/* && logic->Climb*/;}, []{return /*logic->CanUse(RG_HOVER_BOOTS) || (logic->CanClimb() && */logic->MQSpiritWestToPots()/*)*/;}}},
|
||||
{RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, {7, 0, 0, 0, []{return logic->CanHitSwitch()/* && logic->CanClimbHigh()*/;}, []{return true;}, []{return true;}}},
|
||||
{RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM, {7, 0, 0, 0, []{return logic->CanHitSwitch() && logic->MQSpiritStatueToSunBlock()/* && logic->CanClimbHigh()*/;}, []{return logic->MQSpiritStatueToSunBlock()/* && logic->Climb*/;}, []{return logic->MQSpiritStatueToSunBlock()/* && (logic->CanClimb() || logic->CanUse(RG_HOVER_BOOTS))*/;}}},
|
||||
//RANDOTODO FIX
|
||||
{RR_SPIRIT_TEMPLE_MQ_OUTER_WEST_HAND, {7, 7, 4, 4, []{return logic->CanHitSwitch() && logic->MQSpiritStatueToSunBlock() //For the purpose of shared, adult needs to get to west side via BOTH possible routes for it to count //Only using HasItem here for adult items so child can pass this check
|
||||
/* && logic->CanClimbHigh() && str0*/;}, []{return logic->MQSpirit4KeyWestHand();}, []{return logic->CouldMQSpirit4KeyWestHand();}}},
|
||||
{RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_NORTH, {7, 0, 0, 0, []{return logic->CanHitSwitch() &&
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_NORTH].Here([]{return logic->MQSpiritStatueSouthDoor();})
|
||||
/* && logic->CanClimbHigh()*/;}, []{return true;}, []{return areaTable[RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_NORTH].Here([]{return logic->MQSpiritStatueSouthDoor();});}}},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
bool SpiritCertainAccess(RandomizerRegion region) {
|
||||
SpiritLogicData& curRegionData = Region::spiritLogicData[region];
|
||||
uint8_t keys = curRegionData.adultKeys;
|
||||
bool canReach = false;
|
||||
if (logic->IsChild) {
|
||||
uint8_t keys = curRegionData.childKeys;
|
||||
uint8_t revKeys = curRegionData.childRevKeys;
|
||||
bool knownFrontAccess = logic->ForwardsSpiritChild || !logic->IsReverseAccessPossible();
|
||||
// revKeys set to 9 means it's the sun on floor room in MQ
|
||||
// If child enters in reverse, then they have access to Certain Access to Broken Wall room in 6 keys,
|
||||
// the ability to hit switches and the ability to climb because only child can reach the initial child lock
|
||||
// without opening the Statue room to Broken Wall Room lock first
|
||||
keys = (logic->ReverseSpiritChild && logic->CanHitSwitch() /* && CanClimbHigh()*/)
|
||||
? curRegionData.childReverseKeys
|
||||
: curRegionData.childKeys;
|
||||
canReach = (areaTable[region].Child() || curRegionData.childAccess()) && (!logic->IsReverseAccessPossible() || curRegionData.reverseAccess());
|
||||
} else {
|
||||
canReach = (areaTable[region].Adult() || curRegionData.adultAccess()) && (!logic->IsReverseAccessPossible() || curRegionData.reverseAccess());
|
||||
}
|
||||
//keys set to 9 means it's the bombchu edge case.
|
||||
if (keys == 9){
|
||||
keys = ctx->GetOption(RSK_BOMBCHU_BAG) && logic->BombchuRefill() ? 2 : 3;
|
||||
}
|
||||
if (revKeys == 9){
|
||||
revKeys = (logic->ReverseSpiritChild && logic->CanHitSwitch() /* && CanClimbHigh()*/) ? 6 : 7;
|
||||
}
|
||||
|
||||
// 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
|
||||
return canReach && logic->SmallKeys(RR_SPIRIT_TEMPLE, keys);
|
||||
// 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
|
||||
return ((knownFrontAccess && curRegionData.childAccess()) && logic->SmallKeys(RR_SPIRIT_TEMPLE, keys)) ||
|
||||
((logic->ReverseSpiritChild && curRegionData.reverseAccess()) && logic->SmallKeys(RR_SPIRIT_TEMPLE, revKeys)) ||
|
||||
(curRegionData.childAccess() && curRegionData.reverseAccess() && logic->SmallKeys(RR_SPIRIT_TEMPLE, keys > revKeys ? keys : revKeys));
|
||||
} else {
|
||||
uint8_t keys = curRegionData.adultKeys;
|
||||
uint8_t revKeys = curRegionData.adultRevKeys;
|
||||
bool knownFrontAccess = logic->ForwardsSpiritAdult || !logic->IsReverseAccessPossible();
|
||||
auto test = logic->IsReverseAccessPossible();
|
||||
auto test2 = (knownFrontAccess && curRegionData.adultAccess());
|
||||
auto test3 = (logic->ReverseSpiritAdult && curRegionData.reverseAccess());
|
||||
auto test4 = curRegionData.adultAccess() && curRegionData.reverseAccess();
|
||||
// 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
|
||||
return ((knownFrontAccess && curRegionData.adultAccess()) && logic->SmallKeys(RR_SPIRIT_TEMPLE, keys)) ||
|
||||
((logic->ReverseSpiritAdult && curRegionData.reverseAccess()) && logic->SmallKeys(RR_SPIRIT_TEMPLE, revKeys)) ||
|
||||
(curRegionData.adultAccess() && curRegionData.reverseAccess() && logic->SmallKeys(RR_SPIRIT_TEMPLE, keys > revKeys ? keys : revKeys));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -705,11 +731,11 @@ bool SpiritShared(RandomizerRegion region, ConditionFn condition, bool anyAge, R
|
|||
// If we have Certain Access, we just run the condition.
|
||||
// Otherwise, if we have the keys to know either age can reach, we need to see if we could reach as Adult
|
||||
// and if needed, in reverse
|
||||
if (!ChildCertainAccess && result &&
|
||||
(!logic->IsReverseAccessPossible() || Region::spiritLogicData[otherRegion].reverseAccess())) {
|
||||
if (!ChildCertainAccess && result) {
|
||||
// Switch to Adult
|
||||
logic->IsChild = false;
|
||||
logic->IsAdult = true;
|
||||
|
||||
// If Adult can get there and get the check, we can get the check in logic
|
||||
// If reverse spirit is also possible, we need to make sure Adult can get it via reverse entry too
|
||||
result = (curRegionData.adultAccess() &&
|
||||
|
@ -729,8 +755,7 @@ bool SpiritShared(RandomizerRegion region, ConditionFn condition, bool anyAge, R
|
|||
// Alternatively, if we have entered in reverse and can reach from the face, we have Certain Access
|
||||
// Otherwise, if we have the keys to know either age can reach, we need to see if we could reach as Child
|
||||
// and if needed, in reverse
|
||||
if (!AdultCertainAccess && result &&
|
||||
(!logic->IsReverseAccessPossible() || Region::spiritLogicData[otherRegion].reverseAccess)) {
|
||||
if (!AdultCertainAccess && result) {
|
||||
// Switch to Child
|
||||
logic->IsChild = true;
|
||||
logic->IsAdult = false;
|
||||
|
|
|
@ -118,12 +118,14 @@ enum class EntranceType;
|
|||
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;
|
||||
// 9 means MQ broken wall room, as the first child lock can only be opened by Child
|
||||
// without opening the lock to Statue room, guaranteeing access with 6 keys if you can hit a switch
|
||||
uint8_t childRevKeys;
|
||||
// the number of keys that guarantees Adult can reach this region
|
||||
// if it is 9, that means the bombchu edge case is to be checked.
|
||||
uint8_t adultKeys;
|
||||
// the number of keys that guarantees Adult can reach this region with reverse entry
|
||||
uint8_t adultRevKeys;
|
||||
// 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
|
||||
|
|
|
@ -16,7 +16,12 @@ void RegionTable_Init_SpiritTemple() {
|
|||
|
||||
#pragma region Vanilla
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_LOBBY] = Region("Spirit Temple Lobby", SCENE_SPIRIT_TEMPLE, {}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_LOBBY] = Region("Spirit Temple Lobby", SCENE_SPIRIT_TEMPLE, {
|
||||
// Events
|
||||
//WARNING these events assume you need less or equal keys for forwards entry and reverse
|
||||
EventAccess(&logic->ForwardsSpiritChild, []{return logic->IsChild;}),
|
||||
EventAccess(&logic->ForwardsSpiritAdult, []{return logic->IsAdult;}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_LOBBY_POT_1, logic->CanBreakPots()),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_LOBBY_POT_2, logic->CanBreakPots()),
|
||||
|
@ -105,7 +110,7 @@ void RegionTable_Init_SpiritTemple() {
|
|||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_1F_WEST, []{return logic->IsChild/*CanUse(RG_CRAWL)*/;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_BROKEN_WALL, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 1);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_SUN_ON_FLOOR, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 1);}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_WEST_CLIMB_BASE] = Region("Spirit Temple Child Climb Base", SCENE_SPIRIT_TEMPLE, {}, {
|
||||
|
@ -115,19 +120,19 @@ void RegionTable_Init_SpiritTemple() {
|
|||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_1F_BOXES, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 5);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_BROKEN_WALL, []{return true/*CanClimbHigh()*/;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_SUN_ON_FLOOR, []{return true/*CanClimbHigh()*/;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_BROKEN_WALL] = Region("Spirit Temple Broken Wall", SCENE_SPIRIT_TEMPLE, {}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_SUN_ON_FLOOR] = Region("Spirit Temple Broken Wall", SCENE_SPIRIT_TEMPLE, {}, {
|
||||
//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);})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_CHILD_CLIMB_NORTH_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_SUN_ON_FLOOR, []{return logic->CanHitSwitch(ED_BOMB_THROW);})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_CHILD_CLIMB_EAST_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_SUN_ON_FLOOR, []{return logic->CanHitSwitch(ED_BOMB_THROW);})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_GS_SUN_ON_FLOOR_ROOM, SpiritShared(RR_SPIRIT_TEMPLE_SUN_ON_FLOOR, []{return logic->CanKillEnemy(RE_GOLD_SKULLTULA, logic->TakeDamage() ? ED_SHORT_JUMPSLASH : ED_BOMB_THROW);})),
|
||||
}, {
|
||||
//Exits
|
||||
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();}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_STATUE_ROOM, []{return logic->SpiritSunOnFloorToStatue();}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_1F_EAST] = Region("Spirit Temple 1F East", SCENE_SPIRIT_TEMPLE, {}, {}, {
|
||||
|
@ -202,7 +207,7 @@ void RegionTable_Init_SpiritTemple() {
|
|||
RR_SPIRIT_TEMPLE_GS_LEDGE, []{return logic->CanKillEnemy(RE_GOLD_SKULLTULA);})),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_BROKEN_WALL, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_SUN_ON_FLOOR, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_INNER_WEST_HAND, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_GS_LEDGE, []{return logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_SCARECROW);}),
|
||||
// RT_SPIRIT_PLATFORM_HOOKSHOT is currently disabled
|
||||
|
@ -214,7 +219,7 @@ void RegionTable_Init_SpiritTemple() {
|
|||
//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 && /*str0 &&*/
|
||||
Entrance(RR_DESERT_COLOSSUS, []{return ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF) && /*str0 &&*/
|
||||
logic->IsChild/*CanUse(RG_CRAWL)*/ && logic->SmallKeys(RR_SPIRIT_TEMPLE, 4) && logic->CanKillEnemy(RE_IRON_KNUCKLE);}),
|
||||
});
|
||||
|
||||
|
@ -258,7 +263,17 @@ void RegionTable_Init_SpiritTemple() {
|
|||
//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_SHORTCUT, []{return logic->SpiritStatueRoomSouthDoor;}),
|
||||
});
|
||||
//!QUANTUM LOGIC!
|
||||
//If dungeon entrance randomiser is off, Adult entered spirit in reverse, and they have str 2 to get there from the front and Explosives,
|
||||
//it is always possible for them to reach 1F_EAST with only 2 keys. This is because you can only waste 1 key (on the first child side lock)
|
||||
//before you either allow you to climb down through 2F mirror room, or give yourself access to a hand to jump down from.
|
||||
//If for whatever reason you can reach east hand but not west hand, this becomes possible with 3 keys instead.
|
||||
//If you do not have explosives to kill Beamos, but do have a way to defeat Iron Knuckles, this becomes possible with 4 keys instead.
|
||||
Entrance(RR_SPIRIT_TEMPLE_1F_EAST, []{return ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF) &&
|
||||
logic->CanUse(RG_SILVER_GAUNTLETS) && logic->IsAdult &&
|
||||
((logic->CanKillEnemy(RE_BEAMOS) && logic->SmallKeys(RR_SPIRIT_TEMPLE, /*CanClimb() && str0 ?*/ 2 /*: 3*/)) ||
|
||||
(/*CanClimb() && str0 && */logic->CanKillEnemy(RE_IRON_KNUCKLE) && logic->SmallKeys(RR_SPIRIT_TEMPLE, 4)));}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_EMPTY_STAIRS] = Region("Spirit Temple Empty Stairs", SCENE_SPIRIT_TEMPLE, {}, {}, {
|
||||
//Exits
|
||||
|
@ -315,7 +330,7 @@ void RegionTable_Init_SpiritTemple() {
|
|||
Entrance(RR_SPIRIT_TEMPLE_OUTER_WEST_HAND, []{return true;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_OUTER_WEST_HAND] = Region("Spirit Temple West Hand", SCENE_SPIRIT_TEMPLE, {}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_OUTER_WEST_HAND] = Region("Spirit Temple Outer West Hand", SCENE_SPIRIT_TEMPLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_OUTER_WEST_HAND, []{return true;})),
|
||||
}, {
|
||||
|
@ -332,27 +347,6 @@ void RegionTable_Init_SpiritTemple() {
|
|||
//(IsAdult && ctx->GetTrickOption(RT_SPIRIT_STATUE_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 leaving spirit onto the hands and jumping down, as you would have to
|
||||
//open the west hand door and then adult could climb through sun block room to jump down from there
|
||||
//This requires that adult can complete both routes
|
||||
//Implies CanKillEnemy(RE_IRON_KNUCKLE)
|
||||
Entrance(RR_DESERT_COLOSSUS, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) && logic->CanKillEnemy(RE_BEAMOS)/* && CanClimb() && str0*/;}),
|
||||
//!QUANTUM LOGIC!
|
||||
//Continuing from above, if we have the longshot, we can guarantee access to the outer west hand as you can longshot from the east hand to the west
|
||||
//Implies CanKillEnemy(RE_IRON_KNUCKLE)
|
||||
Entrance(RR_SPIRIT_TEMPLE_OUTER_WEST_HAND, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) && logic->CanKillEnemy(RE_BEAMOS) && /*CanClimb() && str0 &&*/
|
||||
logic->CanUse(RG_LONGSHOT);}),
|
||||
//!QUANTUM LOGIC!
|
||||
//A variant of the above, if dungeon entrance randomiser is off, Adult entered spirit in reverse, and they have str 2 to get there from the front,
|
||||
//it is always possible for them to reach 1F_EAST with only 2 keys. This is because you can only waste 1 key (on the first child side lock)
|
||||
//before you either allow you to climb down through 2F mirror room, or give yourself access to a hand to jump down from.
|
||||
//If for whatever reason you can reach east hand but not west hand, this becomes possible with 3 keys instead.
|
||||
//If for whatever reason you can reach west hand but not east hand, this becomes possible with 4 keys instead.
|
||||
Entrance(RR_SPIRIT_TEMPLE_1F_EAST, []{return ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF) &&
|
||||
logic->CanUse(RG_SILVER_GAUNTLETS) &&
|
||||
((logic->CanKillEnemy(RE_BEAMOS) && logic->SmallKeys(RR_SPIRIT_TEMPLE, /*CanClimb() && str0 ?*/ 2 /*: 3*/)) ||
|
||||
(/*CanClimb() && str0 && */logic->CanKillEnemy(RE_IRON_KNUCKLE) && logic->SmallKeys(RR_SPIRIT_TEMPLE, 4)));}),
|
||||
//RT_SPIRIT_PLATFORM_HOOKSHOT is currently disabled
|
||||
Entrance(RR_SPIRIT_TEMPLE_PLATFORM, []{return logic->SpiritPlatformLowered &&
|
||||
(logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_SPIRIT_PLATFORM_HOOKSHOT) && logic->CanUse(RG_HOOKSHOT)));}),
|
||||
|
@ -534,6 +528,7 @@ void RegionTable_Init_SpiritTemple() {
|
|||
//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;}),
|
||||
|
@ -549,7 +544,12 @@ void RegionTable_Init_SpiritTemple() {
|
|||
|
||||
#pragma region MQ
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_LOBBY] = Region("Spirit Temple MQ Lobby", SCENE_SPIRIT_TEMPLE, {}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_LOBBY] = Region("Spirit Temple MQ Lobby", SCENE_SPIRIT_TEMPLE, {
|
||||
// Events
|
||||
//WARNING these events assume you need less or equal keys for forwards entry and reverse
|
||||
EventAccess(&logic->ForwardsSpiritChild, []{return logic->IsChild;}),
|
||||
EventAccess(&logic->ForwardsSpiritAdult, []{return logic->IsAdult;}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_LEFT_CHEST, true),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_LEFT_CHEST, Here(RR_SPIRIT_TEMPLE_MQ_LOBBY, []{return logic->BlastOrSmash();}) && logic->CanHitEyeTargets()),
|
||||
|
@ -671,15 +671,15 @@ void RegionTable_Init_SpiritTemple() {
|
|||
//Exits
|
||||
//This covers adult and reverse access only, as child going forwards arrives here from the other side of this door
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_WEST_1F_RUSTED_SWITCH, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 7);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_BROKEN_WALL_ROOM, []{return logic->CanHitSwitch()/* && CanClimbHigh()*/;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_SUN_ON_FLOOR, []{return logic->CanHitSwitch()/* && CanClimbHigh()*/;}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_BROKEN_WALL_ROOM] = Region("Spirit Temple MQ Broken Wall Room", SCENE_SPIRIT_TEMPLE, {}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_SUN_ON_FLOOR] = Region("Spirit Temple MQ Broken Wall Room", SCENE_SPIRIT_TEMPLE, {}, {
|
||||
//Locations
|
||||
//Implies CanKillEnemy(RE_LIKE_LIKE)
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_NORTH_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_MQ_BROKEN_WALL_ROOM, []{return logic->CanKillEnemy(RE_BEAMOS);})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_NORTH_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_MQ_SUN_ON_FLOOR, []{return logic->CanKillEnemy(RE_BEAMOS);})),
|
||||
//Sunlights only temp spawn this chest, which is unintuitive/a bug.
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_SOUTH_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_MQ_BROKEN_WALL_ROOM, []{return (logic->HasExplosives() || logic->SunlightArrows()) && logic->CanUse(RG_HOOKSHOT);})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_SOUTH_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_MQ_SUN_ON_FLOOR, []{return (logic->HasExplosives() || logic->SunlightArrows()) && logic->CanUse(RG_HOOKSHOT);})),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_UNDER_LIKE_LIKE, []{return logic->CanHitSwitch();}),
|
||||
|
@ -693,19 +693,20 @@ void RegionTable_Init_SpiritTemple() {
|
|||
}, {
|
||||
//Exits
|
||||
//!QUANTUM LOGIC!
|
||||
//If we entered in reverse and dungeon entrances are off, we only need 6 keys, access to Gauntlets Hand and the ability to crawl to reach colossus
|
||||
//If we entered in reverse and dungeon entrances are off, we only need 6 keys, access to Gauntlets Hand, and the ability to
|
||||
// crawl through the boulder filled tunnel to reach colossus.
|
||||
//This is because with 6 keys it becomes impossible to avoid opening either the west hand lock or the first child side lock
|
||||
//and either direction lets child reach colossus. CanHitSwitch and CanKillEnemy(RE_IRON_KNUCKLE) is implied.
|
||||
//Logic can then allow child back into spirit, putting 1F west in logic with only 6 keys without forwards entry
|
||||
Entrance(RR_DESERT_COLOSSUS, []{return logic->IsChild/*CanUse(RG_CRAWL)*/ && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF) &&
|
||||
logic->ReverseSpiritChild && logic->SmallKeys(RR_SPIRIT_TEMPLE, 6) && logic->MQSpiritStatueToSunBlock() &&
|
||||
logic->SmallKeys(RR_SPIRIT_TEMPLE, 6) && logic->MQSpiritStatueToSunBlock() &&
|
||||
(logic->CanUse(RG_BOMBCHU_5) || (ctx->GetTrickOption(RT_RUSTED_SWITCHES) && Here(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM_WEST, []{return logic->CanUse(RG_MEGATON_HAMMER);})));}),
|
||||
//!QUANTUM LOGIC!
|
||||
//If we have 6 keys and Child reverse spirit entry, we can gurantee broken wall room access for Child
|
||||
//If we have 6 keys and Child reverse spirit entry, we can guarantee broken wall room access for Child
|
||||
//as long as we can hit a switch and climb because Adult cannot reach the initial child lock without
|
||||
//first opening the Statue Room to Broken Wall Room lock. The details of this are handled in SpiritShared.
|
||||
//if adult can ever cross crawlspaces this becomes more complicated.
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_BROKEN_WALL_ROOM, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 6);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_SUN_ON_FLOOR, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 6);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_POT_LEDGE, []{return logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_SONG_OF_TIME);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_INNER_WEST_HAND, []{return logic->IsAdult || logic->CanJumpslash() || logic->CanUse(RG_HOVER_BOOTS)/* || CanBunnyJump()*/;}),
|
||||
//(IsAdult || ctx->GetTrickOption(RT_SPIRIT_MQ_SUN_BLOCK_SOT) || CanUse(RG_SONG_OF_TIME) || CanBunnyJump()) && str0
|
||||
|
@ -720,10 +721,10 @@ void RegionTable_Init_SpiritTemple() {
|
|||
EventAccess(&logic->SpiritStatueRoomSouthDoor, []{return ctx->GetTrickOption(RT_SPIRIT_MQ_FROZEN_EYE) && logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_SONG_OF_TIME);}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_3F_EAST_POT, SpiritShared(RR_SPIRIT_TEMPLE_MQ_POT_LEDGE , []{return logic->CanBreakPots();}, false,
|
||||
RR_SPIRIT_TEMPLE_MQ_INNER_WEST_HAND , []{return logic->CanUse(RG_BOOMERANG);})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_3F_WEST_POT, SpiritShared(RR_SPIRIT_TEMPLE_MQ_POT_LEDGE , []{return logic->CanBreakPots();}, false,
|
||||
RR_SPIRIT_TEMPLE_MQ_INNER_WEST_HAND , []{return ctx->GetTrickOption(RT_SPIRIT_WEST_LEDGE) && logic->CanUse(RG_BOOMERANG);})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_3F_EAST_POT, SpiritShared(RR_SPIRIT_TEMPLE_MQ_POT_LEDGE, []{return logic->CanBreakPots();}, false,
|
||||
RR_SPIRIT_TEMPLE_MQ_INNER_WEST_HAND, []{return logic->CanUse(RG_BOOMERANG);})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_3F_WEST_POT, SpiritShared(RR_SPIRIT_TEMPLE_MQ_POT_LEDGE, []{return logic->CanBreakPots();}, false,
|
||||
RR_SPIRIT_TEMPLE_MQ_INNER_WEST_HAND, []{return ctx->GetTrickOption(RT_SPIRIT_WEST_LEDGE) && logic->CanUse(RG_BOOMERANG);})),
|
||||
}, {
|
||||
//Exits
|
||||
//This is pretty tight to reach the SoT block, but you can just go via the hand...
|
||||
|
@ -1125,6 +1126,7 @@ void RegionTable_Init_SpiritTemple() {
|
|||
//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_STATUE_ROOM, []{return true;}),
|
||||
|
|
|
@ -2365,12 +2365,12 @@ void Logic::SetInLogic(LogicVal logicVal, bool value) {
|
|||
|
||||
bool Logic::IsReverseAccessPossible() {
|
||||
//If we ever allow dungeon entrances to connect to boss rooms directly in dungeon chains, or for 1 boss door to lead to another dungeons boss door, add RSK_MIX_DUNGEON_ENTRANCES to the final condition
|
||||
return ctx->GetOption(RSK_SHUFFLE_BOSS_ENTRANCES) &&
|
||||
return !ctx->GetOption(RSK_SHUFFLE_BOSS_ENTRANCES).Is(RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF) &&
|
||||
(ctx->GetOption(RSK_DECOUPLED_ENTRANCES) ||
|
||||
(ctx->GetOption(RSK_MIX_BOSS_ENTRANCES) && (ctx->GetOption(RSK_MIX_OVERWORLD_ENTRANCES) || ctx->GetOption(RSK_MIX_INTERIOR_ENTRANCES))));
|
||||
}
|
||||
|
||||
bool Logic::SpiritBrokenWallToStatue() {
|
||||
bool Logic::SpiritSunOnFloorToStatue() {
|
||||
return /*CanClimbHigh() &&*/ (HasExplosives() || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && CanUse(RG_LIGHT_ARROWS)));
|
||||
}
|
||||
|
||||
|
@ -2630,6 +2630,7 @@ void Logic::Reset(bool resetSaveContext /*= true*/) {
|
|||
Spirit4FSwitch = false;
|
||||
SpiritPushed4FMirrors = false;
|
||||
ReverseSpiritChild = false;
|
||||
ReverseSpiritAdult = false;
|
||||
|
||||
CalculatingAvailableChecks = false;
|
||||
|
||||
|
|
|
@ -187,6 +187,9 @@ class Logic {
|
|||
bool Spirit4FSwitch = false;
|
||||
bool SpiritPushed4FMirrors = false;
|
||||
bool ReverseSpiritChild = false;
|
||||
bool ReverseSpiritAdult = false;
|
||||
bool ForwardsSpiritChild = false;
|
||||
bool ForwardsSpiritAdult = false;
|
||||
|
||||
/* --- END OF HELPERS AND LOCATION ACCESS --- */
|
||||
|
||||
|
@ -300,7 +303,7 @@ class Logic {
|
|||
static std::map<RandomizerGet, uint32_t> RandoGetToEquipFlag;
|
||||
static std::map<RandomizerGet, uint32_t> RandoGetToRandInf;
|
||||
bool IsReverseAccessPossible();
|
||||
bool SpiritBrokenWallToStatue();
|
||||
bool SpiritSunOnFloorToStatue();
|
||||
bool SpiritEastToSwitch();
|
||||
bool SpiritWestToSkull();
|
||||
bool SpiritSunBlockSouthLedge();
|
||||
|
|
|
@ -869,7 +869,7 @@ typedef enum {
|
|||
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_SUN_ON_FLOOR,
|
||||
RR_SPIRIT_TEMPLE_1F_EAST,
|
||||
RR_SPIRIT_TEMPLE_SAND_PIT,
|
||||
RR_SPIRIT_TEMPLE_BOULDERS,
|
||||
|
@ -918,7 +918,7 @@ typedef enum {
|
|||
RR_SPIRIT_TEMPLE_MQ_MAP_ROOM_SOUTH,
|
||||
RR_SPIRIT_TEMPLE_MQ_WEST_1F_RUSTED_SWITCH,
|
||||
RR_SPIRIT_TEMPLE_MQ_UNDER_LIKE_LIKE,
|
||||
RR_SPIRIT_TEMPLE_MQ_BROKEN_WALL_ROOM,
|
||||
RR_SPIRIT_TEMPLE_MQ_SUN_ON_FLOOR,
|
||||
RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM_WEST,
|
||||
RR_SPIRIT_TEMPLE_MQ_INNER_WEST_HAND,
|
||||
RR_SPIRIT_TEMPLE_MQ_POT_LEDGE,
|
||||
|
|
|
@ -379,9 +379,12 @@ void Settings::CreateOptions() {
|
|||
"Allows the following possible without Tunics:\n- Enter Water Temple. The area below the center pillar "
|
||||
"still requires Zora Tunic. Applies to MQ also.\n- Enter Fire Temple. Volvagia still requires Goron "
|
||||
"Tunic. Applies to MQ also, and includes child access to first floor with dungeon shuffle.");
|
||||
OPT_TRICK(RT_RUSTED_SWITCHES, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::NOVICE },
|
||||
"Hammer Rusted Switches Through Walls",
|
||||
"Applies to:\n- Fire Temple Highest Goron Chest.\n- MQ Fire Temple Lizalfos Maze.\n- MQ Spirit Trial.");
|
||||
OPT_TRICK(RT_RUSTED_SWITCHES, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::NOVICE },"Hammer Through Collision",
|
||||
"Applies to:\n"
|
||||
"- Hitting Fire Temple Highest Goron Chest's Rusted Switch in the SoT Block without Song of Time.\n"
|
||||
"- Hitting MQ Fire Temple Lizalfos Maze's Rusted Switch in the wall.\n"
|
||||
"- Having Adult hammer the rock in the west side crawlspace of MQ Spirit so child can get through without bombchus."
|
||||
"- MQ Spirit Trial's Rusted Switch between the thrones without hitting the eye target to drop an Iron Knuckle.\n");
|
||||
OPT_TRICK(RT_FLAMING_CHESTS, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::INTERMEDIATE }, "Flaming Chests",
|
||||
"The chests encircled in flames in Gerudo Training Ground and in Spirit Temple can be opened by running "
|
||||
"into the flames while Link is invincible after taking damage.");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue