diff --git a/soh/soh/Enhancements/debugger/performanceTimer.h b/soh/soh/Enhancements/debugger/performanceTimer.h index f4bc8f017..7df90db70 100644 --- a/soh/soh/Enhancements/debugger/performanceTimer.h +++ b/soh/soh/Enhancements/debugger/performanceTimer.h @@ -25,6 +25,7 @@ typedef enum { PT_TOD_ACCESS, PT_ENTRANCE_LOGIC, PT_LOCATION_LOGIC, + PT_RECALCULATE_ACCESSIBLE_CHECKS, PT_MAX } TimerID; diff --git a/soh/soh/Enhancements/randomizer/3drando/fill.cpp b/soh/soh/Enhancements/randomizer/3drando/fill.cpp index ff3413e98..0f71adf89 100644 --- a/soh/soh/Enhancements/randomizer/3drando/fill.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/fill.cpp @@ -401,6 +401,12 @@ bool AddCheckToLogic(LocationAccess& locPair, GetAccessibleLocationsStruct& gals if (!location->IsAddedToPool() && locPair.ConditionsMet(parentRegion)) { location->AddToPool(); + if (gals.calculatingAccessibleChecks) { + gals.accessibleLocations.push_back(loc); + StopPerformanceTimer(PT_LOCATION_LOGIC); + return false; + } + if (locItem == RG_NONE) { gals.accessibleLocations.push_back(loc); //Empty location, consider for placement } else { @@ -494,9 +500,10 @@ void ProcessRegion(Region* region, GetAccessibleLocationsStruct& gals, Randomize } // Return any of the targetLocations that are accessible in logic -std::vector ReachabilitySearch(const std::vector& targetLocations, RandomizerGet ignore /* = RG_NONE*/) { +std::vector ReachabilitySearch(const std::vector& targetLocations, RandomizerGet ignore /* = RG_NONE*/, bool calculatingAccessibleChecks /* = false */) { auto ctx = Rando::Context::GetInstance(); GetAccessibleLocationsStruct gals(0); + gals.calculatingAccessibleChecks = calculatingAccessibleChecks; ResetLogic(ctx, gals, true); do { gals.InitLoop(); diff --git a/soh/soh/Enhancements/randomizer/3drando/fill.hpp b/soh/soh/Enhancements/randomizer/3drando/fill.hpp index 106af7aab..8ca5999d4 100644 --- a/soh/soh/Enhancements/randomizer/3drando/fill.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/fill.hpp @@ -34,6 +34,8 @@ struct GetAccessibleLocationsStruct { std::vector itemSphere; std::list entranceSphere; + bool calculatingAccessibleChecks = false; + GetAccessibleLocationsStruct(int _maxGsCount){ regionPool = {RR_ROOT}; gsCount = 0; @@ -62,7 +64,7 @@ std::vector GetEmptyLocations(std::vector allo void ProcessRegion(Region* region, GetAccessibleLocationsStruct& gals, RandomizerGet ignore = RG_NONE, bool stopOnBeatable = false, bool addToPlaythrough = false); -std::vector ReachabilitySearch(const std::vector& allowedLocations, RandomizerGet ignore=RG_NONE); +std::vector ReachabilitySearch(const std::vector& allowedLocations, RandomizerGet ignore=RG_NONE, bool calculatingAccessibleChecks=false); void GeneratePlaythrough(); diff --git a/soh/soh/Enhancements/randomizer/location_access.h b/soh/soh/Enhancements/randomizer/location_access.h index 788a1ca70..986d08d6a 100644 --- a/soh/soh/Enhancements/randomizer/location_access.h +++ b/soh/soh/Enhancements/randomizer/location_access.h @@ -196,15 +196,9 @@ class Region { bool pastAdult = logic->IsAdult; bool pastChild = logic->IsChild; - if (logic->mSaveContext != nullptr) { - logic->IsChild = logic->mSaveContext->linkAge == LinkAge::LINK_AGE_CHILD; - logic->IsAdult = logic->mSaveContext->linkAge == LinkAge::LINK_AGE_ADULT; - } - else { - //set age access as this areas ages - logic->IsChild = Child(); - logic->IsAdult = Adult(); - } + //set age access as this areas ages + logic->IsChild = Child(); + logic->IsAdult = Adult(); //heck condition as well as having at least child or adult access bool hereVal = condition() && (logic->IsAdult || logic->IsChild); diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index e4b268284..ea8980d4d 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -2147,7 +2147,7 @@ namespace Rando { } bool Logic::DoorUnlocked(TempleDoor door) { - return gSaveContext.sceneFlags[door >> 16].swch & (1 << (door & 0x3F)); + return gSaveContext.sceneFlags[door >> 8].swch & (1 << (door & 0x3F)); } void Logic::Reset() { diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index d20d3342e..6342c4e0a 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -10,6 +10,8 @@ #include "dungeon.h" #include "entrance.h" #include "location_access.h" +#include "3drando/fill.hpp" +#include "soh/Enhancements/debugger/performanceTimer.h" #include #include @@ -827,9 +829,6 @@ void LoadFile() { if (areaTable[RR_ROOT].regionName.empty()) { RegionTable_Init(); } - if (Rando::Context::GetInstance() == nullptr) { - Rando::Context::CreateInstance(); - } RecalculateAccessibleChecks(); } } @@ -1765,63 +1764,31 @@ void CalculateAccessibleEntrances(const Region& region, } } -void _RecalculateAccessibleChecks(std::stop_token stopToken) { - logic->IsChild = logic->mSaveContext->linkAge == LinkAge::LINK_AGE_CHILD; - logic->IsAdult = logic->mSaveContext->linkAge == LinkAge::LINK_AGE_ADULT; - logic->AtDay = true; - logic->AtNight = true; - - for (auto& region : areaTable) { - for (auto& event : region.events) { - if (!event.GetEvent() && event.ConditionsMet()) { - event.EventOccurred(); - } - } - } - - if (stopToken.stop_requested()) { - return; - } - - std::vector visitedRegions; - visitedRegions.reserve(70); - std::unordered_map entranceAccessible; - entranceAccessible.reserve(1450); - CalculateAccessibleEntrances(areaTable[RR_ROOT], true, entranceAccessible, visitedRegions, stopToken); - - if (stopToken.stop_requested()) { - return; - } - - for (auto& region : areaTable) { - for (auto& locationInRegion : region.locations) { - auto rc = locationInRegion.GetLocation(); - auto itemLoc = OTRGlobals::Instance->gRandoContext->GetItemLocation(rc); - if (!itemLoc->HasObtained()) { - bool regionAccessible = false; - for (auto& entranceInRegion : region.entrances) { - if (entranceAccessible[entranceInRegion]) { - regionAccessible = true; - break; - } - } - bool locationAccessible = locationInRegion.GetConditionsMet(); - itemLoc->SetAccessible(regionAccessible && locationAccessible); - } - } - } -} - -std::jthread recalculateAccessibleChecksThread; - void RecalculateAccessibleChecks() { - if (recalculateAccessibleChecksThread.joinable()) { - recalculateAccessibleChecksThread.request_stop(); - recalculateAccessibleChecksThread.join(); + StartPerformanceTimer(PT_RECALCULATE_ACCESSIBLE_CHECKS); + + std::vector targetLocations; + targetLocations.reserve(RR_MAX); + for (auto& location : Rando::StaticData::GetLocationTable()) { + RandomizerCheck rc = location.GetRandomizerCheck(); + Rando::ItemLocation* itemLocation = OTRGlobals::Instance->gRandoContext->GetItemLocation(rc); + if (!itemLocation->HasObtained()) { + targetLocations.emplace_back(rc); + itemLocation->SetAccessible(false); + } } - recalculateAccessibleChecksThread = std::jthread(_RecalculateAccessibleChecks); + + std::vector accessibleChecks = ReachabilitySearch(targetLocations, RG_NONE, true); + for (auto& rc : accessibleChecks) { + Rando::ItemLocation* itemLocation = OTRGlobals::Instance->gRandoContext->GetItemLocation(rc); + itemLocation->SetAccessible(true); + } + + StopPerformanceTimer(PT_RECALCULATE_ACCESSIBLE_CHECKS); + SPDLOG_DEBUG("Recalculate Accessible Checks Time: {}ms", GetPerformanceTimer(PT_RECALCULATE_ACCESSIBLE_CHECKS).count()); } + void CheckTrackerWindow::Draw() { if (!IsVisible()) { return;