about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorStar Rauchenberger <fefferburbia@gmail.com>2025-03-11 17:19:54 -0400
committerStar Rauchenberger <fefferburbia@gmail.com>2025-03-11 17:19:54 -0400
commit8ad881fed6e388f7a254350532ce58552ef47a1d (patch)
tree0d4b20f6bcc7c5cbdad1cfe46b8ff3ea16ef85a2 /src
parent788c637adc08175533ef0ea54e76688679910cf3 (diff)
downloadlingo-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.cpp11
-rw-r--r--src/game_data.h2
-rw-r--r--src/subway_map.cpp134
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
15constexpr int AREA_ACTUAL_SIZE = 21; 15constexpr int AREA_ACTUAL_SIZE = 21;
16constexpr int OWL_ACTUAL_SIZE = 32; 16constexpr int OWL_ACTUAL_SIZE = 32;
17constexpr int PAINTING_RADIUS = 9; // the actual circles on the map are radius 11
18constexpr int PAINTING_EXIT_RADIUS = 6;
17 19
18enum class ItemDrawType { kNone, kBox, kOwl }; 20enum class ItemDrawType { kNone, kBox, kOwl, kOwlExit };
21
22namespace {
23
24wxPoint 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
20SubwayMap::SubwayMap(wxWindow *parent) : wxPanel(parent, wxID_ANY) { 35SubwayMap::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
797quadtree::Box<float> SubwayMap::GetItemBox::operator()(const int &id) const { 804quadtree::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}