diff options
author | Star Rauchenberger <fefferburbia@gmail.com> | 2024-05-29 12:56:29 -0400 |
---|---|---|
committer | Star Rauchenberger <fefferburbia@gmail.com> | 2024-05-29 12:56:29 -0400 |
commit | 13d2a129f6972e6e752da9c9cb686a63d5550517 (patch) | |
tree | ea0cfe2197c25732dd0d4d0f0e37717fd977792f | |
parent | d3e2d9518403eb89eb150fa2158966c3483d5339 (diff) | |
download | lingo-ap-tracker-13d2a129f6972e6e752da9c9cb686a63d5550517.tar.gz lingo-ap-tracker-13d2a129f6972e6e752da9c9cb686a63d5550517.tar.bz2 lingo-ap-tracker-13d2a129f6972e6e752da9c9cb686a63d5550517.zip |
Show unchecked paintings
-rw-r--r-- | src/ap_state.cpp | 12 | ||||
-rw-r--r-- | src/ap_state.h | 2 | ||||
-rw-r--r-- | src/area_popup.cpp | 32 | ||||
-rw-r--r-- | src/game_data.cpp | 33 | ||||
-rw-r--r-- | src/game_data.h | 1 | ||||
-rw-r--r-- | src/tracker_panel.cpp | 14 | ||||
-rw-r--r-- | src/tracker_state.cpp | 32 |
7 files changed, 104 insertions, 22 deletions
diff --git a/src/ap_state.cpp b/src/ap_state.cpp index 20245e5..0c75eae 100644 --- a/src/ap_state.cpp +++ b/src/ap_state.cpp | |||
@@ -427,6 +427,14 @@ struct APState { | |||
427 | return std::any_cast<const std::set<std::string>&>(data_storage.at(key)); | 427 | return std::any_cast<const std::set<std::string>&>(data_storage.at(key)); |
428 | } | 428 | } |
429 | 429 | ||
430 | bool IsPaintingChecked(const std::string& painting_id) { | ||
431 | const auto& checked_paintings = GetCheckedPaintings(); | ||
432 | |||
433 | return checked_paintings.count(painting_id) || | ||
434 | (painting_mapping.count(painting_id) && | ||
435 | checked_paintings.count(painting_mapping.at(painting_id))); | ||
436 | } | ||
437 | |||
430 | void RefreshTracker(bool reset) { | 438 | void RefreshTracker(bool reset) { |
431 | wxLogVerbose("Refreshing display..."); | 439 | wxLogVerbose("Refreshing display..."); |
432 | 440 | ||
@@ -506,6 +514,10 @@ const std::set<std::string>& AP_GetCheckedPaintings() { | |||
506 | return GetState().GetCheckedPaintings(); | 514 | return GetState().GetCheckedPaintings(); |
507 | } | 515 | } |
508 | 516 | ||
517 | bool AP_IsPaintingChecked(const std::string& painting_id) { | ||
518 | return GetState().IsPaintingChecked(painting_id); | ||
519 | } | ||
520 | |||
509 | int AP_GetMasteryRequirement() { return GetState().mastery_requirement; } | 521 | int AP_GetMasteryRequirement() { return GetState().mastery_requirement; } |
510 | 522 | ||
511 | int AP_GetLevel2Requirement() { return GetState().level_2_requirement; } | 523 | int AP_GetLevel2Requirement() { return GetState().level_2_requirement; } |
diff --git a/src/ap_state.h b/src/ap_state.h index 0ae6a25..2769bb8 100644 --- a/src/ap_state.h +++ b/src/ap_state.h | |||
@@ -61,6 +61,8 @@ const std::map<std::string, std::string>& AP_GetPaintingMapping(); | |||
61 | 61 | ||
62 | const std::set<std::string>& AP_GetCheckedPaintings(); | 62 | const std::set<std::string>& AP_GetCheckedPaintings(); |
63 | 63 | ||
64 | bool AP_IsPaintingChecked(const std::string& painting_id); | ||
65 | |||
64 | int AP_GetMasteryRequirement(); | 66 | int AP_GetMasteryRequirement(); |
65 | 67 | ||
66 | int AP_GetLevel2Requirement(); | 68 | int AP_GetLevel2Requirement(); |
diff --git a/src/area_popup.cpp b/src/area_popup.cpp index 6e70315..b5c1ccb 100644 --- a/src/area_popup.cpp +++ b/src/area_popup.cpp | |||
@@ -65,6 +65,18 @@ void AreaPopup::UpdateIndicators() { | |||
65 | } | 65 | } |
66 | } | 66 | } |
67 | 67 | ||
68 | if (AP_IsPaintingShuffle()) { | ||
69 | for (const PaintingExit& painting : map_area.paintings) { | ||
70 | wxSize item_extent = mem_dc.GetTextExtent(painting.id); | ||
71 | int item_height = std::max(32, item_extent.GetHeight()) + 10; | ||
72 | acc_height += item_height; | ||
73 | |||
74 | if (item_extent.GetWidth() > col_width) { | ||
75 | col_width = item_extent.GetWidth(); | ||
76 | } | ||
77 | } | ||
78 | } | ||
79 | |||
68 | int item_width = col_width + 10 + 32; | 80 | int item_width = col_width + 10 + 32; |
69 | int full_width = std::max(header_extent.GetWidth(), item_width) + 20; | 81 | int full_width = std::max(header_extent.GetWidth(), item_width) + 20; |
70 | 82 | ||
@@ -109,6 +121,26 @@ void AreaPopup::UpdateIndicators() { | |||
109 | 121 | ||
110 | cur_height += 10 + 32; | 122 | cur_height += 10 + 32; |
111 | } | 123 | } |
124 | |||
125 | if (AP_IsPaintingShuffle()) { | ||
126 | for (const PaintingExit& painting : map_area.paintings) { | ||
127 | bool checked = AP_IsPaintingChecked(painting.id); | ||
128 | wxBitmap* eye_ptr = checked ? &checked_eye_ : &unchecked_eye_; | ||
129 | |||
130 | mem_dc.DrawBitmap(*eye_ptr, {10, cur_height}); | ||
131 | |||
132 | bool reachable = painting.door ? IsDoorOpen(*painting.door) : true; | ||
133 | const wxColour* text_color = reachable ? wxWHITE : wxRED; | ||
134 | mem_dc.SetTextForeground(*text_color); | ||
135 | |||
136 | wxSize item_extent = mem_dc.GetTextExtent(painting.id); | ||
137 | mem_dc.DrawText(painting.id, | ||
138 | {10 + 32 + 10, | ||
139 | cur_height + (32 - mem_dc.GetFontMetrics().height) / 2}); | ||
140 | |||
141 | cur_height += 10 + 32; | ||
142 | } | ||
143 | } | ||
112 | } | 144 | } |
113 | 145 | ||
114 | void AreaPopup::OnPaint(wxPaintEvent& event) { | 146 | void AreaPopup::OnPaint(wxPaintEvent& event) { |
diff --git a/src/game_data.cpp b/src/game_data.cpp index 7c9564b..4dd69e2 100644 --- a/src/game_data.cpp +++ b/src/game_data.cpp | |||
@@ -284,7 +284,7 @@ struct GameData { | |||
284 | .as<int>(); | 284 | .as<int>(); |
285 | } else { | 285 | } else { |
286 | wxLogError("Missing AP location ID for panel %s - %s", | 286 | wxLogError("Missing AP location ID for panel %s - %s", |
287 | rooms_[room_id].name, panels_[panel_id].name); | 287 | rooms_[room_id].name, panels_[panel_id].name); |
288 | } | 288 | } |
289 | } | 289 | } |
290 | } | 290 | } |
@@ -348,7 +348,7 @@ struct GameData { | |||
348 | .as<int>(); | 348 | .as<int>(); |
349 | } else { | 349 | } else { |
350 | wxLogError("Missing AP item ID for door %s - %s", | 350 | wxLogError("Missing AP item ID for door %s - %s", |
351 | rooms_[room_id].name, doors_[door_id].name); | 351 | rooms_[room_id].name, doors_[door_id].name); |
352 | } | 352 | } |
353 | } | 353 | } |
354 | 354 | ||
@@ -422,7 +422,8 @@ struct GameData { | |||
422 | std::string painting_id = painting["id"].as<std::string>(); | 422 | std::string painting_id = painting["id"].as<std::string>(); |
423 | room_by_painting_[painting_id] = room_id; | 423 | room_by_painting_[painting_id] = room_id; |
424 | 424 | ||
425 | if (!painting["exit_only"] || !painting["exit_only"].as<bool>()) { | 425 | if ((!painting["exit_only"] || !painting["exit_only"].as<bool>()) && |
426 | (!painting["disable"] || !painting["disable"].as<bool>())) { | ||
426 | PaintingExit painting_exit; | 427 | PaintingExit painting_exit; |
427 | painting_exit.id = painting_id; | 428 | painting_exit.id = painting_id; |
428 | 429 | ||
@@ -594,11 +595,28 @@ struct GameData { | |||
594 | } | 595 | } |
595 | } | 596 | } |
596 | 597 | ||
598 | for (const Room &room : rooms_) { | ||
599 | std::string area_name = room.name; | ||
600 | if (fold_areas.count(room.name)) { | ||
601 | int fold_area_id = fold_areas[room.name]; | ||
602 | area_name = map_areas_[fold_area_id].name; | ||
603 | } | ||
604 | |||
605 | if (!room.paintings.empty()) { | ||
606 | int area_id = AddOrGetArea(area_name); | ||
607 | MapArea &map_area = map_areas_[area_id]; | ||
608 | |||
609 | for (const PaintingExit &painting : room.paintings) { | ||
610 | map_area.paintings.push_back(painting); | ||
611 | } | ||
612 | } | ||
613 | } | ||
614 | |||
597 | // Report errors. | 615 | // Report errors. |
598 | for (const std::string &area : malconfigured_areas_) { | 616 | for (const std::string &area : malconfigured_areas_) { |
599 | wxLogError("Area data not found for: %s", area); | 617 | wxLogError("Area data not found for: %s", area); |
600 | } | 618 | } |
601 | 619 | ||
602 | // Read in subway items. | 620 | // Read in subway items. |
603 | YAML::Node subway_config = | 621 | YAML::Node subway_config = |
604 | YAML::LoadFile(GetAbsolutePath("assets/subway.yaml")); | 622 | YAML::LoadFile(GetAbsolutePath("assets/subway.yaml")); |
@@ -687,7 +705,8 @@ struct GameData { | |||
687 | if (!door_by_id_.count(full_name)) { | 705 | if (!door_by_id_.count(full_name)) { |
688 | int door_id = doors_.size(); | 706 | int door_id = doors_.size(); |
689 | door_by_id_[full_name] = doors_.size(); | 707 | door_by_id_[full_name] = doors_.size(); |
690 | doors_.push_back({.id = door_id, .room = AddOrGetRoom(room), .name = door}); | 708 | doors_.push_back( |
709 | {.id = door_id, .room = AddOrGetRoom(room), .name = door}); | ||
691 | } | 710 | } |
692 | 711 | ||
693 | return door_by_id_[full_name]; | 712 | return door_by_id_[full_name]; |
@@ -728,7 +747,7 @@ GameData &GetState() { | |||
728 | 747 | ||
729 | } // namespace | 748 | } // namespace |
730 | 749 | ||
731 | bool SubwaySunwarp::operator<(const SubwaySunwarp& rhs) const { | 750 | bool SubwaySunwarp::operator<(const SubwaySunwarp &rhs) const { |
732 | return std::tie(dots, type) < std::tie(rhs.dots, rhs.type); | 751 | return std::tie(dots, type) < std::tie(rhs.dots, rhs.type); |
733 | } | 752 | } |
734 | 753 | ||
@@ -782,7 +801,7 @@ const SubwayItem &GD_GetSubwayItem(int id) { | |||
782 | return GetState().subway_items_.at(id); | 801 | return GetState().subway_items_.at(id); |
783 | } | 802 | } |
784 | 803 | ||
785 | int GD_GetSubwayItemForPainting(const std::string& painting_id) { | 804 | int GD_GetSubwayItemForPainting(const std::string &painting_id) { |
786 | #ifndef NDEBUG | 805 | #ifndef NDEBUG |
787 | if (!GetState().subway_item_by_painting_.count(painting_id)) { | 806 | if (!GetState().subway_item_by_painting_.count(painting_id)) { |
788 | wxLogError("No subway item for painting %s", painting_id); | 807 | wxLogError("No subway item for painting %s", painting_id); |
diff --git a/src/game_data.h b/src/game_data.h index 3afaec3..68ba5e4 100644 --- a/src/game_data.h +++ b/src/game_data.h | |||
@@ -113,6 +113,7 @@ struct MapArea { | |||
113 | int id; | 113 | int id; |
114 | std::string name; | 114 | std::string name; |
115 | std::vector<Location> locations; | 115 | std::vector<Location> locations; |
116 | std::vector<PaintingExit> paintings; | ||
116 | int map_x; | 117 | int map_x; |
117 | int map_y; | 118 | int map_y; |
118 | int classification = 0; | 119 | int classification = 0; |
diff --git a/src/tracker_panel.cpp b/src/tracker_panel.cpp index 66bce81..0385f89 100644 --- a/src/tracker_panel.cpp +++ b/src/tracker_panel.cpp | |||
@@ -171,6 +171,20 @@ void TrackerPanel::Redraw() { | |||
171 | } | 171 | } |
172 | } | 172 | } |
173 | 173 | ||
174 | if (AP_IsPaintingShuffle()) { | ||
175 | for (const PaintingExit &painting : map_area.paintings) { | ||
176 | if (!AP_IsPaintingChecked(painting.id)) { | ||
177 | bool reachable = painting.door ? IsDoorOpen(*painting.door) : true; | ||
178 | |||
179 | if (reachable) { | ||
180 | has_reachable_unchecked = true; | ||
181 | } else { | ||
182 | has_unreachable_unchecked = true; | ||
183 | } | ||
184 | } | ||
185 | } | ||
186 | } | ||
187 | |||
174 | int real_area_x = final_x + (map_area.map_x - (AREA_EFFECTIVE_SIZE / 2)) * | 188 | int real_area_x = final_x + (map_area.map_x - (AREA_EFFECTIVE_SIZE / 2)) * |
175 | final_width / image_size.GetWidth(); | 189 | final_width / image_size.GetWidth(); |
176 | int real_area_y = final_y + (map_area.map_y - (AREA_EFFECTIVE_SIZE / 2)) * | 190 | int real_area_y = final_y + (map_area.map_y - (AREA_EFFECTIVE_SIZE / 2)) * |
diff --git a/src/tracker_state.cpp b/src/tracker_state.cpp index 869f837..faf74cc 100644 --- a/src/tracker_state.cpp +++ b/src/tracker_state.cpp | |||
@@ -15,11 +15,11 @@ namespace { | |||
15 | struct Requirements { | 15 | struct Requirements { |
16 | bool disabled = false; | 16 | bool disabled = false; |
17 | 17 | ||
18 | std::set<int> doors; // non-grouped, handles progressive | 18 | std::set<int> doors; // non-grouped, handles progressive |
19 | std::set<int> items; // all other items | 19 | std::set<int> items; // all other items |
20 | std::set<int> rooms; // maybe | 20 | std::set<int> rooms; // maybe |
21 | bool mastery = false; // maybe | 21 | bool mastery = false; // maybe |
22 | bool panel_hunt = false; // maybe | 22 | bool panel_hunt = false; // maybe |
23 | 23 | ||
24 | void Merge(const Requirements& rhs) { | 24 | void Merge(const Requirements& rhs) { |
25 | if (rhs.disabled) { | 25 | if (rhs.disabled) { |
@@ -228,7 +228,8 @@ class StateCalculator { | |||
228 | 228 | ||
229 | if (AP_IsPaintingShuffle()) { | 229 | if (AP_IsPaintingShuffle()) { |
230 | for (const PaintingExit& out_edge : room_obj.paintings) { | 230 | for (const PaintingExit& out_edge : room_obj.paintings) { |
231 | if (AP_GetPaintingMapping().count(out_edge.id)) { | 231 | if (AP_GetPaintingMapping().count(out_edge.id) && |
232 | AP_GetCheckedPaintings().count(out_edge.id)) { | ||
232 | Exit painting_exit; | 233 | Exit painting_exit; |
233 | painting_exit.destination_room = GD_GetRoomForPainting( | 234 | painting_exit.destination_room = GD_GetRoomForPainting( |
234 | AP_GetPaintingMapping().at(out_edge.id)); | 235 | AP_GetPaintingMapping().at(out_edge.id)); |
@@ -286,7 +287,8 @@ class StateCalculator { | |||
286 | panel_boundary = new_panel_boundary; | 287 | panel_boundary = new_panel_boundary; |
287 | } | 288 | } |
288 | 289 | ||
289 | // Now that we know the full reachable area, let's make sure all doors are evaluated. | 290 | // Now that we know the full reachable area, let's make sure all doors are |
291 | // evaluated. | ||
290 | for (const Door& door : GD_GetDoors()) { | 292 | for (const Door& door : GD_GetDoors()) { |
291 | int discard = IsDoorReachable(door.id); | 293 | int discard = IsDoorReachable(door.id); |
292 | } | 294 | } |
@@ -320,7 +322,8 @@ class StateCalculator { | |||
320 | return has_item ? kYes : kNo; | 322 | return has_item ? kYes : kNo; |
321 | } | 323 | } |
322 | 324 | ||
323 | Decision AreRequirementsSatisfied(const Requirements& reqs, std::map<std::string, bool>* report = nullptr) { | 325 | Decision AreRequirementsSatisfied( |
326 | const Requirements& reqs, std::map<std::string, bool>* report = nullptr) { | ||
324 | if (reqs.disabled) { | 327 | if (reqs.disabled) { |
325 | return kNo; | 328 | return kNo; |
326 | } | 329 | } |
@@ -339,7 +342,7 @@ class StateCalculator { | |||
339 | final_decision = decision; | 342 | final_decision = decision; |
340 | } | 343 | } |
341 | } | 344 | } |
342 | 345 | ||
343 | for (int item_id : reqs.items) { | 346 | for (int item_id : reqs.items) { |
344 | bool has_item = AP_HasItem(item_id); | 347 | bool has_item = AP_HasItem(item_id); |
345 | if (report) { | 348 | if (report) { |
@@ -353,10 +356,9 @@ class StateCalculator { | |||
353 | 356 | ||
354 | for (int room_id : reqs.rooms) { | 357 | for (int room_id : reqs.rooms) { |
355 | bool reachable = reachable_rooms_.count(room_id); | 358 | bool reachable = reachable_rooms_.count(room_id); |
356 | 359 | ||
357 | if (report) { | 360 | if (report) { |
358 | std::string report_name = | 361 | std::string report_name = "Reach \"" + GD_GetRoom(room_id).name + "\""; |
359 | "Reach \"" + GD_GetRoom(room_id).name + "\""; | ||
360 | (*report)[report_name] = reachable; | 362 | (*report)[report_name] = reachable; |
361 | } | 363 | } |
362 | 364 | ||
@@ -364,7 +366,7 @@ class StateCalculator { | |||
364 | final_decision = kMaybe; | 366 | final_decision = kMaybe; |
365 | } | 367 | } |
366 | } | 368 | } |
367 | 369 | ||
368 | if (reqs.mastery) { | 370 | if (reqs.mastery) { |
369 | int achievements_accessible = 0; | 371 | int achievements_accessible = 0; |
370 | 372 | ||
@@ -407,7 +409,7 @@ class StateCalculator { | |||
407 | std::to_string(AP_GetLevel2Requirement()) + " Panels"; | 409 | std::to_string(AP_GetLevel2Requirement()) + " Panels"; |
408 | (*report)[report_name] = can_level2; | 410 | (*report)[report_name] = can_level2; |
409 | } | 411 | } |
410 | 412 | ||
411 | if (can_level2 && final_decision != kNo) { | 413 | if (can_level2 && final_decision != kNo) { |
412 | final_decision = kMaybe; | 414 | final_decision = kMaybe; |
413 | } | 415 | } |
@@ -422,7 +424,7 @@ class StateCalculator { | |||
422 | } else { | 424 | } else { |
423 | door_report_[door_id] = {}; | 425 | door_report_[door_id] = {}; |
424 | } | 426 | } |
425 | 427 | ||
426 | return AreRequirementsSatisfied(GetState().requirements.GetDoor(door_id), | 428 | return AreRequirementsSatisfied(GetState().requirements.GetDoor(door_id), |
427 | &door_report_[door_id]); | 429 | &door_report_[door_id]); |
428 | } | 430 | } |