diff options
Diffstat (limited to 'src/tracker_state.cpp')
-rw-r--r-- | src/tracker_state.cpp | 67 |
1 files changed, 56 insertions, 11 deletions
diff --git a/src/tracker_state.cpp b/src/tracker_state.cpp index 187a4a8..46bdbec 100644 --- a/src/tracker_state.cpp +++ b/src/tracker_state.cpp | |||
@@ -141,6 +141,7 @@ class RequirementCalculator { | |||
141 | struct TrackerState { | 141 | struct TrackerState { |
142 | std::map<int, bool> reachability; | 142 | std::map<int, bool> reachability; |
143 | std::set<int> reachable_doors; | 143 | std::set<int> reachable_doors; |
144 | std::set<int> reachable_paintings; | ||
144 | std::mutex reachability_mutex; | 145 | std::mutex reachability_mutex; |
145 | RequirementCalculator requirements; | 146 | RequirementCalculator requirements; |
146 | std::map<int, std::map<std::string, bool>> door_reports; | 147 | std::map<int, std::map<std::string, bool>> door_reports; |
@@ -170,6 +171,7 @@ class StateCalculator { | |||
170 | 171 | ||
171 | void Calculate() { | 172 | void Calculate() { |
172 | std::list<int> panel_boundary; | 173 | std::list<int> panel_boundary; |
174 | std::list<int> painting_boundary; | ||
173 | std::list<Exit> flood_boundary; | 175 | std::list<Exit> flood_boundary; |
174 | flood_boundary.push_back({.destination_room = options_.start}); | 176 | flood_boundary.push_back({.destination_room = options_.start}); |
175 | 177 | ||
@@ -177,6 +179,8 @@ class StateCalculator { | |||
177 | while (reachable_changed) { | 179 | while (reachable_changed) { |
178 | reachable_changed = false; | 180 | reachable_changed = false; |
179 | 181 | ||
182 | std::list<Exit> new_boundary; | ||
183 | |||
180 | std::list<int> new_panel_boundary; | 184 | std::list<int> new_panel_boundary; |
181 | for (int panel_id : panel_boundary) { | 185 | for (int panel_id : panel_boundary) { |
182 | if (solveable_panels_.count(panel_id)) { | 186 | if (solveable_panels_.count(panel_id)) { |
@@ -192,7 +196,33 @@ class StateCalculator { | |||
192 | } | 196 | } |
193 | } | 197 | } |
194 | 198 | ||
195 | std::list<Exit> new_boundary; | 199 | std::list<int> new_painting_boundary; |
200 | for (int painting_id : painting_boundary) { | ||
201 | if (reachable_paintings_.count(painting_id)) { | ||
202 | continue; | ||
203 | } | ||
204 | |||
205 | Decision painting_reachable = IsPaintingReachable(painting_id); | ||
206 | if (painting_reachable == kYes) { | ||
207 | reachable_paintings_.insert(painting_id); | ||
208 | reachable_changed = true; | ||
209 | |||
210 | PaintingExit cur_painting = GD_GetPaintingExit(painting_id); | ||
211 | if (AP_GetPaintingMapping().count(cur_painting.internal_id) && | ||
212 | AP_GetCheckedPaintings().count(cur_painting.internal_id)) { | ||
213 | Exit painting_exit; | ||
214 | PaintingExit target_painting = | ||
215 | GD_GetPaintingExit(GD_GetPaintingByName( | ||
216 | AP_GetPaintingMapping().at(cur_painting.internal_id))); | ||
217 | painting_exit.destination_room = target_painting.room; | ||
218 | |||
219 | new_boundary.push_back(painting_exit); | ||
220 | } | ||
221 | } else if (painting_reachable == kMaybe) { | ||
222 | new_painting_boundary.push_back(painting_id); | ||
223 | } | ||
224 | } | ||
225 | |||
196 | for (const Exit& room_exit : flood_boundary) { | 226 | for (const Exit& room_exit : flood_boundary) { |
197 | if (reachable_rooms_.count(room_exit.destination_room)) { | 227 | if (reachable_rooms_.count(room_exit.destination_room)) { |
198 | continue; | 228 | continue; |
@@ -227,16 +257,8 @@ class StateCalculator { | |||
227 | } | 257 | } |
228 | 258 | ||
229 | if (AP_IsPaintingShuffle()) { | 259 | if (AP_IsPaintingShuffle()) { |
230 | for (const PaintingExit& out_edge : room_obj.paintings) { | 260 | for (int out_edge : room_obj.paintings) { |
231 | if (AP_GetPaintingMapping().count(out_edge.id) && | 261 | new_painting_boundary.push_back(out_edge); |
232 | AP_GetCheckedPaintings().count(out_edge.id)) { | ||
233 | Exit painting_exit; | ||
234 | painting_exit.destination_room = GD_GetRoomForPainting( | ||
235 | AP_GetPaintingMapping().at(out_edge.id)); | ||
236 | painting_exit.door = out_edge.door; | ||
237 | |||
238 | new_boundary.push_back(painting_exit); | ||
239 | } | ||
240 | } | 262 | } |
241 | } | 263 | } |
242 | 264 | ||
@@ -285,6 +307,7 @@ class StateCalculator { | |||
285 | 307 | ||
286 | flood_boundary = new_boundary; | 308 | flood_boundary = new_boundary; |
287 | panel_boundary = new_panel_boundary; | 309 | panel_boundary = new_panel_boundary; |
310 | painting_boundary = new_painting_boundary; | ||
288 | } | 311 | } |
289 | 312 | ||
290 | // Now that we know the full reachable area, let's make sure all doors are | 313 | // Now that we know the full reachable area, let's make sure all doors are |
@@ -302,6 +325,10 @@ class StateCalculator { | |||
302 | 325 | ||
303 | const std::set<int>& GetSolveablePanels() const { return solveable_panels_; } | 326 | const std::set<int>& GetSolveablePanels() const { return solveable_panels_; } |
304 | 327 | ||
328 | const std::set<int>& GetReachablePaintings() const { | ||
329 | return reachable_paintings_; | ||
330 | } | ||
331 | |||
305 | const std::map<int, std::map<std::string, bool>>& GetDoorReports() const { | 332 | const std::map<int, std::map<std::string, bool>>& GetDoorReports() const { |
306 | return door_report_; | 333 | return door_report_; |
307 | } | 334 | } |
@@ -450,6 +477,15 @@ class StateCalculator { | |||
450 | return AreRequirementsSatisfied(GetState().requirements.GetPanel(panel_id)); | 477 | return AreRequirementsSatisfied(GetState().requirements.GetPanel(panel_id)); |
451 | } | 478 | } |
452 | 479 | ||
480 | Decision IsPaintingReachable(int painting_id) { | ||
481 | const PaintingExit& painting = GD_GetPaintingExit(painting_id); | ||
482 | if (painting.door) { | ||
483 | return IsDoorReachable(*painting.door); | ||
484 | } | ||
485 | |||
486 | return kYes; | ||
487 | } | ||
488 | |||
453 | Decision IsExitUsable(const Exit& room_exit) { | 489 | Decision IsExitUsable(const Exit& room_exit) { |
454 | if (room_exit.type == EntranceType::kPilgrimage) { | 490 | if (room_exit.type == EntranceType::kPilgrimage) { |
455 | if (options_.pilgrimage || !AP_IsPilgrimageEnabled()) { | 491 | if (options_.pilgrimage || !AP_IsPilgrimageEnabled()) { |
@@ -533,6 +569,7 @@ class StateCalculator { | |||
533 | std::set<int> reachable_rooms_; | 569 | std::set<int> reachable_rooms_; |
534 | std::map<int, Decision> door_decisions_; | 570 | std::map<int, Decision> door_decisions_; |
535 | std::set<int> solveable_panels_; | 571 | std::set<int> solveable_panels_; |
572 | std::set<int> reachable_paintings_; | ||
536 | std::map<int, std::map<std::string, bool>> door_report_; | 573 | std::map<int, std::map<std::string, bool>> door_report_; |
537 | }; | 574 | }; |
538 | 575 | ||
@@ -573,6 +610,7 @@ void RecalculateReachability() { | |||
573 | } | 610 | } |
574 | } | 611 | } |
575 | 612 | ||
613 | std::set<int> reachable_paintings = state_calculator.GetReachablePaintings(); | ||
576 | std::map<int, std::map<std::string, bool>> door_reports = | 614 | std::map<int, std::map<std::string, bool>> door_reports = |
577 | state_calculator.GetDoorReports(); | 615 | state_calculator.GetDoorReports(); |
578 | 616 | ||
@@ -580,6 +618,7 @@ void RecalculateReachability() { | |||
580 | std::lock_guard reachability_guard(GetState().reachability_mutex); | 618 | std::lock_guard reachability_guard(GetState().reachability_mutex); |
581 | std::swap(GetState().reachability, new_reachability); | 619 | std::swap(GetState().reachability, new_reachability); |
582 | std::swap(GetState().reachable_doors, new_reachable_doors); | 620 | std::swap(GetState().reachable_doors, new_reachable_doors); |
621 | std::swap(GetState().reachable_paintings, reachable_paintings); | ||
583 | std::swap(GetState().door_reports, door_reports); | 622 | std::swap(GetState().door_reports, door_reports); |
584 | } | 623 | } |
585 | } | 624 | } |
@@ -600,6 +639,12 @@ bool IsDoorOpen(int door_id) { | |||
600 | return GetState().reachable_doors.count(door_id); | 639 | return GetState().reachable_doors.count(door_id); |
601 | } | 640 | } |
602 | 641 | ||
642 | bool IsPaintingReachable(int painting_id) { | ||
643 | std::lock_guard reachability_guard(GetState().reachability_mutex); | ||
644 | |||
645 | return GetState().reachable_paintings.count(painting_id); | ||
646 | } | ||
647 | |||
603 | const std::map<std::string, bool>& GetDoorRequirements(int door_id) { | 648 | const std::map<std::string, bool>& GetDoorRequirements(int door_id) { |
604 | std::lock_guard reachability_guard(GetState().reachability_mutex); | 649 | std::lock_guard reachability_guard(GetState().reachability_mutex); |
605 | 650 | ||