diff --git a/soh/soh/Enhancements/randomizer/3drando/fill.cpp b/soh/soh/Enhancements/randomizer/3drando/fill.cpp index b0548f5ee..78f0dd3ca 100644 --- a/soh/soh/Enhancements/randomizer/3drando/fill.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/fill.cpp @@ -146,6 +146,10 @@ static void ValidateOtherEntrance(GetAccessibleLocationsStruct& gals) { ApplyStartingInventory(); // RANDOTODO when proper ammo logic is done, this could be moved to the start } } + //If we are not shuffling the guard house, add the key so we can properly check for poe merchant access + if (gals.validatedStartingRegion && gals.foundTempleOfTime && !ctx->GetOption(RSK_SHUFFLE_INTERIOR_ENTRANCES).Is(RO_INTERIOR_ENTRANCE_SHUFFLE_ALL)){ + Rando::StaticData::RetrieveItem(RG_GUARD_HOUSE_KEY).ApplyEffect(); + } } // Apply all items that are necessary for checking all location access @@ -162,7 +166,9 @@ static void ApplyAllAdvancmentItems(){ static void ValidateSphereZero(GetAccessibleLocationsStruct& gals){ auto ctx = Rando::Context::GetInstance(); // Condition for verifying everything required for sphere 0, expanding search to all locations - if (logic->CouldEmptyBigPoes && gals.validatedStartingRegion && gals.foundTempleOfTime && gals.haveTimeAccess) { + if ((!logic->AreCheckingBigPoes || logic->CanEmptyBigPoes) && gals.validatedStartingRegion && gals.foundTempleOfTime && gals.haveTimeAccess) { + //stop checking for big poes + logic->AreCheckingBigPoes = false; // Apply all items that are necessary for checking all location access ApplyAllAdvancmentItems(); // Reset access as the non-starting age @@ -563,7 +569,7 @@ void ValidateEntrances(bool checkPoeCollectorAccess, bool checkOtherEntranceAcce ctx->allLocationsReachable = false; if (checkPoeCollectorAccess){ - logic->CouldEmptyBigPoes = false; + logic->AreCheckingBigPoes = true; } if (checkOtherEntranceAccess){ @@ -580,6 +586,11 @@ void ValidateEntrances(bool checkPoeCollectorAccess, bool checkOtherEntranceAcce RegionTable(RR_ROOT)->adultNight = true; RegionTable(RR_ROOT)->childDay = true; RegionTable(RR_ROOT)->adultDay = true; + } else if (checkPoeCollectorAccess){ + //If we are not shuffling the guard house, add the key so we can properly check for poe merchant access + if (!ctx->GetOption(RSK_SHUFFLE_INTERIOR_ENTRANCES).Is(RO_INTERIOR_ENTRANCE_SHUFFLE_ALL)){ + Rando::StaticData::RetrieveItem(RG_GUARD_HOUSE_KEY).ApplyEffect(); + } } else { ApplyAllAdvancmentItems(); } diff --git a/soh/soh/Enhancements/randomizer/location_access.cpp b/soh/soh/Enhancements/randomizer/location_access.cpp index f6b55868b..33abc3ce8 100644 --- a/soh/soh/Enhancements/randomizer/location_access.cpp +++ b/soh/soh/Enhancements/randomizer/location_access.cpp @@ -265,6 +265,9 @@ void RegionTable_Init() { areaTable[RR_ROOT] = Region("Root", "", {RA_LINKS_POCKET}, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->KakarikoVillageGateOpen, []{return ctx->GetOption(RSK_KAK_GATE).Is(RO_KAK_GATE_OPEN);}), + //The big poes bottle softlock safety check does not account for the guard house lock if the guard house is not shuffled, so the key is needed before we can safely allow bottle use in logic + //RANDOTODO a setting that lets you drink/dump big poes so we don't need this logic + EventAccess(&logic->CouldEmptyBigPoes, []{return ctx->GetOption(RSK_SHUFFLE_INTERIOR_ENTRANCES).Is(RO_INTERIOR_ENTRANCE_SHUFFLE_ALL) || logic->CanOpenOverworldDoor(RG_GUARD_HOUSE_KEY);}), }, { //Locations LOCATION(RC_LINKS_POCKET, true), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp index 0e51ea173..777e29050 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp @@ -8,7 +8,7 @@ void RegionTable_Init_Kakariko() { areaTable[RR_KAKARIKO_VILLAGE] = Region("Kakariko Village", "Kakariko Village", {RA_KAKARIKO_VILLAGE}, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->BugRock, []{return true;}), - //Open Gate setting is applies in RR_ROOT + //Open Gate setting is applied in RR_ROOT EventAccess(&logic->KakarikoVillageGateOpen, []{return logic->IsChild && logic->HasItem(RG_ZELDAS_LETTER);}), }, { //Locations diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp index 0fd154259..2016b24cd 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp @@ -50,7 +50,6 @@ void RegionTable_Init_Market() { areaTable[RR_MARKET_GUARD_HOUSE] = Region("Market Guard House", "Market Guard House", {}, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->CouldEmptyBigPoes, []{return logic->IsAdult;}), EventAccess(&logic->CanEmptyBigPoes, []{return logic->IsAdult;}), }, { //Locations diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index 06b1f4494..836a817c4 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -407,6 +407,7 @@ namespace Rando { } } + //RANDOMISERTODO intergrate into HasItem bool Logic::CanOpenOverworldDoor(RandomizerGet key) { if (!ctx->GetOption(RSK_LOCK_OVERWORLD_DOORS)) { return true; @@ -945,7 +946,7 @@ namespace Rando { uint8_t Logic::BottleCount() { uint8_t count = 0; - if (CouldEmptyBigPoes){ + if (CouldEmptyBigPoes && !AreCheckingBigPoes){ for (int i = SLOT_BOTTLE_1; i <= SLOT_BOTTLE_4; i++) { uint8_t item = GetSaveContext()->inventory.items[i]; switch (item) { @@ -2237,7 +2238,8 @@ namespace Rando { //Bottle Count Bottles = 0; NumBottles = 0; - CanEmptyBigPoes = false; + CanEmptyBigPoes = false; + CouldEmptyBigPoes = false; //Drops and Bottle Contents Access NutPot = false; diff --git a/soh/soh/Enhancements/randomizer/logic.h b/soh/soh/Enhancements/randomizer/logic.h index c976287a7..2f68017e2 100644 --- a/soh/soh/Enhancements/randomizer/logic.h +++ b/soh/soh/Enhancements/randomizer/logic.h @@ -66,8 +66,11 @@ class Logic { uint8_t NumBottles = 0; //this event covers if the player can currently empty big poes in logic bool CanEmptyBigPoes = false; - //this check covers if the generation has confirmed that it's possible to empty big poes if needed as adult - bool CouldEmptyBigPoes = true; + //this event covers if the player could, if they filled their bottle with big poes in field, empty them at the poe merchant. + //Works in tandem with the big poes safety check during entrance validation + bool CouldEmptyBigPoes = false; + //this check is used to tell logic that we are checking big poes accessibility in logic, to ensure it's not bottle-locked. + bool AreCheckingBigPoes = false; // Drops and Bottle Contents Access bool NutPot = false;