Changed RecalculateAccessibleChecks to use the logic ReachabilitySearch.

This commit is contained in:
Anthony Stewart 2025-02-21 23:33:05 -06:00
commit 18fd71c3f9
6 changed files with 39 additions and 68 deletions

View file

@ -25,6 +25,7 @@ typedef enum {
PT_TOD_ACCESS, PT_TOD_ACCESS,
PT_ENTRANCE_LOGIC, PT_ENTRANCE_LOGIC,
PT_LOCATION_LOGIC, PT_LOCATION_LOGIC,
PT_RECALCULATE_ACCESSIBLE_CHECKS,
PT_MAX PT_MAX
} TimerID; } TimerID;

View file

@ -401,6 +401,12 @@ bool AddCheckToLogic(LocationAccess& locPair, GetAccessibleLocationsStruct& gals
if (!location->IsAddedToPool() && locPair.ConditionsMet(parentRegion)) { if (!location->IsAddedToPool() && locPair.ConditionsMet(parentRegion)) {
location->AddToPool(); location->AddToPool();
if (gals.calculatingAccessibleChecks) {
gals.accessibleLocations.push_back(loc);
StopPerformanceTimer(PT_LOCATION_LOGIC);
return false;
}
if (locItem == RG_NONE) { if (locItem == RG_NONE) {
gals.accessibleLocations.push_back(loc); //Empty location, consider for placement gals.accessibleLocations.push_back(loc); //Empty location, consider for placement
} else { } else {
@ -494,9 +500,10 @@ void ProcessRegion(Region* region, GetAccessibleLocationsStruct& gals, Randomize
} }
// Return any of the targetLocations that are accessible in logic // Return any of the targetLocations that are accessible in logic
std::vector<RandomizerCheck> ReachabilitySearch(const std::vector<RandomizerCheck>& targetLocations, RandomizerGet ignore /* = RG_NONE*/) { std::vector<RandomizerCheck> ReachabilitySearch(const std::vector<RandomizerCheck>& targetLocations, RandomizerGet ignore /* = RG_NONE*/, bool calculatingAccessibleChecks /* = false */) {
auto ctx = Rando::Context::GetInstance(); auto ctx = Rando::Context::GetInstance();
GetAccessibleLocationsStruct gals(0); GetAccessibleLocationsStruct gals(0);
gals.calculatingAccessibleChecks = calculatingAccessibleChecks;
ResetLogic(ctx, gals, true); ResetLogic(ctx, gals, true);
do { do {
gals.InitLoop(); gals.InitLoop();

View file

@ -34,6 +34,8 @@ struct GetAccessibleLocationsStruct {
std::vector<RandomizerCheck> itemSphere; std::vector<RandomizerCheck> itemSphere;
std::list<Rando::Entrance*> entranceSphere; std::list<Rando::Entrance*> entranceSphere;
bool calculatingAccessibleChecks = false;
GetAccessibleLocationsStruct(int _maxGsCount){ GetAccessibleLocationsStruct(int _maxGsCount){
regionPool = {RR_ROOT}; regionPool = {RR_ROOT};
gsCount = 0; gsCount = 0;
@ -62,7 +64,7 @@ std::vector<RandomizerCheck> GetEmptyLocations(std::vector<RandomizerCheck> allo
void ProcessRegion(Region* region, GetAccessibleLocationsStruct& gals, RandomizerGet ignore = RG_NONE, void ProcessRegion(Region* region, GetAccessibleLocationsStruct& gals, RandomizerGet ignore = RG_NONE,
bool stopOnBeatable = false, bool addToPlaythrough = false); bool stopOnBeatable = false, bool addToPlaythrough = false);
std::vector<RandomizerCheck> ReachabilitySearch(const std::vector<RandomizerCheck>& allowedLocations, RandomizerGet ignore=RG_NONE); std::vector<RandomizerCheck> ReachabilitySearch(const std::vector<RandomizerCheck>& allowedLocations, RandomizerGet ignore=RG_NONE, bool calculatingAccessibleChecks=false);
void GeneratePlaythrough(); void GeneratePlaythrough();

View file

@ -196,15 +196,9 @@ class Region {
bool pastAdult = logic->IsAdult; bool pastAdult = logic->IsAdult;
bool pastChild = logic->IsChild; 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 //set age access as this areas ages
logic->IsChild = Child(); logic->IsChild = Child();
logic->IsAdult = Adult(); logic->IsAdult = Adult();
}
//heck condition as well as having at least child or adult access //heck condition as well as having at least child or adult access
bool hereVal = condition() && (logic->IsAdult || logic->IsChild); bool hereVal = condition() && (logic->IsAdult || logic->IsChild);

View file

@ -2147,7 +2147,7 @@ namespace Rando {
} }
bool Logic::DoorUnlocked(TempleDoor door) { 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() { void Logic::Reset() {

View file

@ -10,6 +10,8 @@
#include "dungeon.h" #include "dungeon.h"
#include "entrance.h" #include "entrance.h"
#include "location_access.h" #include "location_access.h"
#include "3drando/fill.hpp"
#include "soh/Enhancements/debugger/performanceTimer.h"
#include <string> #include <string>
#include <vector> #include <vector>
@ -827,9 +829,6 @@ void LoadFile() {
if (areaTable[RR_ROOT].regionName.empty()) { if (areaTable[RR_ROOT].regionName.empty()) {
RegionTable_Init(); RegionTable_Init();
} }
if (Rando::Context::GetInstance() == nullptr) {
Rando::Context::CreateInstance();
}
RecalculateAccessibleChecks(); 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<RandomizerRegion> visitedRegions;
visitedRegions.reserve(70);
std::unordered_map<const Rando::Entrance*, bool> 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() { void RecalculateAccessibleChecks() {
if (recalculateAccessibleChecksThread.joinable()) { StartPerformanceTimer(PT_RECALCULATE_ACCESSIBLE_CHECKS);
recalculateAccessibleChecksThread.request_stop();
recalculateAccessibleChecksThread.join(); std::vector<RandomizerCheck> 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<RandomizerCheck> 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() { void CheckTrackerWindow::Draw() {
if (!IsVisible()) { if (!IsVisible()) {
return; return;