From 233a0b98a04e6a39cd37cbfc9a6db39a3fcf3e33 Mon Sep 17 00:00:00 2001 From: Star Rauchenberger Date: Sun, 9 Mar 2025 12:00:40 -0400 Subject: Keep reachable doors/panels between reachability calcs Receiving items/paintings shouldn't ever reduce access, so we can keep Yes decisions from prior runs (as long as we clear out everything when connecting to a new slot). --- src/tracker_state.cpp | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'src/tracker_state.cpp') diff --git a/src/tracker_state.cpp b/src/tracker_state.cpp index bcee1d6..9acf312 100644 --- a/src/tracker_state.cpp +++ b/src/tracker_state.cpp @@ -167,6 +167,7 @@ class RequirementCalculator { struct TrackerState { std::map reachability; std::set reachable_doors; + std::set solveable_panels; std::set reachable_paintings; std::mutex reachability_mutex; RequirementCalculator requirements; @@ -206,6 +207,16 @@ class StateCalculator { explicit StateCalculator(StateCalculatorOptions options) : options_(options) {} + void PreloadPanels(const std::set& panels) { + solveable_panels_ = panels; + } + + void PreloadDoors(const std::set& doors) { + for (int door_id : doors) { + door_decisions_[door_id] = kYes; + } + } + void Calculate() { painting_mapping_ = AP_GetPaintingMapping(); checked_paintings_ = AP_GetCheckedPaintings(); @@ -682,6 +693,8 @@ class StateCalculator { void ResetReachabilityRequirements() { std::lock_guard reachability_guard(GetState().reachability_mutex); GetState().requirements.Reset(); + GetState().reachable_doors.clear(); + GetState().solveable_panels.clear(); if (AP_IsPostgameShuffle()) { GetState().non_postgame_areas.clear(); @@ -743,11 +756,16 @@ void ResetReachabilityRequirements() { void RecalculateReachability() { std::lock_guard reachability_guard(GetState().reachability_mutex); + // Receiving items and checking paintings should never remove access to doors + // or panels, so we can preload any doors and panels we already know are + // accessible from previous runs, in order to reduce the work. StateCalculator state_calculator({.start = GD_GetRoomByName("Menu")}); + state_calculator.PreloadDoors(GetState().reachable_doors); + state_calculator.PreloadPanels(GetState().solveable_panels); state_calculator.Calculate(); const std::set& reachable_rooms = state_calculator.GetReachableRooms(); - const std::set& solveable_panels = state_calculator.GetSolveablePanels(); + std::set solveable_panels = state_calculator.GetSolveablePanels(); std::map new_reachability; for (const MapArea& map_area : GD_GetMapAreas()) { @@ -778,6 +796,7 @@ void RecalculateReachability() { std::swap(GetState().reachability, new_reachability); std::swap(GetState().reachable_doors, new_reachable_doors); + std::swap(GetState().solveable_panels, solveable_panels); std::swap(GetState().reachable_paintings, reachable_paintings); std::swap(GetState().door_reports, door_reports); GetState().pilgrimage_doable = state_calculator.IsPilgrimageDoable(); -- cgit 1.4.1