about summary refs log tree commit diff stats
path: root/src/tracker_state.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/tracker_state.cpp')
-rw-r--r--src/tracker_state.cpp67
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 {
141struct TrackerState { 141struct 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
642bool IsPaintingReachable(int painting_id) {
643 std::lock_guard reachability_guard(GetState().reachability_mutex);
644
645 return GetState().reachable_paintings.count(painting_id);
646}
647
603const std::map<std::string, bool>& GetDoorRequirements(int door_id) { 648const 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