diff options
Diffstat (limited to 'src/tracker_panel.cpp')
| -rw-r--r-- | src/tracker_panel.cpp | 185 |
1 files changed, 130 insertions, 55 deletions
| diff --git a/src/tracker_panel.cpp b/src/tracker_panel.cpp index 66bce81..ddb4df9 100644 --- a/src/tracker_panel.cpp +++ b/src/tracker_panel.cpp | |||
| @@ -1,11 +1,15 @@ | |||
| 1 | #include "tracker_panel.h" | 1 | #include "tracker_panel.h" |
| 2 | 2 | ||
| 3 | #include <fmt/core.h> | ||
| 3 | #include <wx/dcbuffer.h> | 4 | #include <wx/dcbuffer.h> |
| 4 | 5 | ||
| 6 | #include <algorithm> | ||
| 7 | |||
| 5 | #include "ap_state.h" | 8 | #include "ap_state.h" |
| 6 | #include "area_popup.h" | 9 | #include "area_popup.h" |
| 7 | #include "game_data.h" | 10 | #include "game_data.h" |
| 8 | #include "global.h" | 11 | #include "global.h" |
| 12 | #include "ipc_state.h" | ||
| 9 | #include "tracker_config.h" | 13 | #include "tracker_config.h" |
| 10 | #include "tracker_state.h" | 14 | #include "tracker_state.h" |
| 11 | 15 | ||
| @@ -39,15 +43,38 @@ TrackerPanel::TrackerPanel(wxWindow *parent) : wxPanel(parent, wxID_ANY) { | |||
| 39 | areas_.push_back(area); | 43 | areas_.push_back(area); |
| 40 | } | 44 | } |
| 41 | 45 | ||
| 46 | Resize(); | ||
| 42 | Redraw(); | 47 | Redraw(); |
| 43 | 48 | ||
| 44 | Bind(wxEVT_PAINT, &TrackerPanel::OnPaint, this); | 49 | Bind(wxEVT_PAINT, &TrackerPanel::OnPaint, this); |
| 45 | Bind(wxEVT_MOTION, &TrackerPanel::OnMouseMove, this); | 50 | Bind(wxEVT_MOTION, &TrackerPanel::OnMouseMove, this); |
| 46 | } | 51 | } |
| 47 | 52 | ||
| 48 | void TrackerPanel::UpdateIndicators() { | 53 | void TrackerPanel::UpdateIndicators(bool reset) { |
| 49 | for (AreaIndicator &area : areas_) { | 54 | if (reset) { |
| 50 | area.popup->UpdateIndicators(); | 55 | for (AreaIndicator &area : areas_) { |
| 56 | const MapArea &map_area = GD_GetMapArea(area.area_id); | ||
| 57 | |||
| 58 | if ((!AP_IsLocationVisible(map_area.classification) || | ||
| 59 | IsAreaPostgame(area.area_id)) && | ||
| 60 | !(map_area.hunt && | ||
| 61 | GetTrackerConfig().visible_panels == TrackerConfig::kHUNT_PANELS) && | ||
| 62 | !(map_area.has_single_panel && | ||
| 63 | GetTrackerConfig().visible_panels == TrackerConfig::kALL_PANELS) && | ||
| 64 | !(AP_IsPaintingShuffle() && !map_area.paintings.empty())) { | ||
| 65 | area.active = false; | ||
| 66 | } else { | ||
| 67 | area.active = true; | ||
| 68 | } | ||
| 69 | |||
| 70 | area.popup->ResetIndicators(); | ||
| 71 | } | ||
| 72 | |||
| 73 | Resize(); | ||
| 74 | } else { | ||
| 75 | for (AreaIndicator &area : areas_) { | ||
| 76 | area.popup->UpdateIndicators(); | ||
| 77 | } | ||
| 51 | } | 78 | } |
| 52 | 79 | ||
| 53 | Redraw(); | 80 | Redraw(); |
| @@ -55,22 +82,35 @@ void TrackerPanel::UpdateIndicators() { | |||
| 55 | 82 | ||
| 56 | void TrackerPanel::OnPaint(wxPaintEvent &event) { | 83 | void TrackerPanel::OnPaint(wxPaintEvent &event) { |
| 57 | if (GetSize() != rendered_.GetSize()) { | 84 | if (GetSize() != rendered_.GetSize()) { |
| 85 | Resize(); | ||
| 58 | Redraw(); | 86 | Redraw(); |
| 59 | } | 87 | } |
| 60 | 88 | ||
| 61 | wxBufferedPaintDC dc(this); | 89 | wxBufferedPaintDC dc(this); |
| 62 | dc.DrawBitmap(rendered_, 0, 0); | 90 | dc.DrawBitmap(rendered_, 0, 0); |
| 63 | 91 | ||
| 64 | if (AP_GetPlayerPosition().has_value()) { | 92 | std::optional<std::tuple<int, int>> player_position; |
| 93 | if (GetTrackerConfig().track_position) | ||
| 94 | { | ||
| 95 | if (IPC_IsConnected()) { | ||
| 96 | player_position = IPC_GetPlayerPosition(); | ||
| 97 | } else { | ||
| 98 | player_position = AP_GetPlayerPosition(); | ||
| 99 | } | ||
| 100 | } | ||
| 101 | |||
| 102 | if (player_position.has_value()) { | ||
| 65 | // 1588, 1194 | 103 | // 1588, 1194 |
| 66 | // 14x14 -> 154x154 | 104 | // 14x14 -> 154x154 |
| 67 | double intended_x = | 105 | double intended_x = |
| 68 | 1588.0 + (std::get<0>(*AP_GetPlayerPosition()) * (154.0 / 14.0)); | 106 | 1588.0 + (std::get<0>(*player_position) * (154.0 / 14.0)); |
| 69 | double intended_y = | 107 | double intended_y = |
| 70 | 1194.0 + (std::get<1>(*AP_GetPlayerPosition()) * (154.0 / 14.0)); | 108 | 1194.0 + (std::get<1>(*player_position) * (154.0 / 14.0)); |
| 71 | 109 | ||
| 72 | int real_x = offset_x_ + scale_x_ * intended_x - scaled_player_.GetWidth() / 2; | 110 | int real_x = |
| 73 | int real_y = offset_y_ + scale_y_ * intended_y - scaled_player_.GetHeight() / 2; | 111 | offset_x_ + scale_x_ * intended_x - scaled_player_.GetWidth() / 2; |
| 112 | int real_y = | ||
| 113 | offset_y_ + scale_y_ * intended_y - scaled_player_.GetHeight() / 2; | ||
| 74 | 114 | ||
| 75 | dc.DrawBitmap(scaled_player_, real_x, real_y); | 115 | dc.DrawBitmap(scaled_player_, real_x, real_y); |
| 76 | } | 116 | } |
| @@ -92,8 +132,8 @@ void TrackerPanel::OnMouseMove(wxMouseEvent &event) { | |||
| 92 | event.Skip(); | 132 | event.Skip(); |
| 93 | } | 133 | } |
| 94 | 134 | ||
| 95 | void TrackerPanel::Redraw() { | 135 | void TrackerPanel::Resize() { |
| 96 | wxSize panel_size = GetSize(); | 136 | wxSize panel_size = GetClientSize(); |
| 97 | wxSize image_size = map_image_.GetSize(); | 137 | wxSize image_size = map_image_.GetSize(); |
| 98 | 138 | ||
| 99 | int final_x = 0; | 139 | int final_x = 0; |
| @@ -112,7 +152,7 @@ void TrackerPanel::Redraw() { | |||
| 112 | final_x = (panel_size.GetWidth() - final_width) / 2; | 152 | final_x = (panel_size.GetWidth() - final_width) / 2; |
| 113 | } | 153 | } |
| 114 | 154 | ||
| 115 | rendered_ = wxBitmap( | 155 | scaled_map_ = wxBitmap( |
| 116 | map_image_.Scale(final_width, final_height, wxIMAGE_QUALITY_NORMAL) | 156 | map_image_.Scale(final_width, final_height, wxIMAGE_QUALITY_NORMAL) |
| 117 | .Size(panel_size, {final_x, final_y}, 0, 0, 0)); | 157 | .Size(panel_size, {final_x, final_y}, 0, 0, 0)); |
| 118 | 158 | ||
| @@ -127,27 +167,64 @@ void TrackerPanel::Redraw() { | |||
| 127 | wxBitmap(player_image_.Scale(player_width > 0 ? player_width : 1, | 167 | wxBitmap(player_image_.Scale(player_width > 0 ? player_width : 1, |
| 128 | player_height > 0 ? player_height : 1)); | 168 | player_height > 0 ? player_height : 1)); |
| 129 | 169 | ||
| 170 | real_area_size_ = final_width * AREA_EFFECTIVE_SIZE / image_size.GetWidth(); | ||
| 171 | |||
| 172 | for (AreaIndicator &area : areas_) { | ||
| 173 | const MapArea &map_area = GD_GetMapArea(area.area_id); | ||
| 174 | |||
| 175 | int real_area_x = final_x + (map_area.map_x - (AREA_EFFECTIVE_SIZE / 2)) * | ||
| 176 | final_width / image_size.GetWidth(); | ||
| 177 | int real_area_y = final_y + (map_area.map_y - (AREA_EFFECTIVE_SIZE / 2)) * | ||
| 178 | final_width / image_size.GetWidth(); | ||
| 179 | |||
| 180 | area.real_x1 = real_area_x; | ||
| 181 | area.real_x2 = real_area_x + real_area_size_; | ||
| 182 | area.real_y1 = real_area_y; | ||
| 183 | area.real_y2 = real_area_y + real_area_size_; | ||
| 184 | |||
| 185 | int popup_x = | ||
| 186 | final_x + map_area.map_x * final_width / image_size.GetWidth(); | ||
| 187 | int popup_y = | ||
| 188 | final_y + map_area.map_y * final_width / image_size.GetWidth(); | ||
| 189 | |||
| 190 | area.popup->SetClientSize( | ||
| 191 | area.popup->GetFullWidth(), | ||
| 192 | std::min(panel_size.GetHeight(), area.popup->GetFullHeight())); | ||
| 193 | |||
| 194 | if (area.popup->GetSize().GetHeight() > panel_size.GetHeight()) { | ||
| 195 | area.popup->SetSize(area.popup->GetSize().GetWidth(), | ||
| 196 | panel_size.GetHeight()); | ||
| 197 | } | ||
| 198 | |||
| 199 | if (popup_x + area.popup->GetSize().GetWidth() > panel_size.GetWidth()) { | ||
| 200 | popup_x = panel_size.GetWidth() - area.popup->GetSize().GetWidth(); | ||
| 201 | } | ||
| 202 | if (popup_y + area.popup->GetSize().GetHeight() > panel_size.GetHeight()) { | ||
| 203 | popup_y = panel_size.GetHeight() - area.popup->GetSize().GetHeight(); | ||
| 204 | } | ||
| 205 | area.popup->SetPosition({popup_x, popup_y}); | ||
| 206 | } | ||
| 207 | } | ||
| 208 | |||
| 209 | void TrackerPanel::Redraw() { | ||
| 210 | rendered_ = scaled_map_; | ||
| 211 | |||
| 130 | wxMemoryDC dc; | 212 | wxMemoryDC dc; |
| 131 | dc.SelectObject(rendered_); | 213 | dc.SelectObject(rendered_); |
| 132 | 214 | ||
| 133 | int real_area_size = | ||
| 134 | final_width * AREA_EFFECTIVE_SIZE / image_size.GetWidth(); | ||
| 135 | int actual_border_size = | 215 | int actual_border_size = |
| 136 | real_area_size * AREA_BORDER_SIZE / AREA_EFFECTIVE_SIZE; | 216 | real_area_size_ * AREA_BORDER_SIZE / AREA_EFFECTIVE_SIZE; |
| 137 | const wxPoint upper_left_triangle[] = { | 217 | const wxPoint upper_left_triangle[] = { |
| 138 | {0, 0}, {0, real_area_size}, {real_area_size, 0}}; | 218 | {0, 0}, {0, real_area_size_}, {real_area_size_, 0}}; |
| 139 | const wxPoint lower_right_triangle[] = {{0, real_area_size - 1}, | 219 | const wxPoint lower_right_triangle[] = {{0, real_area_size_ - 1}, |
| 140 | {real_area_size - 1, 0}, | 220 | {real_area_size_ - 1, 0}, |
| 141 | {real_area_size, real_area_size}}; | 221 | {real_area_size_, real_area_size_}}; |
| 142 | 222 | ||
| 143 | for (AreaIndicator &area : areas_) { | 223 | for (AreaIndicator &area : areas_) { |
| 144 | const MapArea &map_area = GD_GetMapArea(area.area_id); | 224 | const MapArea &map_area = GD_GetMapArea(area.area_id); |
| 145 | if (!AP_IsLocationVisible(map_area.classification) && | 225 | |
| 146 | !(map_area.hunt && GetTrackerConfig().show_hunt_panels)) { | 226 | if (!area.active) { |
| 147 | area.active = false; | ||
| 148 | continue; | 227 | continue; |
| 149 | } else { | ||
| 150 | area.active = true; | ||
| 151 | } | 228 | } |
| 152 | 229 | ||
| 153 | bool has_reachable_unchecked = false; | 230 | bool has_reachable_unchecked = false; |
| @@ -156,10 +233,15 @@ void TrackerPanel::Redraw() { | |||
| 156 | bool has_unchecked = false; | 233 | bool has_unchecked = false; |
| 157 | if (IsLocationWinCondition(section)) { | 234 | if (IsLocationWinCondition(section)) { |
| 158 | has_unchecked = !AP_HasReachedGoal(); | 235 | has_unchecked = !AP_HasReachedGoal(); |
| 159 | } else if (AP_IsLocationVisible(section.classification)) { | 236 | } else if (AP_IsLocationVisible(section.classification) && |
| 237 | !IsLocationPostgame(section.ap_location_id)) { | ||
| 160 | has_unchecked = !AP_HasCheckedGameLocation(section.ap_location_id); | 238 | has_unchecked = !AP_HasCheckedGameLocation(section.ap_location_id); |
| 161 | } else if (section.hunt && GetTrackerConfig().show_hunt_panels) { | 239 | } else if ((section.hunt && GetTrackerConfig().visible_panels == |
| 162 | has_unchecked = !AP_HasCheckedHuntPanel(section.ap_location_id); | 240 | TrackerConfig::kHUNT_PANELS) || |
| 241 | (section.single_panel && GetTrackerConfig().visible_panels == | ||
| 242 | TrackerConfig::kALL_PANELS)) { | ||
| 243 | has_unchecked = | ||
| 244 | !AP_IsPanelSolved(GD_GetPanel(*section.single_panel).solve_index); | ||
| 163 | } | 245 | } |
| 164 | 246 | ||
| 165 | if (has_unchecked) { | 247 | if (has_unchecked) { |
| @@ -171,10 +253,26 @@ void TrackerPanel::Redraw() { | |||
| 171 | } | 253 | } |
| 172 | } | 254 | } |
| 173 | 255 | ||
| 174 | int real_area_x = final_x + (map_area.map_x - (AREA_EFFECTIVE_SIZE / 2)) * | 256 | if (AP_IsPaintingShuffle()) { |
| 175 | final_width / image_size.GetWidth(); | 257 | for (int painting_id : map_area.paintings) { |
| 176 | int real_area_y = final_y + (map_area.map_y - (AREA_EFFECTIVE_SIZE / 2)) * | 258 | if (IsPaintingPostgame(painting_id)) { |
| 177 | final_width / image_size.GetWidth(); | 259 | continue; |
| 260 | } | ||
| 261 | |||
| 262 | const PaintingExit &painting = GD_GetPaintingExit(painting_id); | ||
| 263 | bool reachable = IsPaintingReachable(painting_id); | ||
| 264 | if (!reachable || !AP_IsPaintingChecked(painting.internal_id)) { | ||
| 265 | if (reachable) { | ||
| 266 | has_reachable_unchecked = true; | ||
| 267 | } else { | ||
| 268 | has_unreachable_unchecked = true; | ||
| 269 | } | ||
| 270 | } | ||
| 271 | } | ||
| 272 | } | ||
| 273 | |||
| 274 | int real_area_x = area.real_x1; | ||
| 275 | int real_area_y = area.real_y1; | ||
| 178 | 276 | ||
| 179 | if (has_reachable_unchecked && has_unreachable_unchecked && | 277 | if (has_reachable_unchecked && has_unreachable_unchecked && |
| 180 | GetTrackerConfig().hybrid_areas) { | 278 | GetTrackerConfig().hybrid_areas) { |
| @@ -188,7 +286,7 @@ void TrackerPanel::Redraw() { | |||
| 188 | dc.SetPen(*wxThePenList->FindOrCreatePen(*wxBLACK, actual_border_size)); | 286 | dc.SetPen(*wxThePenList->FindOrCreatePen(*wxBLACK, actual_border_size)); |
| 189 | dc.SetBrush(*wxTRANSPARENT_BRUSH); | 287 | dc.SetBrush(*wxTRANSPARENT_BRUSH); |
| 190 | dc.DrawRectangle({real_area_x, real_area_y}, | 288 | dc.DrawRectangle({real_area_x, real_area_y}, |
| 191 | {real_area_size, real_area_size}); | 289 | {real_area_size_, real_area_size_}); |
| 192 | 290 | ||
| 193 | } else { | 291 | } else { |
| 194 | const wxBrush *brush_color = wxGREY_BRUSH; | 292 | const wxBrush *brush_color = wxGREY_BRUSH; |
| @@ -203,30 +301,7 @@ void TrackerPanel::Redraw() { | |||
| 203 | dc.SetPen(*wxThePenList->FindOrCreatePen(*wxBLACK, actual_border_size)); | 301 | dc.SetPen(*wxThePenList->FindOrCreatePen(*wxBLACK, actual_border_size)); |
| 204 | dc.SetBrush(*brush_color); | 302 | dc.SetBrush(*brush_color); |
| 205 | dc.DrawRectangle({real_area_x, real_area_y}, | 303 | dc.DrawRectangle({real_area_x, real_area_y}, |
| 206 | {real_area_size, real_area_size}); | 304 | {real_area_size_, real_area_size_}); |
| 207 | } | 305 | } |
| 208 | |||
| 209 | area.real_x1 = real_area_x; | ||
| 210 | area.real_x2 = real_area_x + real_area_size; | ||
| 211 | area.real_y1 = real_area_y; | ||
| 212 | area.real_y2 = real_area_y + real_area_size; | ||
| 213 | |||
| 214 | int popup_x = | ||
| 215 | final_x + map_area.map_x * final_width / image_size.GetWidth(); | ||
| 216 | int popup_y = | ||
| 217 | final_y + map_area.map_y * final_width / image_size.GetWidth(); | ||
| 218 | |||
| 219 | area.popup->SetClientSize( | ||
| 220 | area.popup->GetVirtualSize().GetWidth(), | ||
| 221 | std::min(panel_size.GetHeight(), | ||
| 222 | area.popup->GetVirtualSize().GetHeight())); | ||
| 223 | |||
| 224 | if (popup_x + area.popup->GetSize().GetWidth() > panel_size.GetWidth()) { | ||
| 225 | popup_x = panel_size.GetWidth() - area.popup->GetSize().GetWidth(); | ||
| 226 | } | ||
| 227 | if (popup_y + area.popup->GetSize().GetHeight() > panel_size.GetHeight()) { | ||
| 228 | popup_y = panel_size.GetHeight() - area.popup->GetSize().GetHeight(); | ||
| 229 | } | ||
| 230 | area.popup->SetPosition({popup_x, popup_y}); | ||
| 231 | } | 306 | } |
| 232 | } | 307 | } |
