about summary refs log tree commit diff stats
path: root/src/subway_map.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/subway_map.cpp')
-rw-r--r--src/subway_map.cpp129
1 files changed, 123 insertions, 6 deletions
diff --git a/src/subway_map.cpp b/src/subway_map.cpp index f857270..a03f0d8 100644 --- a/src/subway_map.cpp +++ b/src/subway_map.cpp
@@ -2,6 +2,9 @@
2 2
3#include <wx/dcbuffer.h> 3#include <wx/dcbuffer.h>
4 4
5#include <sstream>
6
7#include "ap_state.h"
5#include "game_data.h" 8#include "game_data.h"
6#include "global.h" 9#include "global.h"
7#include "tracker_state.h" 10#include "tracker_state.h"
@@ -42,10 +45,61 @@ SubwayMap::SubwayMap(wxWindow *parent) : wxPanel(parent, wxID_ANY) {
42 Bind(wxEVT_MOTION, &SubwayMap::OnMouseMove, this); 45 Bind(wxEVT_MOTION, &SubwayMap::OnMouseMove, this);
43} 46}
44 47
48void SubwayMap::OnConnect() {
49 networks_.Clear();
50
51 std::map<std::string, std::vector<int>> tagged;
52 for (const SubwayItem &subway_item : GD_GetSubwayItems()) {
53 if (AP_IsPaintingShuffle() && !subway_item.paintings.empty()) {
54 continue;
55 }
56
57 for (const std::string &tag : subway_item.tags) {
58 tagged[tag].push_back(subway_item.id);
59 }
60
61 if (!AP_IsSunwarpShuffle() && subway_item.sunwarp && subway_item.sunwarp->type != SubwaySunwarpType::kFinal) {
62 std::ostringstream tag;
63 tag << "sunwarp" << subway_item.sunwarp->dots;
64
65 tagged[tag.str()].push_back(subway_item.id);
66 }
67 }
68
69 for (const auto &[tag, items] : tagged) {
70 // Pairwise connect all items with the same tag.
71 for (auto tag_it1 = items.begin(); std::next(tag_it1) != items.end();
72 tag_it1++) {
73 for (auto tag_it2 = std::next(tag_it1); tag_it2 != items.end();
74 tag_it2++) {
75 networks_.AddLink(*tag_it1, *tag_it2);
76 }
77 }
78 }
79
80 checked_paintings_.clear();
81}
82
45void SubwayMap::UpdateIndicators() { 83void SubwayMap::UpdateIndicators() {
46 Redraw(); 84 Redraw();
47} 85}
48 86
87void SubwayMap::UpdatePainting(std::string from_painting_id,
88 std::optional<std::string> to_painting_id) {
89 checked_paintings_.insert(from_painting_id);
90
91 if (to_painting_id) {
92 networks_.AddLink(GD_GetSubwayItemForPainting(from_painting_id),
93 GD_GetSubwayItemForPainting(*to_painting_id));
94 }
95}
96
97void SubwayMap::UpdateSunwarp(SubwaySunwarp from_sunwarp,
98 SubwaySunwarp to_sunwarp) {
99 networks_.AddLink(GD_GetSubwayItemForSunwarp(from_sunwarp),
100 GD_GetSubwayItemForSunwarp(to_sunwarp));
101}
102
49void SubwayMap::OnPaint(wxPaintEvent &event) { 103void SubwayMap::OnPaint(wxPaintEvent &event) {
50 if (GetSize() != rendered_.GetSize()) { 104 if (GetSize() != rendered_.GetSize()) {
51 Redraw(); 105 Redraw();
@@ -54,6 +108,73 @@ void SubwayMap::OnPaint(wxPaintEvent &event) {
54 wxBufferedPaintDC dc(this); 108 wxBufferedPaintDC dc(this);
55 dc.DrawBitmap(rendered_, 0, 0); 109 dc.DrawBitmap(rendered_, 0, 0);
56 110
111 if (hovered_item_ && networks_.IsItemInNetwork(*hovered_item_)) {
112 dc.SetBrush(*wxTRANSPARENT_BRUSH);
113
114 int network_id = networks_.GetNetworkWithItem(*hovered_item_);
115 for (const auto &[item_id1, item_id2] :
116 networks_.GetNetworkGraph(network_id)) {
117 const SubwayItem &item1 = GD_GetSubwayItem(item_id1);
118 const SubwayItem &item2 = GD_GetSubwayItem(item_id2);
119
120 int item1_x = (item1.x + AREA_ACTUAL_SIZE / 2) * render_width_ / map_image_.GetWidth() + render_x_;
121 int item1_y = (item1.y + AREA_ACTUAL_SIZE / 2) * render_width_ / map_image_.GetWidth() + render_y_;
122
123 int item2_x = (item2.x + AREA_ACTUAL_SIZE / 2) * render_width_ / map_image_.GetWidth() + render_x_;
124 int item2_y = (item2.y + AREA_ACTUAL_SIZE / 2) * render_width_ / map_image_.GetWidth() + render_y_;
125
126 int left = std::min(item1_x, item2_x);
127 int top = std::min(item1_y, item2_y);
128 int right = std::max(item1_x, item2_x);
129 int bottom = std::max(item1_y, item2_y);
130
131 int halfwidth = right - left;
132 int halfheight = bottom - top;
133
134 int ellipse_x;
135 int ellipse_y;
136 double start;
137 double end;
138
139 if (item1_x > item2_x) {
140 ellipse_y = top;
141
142 if (item1_y > item2_y) {
143 ellipse_x = left - halfwidth;
144
145 start = 0;
146 end = 90;
147 } else {
148 ellipse_x = left;
149
150 start = 90;
151 end = 180;
152 }
153 } else {
154 ellipse_y = top - halfheight;
155
156 if (item1_y > item2_y) {
157 ellipse_x = left - halfwidth;
158
159 start = 270;
160 end = 360;
161 } else {
162 ellipse_x = left;
163
164 start = 180;
165 end = 270;
166 }
167 }
168
169 dc.SetPen(*wxThePenList->FindOrCreatePen(*wxBLACK, 4));
170 dc.DrawEllipticArc(ellipse_x, ellipse_y, halfwidth * 2, halfheight * 2,
171 start, end);
172 dc.SetPen(*wxThePenList->FindOrCreatePen(*wxCYAN, 2));
173 dc.DrawEllipticArc(ellipse_x, ellipse_y, halfwidth * 2, halfheight * 2,
174 start, end);
175 }
176 }
177
57 event.Skip(); 178 event.Skip();
58} 179}
59 180
@@ -73,13 +194,9 @@ void SubwayMap::OnMouseMove(wxMouseEvent &event) {
73 } 194 }
74 195
75 if (new_hovered_item != hovered_item_) { 196 if (new_hovered_item != hovered_item_) {
76 if (new_hovered_item) {
77 wxLogVerbose("Hovered: %d", *new_hovered_item);
78 } else {
79 wxLogVerbose("Un-hovered: %d", *hovered_item_);
80 }
81
82 hovered_item_ = new_hovered_item; 197 hovered_item_ = new_hovered_item;
198
199 Refresh();
83 } 200 }
84 201
85 event.Skip(); 202 event.Skip();