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 | } |
