diff options
Diffstat (limited to 'src/subway_map.cpp')
-rw-r--r-- | src/subway_map.cpp | 129 |
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 | ||
48 | void 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 | |||
45 | void SubwayMap::UpdateIndicators() { | 83 | void SubwayMap::UpdateIndicators() { |
46 | Redraw(); | 84 | Redraw(); |
47 | } | 85 | } |
48 | 86 | ||
87 | void 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 | |||
97 | void SubwayMap::UpdateSunwarp(SubwaySunwarp from_sunwarp, | ||
98 | SubwaySunwarp to_sunwarp) { | ||
99 | networks_.AddLink(GD_GetSubwayItemForSunwarp(from_sunwarp), | ||
100 | GD_GetSubwayItemForSunwarp(to_sunwarp)); | ||
101 | } | ||
102 | |||
49 | void SubwayMap::OnPaint(wxPaintEvent &event) { | 103 | void 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(); |