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_ENTRANCE_LOGIC,
PT_LOCATION_LOGIC,
PT_RECALCULATE_ACCESSIBLE_CHECKS,
PT_MAX
} TimerID;

View file

@ -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<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();
GetAccessibleLocationsStruct gals(0);
gals.calculatingAccessibleChecks = calculatingAccessibleChecks;
ResetLogic(ctx, gals, true);
do {
gals.InitLoop();

View file

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

View file

@ -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);

View file

@ -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() {

View file

@ -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 <string>
#include <vector>
@ -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<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() {
if (recalculateAccessibleChecksThread.joinable()) {
recalculateAccessibleChecksThread.request_stop();
recalculateAccessibleChecksThread.join();
StartPerformanceTimer(PT_RECALCULATE_ACCESSIBLE_CHECKS);
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() {
if (!IsVisible()) {
return;