mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-08-20 13:23:45 -07:00
finish implementation and cleanup
This commit is contained in:
parent
e263acd4a6
commit
076b138a80
6 changed files with 153 additions and 138 deletions
|
@ -573,14 +573,15 @@ bool Here(const RandomizerRegion region, ConditionFn condition) {
|
||||||
* Additionally, if it is possible to enter spirit in reverse, there are 2 more universes:
|
* Additionally, if it is possible to enter spirit in reverse, there are 2 more universes:
|
||||||
* In the third universe, adult enters in reverse, and wastes all the keys so noone can enter through the front
|
* In the third universe, adult enters in reverse, and wastes all the keys so noone can enter through the front
|
||||||
* In the forth, child manages to do the same, and lock people out of the front
|
* In the forth, child manages to do the same, and lock people out of the front
|
||||||
* All access from the boss door in shared areas is Certain
|
* However all access from the boss door in Statue Room and adjacent areas is Certain, so this is not usually
|
||||||
|
relevant
|
||||||
|
|
||||||
* While other universes exist, such as both ages entering in reverse or
|
* While other universes exist, such as both ages entering in reverse or
|
||||||
child using their key, getting stuck, then coming back to do the dungeon as adult, these
|
child using their key, getting stuck, then coming back to do the dungeon as adult, these
|
||||||
are all sub-possibilities of these 4 universes
|
are all sub-possibilities of these 4 universes
|
||||||
|
|
||||||
* As we do not know which universe we are in until the player chooses one in-game,
|
* As we do not know which universe we are in until the player chooses one in-game,
|
||||||
we must be able to collect the check in both universes
|
we must be able to collect the check in all universes
|
||||||
|
|
||||||
* When an Age can no longer be kept out by conflicting universes, that age is said to have Certain Access to a
|
* When an Age can no longer be kept out by conflicting universes, that age is said to have Certain Access to a
|
||||||
region
|
region
|
||||||
|
@ -592,61 +593,46 @@ bool Here(const RandomizerRegion region, ConditionFn condition) {
|
||||||
* We must check for these universes manually as we allow technical access with minimum keys for
|
* We must check for these universes manually as we allow technical access with minimum keys for
|
||||||
* technical reasons as otherwise the logic code will never run
|
* technical reasons as otherwise the logic code will never run
|
||||||
|
|
||||||
* The first and 3rd column list how many keys are needed for each age to have Certain Access
|
* The 1st and 3rd column list how many keys are needed for each age to have Certain Access from the front
|
||||||
* the second column is child keys in case there's Child reverse access, due to an edge case in MQ spirit logic
|
* the 2nd and 4th column list how many keys are needed for each age to have Certain Access from the boss door
|
||||||
* where the broken wall room can be reached with 6 keys if you can hit switches and have reverse Child access
|
* Sometimes, we may check for a higher number of keys in the condition, this happens in cases where the number of
|
||||||
|
keys
|
||||||
|
* for Certain Access depends on a certain condition, the listed number is the lowest possible to make sure the
|
||||||
|
condition is checked.
|
||||||
|
|
||||||
* The first condition is the combined conditions needed to move from the 1F child lock to the area being checks
|
* The 1st condition is the combined conditions needed to move from the 1F child lock to the area being checks
|
||||||
* the second condition is the same for adult 1F lock, and the third is the access from the boss door.
|
* the 2nd condition is the same for adult 1F lock, and the 3rd 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
|
// clang-format off
|
||||||
std::map<RandomizerRegion, SpiritLogicData> Region::spiritLogicData = {
|
std::map<RandomizerRegion, SpiritLogicData> Region::spiritLogicData = {
|
||||||
//Vanilla Child uses ExplosiveKeyLogic here because they need to exist for shared adult checks
|
//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_WEST_CLIMB_BASE, {5, 0, 3, 0, []{return true;}, []{return logic->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_SUN_ON_FLOOR, {5, 0, 3, 0, []{return true/*logic->CanClimbHigh()*/;}, []{return logic->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_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_STATUE_ROOM_WEST, {5, 0, 3, 0, []{return logic->SpiritExplosiveKeyLogic()/* && logic->CanClimbHigh()*/;}, []{return logic->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_INNER_WEST_HAND, {5, 0, 3, 0, []{return logic->SpiritExplosiveKeyLogic()/* && logic->CanClimbHigh()*/;}, []{return logic->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_GS_LEDGE, {5, 0, 3, 0, []{return logic->SpiritExplosiveKeyLogic() && logic->SpiritWestToSkull()/* && logic->CanClimbHigh()*/;}, []{return logic->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;}}},
|
{RR_SPIRIT_TEMPLE_STATUE_ROOM, {5, 0, 3, 0, []{return logic->SpiritExplosiveKeyLogic();}, []{return logic->SpiritExplosiveKeyLogic()/* && logic->CanClimbHigh() && str0*/;}, []{return true;}}},
|
||||||
//Assumes SpiritSunBlockSouthLedge() for all access
|
//Assumes SpiritSunBlockSouthLedge() for all access
|
||||||
{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_SUN_BLOCK_SOUTH_LEDGE, {5, 0, 3, 0, []{return logic->SpiritExplosiveKeyLogic()/* && logic->CanClimbHigh() && str0*/;}, []{return logic->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_SKULLTULA_STAIRS, {5, 0, 3, 0, []{return logic->SpiritExplosiveKeyLogic()/* && logic->CanClimbHigh() && str0*/;}, []{return logic->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_OUTER_WEST_HAND, {5, 5, 3, 3, []{return logic->OuterWestHandLogic();}, []{return logic->OuterWestHandLogic();}, []{return logic->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_STATUE_ROOM_EAST, {5, 0, 3, 0, []{return logic->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_INNER_EAST_HAND, {5, 0, 3, 0, []{return logic->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));}}},
|
{RR_SPIRIT_TEMPLE_SHORTCUT_SWITCH, {5, 0, 3, 0, []{return logic->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()*/
|
//MQ /*&& logic->CanClimbHigh()*/
|
||||||
{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_UNDER_LIKE_LIKE, {7, 6, 7, 7, []{return logic->StatueRoomMQKeyLogic();}, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 6) && logic->CanHitSwitch()/* && logic->Climb*/;}, []{return logic->StatueRoomMQKeyLogic() && 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_SUN_ON_FLOOR, {7, 6, 7, 7, []{return logic->StatueRoomMQKeyLogic() && logic->CanHitSwitch()/* && logic->CanClimbHigh()*/;}, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 6)/* && logic->Climb*/;}, []{return logic->StatueRoomMQKeyLogic()/* && (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_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_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_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_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))*/;}}},
|
{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->OuterWestHandMQLogic()/* && logic->CanClimbHigh() && str0*/;}, []{return logic->OuterWestHandMQLogic();}, []{return logic->OuterWestHandMQLogic();}}},
|
||||||
{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() &&
|
{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();})
|
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();});}}},
|
/* && logic->CanClimbHigh()*/;}, []{return true;}, []{return areaTable[RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_NORTH].Here([]{return logic->MQSpiritStatueSouthDoor();});}}},
|
||||||
};
|
};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
|
@ -655,33 +641,25 @@ bool SpiritCertainAccess(RandomizerRegion region) {
|
||||||
if (logic->IsChild) {
|
if (logic->IsChild) {
|
||||||
uint8_t keys = curRegionData.childKeys;
|
uint8_t keys = curRegionData.childKeys;
|
||||||
uint8_t revKeys = curRegionData.childRevKeys;
|
uint8_t revKeys = curRegionData.childRevKeys;
|
||||||
bool knownFrontAccess = logic->ForwardsSpiritChild || !logic->IsReverseAccessPossible();
|
bool knownFrontAccess = logic->ForwardsSpiritChild || !logic->IsAdultReverseAccessPossible();
|
||||||
// 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
|
|
||||||
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
|
// 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
|
// 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)) ||
|
return ((knownFrontAccess && curRegionData.childAccess()) && logic->SmallKeys(RR_SPIRIT_TEMPLE, keys)) ||
|
||||||
((logic->ReverseSpiritChild && curRegionData.reverseAccess()) && logic->SmallKeys(RR_SPIRIT_TEMPLE, revKeys)) ||
|
((logic->ReverseSpiritChild && curRegionData.reverseAccess()) &&
|
||||||
(curRegionData.childAccess() && curRegionData.reverseAccess() && logic->SmallKeys(RR_SPIRIT_TEMPLE, keys > revKeys ? keys : revKeys));
|
logic->SmallKeys(RR_SPIRIT_TEMPLE, revKeys)) ||
|
||||||
|
(curRegionData.childAccess() && curRegionData.reverseAccess() &&
|
||||||
|
logic->SmallKeys(RR_SPIRIT_TEMPLE, keys > revKeys ? keys : revKeys));
|
||||||
} else {
|
} else {
|
||||||
uint8_t keys = curRegionData.adultKeys;
|
uint8_t keys = curRegionData.adultKeys;
|
||||||
uint8_t revKeys = curRegionData.adultRevKeys;
|
uint8_t revKeys = curRegionData.adultRevKeys;
|
||||||
bool knownFrontAccess = logic->ForwardsSpiritAdult || !logic->IsReverseAccessPossible();
|
bool knownFrontAccess = logic->ForwardsSpiritAdult || !logic->IsAdultReverseAccessPossible();
|
||||||
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
|
// 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
|
// 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)) ||
|
return ((knownFrontAccess && curRegionData.adultAccess()) && logic->SmallKeys(RR_SPIRIT_TEMPLE, keys)) ||
|
||||||
((logic->ReverseSpiritAdult && curRegionData.reverseAccess()) && logic->SmallKeys(RR_SPIRIT_TEMPLE, revKeys)) ||
|
((logic->ReverseSpiritAdult && curRegionData.reverseAccess()) &&
|
||||||
(curRegionData.adultAccess() && curRegionData.reverseAccess() && logic->SmallKeys(RR_SPIRIT_TEMPLE, keys > revKeys ? keys : revKeys));
|
logic->SmallKeys(RR_SPIRIT_TEMPLE, revKeys)) ||
|
||||||
|
(curRegionData.adultAccess() && curRegionData.reverseAccess() &&
|
||||||
|
logic->SmallKeys(RR_SPIRIT_TEMPLE, keys > revKeys ? keys : revKeys));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -738,16 +716,17 @@ bool SpiritShared(RandomizerRegion region, ConditionFn condition, bool anyAge, R
|
||||||
|
|
||||||
// If Adult can get there and get the check, we can get the check in logic
|
// 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
|
// If reverse spirit is also possible, we need to make sure Adult can get it via reverse entry too
|
||||||
result = (curRegionData.adultAccess() &&
|
result =
|
||||||
(!logic->IsReverseAccessPossible() || curRegionData.reverseAccess) && condition()) ||
|
(curRegionData.adultAccess() &&
|
||||||
(otherRegion != RR_NONE &&
|
(!logic->IsAdultReverseAccessPossible() || curRegionData.reverseAccess) && condition()) ||
|
||||||
(Region::spiritLogicData[otherRegion].adultAccess() &&
|
(otherRegion != RR_NONE &&
|
||||||
(!logic->IsReverseAccessPossible() || Region::spiritLogicData[otherRegion].reverseAccess()) &&
|
(Region::spiritLogicData[otherRegion].adultAccess() &&
|
||||||
otherCondition())) ||
|
(!logic->IsAdultReverseAccessPossible() || Region::spiritLogicData[otherRegion].reverseAccess()) &&
|
||||||
(thirdRegion != RR_NONE &&
|
otherCondition())) ||
|
||||||
(Region::spiritLogicData[thirdRegion].adultAccess() &&
|
(thirdRegion != RR_NONE &&
|
||||||
(!logic->IsReverseAccessPossible() || Region::spiritLogicData[thirdRegion].reverseAccess()) &&
|
(Region::spiritLogicData[thirdRegion].adultAccess() &&
|
||||||
thirdCondition()));
|
(!logic->IsAdultReverseAccessPossible() || Region::spiritLogicData[thirdRegion].reverseAccess()) &&
|
||||||
|
thirdCondition()));
|
||||||
}
|
}
|
||||||
} else if (areaTable[region].Adult() && pastAdult) {
|
} else if (areaTable[region].Adult() && pastAdult) {
|
||||||
result = condition();
|
result = condition();
|
||||||
|
@ -762,16 +741,17 @@ bool SpiritShared(RandomizerRegion region, ConditionFn condition, bool anyAge, R
|
||||||
|
|
||||||
// If Child can get there and get the check, we can get the check in logic
|
// 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
|
// If reverse spirit is also possible, we need to make sure Child can get it via reverse entry too
|
||||||
result = (curRegionData.childAccess() &&
|
result =
|
||||||
(!logic->IsReverseAccessPossible() || curRegionData.reverseAccess()) && condition()) ||
|
(curRegionData.childAccess() &&
|
||||||
(otherRegion != RR_NONE &&
|
(!logic->IsAdultReverseAccessPossible() || curRegionData.reverseAccess()) && condition()) ||
|
||||||
(Region::spiritLogicData[otherRegion].childAccess() &&
|
(otherRegion != RR_NONE &&
|
||||||
(!logic->IsReverseAccessPossible() || Region::spiritLogicData[otherRegion].reverseAccess()) &&
|
(Region::spiritLogicData[otherRegion].childAccess() &&
|
||||||
otherCondition())) ||
|
(!logic->IsAdultReverseAccessPossible() || Region::spiritLogicData[otherRegion].reverseAccess()) &&
|
||||||
(thirdRegion != RR_NONE &&
|
otherCondition())) ||
|
||||||
(Region::spiritLogicData[thirdRegion].childAccess() &&
|
(thirdRegion != RR_NONE &&
|
||||||
(!logic->IsReverseAccessPossible() || Region::spiritLogicData[thirdRegion].reverseAccess()) &&
|
(Region::spiritLogicData[thirdRegion].childAccess() &&
|
||||||
thirdCondition()));
|
(!logic->IsAdultReverseAccessPossible() || Region::spiritLogicData[thirdRegion].reverseAccess()) &&
|
||||||
|
thirdCondition()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// set back age variables
|
// set back age variables
|
||||||
|
|
|
@ -153,7 +153,7 @@ void RegionTable_Init_SpiritTemple() {
|
||||||
|
|
||||||
areaTable[RR_SPIRIT_TEMPLE_ABOVE_BOULDERS] = Region("Spirit Temple Above Boulders", SCENE_SPIRIT_TEMPLE, {
|
areaTable[RR_SPIRIT_TEMPLE_ABOVE_BOULDERS] = Region("Spirit Temple Above Boulders", SCENE_SPIRIT_TEMPLE, {
|
||||||
//Events
|
//Events
|
||||||
//Jump slash is possible as child, but pretty tight. Jumpslash as late as you can
|
//Jumpslash 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 to land on the middle of the boulder
|
//A damage boost off the boulder is also possible, but you need to land on the middle of the boulder
|
||||||
//to get enough distance to reach the rupee
|
//to get enough distance to reach the rupee
|
||||||
EventAccess(&logic->SpiritBouldersSilvers, []{return logic->CanUse(RG_HOVER_BOOTS) || logic->CanJumpslash() || logic->CanUse(RG_LONGSHOT)/* || CanBunnyHop()*/;}),
|
EventAccess(&logic->SpiritBouldersSilvers, []{return logic->CanUse(RG_HOVER_BOOTS) || logic->CanJumpslash() || logic->CanUse(RG_LONGSHOT)/* || CanBunnyHop()*/;}),
|
||||||
|
@ -394,7 +394,6 @@ void RegionTable_Init_SpiritTemple() {
|
||||||
|
|
||||||
areaTable[RR_SPIRIT_TEMPLE_BEAMOS_PITS] = Region("Spirit Temple Beamos Pits", SCENE_SPIRIT_TEMPLE, {}, {}, {
|
areaTable[RR_SPIRIT_TEMPLE_BEAMOS_PITS] = Region("Spirit Temple Beamos Pits", SCENE_SPIRIT_TEMPLE, {}, {}, {
|
||||||
//Exits
|
//Exits
|
||||||
//Implies killing the anubis with the fire ring, doing so itemless requires voiding out, which can lock hardcore + OHKO seeds
|
|
||||||
Entrance(RR_SPIRIT_TEMPLE_POT_STAIRS, []{return logic->CanKillEnemy(RE_BEAMOS);}),
|
Entrance(RR_SPIRIT_TEMPLE_POT_STAIRS, []{return logic->CanKillEnemy(RE_BEAMOS);}),
|
||||||
Entrance(RR_SPIRIT_TEMPLE_FOUR_ARMOS, []{return logic->CanKillEnemy(RE_BEAMOS);}),
|
Entrance(RR_SPIRIT_TEMPLE_FOUR_ARMOS, []{return logic->CanKillEnemy(RE_BEAMOS);}),
|
||||||
Entrance(RR_SPIRIT_TEMPLE_BIG_WALL_BASE, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 5);}),
|
Entrance(RR_SPIRIT_TEMPLE_BIG_WALL_BASE, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 5);}),
|
||||||
|
@ -674,7 +673,7 @@ void RegionTable_Init_SpiritTemple() {
|
||||||
Entrance(RR_SPIRIT_TEMPLE_MQ_SUN_ON_FLOOR, []{return logic->CanHitSwitch()/* && CanClimbHigh()*/;}),
|
Entrance(RR_SPIRIT_TEMPLE_MQ_SUN_ON_FLOOR, []{return logic->CanHitSwitch()/* && CanClimbHigh()*/;}),
|
||||||
});
|
});
|
||||||
|
|
||||||
areaTable[RR_SPIRIT_TEMPLE_MQ_SUN_ON_FLOOR] = Region("Spirit Temple MQ Broken Wall Room", SCENE_SPIRIT_TEMPLE, {}, {
|
areaTable[RR_SPIRIT_TEMPLE_MQ_SUN_ON_FLOOR] = Region("Spirit Temple MQ Sun on Floor Room", SCENE_SPIRIT_TEMPLE, {}, {
|
||||||
//Locations
|
//Locations
|
||||||
//Implies CanKillEnemy(RE_LIKE_LIKE)
|
//Implies CanKillEnemy(RE_LIKE_LIKE)
|
||||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_NORTH_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_MQ_SUN_ON_FLOOR, []{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);})),
|
||||||
|
@ -694,18 +693,13 @@ void RegionTable_Init_SpiritTemple() {
|
||||||
//Exits
|
//Exits
|
||||||
//!QUANTUM LOGIC!
|
//!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
|
//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.
|
//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
|
//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.
|
//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
|
//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) &&
|
Entrance(RR_DESERT_COLOSSUS, []{return logic->IsChild/*CanUse(RG_CRAWL)*/ && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF) &&
|
||||||
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);})));}),
|
(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 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_SUN_ON_FLOOR, []{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_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()*/;}),
|
Entrance(RR_SPIRIT_TEMPLE_MQ_INNER_WEST_HAND, []{return logic->IsAdult || logic->CanJumpslash() || logic->CanUse(RG_HOVER_BOOTS)/* || CanBunnyJump()*/;}),
|
||||||
|
@ -784,7 +778,6 @@ void RegionTable_Init_SpiritTemple() {
|
||||||
|
|
||||||
areaTable[RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM] = Region("Spirit Temple MQ Sun Block Room", SCENE_SPIRIT_TEMPLE, {}, {
|
areaTable[RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM] = Region("Spirit Temple MQ Sun Block Room", SCENE_SPIRIT_TEMPLE, {}, {
|
||||||
//Locations
|
//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, SpiritShared(RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM, []{return true/*str0*/;})),
|
LOCATION(RC_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM_CHEST, SpiritShared(RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM, []{return true/*str0*/;})),
|
||||||
//RT_SPIRIT_MQ_SUN_BLOCK_GS should probably be expanded to cover all ground based methods when str0 is added, as it can be hit with longshot because the skull hitbox is larger than the model
|
//RT_SPIRIT_MQ_SUN_BLOCK_GS should probably be expanded to cover all ground based methods when str0 is added, as it can be hit with longshot because the skull hitbox is larger than the model
|
||||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_SUN_BLOCK_ROOM, SpiritShared(RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM, []{return (logic->CanUse(RG_HOOKSHOT)/* && (str0 || SunlightArrows())*/) ||
|
LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_SUN_BLOCK_ROOM, SpiritShared(RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM, []{return (logic->CanUse(RG_HOOKSHOT)/* && (str0 || SunlightArrows())*/) ||
|
||||||
|
@ -851,25 +844,17 @@ void RegionTable_Init_SpiritTemple() {
|
||||||
Entrance(RR_SPIRIT_TEMPLE_MQ_CHEST_LEDGE, []{return logic->CanUse(RG_HOVER_BOOTS) ||
|
Entrance(RR_SPIRIT_TEMPLE_MQ_CHEST_LEDGE, []{return logic->CanUse(RG_HOVER_BOOTS) ||
|
||||||
((ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_LONGSHOT));}),
|
((ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_LONGSHOT));}),
|
||||||
Entrance(RR_SPIRIT_TEMPLE_MQ_THREE_SUNS_ROOM_2F, []{return logic->MQSpiritStatueRoomTorches;}),
|
Entrance(RR_SPIRIT_TEMPLE_MQ_THREE_SUNS_ROOM_2F, []{return logic->MQSpiritStatueRoomTorches;}),
|
||||||
//!QUANTUM LOGIC!
|
/* logic->CanAvoidEnemy(RE_BEAMOS, true, 4) && logic->CanUse(RG_SONG_OF_TIME) &&
|
||||||
//We only need 4 keys and the ability to reach both hands for adult to logically be able to drop down onto Desert Colossus
|
logic->CanJumpslash() && (str0 || SunlightArrows) &&
|
||||||
//This is because there are only 3 keys that can be wasted without opening up either this lock to East hand, or the West Hand lock through Sun Block Room
|
|
||||||
//and both directions allow you to drop onto colossus
|
|
||||||
//logic->CanKillEnemy(RE_FLOORMASTER) is implied
|
|
||||||
Entrance(RR_DESERT_COLOSSUS, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 4) &&
|
|
||||||
logic->CanAvoidEnemy(RE_BEAMOS, true, 4) && logic->CanUse(RG_SONG_OF_TIME) &&
|
|
||||||
logic->CanJumpslash() && /*(str0 || SunlightArrows) &&*/
|
|
||||||
(ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) &&
|
(ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) &&
|
||||||
logic->CanKillEnemy(RE_IRON_KNUCKLE) &&
|
logic->CanKillEnemy(RE_IRON_KNUCKLE) &&
|
||||||
logic->CanUse(RG_HOOKSHOT);}),
|
logic->CanUse(RG_HOOKSHOT)*/
|
||||||
//!QUANTUM LOGIC!
|
Entrance(RR_DESERT_COLOSSUS, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 4) && logic->MQSpirit4KeyColossus();}),
|
||||||
//Continuing from above, if we also have a longshot, we can go from the East hand to the West hand, meaning we always have access to East Hand
|
/* logic->CanAvoidEnemy(RE_BEAMOS, true, 4) && logic->CanUse(RG_SONG_OF_TIME) &&
|
||||||
/*
|
logic->CanJumpslash() && (str0 || SunlightArrows) &&
|
||||||
logic->CanAvoidEnemy(RE_BEAMOS, true, 4) && logic->CanUse(RG_SONG_OF_TIME) &&
|
(ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) &&
|
||||||
logic->CanJumpslash() && (str0 || SunlightArrows) &&
|
logic->CanKillEnemy(RE_IRON_KNUCKLE) &&
|
||||||
(ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) &&
|
logic->CanUse(RG_LONGSHOT) */
|
||||||
logic->CanKillEnemy(RE_IRON_KNUCKLE) &&
|
|
||||||
logic->CanUse(RG_LONGSHOT) */
|
|
||||||
Entrance(RR_SPIRIT_TEMPLE_MQ_OUTER_WEST_HAND, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 4) && logic->MQSpirit4KeyWestHand();}),
|
Entrance(RR_SPIRIT_TEMPLE_MQ_OUTER_WEST_HAND, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 4) && logic->MQSpirit4KeyWestHand();}),
|
||||||
Entrance(RR_SPIRIT_TEMPLE_MQ_FIRE_WALL_STAIRS_LOWER, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 5);}),
|
Entrance(RR_SPIRIT_TEMPLE_MQ_FIRE_WALL_STAIRS_LOWER, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 5);}),
|
||||||
// RT_SPIRIT_PLATFORM_HOOKSHOT is currently disabled
|
// RT_SPIRIT_PLATFORM_HOOKSHOT is currently disabled
|
||||||
|
@ -998,7 +983,7 @@ void RegionTable_Init_SpiritTemple() {
|
||||||
//Exits
|
//Exits
|
||||||
Entrance(RR_SPIRIT_TEMPLE_MQ_BEAMOS_PITS, []{return true;}),
|
Entrance(RR_SPIRIT_TEMPLE_MQ_BEAMOS_PITS, []{return true;}),
|
||||||
Entrance(RR_SPIRIT_TEMPLE_MQ_FLOORMASTER_STAIRS, []{return logic->CanJumpslash();}),
|
Entrance(RR_SPIRIT_TEMPLE_MQ_FLOORMASTER_STAIRS, []{return logic->CanJumpslash();}),
|
||||||
Entrance(RR_SPIRIT_TEMPLE_MQ_3F_GIBDO_ROOM, []{return Here(RR_SPIRIT_TEMPLE_MQ_SOT_SUN_ROOM, []{return (logic->IsAdult || logic->CanUse(RG_SONG_OF_TIME)) && logic->CanUse(RG_MIRROR_SHIELD);});}),
|
Entrance(RR_SPIRIT_TEMPLE_MQ_3F_GIBDO_ROOM, []{return Here(RR_SPIRIT_TEMPLE_MQ_SOT_SUN_ROOM, []{return ((logic->IsAdult || logic->CanUse(RG_SONG_OF_TIME)) && logic->CanUse(RG_MIRROR_SHIELD)) || logic->SunlightArrows();});}),
|
||||||
});
|
});
|
||||||
|
|
||||||
areaTable[RR_SPIRIT_TEMPLE_MQ_FLOORMASTER_STAIRS] = Region("Spirit Temple MQ Floormaster Stairs", SCENE_SPIRIT_TEMPLE, {}, {}, {
|
areaTable[RR_SPIRIT_TEMPLE_MQ_FLOORMASTER_STAIRS] = Region("Spirit Temple MQ Floormaster Stairs", SCENE_SPIRIT_TEMPLE, {}, {}, {
|
||||||
|
@ -1049,7 +1034,7 @@ void RegionTable_Init_SpiritTemple() {
|
||||||
|
|
||||||
areaTable[RR_SPIRIT_TEMPLE_MQ_BIG_WALL_UPPER] = Region("Spirit Temple MQ Big Wall Upper", SCENE_SPIRIT_TEMPLE, {
|
areaTable[RR_SPIRIT_TEMPLE_MQ_BIG_WALL_UPPER] = Region("Spirit Temple MQ Big Wall Upper", SCENE_SPIRIT_TEMPLE, {
|
||||||
//Events
|
//Events
|
||||||
//Getting some of these with just climbing downwards is theoretically possible but definitly a trick
|
//Getting some of these with just climbing downwards is theoretically possible but definitely a trick
|
||||||
EventAccess(&logic->MQSpiritBigWallSilvers, []{return /*(*/logic->CanKillEnemy(RE_KEESE)/*|| CanUse(RG_SKULL_MASK)) && CanClimbHigh()*/;}),
|
EventAccess(&logic->MQSpiritBigWallSilvers, []{return /*(*/logic->CanKillEnemy(RE_KEESE)/*|| CanUse(RG_SKULL_MASK)) && CanClimbHigh()*/;}),
|
||||||
}, {}, {
|
}, {}, {
|
||||||
//Exits
|
//Exits
|
||||||
|
|
|
@ -2363,20 +2363,25 @@ void Logic::SetInLogic(LogicVal logicVal, bool value) {
|
||||||
inLogic[logicVal] = value;
|
inLogic[logicVal] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Logic::IsReverseAccessPossible() {
|
bool Logic::IsAdultReverseAccessPossible() {
|
||||||
//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
|
// 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
|
||||||
|
// RANDOTODO Check for Age-Locked Boss entrances + Ganon's tower when it is shuffled
|
||||||
return !ctx->GetOption(RSK_SHUFFLE_BOSS_ENTRANCES).Is(RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF) &&
|
return !ctx->GetOption(RSK_SHUFFLE_BOSS_ENTRANCES).Is(RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF) &&
|
||||||
(ctx->GetOption(RSK_DECOUPLED_ENTRANCES) ||
|
((ctx->GetOption(RSK_DECOUPLED_ENTRANCES) &&
|
||||||
(ctx->GetOption(RSK_MIX_BOSS_ENTRANCES) && (ctx->GetOption(RSK_MIX_OVERWORLD_ENTRANCES) || ctx->GetOption(RSK_MIX_INTERIOR_ENTRANCES))));
|
ctx->GetOption(RSK_SHUFFLE_BOSS_ENTRANCES).Is(RO_BOSS_ROOM_ENTRANCE_SHUFFLE_FULL)) ||
|
||||||
|
(ctx->GetOption(RSK_MIX_BOSS_ENTRANCES) &&
|
||||||
|
(ctx->GetOption(RSK_MIX_OVERWORLD_ENTRANCES) || ctx->GetOption(RSK_MIX_INTERIOR_ENTRANCES))));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Logic::SpiritSunOnFloorToStatue() {
|
bool Logic::SpiritSunOnFloorToStatue() {
|
||||||
return /*CanClimbHigh() &&*/ (HasExplosives() || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && CanUse(RG_LIGHT_ARROWS)));
|
return /*CanClimbHigh() &&*/ (HasExplosives() || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && CanUse(RG_LIGHT_ARROWS)));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Logic::SpiritEastToSwitch() {
|
bool Logic::SpiritExplosiveKeyLogic() {
|
||||||
return (IsAdult && ctx->GetTrickOption(RT_SPIRIT_STATUE_JUMP)) || CanUse(RG_HOVER_BOOTS) ||
|
return SmallKeys(RR_SPIRIT_TEMPLE, HasExplosives() ? 1
|
||||||
(CanUse(RG_ZELDAS_LULLABY) && CanUse(RG_HOOKSHOT));
|
: ctx->GetOption(RSK_BOMBCHU_BAG) && BombchuRefill() ? 2
|
||||||
|
: 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Logic::SpiritWestToSkull() {
|
bool Logic::SpiritWestToSkull() {
|
||||||
|
@ -2393,6 +2398,12 @@ bool Logic::SpiritSunBlockSouthLedge() {
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Logic::SpiritEastToSwitch() {
|
||||||
|
return (IsAdult && ctx->GetTrickOption(RT_SPIRIT_STATUE_JUMP)) || CanUse(RG_HOVER_BOOTS) ||
|
||||||
|
(CanUse(RG_ZELDAS_LULLABY) && CanUse(RG_HOOKSHOT));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Combines crossing the ledge directly and the jump from the hand
|
// Combines crossing the ledge directly and the jump from the hand
|
||||||
bool Logic::MQSpiritWestToPots() {
|
bool Logic::MQSpiritWestToPots() {
|
||||||
return (IsAdult && ctx->GetTrickOption(RT_SPIRIT_STATUE_JUMP)) || CanUse(RG_HOVER_BOOTS) || CanUse(RG_SONG_OF_TIME);
|
return (IsAdult && ctx->GetTrickOption(RT_SPIRIT_STATUE_JUMP)) || CanUse(RG_HOVER_BOOTS) || CanUse(RG_SONG_OF_TIME);
|
||||||
|
@ -2408,20 +2419,52 @@ bool Logic::MQSpiritStatueSouthDoor() {
|
||||||
CanUse(RG_SONG_OF_TIME) /* && CanClimb()*/);
|
CanUse(RG_SONG_OF_TIME) /* && CanClimb()*/);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Logic::MQSpirit4KeyWestHand() {
|
bool Logic::MQSpirit4KeyColossus() {
|
||||||
|
// !QUANTUM LOGIC!
|
||||||
|
// We only need 4 keys and the ability to reach both hands for adult to logically be able to drop down onto Desert Colossus
|
||||||
|
// This is because there are only 3 keys that can be wasted without opening up either this lock to East hand, or the West Hand lock through Sun Block Room
|
||||||
|
// and both directions allow you to drop onto colossus
|
||||||
|
// logic->CanKillEnemy(RE_FLOORMASTER) is implied
|
||||||
return CanAvoidEnemy(RE_BEAMOS, true, 4) && CanUse(RG_SONG_OF_TIME) &&
|
return CanAvoidEnemy(RE_BEAMOS, true, 4) && CanUse(RG_SONG_OF_TIME) &&
|
||||||
CanJumpslash() && /*(str0 || SunlightArrows) &&*/
|
CanJumpslash() && /*(str0 || SunlightArrows) &&*/
|
||||||
(ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || CanUse(RG_LENS_OF_TRUTH)) && CanKillEnemy(RE_IRON_KNUCKLE) &&
|
(ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || CanUse(RG_LENS_OF_TRUTH)) && CanKillEnemy(RE_IRON_KNUCKLE) &&
|
||||||
CanUse(RG_LONGSHOT);
|
CanUse(RG_HOOKSHOT);
|
||||||
}
|
}
|
||||||
// This version of the function handles reaching there as child, based on what adult could do if they existed
|
|
||||||
|
bool Logic::MQSpirit4KeyWestHand() {
|
||||||
|
// !QUANTUM LOGIC!
|
||||||
|
// Continuing from MQSpirit4KeyColossus, if we also have a longshot, we can go from the East hand to the West hand, meaning we always have access to East Hand
|
||||||
|
return CanUse(RG_LONGSHOT) && MQSpirit4KeyColossus();
|
||||||
|
}
|
||||||
|
// This version of the function handles Shared Access for child, based on what adult could do if they existed
|
||||||
bool Logic::CouldMQSpirit4KeyWestHand() {
|
bool Logic::CouldMQSpirit4KeyWestHand() {
|
||||||
return CanAvoidEnemy(RE_BEAMOS, true, 4) && CanUse(RG_SONG_OF_TIME) && HasItem(RG_MASTER_SWORD) ||
|
return CanAvoidEnemy(RE_BEAMOS, true, 4) && CanUse(RG_SONG_OF_TIME) &&
|
||||||
HasItem(RG_BIGGORON_SWORD) ||
|
(HasItem(RG_MASTER_SWORD) || HasItem(RG_BIGGORON_SWORD) || HasItem(RG_MEGATON_HAMMER)) &&
|
||||||
HasItem(RG_MEGATON_HAMMER) &&
|
/*(str0 || SunlightArrows) &&*/
|
||||||
/*(str0 || SunlightArrows) &&*/
|
(ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || CanUse(RG_LENS_OF_TRUTH)) && HasItem(RG_LONGSHOT);
|
||||||
(ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || CanUse(RG_LENS_OF_TRUTH)) && CanKillEnemy(RE_IRON_KNUCKLE) &&
|
}
|
||||||
HasItem(RG_LONGSHOT);
|
|
||||||
|
// !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 Logic::OuterWestHandLogic() {
|
||||||
|
return HasExplosives() /* && CanClimbHigh() && str0*/ && SmallKeys(RR_SPIRIT_TEMPLE, HasItem(RG_LONGSHOT) ? 3 : 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Logic::OuterWestHandMQLogic() {
|
||||||
|
return MQSpiritStatueToSunBlock() && SmallKeys(RR_SPIRIT_TEMPLE, CouldMQSpirit4KeyWestHand() ? 4 : 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Logic::StatueRoomMQKeyLogic() {
|
||||||
|
// !QUANTUM LOGIC!
|
||||||
|
// 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
|
||||||
|
// if adult can ever cross crawlspaces this becomes more complicated.
|
||||||
|
return SmallKeys(RR_SPIRIT_TEMPLE, IsChild && ReverseSpiritChild && CanHitSwitch() /* && CanClimbHigh()*/ ? 6 : 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Logic::Reset(bool resetSaveContext /*= true*/) {
|
void Logic::Reset(bool resetSaveContext /*= true*/) {
|
||||||
|
|
|
@ -302,7 +302,7 @@ class Logic {
|
||||||
static std::map<uint32_t, uint32_t> RandoGetToDungeonScene;
|
static std::map<uint32_t, uint32_t> RandoGetToDungeonScene;
|
||||||
static std::map<RandomizerGet, uint32_t> RandoGetToEquipFlag;
|
static std::map<RandomizerGet, uint32_t> RandoGetToEquipFlag;
|
||||||
static std::map<RandomizerGet, uint32_t> RandoGetToRandInf;
|
static std::map<RandomizerGet, uint32_t> RandoGetToRandInf;
|
||||||
bool IsReverseAccessPossible();
|
bool IsAdultReverseAccessPossible();
|
||||||
bool SpiritSunOnFloorToStatue();
|
bool SpiritSunOnFloorToStatue();
|
||||||
bool SpiritEastToSwitch();
|
bool SpiritEastToSwitch();
|
||||||
bool SpiritWestToSkull();
|
bool SpiritWestToSkull();
|
||||||
|
@ -310,8 +310,13 @@ class Logic {
|
||||||
bool MQSpiritWestToPots();
|
bool MQSpiritWestToPots();
|
||||||
bool MQSpiritStatueToSunBlock();
|
bool MQSpiritStatueToSunBlock();
|
||||||
bool MQSpiritStatueSouthDoor();
|
bool MQSpiritStatueSouthDoor();
|
||||||
|
bool MQSpirit4KeyColossus();
|
||||||
bool MQSpirit4KeyWestHand();
|
bool MQSpirit4KeyWestHand();
|
||||||
bool CouldMQSpirit4KeyWestHand();
|
bool CouldMQSpirit4KeyWestHand();
|
||||||
|
bool OuterWestHandLogic();
|
||||||
|
bool OuterWestHandMQLogic();
|
||||||
|
bool SpiritExplosiveKeyLogic();
|
||||||
|
bool StatueRoomMQKeyLogic();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<Context> ctx;
|
std::shared_ptr<Context> ctx;
|
||||||
|
|
|
@ -379,12 +379,14 @@ void Settings::CreateOptions() {
|
||||||
"Allows the following possible without Tunics:\n- Enter Water Temple. The area below the center pillar "
|
"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 "
|
"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.");
|
"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 Through Collision",
|
OPT_TRICK(RT_RUSTED_SWITCHES, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::NOVICE }, "Hammer Through Collision",
|
||||||
"Applies to:\n"
|
"Applies to:\n"
|
||||||
"- Hitting Fire Temple Highest Goron Chest's Rusted Switch in the SoT Block without Song of Time.\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"
|
"- 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."
|
"- Having Adult hammer the rock in the west side crawlspace of MQ Spirit so child can get through "
|
||||||
"- MQ Spirit Trial's Rusted Switch between the thrones without hitting the eye target to drop an Iron Knuckle.\n");
|
"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",
|
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 "
|
"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.");
|
"into the flames while Link is invincible after taking damage.");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue