about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--assets/player.pngbin0 -> 1457 bytes
-rw-r--r--src/ap_state.cpp58
-rw-r--r--src/ap_state.h4
-rw-r--r--src/tracker_panel.cpp32
-rw-r--r--src/tracker_panel.h7
5 files changed, 82 insertions, 19 deletions
diff --git a/assets/player.png b/assets/player.png new file mode 100644 index 0000000..6e0cba4 --- /dev/null +++ b/assets/player.png
Binary files differ
diff --git a/src/ap_state.cpp b/src/ap_state.cpp index 8134cdb..58670e6 100644 --- a/src/ap_state.cpp +++ b/src/ap_state.cpp
@@ -54,6 +54,7 @@ struct APState {
54 std::map<int64_t, int> inventory; 54 std::map<int64_t, int> inventory;
55 std::set<int64_t> checked_locations; 55 std::set<int64_t> checked_locations;
56 std::map<std::string, std::any> data_storage; 56 std::map<std::string, std::any> data_storage;
57 std::optional<std::tuple<int, int>> player_pos;
57 58
58 DoorShuffleMode door_shuffle_mode = kNO_DOORS; 59 DoorShuffleMode door_shuffle_mode = kNO_DOORS;
59 bool color_shuffle = false; 60 bool color_shuffle = false;
@@ -95,6 +96,8 @@ struct APState {
95 } 96 }
96 } 97 }
97 98
99 tracked_data_storage_keys.push_back("PlayerPos");
100
98 initialized = true; 101 initialized = true;
99 } 102 }
100 103
@@ -122,6 +125,7 @@ struct APState {
122 inventory.clear(); 125 inventory.clear();
123 checked_locations.clear(); 126 checked_locations.clear();
124 data_storage.clear(); 127 data_storage.clear();
128 player_pos = std::nullopt;
125 victory_data_storage_key.clear(); 129 victory_data_storage_key.clear();
126 door_shuffle_mode = kNO_DOORS; 130 door_shuffle_mode = kNO_DOORS;
127 color_shuffle = false; 131 color_shuffle = false;
@@ -187,15 +191,7 @@ struct APState {
187 apclient->set_retrieved_handler( 191 apclient->set_retrieved_handler(
188 [this](const std::map<std::string, nlohmann::json>& data) { 192 [this](const std::map<std::string, nlohmann::json>& data) {
189 for (const auto& [key, value] : data) { 193 for (const auto& [key, value] : data) {
190 if (value.is_boolean()) { 194 HandleDataStorage(key, value);
191 data_storage[key] = value.get<bool>();
192 TrackerLog("Data storage " + key + " retrieved as " +
193 (value.get<bool>() ? "true" : "false"));
194 } else if (value.is_number()) {
195 data_storage[key] = value.get<int>();
196 TrackerLog("Data storage " + key + " retrieved as " +
197 std::to_string(value.get<int>()));
198 }
199 } 195 }
200 196
201 RefreshTracker(); 197 RefreshTracker();
@@ -204,16 +200,7 @@ struct APState {
204 apclient->set_set_reply_handler([this](const std::string& key, 200 apclient->set_set_reply_handler([this](const std::string& key,
205 const nlohmann::json& value, 201 const nlohmann::json& value,
206 const nlohmann::json&) { 202 const nlohmann::json&) {
207 if (value.is_boolean()) { 203 HandleDataStorage(key, value);
208 data_storage[key] = value.get<bool>();
209 TrackerLog("Data storage " + key + " retrieved as " +
210 (value.get<bool>() ? "true" : "false"));
211 } else if (value.is_number()) {
212 data_storage[key] = value.get<int>();
213 TrackerLog("Data storage " + key + " retrieved as " +
214 std::to_string(value.get<int>()));
215 }
216
217 RefreshTracker(); 204 RefreshTracker();
218 }); 205 });
219 206
@@ -335,6 +322,35 @@ struct APState {
335 } 322 }
336 } 323 }
337 324
325 void HandleDataStorage(const std::string& key, const nlohmann::json& value) {
326 if (value.is_boolean()) {
327 data_storage[key] = value.get<bool>();
328 TrackerLog("Data storage " + key + " retrieved as " +
329 (value.get<bool>() ? "true" : "false"));
330 } else if (value.is_number()) {
331 data_storage[key] = value.get<int>();
332 TrackerLog("Data storage " + key + " retrieved as " +
333 std::to_string(value.get<int>()));
334 } else if (value.is_object()) {
335 if (key.ends_with("PlayerPos")) {
336 auto map_value = value.get<std::map<std::string, int>>();
337 player_pos = std::tuple<int, int>(map_value["x"], map_value["z"]);
338 } else {
339 data_storage[key] = value.get<std::map<std::string, int>>();
340 }
341
342 TrackerLog("Data storage " + key + " retrieved as dictionary");
343 } else if (value.is_null()) {
344 if (key.ends_with("PlayerPos")) {
345 player_pos = std::nullopt;
346 } else {
347 data_storage.erase(key);
348 }
349
350 TrackerLog("Data storage " + key + " retrieved as null");
351 }
352 }
353
338 bool HasCheckedGameLocation(int location_id) { 354 bool HasCheckedGameLocation(int location_id) {
339 return checked_locations.count(location_id); 355 return checked_locations.count(location_id);
340 } 356 }
@@ -446,3 +462,7 @@ bool AP_HasAchievement(const std::string& achievement_name) {
446bool AP_HasEarlyColorHallways() { return GetState().early_color_hallways; } 462bool AP_HasEarlyColorHallways() { return GetState().early_color_hallways; }
447 463
448bool AP_HasReachedGoal() { return GetState().HasReachedGoal(); } 464bool AP_HasReachedGoal() { return GetState().HasReachedGoal(); }
465
466std::optional<std::tuple<int, int>> AP_GetPlayerPosition() {
467 return GetState().player_pos;
468}
diff --git a/src/ap_state.h b/src/ap_state.h index cc51a78..420a032 100644 --- a/src/ap_state.h +++ b/src/ap_state.h
@@ -2,7 +2,9 @@
2#define AP_STATE_H_664A4180 2#define AP_STATE_H_664A4180
3 3
4#include <map> 4#include <map>
5#include <optional>
5#include <string> 6#include <string>
7#include <tuple>
6 8
7#include "game_data.h" 9#include "game_data.h"
8 10
@@ -46,4 +48,6 @@ bool AP_HasEarlyColorHallways();
46 48
47bool AP_HasReachedGoal(); 49bool AP_HasReachedGoal();
48 50
51std::optional<std::tuple<int, int>> AP_GetPlayerPosition();
52
49#endif /* end of include guard: AP_STATE_H_664A4180 */ 53#endif /* end of include guard: AP_STATE_H_664A4180 */
diff --git a/src/tracker_panel.cpp b/src/tracker_panel.cpp index daaeff7..5f9f8ea 100644 --- a/src/tracker_panel.cpp +++ b/src/tracker_panel.cpp
@@ -10,6 +10,7 @@
10constexpr int AREA_ACTUAL_SIZE = 64; 10constexpr int AREA_ACTUAL_SIZE = 64;
11constexpr int AREA_BORDER_SIZE = 5; 11constexpr int AREA_BORDER_SIZE = 5;
12constexpr int AREA_EFFECTIVE_SIZE = AREA_ACTUAL_SIZE + AREA_BORDER_SIZE * 2; 12constexpr int AREA_EFFECTIVE_SIZE = AREA_ACTUAL_SIZE + AREA_BORDER_SIZE * 2;
13constexpr int PLAYER_SIZE = 96;
13 14
14TrackerPanel::TrackerPanel(wxWindow *parent) : wxPanel(parent, wxID_ANY) { 15TrackerPanel::TrackerPanel(wxWindow *parent) : wxPanel(parent, wxID_ANY) {
15 map_image_ = wxImage(GetAbsolutePath("assets/lingo_map.png").c_str(), 16 map_image_ = wxImage(GetAbsolutePath("assets/lingo_map.png").c_str(),
@@ -18,6 +19,12 @@ TrackerPanel::TrackerPanel(wxWindow *parent) : wxPanel(parent, wxID_ANY) {
18 return; 19 return;
19 } 20 }
20 21
22 player_image_ =
23 wxImage(GetAbsolutePath("assets/player.png").c_str(), wxBITMAP_TYPE_PNG);
24 if (!player_image_.IsOk()) {
25 return;
26 }
27
21 for (const MapArea &map_area : GD_GetMapAreas()) { 28 for (const MapArea &map_area : GD_GetMapAreas()) {
22 AreaIndicator area; 29 AreaIndicator area;
23 area.area_id = map_area.id; 30 area.area_id = map_area.id;
@@ -50,6 +57,20 @@ void TrackerPanel::OnPaint(wxPaintEvent &event) {
50 wxPaintDC dc(this); 57 wxPaintDC dc(this);
51 dc.DrawBitmap(rendered_, 0, 0); 58 dc.DrawBitmap(rendered_, 0, 0);
52 59
60 if (AP_GetPlayerPosition().has_value()) {
61 // 1588, 1194
62 // 14x14 -> 154x154
63 double intended_x =
64 1588.0 + (std::get<0>(*AP_GetPlayerPosition()) * (154.0 / 14.0));
65 double intended_y =
66 1194.0 + (std::get<1>(*AP_GetPlayerPosition()) * (154.0 / 14.0));
67
68 int real_x = offset_x_ + scale_x_ * intended_x - scaled_player_.GetWidth() / 2;
69 int real_y = offset_y_ + scale_y_ * intended_y - scaled_player_.GetHeight() / 2;
70
71 dc.DrawBitmap(scaled_player_, real_x, real_y);
72 }
73
53 event.Skip(); 74 event.Skip();
54} 75}
55 76
@@ -91,6 +112,17 @@ void TrackerPanel::Redraw() {
91 map_image_.Scale(final_width, final_height, wxIMAGE_QUALITY_NORMAL) 112 map_image_.Scale(final_width, final_height, wxIMAGE_QUALITY_NORMAL)
92 .Size(panel_size, {final_x, final_y}, 0, 0, 0)); 113 .Size(panel_size, {final_x, final_y}, 0, 0, 0));
93 114
115 offset_x_ = final_x;
116 offset_y_ = final_y;
117 scale_x_ = static_cast<double>(final_width) / image_size.GetWidth();
118 scale_y_ = static_cast<double>(final_height) / image_size.GetHeight();
119
120 int player_width = PLAYER_SIZE * scale_x_;
121 int player_height = PLAYER_SIZE * scale_y_;
122 scaled_player_ =
123 wxBitmap(player_image_.Scale(player_width > 0 ? player_width : 1,
124 player_height > 0 ? player_height : 1));
125
94 wxMemoryDC dc; 126 wxMemoryDC dc;
95 dc.SelectObject(rendered_); 127 dc.SelectObject(rendered_);
96 128
diff --git a/src/tracker_panel.h b/src/tracker_panel.h index cb4f082..b26d971 100644 --- a/src/tracker_panel.h +++ b/src/tracker_panel.h
@@ -32,7 +32,14 @@ class TrackerPanel : public wxPanel {
32 void Redraw(); 32 void Redraw();
33 33
34 wxImage map_image_; 34 wxImage map_image_;
35 wxImage player_image_;
35 wxBitmap rendered_; 36 wxBitmap rendered_;
37 wxBitmap scaled_player_;
38
39 int offset_x_ = 0;
40 int offset_y_ = 0;
41 double scale_x_ = 0;
42 double scale_y_ = 0;
36 43
37 std::vector<AreaIndicator> areas_; 44 std::vector<AreaIndicator> areas_;
38}; 45};