mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-08-22 22:33:43 -07:00
initial SharedSpirit implementation
This commit is contained in:
parent
4d60f4c410
commit
403d905b7e
3 changed files with 59 additions and 38 deletions
|
@ -210,12 +210,20 @@ bool Here(const RandomizerRegion region, ConditionFn condition) {
|
||||||
return areaTable[region].Here(condition);
|
return areaTable[region].Here(condition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SpiritExplosiveLogic(){
|
||||||
|
return logic->HasExplosives() ? 1 : ctx->GetOption(RSK_BOMBCHU_BAG) && logic->BombchuRefill() ? 2 : 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SpiritSharedStatueRoom(const RandomizerRegion region, ConditionFn condition, bool anyAge) {
|
||||||
|
return areaTable[region].SpiritShared(condition, []{return logic->HasExplosives();}, []{return true;}, 5, 3, SpiritExplosiveLogic(), anyAge);
|
||||||
|
}
|
||||||
|
|
||||||
bool MQSpiritSharedStatueRoom(const RandomizerRegion region, ConditionFn condition, bool anyAge) {
|
bool MQSpiritSharedStatueRoom(const RandomizerRegion region, ConditionFn condition, bool anyAge) {
|
||||||
return areaTable[region].MQSpiritShared(condition, false, anyAge);
|
return areaTable[region].SpiritShared(condition, []{return true;}, []{return true;}, 7, 0, 0, anyAge);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MQSpiritSharedBrokenWallRoom(const RandomizerRegion region, ConditionFn condition, bool anyAge) {
|
bool MQSpiritSharedBrokenWallRoom(const RandomizerRegion region, ConditionFn condition, bool anyAge) {
|
||||||
return areaTable[region].MQSpiritShared(condition, true, anyAge);
|
return areaTable[region].SpiritShared(condition, []{return true;}, []{return true;}, 7, 7, 6, anyAge);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BeanPlanted(const RandomizerRegion region) {
|
bool BeanPlanted(const RandomizerRegion region) {
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "soh/Enhancements/randomizer/randomizerTypes.h"
|
#include "soh/Enhancements/randomizer/randomizerTypes.h"
|
||||||
#include "soh/Enhancements/randomizer/context.h"
|
#include "soh/Enhancements/randomizer/context.h"
|
||||||
#include "soh/Enhancements/randomizer/logic.h"
|
#include "soh/Enhancements/randomizer/logic.h"
|
||||||
|
#include "soh/Enhancements/randomizer/dungeon.h"
|
||||||
|
|
||||||
typedef bool (*ConditionFn)();
|
typedef bool (*ConditionFn)();
|
||||||
|
|
||||||
|
@ -232,6 +233,7 @@ class Region {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
RANDOTODO edit this
|
||||||
* This logic covers checks that exist in the shared areas of MQ spirit from a glitchless standpoint.
|
* This logic covers checks that exist in the shared areas of MQ spirit from a glitchless standpoint.
|
||||||
* This room has Quantum logic that I am currently handling with this function, however this is NOT suitable for
|
* This room has Quantum logic that I am currently handling with this function, however this is NOT suitable for
|
||||||
glitch logic as it relies on specific ages
|
glitch logic as it relies on specific ages
|
||||||
|
@ -282,42 +284,57 @@ class Region {
|
||||||
* - If Child and Adult can get the check (ignoring actual adult access to the location), and the location is either
|
* - If Child and Adult can get the check (ignoring actual adult access to the location), and the location is either
|
||||||
not 6 key locked or we have 6 keys, we can get the check with the overlap
|
not 6 key locked or we have 6 keys, we can get the check with the overlap
|
||||||
*/
|
*/
|
||||||
bool MQSpiritShared(ConditionFn condition, bool IsBrokenWall, bool anyAge = false) {
|
|
||||||
// if we have Certain Access as child, we can check anyAge and if true, resolve a condition with Here as if
|
bool SpiritShared(ConditionFn condition, ConditionFn childAccess, ConditionFn adultAccess, uint8_t adultKeys, uint8_t childKeys, uint8_t eitherKeys, bool anyAge = false){
|
||||||
// adult is here it's also Certain Access
|
//If we have all of the keys, we know that access is Certain Access
|
||||||
if (logic->SmallKeys(RR_SPIRIT_TEMPLE, 7)) {
|
if (ctx->GetDungeon(Rando::SPIRIT_TEMPLE)->IsMQ() ? logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) : logic->SmallKeys(RR_SPIRIT_TEMPLE, 5)) {
|
||||||
if (anyAge) {
|
if (anyAge) {
|
||||||
return Here(condition);
|
return Here(condition);
|
||||||
}
|
}
|
||||||
return condition();
|
return condition();
|
||||||
// else, if we are here as adult, we have Certain Access from that and don't need special handling for
|
// otherwise, we have to check the current age and...
|
||||||
// checking adult
|
} else if (Child() && logic->IsChild) {
|
||||||
} else if (Adult() && logic->IsAdult) {
|
bool result = condition();
|
||||||
return condition();
|
//if we have enough keys to have Certain Access, we just run the condition
|
||||||
// if we do not have Certain Access, we need to check the overlap by seeing if we are both here as child and
|
if (logic->SmallKeys(RR_SPIRIT_TEMPLE, childKeys)){
|
||||||
// meet the adult universe's access condition We only need to do it as child, as only child access matters
|
return result;
|
||||||
// for this check, as adult access is assumed based on keys
|
//otherwise we need to check both ages if we have enough keys that either can get there
|
||||||
} else if (Child() && logic->IsChild && (!IsBrokenWall || logic->SmallKeys(RR_SPIRIT_TEMPLE, 6))) {
|
} else if (result && logic->SmallKeys(RR_SPIRIT_TEMPLE, eitherKeys) && adultAccess) {
|
||||||
bool result = false;
|
// store current age variables
|
||||||
// store current age variables
|
bool pastAdult = logic->IsAdult;
|
||||||
bool pastAdult = logic->IsAdult;
|
bool pastChild = logic->IsChild;
|
||||||
bool pastChild = logic->IsChild;
|
|
||||||
|
|
||||||
// First check if the check is possible as child
|
|
||||||
logic->IsChild = true;
|
|
||||||
logic->IsAdult = false;
|
|
||||||
result = condition();
|
|
||||||
// If so, check again as adult. both have to be true for result to be true
|
|
||||||
if (result) {
|
|
||||||
logic->IsChild = false;
|
logic->IsChild = false;
|
||||||
logic->IsAdult = true;
|
logic->IsAdult = true;
|
||||||
result = condition();
|
|
||||||
}
|
|
||||||
|
|
||||||
// set back age variables
|
result = condition();
|
||||||
logic->IsChild = pastChild;
|
|
||||||
logic->IsAdult = pastAdult;
|
logic->IsChild = pastChild;
|
||||||
return result;
|
logic->IsAdult = pastAdult;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
} else if (Adult() && logic->IsAdult) {
|
||||||
|
bool result = condition();
|
||||||
|
//if we have enough keys to have Certain Access, we just run the condition
|
||||||
|
if (logic->SmallKeys(RR_SPIRIT_TEMPLE, childKeys)){
|
||||||
|
return result;
|
||||||
|
//otherwise we need to check both ages
|
||||||
|
} else if (result && logic->SmallKeys(RR_SPIRIT_TEMPLE, eitherKeys) && childAccess) {
|
||||||
|
// store current age variables
|
||||||
|
bool pastAdult = logic->IsAdult;
|
||||||
|
bool pastChild = logic->IsChild;
|
||||||
|
|
||||||
|
logic->IsChild = true;
|
||||||
|
logic->IsAdult = false;
|
||||||
|
|
||||||
|
result = condition();
|
||||||
|
|
||||||
|
logic->IsChild = pastChild;
|
||||||
|
logic->IsAdult = pastAdult;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -329,6 +346,7 @@ extern std::vector<EventAccess> grottoEvents;
|
||||||
bool Here(const RandomizerRegion region,
|
bool Here(const RandomizerRegion region,
|
||||||
ConditionFn
|
ConditionFn
|
||||||
condition); // RANDOTODO make a less stupid way to check own at either age than self referencing with this
|
condition); // RANDOTODO make a less stupid way to check own at either age than self referencing with this
|
||||||
|
bool SpiritSharedStatueRoom(const RandomizerRegion region, ConditionFn condition, bool anyAge = false);
|
||||||
bool MQSpiritSharedStatueRoom(const RandomizerRegion region, ConditionFn condition, bool anyAge = false);
|
bool MQSpiritSharedStatueRoom(const RandomizerRegion region, ConditionFn condition, bool anyAge = false);
|
||||||
bool MQSpiritSharedBrokenWallRoom(const RandomizerRegion region, ConditionFn condition, bool anyAge = false);
|
bool MQSpiritSharedBrokenWallRoom(const RandomizerRegion region, ConditionFn condition, bool anyAge = false);
|
||||||
bool CanPlantBean(const RandomizerRegion region);
|
bool CanPlantBean(const RandomizerRegion region);
|
||||||
|
|
|
@ -160,14 +160,9 @@ void RegionTable_Init_SpiritTemple() {
|
||||||
|
|
||||||
areaTable[RR_SPIRIT_TEMPLE_STATUE_ROOM] = Region("Spirit Temple Statue Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
areaTable[RR_SPIRIT_TEMPLE_STATUE_ROOM] = Region("Spirit Temple Statue Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||||
//Locations
|
//Locations
|
||||||
LOCATION(RC_SPIRIT_TEMPLE_MAP_CHEST, ((logic->HasExplosives() || logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && ctx->GetOption(RSK_BOMBCHU_BAG) && logic->BombchuRefill() && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) &&
|
LOCATION(RC_SPIRIT_TEMPLE_MAP_CHEST, SpiritSharedStatueRoom(RR_SPIRIT_TEMPLE_STATUE_ROOM, []{return logic->HasFireSource() || (ctx->GetTrickOption(RT_SPIRIT_MAP_CHEST) && logic->CanUse(RG_FAIRY_BOW));})),
|
||||||
(logic->HasFireSource() || (ctx->GetTrickOption(RT_SPIRIT_MAP_CHEST) && logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_STICKS)))) ||
|
LOCATION(RC_SPIRIT_TEMPLE_GS_LOBBY, SpiritSharedStatueRoom(RR_SPIRIT_TEMPLE_STATUE_ROOM, []{return logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA,
|
||||||
(logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->HasExplosives() && logic->CanUse(RG_STICKS)) ||
|
(ctx->GetTrickOption(RT_SPIRIT_LOBBY_JUMP) || logic->CanUse(RG_HOVER_BOOTS)) ? ED_CLOSE : ctx->GetTrickOption(RT_SPIRIT_LOBBY_GS) ? ED_BOOMERANG : ED_HOOKSHOT);})),
|
||||||
(logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) && (logic->CanUse(RG_FIRE_ARROWS) || (ctx->GetTrickOption(RT_SPIRIT_MAP_CHEST) && logic->CanUse(RG_FAIRY_BOW))) && logic->CanUse(RG_SILVER_GAUNTLETS))),
|
|
||||||
LOCATION(RC_SPIRIT_TEMPLE_GS_LOBBY, ((logic->HasExplosives() || logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && ctx->GetOption(RSK_BOMBCHU_BAG) && logic->BombchuRefill() && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) &&
|
|
||||||
ctx->GetTrickOption(RT_SPIRIT_LOBBY_GS) && logic->CanUse(RG_BOOMERANG) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_SPIRIT_LOBBY_JUMP))) ||
|
|
||||||
(ctx->GetTrickOption(RT_SPIRIT_LOBBY_GS) && logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->HasExplosives() && logic->CanUse(RG_BOOMERANG)) ||
|
|
||||||
(logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) && logic->CanUse(RG_SILVER_GAUNTLETS) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_SPIRIT_LOBBY_JUMP)))),
|
|
||||||
LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_1, logic->CanBreakPots()),
|
LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_1, logic->CanBreakPots()),
|
||||||
LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_2, logic->CanBreakPots()),
|
LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_2, logic->CanBreakPots()),
|
||||||
LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_3, logic->CanBreakPots()),
|
LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_3, logic->CanBreakPots()),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue