diff options
author | Star Rauchenberger <fefferburbia@gmail.com> | 2025-03-11 17:19:54 -0400 |
---|---|---|
committer | Star Rauchenberger <fefferburbia@gmail.com> | 2025-03-11 17:19:54 -0400 |
commit | 8ad881fed6e388f7a254350532ce58552ef47a1d (patch) | |
tree | 0d4b20f6bcc7c5cbdad1cfe46b8ff3ea16ef85a2 /src | |
parent | 788c637adc08175533ef0ea54e76688679910cf3 (diff) | |
download | lingo-ap-tracker-8ad881fed6e388f7a254350532ce58552ef47a1d.tar.gz lingo-ap-tracker-8ad881fed6e388f7a254350532ce58552ef47a1d.tar.bz2 lingo-ap-tracker-8ad881fed6e388f7a254350532ce58552ef47a1d.zip |
New subway map paintings
Diffstat (limited to 'src')
-rw-r--r-- | src/game_data.cpp | 11 | ||||
-rw-r--r-- | src/game_data.h | 2 | ||||
-rw-r--r-- | src/subway_map.cpp | 134 |
3 files changed, 79 insertions, 68 deletions
diff --git a/src/game_data.cpp b/src/game_data.cpp index 54b25b4..8ccc0da 100644 --- a/src/game_data.cpp +++ b/src/game_data.cpp | |||
@@ -778,13 +778,10 @@ struct GameData { | |||
778 | subway_it["door"].as<std::string>()); | 778 | subway_it["door"].as<std::string>()); |
779 | } | 779 | } |
780 | 780 | ||
781 | if (subway_it["paintings"]) { | 781 | if (subway_it["painting"]) { |
782 | for (const auto &painting_it : subway_it["paintings"]) { | 782 | std::string painting_id = subway_it["painting"].as<std::string>(); |
783 | std::string painting_id = painting_it.as<std::string>(); | 783 | subway_item.painting = painting_id; |
784 | 784 | subway_item_by_painting_[painting_id] = subway_item.id; | |
785 | subway_item.paintings.push_back(painting_id); | ||
786 | subway_item_by_painting_[painting_id] = subway_item.id; | ||
787 | } | ||
788 | } | 785 | } |
789 | 786 | ||
790 | if (subway_it["tags"]) { | 787 | if (subway_it["tags"]) { |
diff --git a/src/game_data.h b/src/game_data.h index b087734..be10900 100644 --- a/src/game_data.h +++ b/src/game_data.h | |||
@@ -157,7 +157,7 @@ struct SubwayItem { | |||
157 | int x; | 157 | int x; |
158 | int y; | 158 | int y; |
159 | std::optional<int> door; | 159 | std::optional<int> door; |
160 | std::vector<std::string> paintings; | 160 | std::optional<std::string> painting; |
161 | std::vector<std::string> tags; // 2-way teleports | 161 | std::vector<std::string> tags; // 2-way teleports |
162 | std::vector<std::string> entrances; // teleport entrances | 162 | std::vector<std::string> entrances; // teleport entrances |
163 | std::vector<std::string> exits; // teleport exits | 163 | std::vector<std::string> exits; // teleport exits |
diff --git a/src/subway_map.cpp b/src/subway_map.cpp index 9a35eef..f00f03f 100644 --- a/src/subway_map.cpp +++ b/src/subway_map.cpp | |||
@@ -14,8 +14,23 @@ | |||
14 | 14 | ||
15 | constexpr int AREA_ACTUAL_SIZE = 21; | 15 | constexpr int AREA_ACTUAL_SIZE = 21; |
16 | constexpr int OWL_ACTUAL_SIZE = 32; | 16 | constexpr int OWL_ACTUAL_SIZE = 32; |
17 | constexpr int PAINTING_RADIUS = 9; // the actual circles on the map are radius 11 | ||
18 | constexpr int PAINTING_EXIT_RADIUS = 6; | ||
17 | 19 | ||
18 | enum class ItemDrawType { kNone, kBox, kOwl }; | 20 | enum class ItemDrawType { kNone, kBox, kOwl, kOwlExit }; |
21 | |||
22 | namespace { | ||
23 | |||
24 | wxPoint GetSubwayItemMapCenter(const SubwayItem &subway_item) { | ||
25 | if (subway_item.painting) { | ||
26 | return {subway_item.x, subway_item.y}; | ||
27 | } else { | ||
28 | return {subway_item.x + AREA_ACTUAL_SIZE / 2, | ||
29 | subway_item.y + AREA_ACTUAL_SIZE / 2}; | ||
30 | } | ||
31 | } | ||
32 | |||
33 | } // namespace | ||
19 | 34 | ||
20 | SubwayMap::SubwayMap(wxWindow *parent) : wxPanel(parent, wxID_ANY) { | 35 | SubwayMap::SubwayMap(wxWindow *parent) : wxPanel(parent, wxID_ANY) { |
21 | SetBackgroundStyle(wxBG_STYLE_PAINT); | 36 | SetBackgroundStyle(wxBG_STYLE_PAINT); |
@@ -68,11 +83,11 @@ void SubwayMap::OnConnect() { | |||
68 | std::map<std::string, std::vector<int>> exits; | 83 | std::map<std::string, std::vector<int>> exits; |
69 | for (const SubwayItem &subway_item : GD_GetSubwayItems()) { | 84 | for (const SubwayItem &subway_item : GD_GetSubwayItems()) { |
70 | if (AP_HasEarlyColorHallways() && | 85 | if (AP_HasEarlyColorHallways() && |
71 | subway_item.special == "starting_room_paintings") { | 86 | subway_item.special == "early_color_hallways") { |
72 | entrances["early_ch"].push_back(subway_item.id); | 87 | entrances["early_ch"].push_back(subway_item.id); |
73 | } | 88 | } |
74 | 89 | ||
75 | if (AP_IsPaintingShuffle() && !subway_item.paintings.empty()) { | 90 | if (AP_IsPaintingShuffle() && subway_item.painting) { |
76 | continue; | 91 | continue; |
77 | } | 92 | } |
78 | 93 | ||
@@ -319,10 +334,8 @@ void SubwayMap::OnPaint(wxPaintEvent &event) { | |||
319 | const SubwayItem &item1 = GD_GetSubwayItem(node.entry); | 334 | const SubwayItem &item1 = GD_GetSubwayItem(node.entry); |
320 | const SubwayItem &item2 = GD_GetSubwayItem(node.exit); | 335 | const SubwayItem &item2 = GD_GetSubwayItem(node.exit); |
321 | 336 | ||
322 | wxPoint item1_pos = MapPosToRenderPos( | 337 | wxPoint item1_pos = MapPosToRenderPos(GetSubwayItemMapCenter(item1)); |
323 | {item1.x + AREA_ACTUAL_SIZE / 2, item1.y + AREA_ACTUAL_SIZE / 2}); | 338 | wxPoint item2_pos = MapPosToRenderPos(GetSubwayItemMapCenter(item2)); |
324 | wxPoint item2_pos = MapPosToRenderPos( | ||
325 | {item2.x + AREA_ACTUAL_SIZE / 2, item2.y + AREA_ACTUAL_SIZE / 2}); | ||
326 | 339 | ||
327 | int left = std::min(item1_pos.x, item2_pos.x); | 340 | int left = std::min(item1_pos.x, item2_pos.x); |
328 | int top = std::min(item1_pos.y, item2_pos.y); | 341 | int top = std::min(item1_pos.y, item2_pos.y); |
@@ -508,11 +521,12 @@ void SubwayMap::OnClickHelp(wxCommandEvent &event) { | |||
508 | "your mouse. Click again to stop.\nHover over a door to see the " | 521 | "your mouse. Click again to stop.\nHover over a door to see the " |
509 | "requirements to open it.\nHover over a warp or active painting to see " | 522 | "requirements to open it.\nHover over a warp or active painting to see " |
510 | "what it is connected to.\nFor one-way connections, there will be a " | 523 | "what it is connected to.\nFor one-way connections, there will be a " |
511 | "circle at the exit.\nIn painting shuffle, paintings that have not " | 524 | "circle at the exit.\nCircles represent paintings.\nA red circle means " |
512 | "yet been checked will not show their connections.\nA green shaded owl " | 525 | "that the painting is locked by a door.\nA blue circle means painting " |
513 | "means that there is a painting entrance there.\nA red shaded owl means " | 526 | "shuffle is enabled and the painting has not been checked yet.\nA black " |
514 | "that there are only painting exits there.\nClick on a door or " | 527 | "circle means the painting is not a warp.\nA green circle means that the " |
515 | "warp to make the popup stick until you click again.", | 528 | "painting is a warp.\nPainting exits will be indicated with an X.\nClick " |
529 | "on a door or warp to make the popup stick until you click again.", | ||
516 | "Subway Map Help"); | 530 | "Subway Map Help"); |
517 | } | 531 | } |
518 | 532 | ||
@@ -529,20 +543,20 @@ void SubwayMap::Redraw() { | |||
529 | for (const SubwayItem &subway_item : GD_GetSubwayItems()) { | 543 | for (const SubwayItem &subway_item : GD_GetSubwayItems()) { |
530 | ItemDrawType draw_type = ItemDrawType::kNone; | 544 | ItemDrawType draw_type = ItemDrawType::kNone; |
531 | const wxBrush *brush_color = wxGREY_BRUSH; | 545 | const wxBrush *brush_color = wxGREY_BRUSH; |
532 | std::optional<wxColour> shade_color; | ||
533 | std::optional<int> subway_door = GetRealSubwayDoor(subway_item); | 546 | std::optional<int> subway_door = GetRealSubwayDoor(subway_item); |
534 | 547 | ||
535 | if (AP_HasEarlyColorHallways() && | 548 | if (AP_HasEarlyColorHallways() && |
536 | subway_item.special == "starting_room_paintings") { | 549 | subway_item.special == "early_color_hallways") { |
537 | draw_type = ItemDrawType::kOwl; | 550 | draw_type = ItemDrawType::kOwl; |
538 | shade_color = wxColour(0, 255, 0, 128); | 551 | brush_color = wxGREEN_BRUSH; |
552 | } else if (subway_item.special == "starting_room_overhead") { | ||
553 | // Do not draw. | ||
539 | } else if (subway_item.special == "sun_painting") { | 554 | } else if (subway_item.special == "sun_painting") { |
540 | if (!AP_IsPilgrimageEnabled()) { | 555 | if (!AP_IsPilgrimageEnabled()) { |
556 | draw_type = ItemDrawType::kOwl; | ||
541 | if (IsDoorOpen(*subway_item.door)) { | 557 | if (IsDoorOpen(*subway_item.door)) { |
542 | draw_type = ItemDrawType::kOwl; | 558 | brush_color = wxGREEN_BRUSH; |
543 | shade_color = wxColour(0, 255, 0, 128); | ||
544 | } else { | 559 | } else { |
545 | draw_type = ItemDrawType::kBox; | ||
546 | brush_color = wxRED_BRUSH; | 560 | brush_color = wxRED_BRUSH; |
547 | } | 561 | } |
548 | } | 562 | } |
@@ -556,41 +570,28 @@ void SubwayMap::Redraw() { | |||
556 | } else { | 570 | } else { |
557 | brush_color = wxRED_BRUSH; | 571 | brush_color = wxRED_BRUSH; |
558 | } | 572 | } |
559 | } else if (!subway_item.paintings.empty()) { | 573 | } else if (subway_item.painting) { |
560 | if (AP_IsPaintingShuffle()) { | 574 | if (subway_door && !IsDoorOpen(*subway_door)) { |
561 | bool has_checked_painting = false; | 575 | draw_type = ItemDrawType::kOwl; |
562 | bool has_unchecked_painting = false; | 576 | brush_color = wxRED_BRUSH; |
563 | bool has_mapped_painting = false; | 577 | } else if (AP_IsPaintingShuffle()) { |
564 | bool has_codomain_painting = false; | 578 | if (!checked_paintings_.count(*subway_item.painting)) { |
565 | |||
566 | for (const std::string &painting_id : subway_item.paintings) { | ||
567 | if (checked_paintings_.count(painting_id)) { | ||
568 | has_checked_painting = true; | ||
569 | |||
570 | if (painting_mapping.count(painting_id)) { | ||
571 | has_mapped_painting = true; | ||
572 | } else if (AP_IsPaintingMappedTo(painting_id)) { | ||
573 | has_codomain_painting = true; | ||
574 | } | ||
575 | } else { | ||
576 | has_unchecked_painting = true; | ||
577 | } | ||
578 | } | ||
579 | |||
580 | if (has_unchecked_painting || has_mapped_painting || | ||
581 | has_codomain_painting) { | ||
582 | draw_type = ItemDrawType::kOwl; | 579 | draw_type = ItemDrawType::kOwl; |
583 | 580 | brush_color = wxBLUE_BRUSH; | |
584 | if (has_checked_painting) { | 581 | } else if (painting_mapping.count(*subway_item.painting)) { |
585 | if (has_mapped_painting) { | 582 | draw_type = ItemDrawType::kOwl; |
586 | shade_color = wxColour(0, 255, 0, 128); | 583 | brush_color = wxGREEN_BRUSH; |
587 | } else { | 584 | } else if (AP_IsPaintingMappedTo(*subway_item.painting)) { |
588 | shade_color = wxColour(255, 0, 0, 128); | 585 | draw_type = ItemDrawType::kOwlExit; |
589 | } | 586 | brush_color = wxGREEN_BRUSH; |
590 | } | ||
591 | } | 587 | } |
592 | } else if (subway_item.HasWarps()) { | 588 | } else if (subway_item.HasWarps()) { |
593 | draw_type = ItemDrawType::kOwl; | 589 | brush_color = wxGREEN_BRUSH; |
590 | if (!subway_item.exits.empty()) { | ||
591 | draw_type = ItemDrawType::kOwlExit; | ||
592 | } else { | ||
593 | draw_type = ItemDrawType::kOwl; | ||
594 | } | ||
594 | } | 595 | } |
595 | } else if (subway_door) { | 596 | } else if (subway_door) { |
596 | draw_type = ItemDrawType::kBox; | 597 | draw_type = ItemDrawType::kBox; |
@@ -611,14 +612,20 @@ void SubwayMap::Redraw() { | |||
611 | gcdc.SetPen(*wxThePenList->FindOrCreatePen(*wxBLACK, 1)); | 612 | gcdc.SetPen(*wxThePenList->FindOrCreatePen(*wxBLACK, 1)); |
612 | gcdc.SetBrush(*brush_color); | 613 | gcdc.SetBrush(*brush_color); |
613 | gcdc.DrawRectangle(real_area_pos, {real_area_size, real_area_size}); | 614 | gcdc.DrawRectangle(real_area_pos, {real_area_size, real_area_size}); |
614 | } else if (draw_type == ItemDrawType::kOwl) { | 615 | } else if (draw_type == ItemDrawType::kOwl || draw_type == ItemDrawType::kOwlExit) { |
615 | wxBitmap owl_bitmap = wxBitmap(owl_image_.Scale( | 616 | gcdc.SetPen(*wxThePenList->FindOrCreatePen(*wxBLACK, 1)); |
616 | real_area_size, real_area_size, wxIMAGE_QUALITY_BILINEAR)); | 617 | gcdc.SetBrush(*brush_color); |
617 | gcdc.DrawBitmap(owl_bitmap, real_area_pos); | 618 | gcdc.DrawCircle(real_area_pos, PAINTING_RADIUS); |
618 | 619 | ||
619 | if (shade_color) { | 620 | if (draw_type == ItemDrawType::kOwlExit) { |
620 | gcdc.SetBrush(wxBrush(*shade_color)); | 621 | gcdc.DrawLine(subway_item.x - PAINTING_EXIT_RADIUS, |
621 | gcdc.DrawRectangle(real_area_pos, {real_area_size, real_area_size}); | 622 | subway_item.y - PAINTING_EXIT_RADIUS, |
623 | subway_item.x + PAINTING_EXIT_RADIUS, | ||
624 | subway_item.y + PAINTING_EXIT_RADIUS); | ||
625 | gcdc.DrawLine(subway_item.x + PAINTING_EXIT_RADIUS, | ||
626 | subway_item.y - PAINTING_EXIT_RADIUS, | ||
627 | subway_item.x - PAINTING_EXIT_RADIUS, | ||
628 | subway_item.y + PAINTING_EXIT_RADIUS); | ||
622 | } | 629 | } |
623 | } | 630 | } |
624 | } | 631 | } |
@@ -796,6 +803,13 @@ std::optional<int> SubwayMap::GetRealSubwayDoor(const SubwayItem subway_item) { | |||
796 | 803 | ||
797 | quadtree::Box<float> SubwayMap::GetItemBox::operator()(const int &id) const { | 804 | quadtree::Box<float> SubwayMap::GetItemBox::operator()(const int &id) const { |
798 | const SubwayItem &subway_item = GD_GetSubwayItem(id); | 805 | const SubwayItem &subway_item = GD_GetSubwayItem(id); |
799 | return {static_cast<float>(subway_item.x), static_cast<float>(subway_item.y), | 806 | if (subway_item.painting) { |
800 | AREA_ACTUAL_SIZE, AREA_ACTUAL_SIZE}; | 807 | return {static_cast<float>(subway_item.x) - PAINTING_RADIUS, |
808 | static_cast<float>(subway_item.y) - PAINTING_RADIUS, | ||
809 | PAINTING_RADIUS * 2, PAINTING_RADIUS * 2}; | ||
810 | } else { | ||
811 | return {static_cast<float>(subway_item.x), | ||
812 | static_cast<float>(subway_item.y), AREA_ACTUAL_SIZE, | ||
813 | AREA_ACTUAL_SIZE}; | ||
814 | } | ||
801 | } | 815 | } |