From 3037b9305b10b58e01055c21bbce223d7b2c673f Mon Sep 17 00:00:00 2001 From: Star Rauchenberger Date: Wed, 3 Apr 2024 14:33:30 -0400 Subject: Added player position tracking --- src/ap_state.cpp | 58 ++++++++++++++++++++++++++++++++++----------------- src/ap_state.h | 4 ++++ src/tracker_panel.cpp | 32 ++++++++++++++++++++++++++++ src/tracker_panel.h | 7 +++++++ 4 files changed, 82 insertions(+), 19 deletions(-) (limited to 'src') 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 { std::map inventory; std::set checked_locations; std::map data_storage; + std::optional> player_pos; DoorShuffleMode door_shuffle_mode = kNO_DOORS; bool color_shuffle = false; @@ -95,6 +96,8 @@ struct APState { } } + tracked_data_storage_keys.push_back("PlayerPos"); + initialized = true; } @@ -122,6 +125,7 @@ struct APState { inventory.clear(); checked_locations.clear(); data_storage.clear(); + player_pos = std::nullopt; victory_data_storage_key.clear(); door_shuffle_mode = kNO_DOORS; color_shuffle = false; @@ -187,15 +191,7 @@ struct APState { apclient->set_retrieved_handler( [this](const std::map& data) { for (const auto& [key, value] : data) { - if (value.is_boolean()) { - data_storage[key] = value.get(); - TrackerLog("Data storage " + key + " retrieved as " + - (value.get() ? "true" : "false")); - } else if (value.is_number()) { - data_storage[key] = value.get(); - TrackerLog("Data storage " + key + " retrieved as " + - std::to_string(value.get())); - } + HandleDataStorage(key, value); } RefreshTracker(); @@ -204,16 +200,7 @@ struct APState { apclient->set_set_reply_handler([this](const std::string& key, const nlohmann::json& value, const nlohmann::json&) { - if (value.is_boolean()) { - data_storage[key] = value.get(); - TrackerLog("Data storage " + key + " retrieved as " + - (value.get() ? "true" : "false")); - } else if (value.is_number()) { - data_storage[key] = value.get(); - TrackerLog("Data storage " + key + " retrieved as " + - std::to_string(value.get())); - } - + HandleDataStorage(key, value); RefreshTracker(); }); @@ -335,6 +322,35 @@ struct APState { } } + void HandleDataStorage(const std::string& key, const nlohmann::json& value) { + if (value.is_boolean()) { + data_storage[key] = value.get(); + TrackerLog("Data storage " + key + " retrieved as " + + (value.get() ? "true" : "false")); + } else if (value.is_number()) { + data_storage[key] = value.get(); + TrackerLog("Data storage " + key + " retrieved as " + + std::to_string(value.get())); + } else if (value.is_object()) { + if (key.ends_with("PlayerPos")) { + auto map_value = value.get>(); + player_pos = std::tuple(map_value["x"], map_value["z"]); + } else { + data_storage[key] = value.get>(); + } + + TrackerLog("Data storage " + key + " retrieved as dictionary"); + } else if (value.is_null()) { + if (key.ends_with("PlayerPos")) { + player_pos = std::nullopt; + } else { + data_storage.erase(key); + } + + TrackerLog("Data storage " + key + " retrieved as null"); + } + } + bool HasCheckedGameLocation(int location_id) { return checked_locations.count(location_id); } @@ -446,3 +462,7 @@ bool AP_HasAchievement(const std::string& achievement_name) { bool AP_HasEarlyColorHallways() { return GetState().early_color_hallways; } bool AP_HasReachedGoal() { return GetState().HasReachedGoal(); } + +std::optional> AP_GetPlayerPosition() { + return GetState().player_pos; +} 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 @@ #define AP_STATE_H_664A4180 #include +#include #include +#include #include "game_data.h" @@ -46,4 +48,6 @@ bool AP_HasEarlyColorHallways(); bool AP_HasReachedGoal(); +std::optional> AP_GetPlayerPosition(); + #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 @@ constexpr int AREA_ACTUAL_SIZE = 64; constexpr int AREA_BORDER_SIZE = 5; constexpr int AREA_EFFECTIVE_SIZE = AREA_ACTUAL_SIZE + AREA_BORDER_SIZE * 2; +constexpr int PLAYER_SIZE = 96; TrackerPanel::TrackerPanel(wxWindow *parent) : wxPanel(parent, wxID_ANY) { map_image_ = wxImage(GetAbsolutePath("assets/lingo_map.png").c_str(), @@ -18,6 +19,12 @@ TrackerPanel::TrackerPanel(wxWindow *parent) : wxPanel(parent, wxID_ANY) { return; } + player_image_ = + wxImage(GetAbsolutePath("assets/player.png").c_str(), wxBITMAP_TYPE_PNG); + if (!player_image_.IsOk()) { + return; + } + for (const MapArea &map_area : GD_GetMapAreas()) { AreaIndicator area; area.area_id = map_area.id; @@ -50,6 +57,20 @@ void TrackerPanel::OnPaint(wxPaintEvent &event) { wxPaintDC dc(this); dc.DrawBitmap(rendered_, 0, 0); + if (AP_GetPlayerPosition().has_value()) { + // 1588, 1194 + // 14x14 -> 154x154 + double intended_x = + 1588.0 + (std::get<0>(*AP_GetPlayerPosition()) * (154.0 / 14.0)); + double intended_y = + 1194.0 + (std::get<1>(*AP_GetPlayerPosition()) * (154.0 / 14.0)); + + int real_x = offset_x_ + scale_x_ * intended_x - scaled_player_.GetWidth() / 2; + int real_y = offset_y_ + scale_y_ * intended_y - scaled_player_.GetHeight() / 2; + + dc.DrawBitmap(scaled_player_, real_x, real_y); + } + event.Skip(); } @@ -91,6 +112,17 @@ void TrackerPanel::Redraw() { map_image_.Scale(final_width, final_height, wxIMAGE_QUALITY_NORMAL) .Size(panel_size, {final_x, final_y}, 0, 0, 0)); + offset_x_ = final_x; + offset_y_ = final_y; + scale_x_ = static_cast(final_width) / image_size.GetWidth(); + scale_y_ = static_cast(final_height) / image_size.GetHeight(); + + int player_width = PLAYER_SIZE * scale_x_; + int player_height = PLAYER_SIZE * scale_y_; + scaled_player_ = + wxBitmap(player_image_.Scale(player_width > 0 ? player_width : 1, + player_height > 0 ? player_height : 1)); + wxMemoryDC dc; dc.SelectObject(rendered_); 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 { void Redraw(); wxImage map_image_; + wxImage player_image_; wxBitmap rendered_; + wxBitmap scaled_player_; + + int offset_x_ = 0; + int offset_y_ = 0; + double scale_x_ = 0; + double scale_y_ = 0; std::vector areas_; }; -- cgit 1.4.1