From bb12ecd88fe16e4009b0d8927c5653d72972e284 Mon Sep 17 00:00:00 2001 From: Star Rauchenberger Date: Sun, 21 May 2023 13:16:25 -0400 Subject: Show list of achievements on the side --- CMakeLists.txt | 1 + src/achievements_pane.cpp | 33 +++++++++++++++++++++++++++++++++ src/achievements_pane.h | 22 ++++++++++++++++++++++ src/ap_state.cpp | 46 ++++++++++++++++++++++++++++++++++++++++++++++ src/ap_state.h | 2 ++ src/game_data.cpp | 7 +++---- src/game_data.h | 1 + src/tracker_frame.cpp | 13 +++++++++++++ src/tracker_frame.h | 2 ++ 9 files changed, 123 insertions(+), 4 deletions(-) create mode 100644 src/achievements_pane.cpp create mode 100644 src/achievements_pane.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 0b68a5f..ac5467d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,6 +39,7 @@ add_executable(lingo_ap_tracker "src/tracker_state.cpp" "src/tracker_config.cpp" "src/logger.cpp" + "src/achievements_pane.cpp" ) set_property(TARGET lingo_ap_tracker PROPERTY CXX_STANDARD 20) set_property(TARGET lingo_ap_tracker PROPERTY CXX_STANDARD_REQUIRED ON) diff --git a/src/achievements_pane.cpp b/src/achievements_pane.cpp new file mode 100644 index 0000000..8ec3727 --- /dev/null +++ b/src/achievements_pane.cpp @@ -0,0 +1,33 @@ +#include "achievements_pane.h" + +#include "ap_state.h" +#include "game_data.h" + +AchievementsPane::AchievementsPane(wxWindow* parent) + : wxListView(parent, wxID_ANY) { + AppendColumn("Achievement"); + + for (int panel_id : GD_GetAchievementPanels()) { + achievement_names_.push_back(GD_GetPanel(panel_id).achievement_name); + } + + std::sort(std::begin(achievement_names_), std::end(achievement_names_)); + + for (int i = 0; i < achievement_names_.size(); i++) { + InsertItem(i, achievement_names_.at(i)); + } + + SetColumnWidth(0, wxLIST_AUTOSIZE); + + UpdateIndicators(); +} + +void AchievementsPane::UpdateIndicators() { + for (int i = 0; i < achievement_names_.size(); i++) { + if (AP_HasAchievement(achievement_names_.at(i))) { + SetItemTextColour(i, *wxBLACK); + } else { + SetItemTextColour(i, *wxRED); + } + } +} diff --git a/src/achievements_pane.h b/src/achievements_pane.h new file mode 100644 index 0000000..ac88cac --- /dev/null +++ b/src/achievements_pane.h @@ -0,0 +1,22 @@ +#ifndef ACHIEVEMENTS_PANE_H_C320D0B8 +#define ACHIEVEMENTS_PANE_H_C320D0B8 + +#include + +#ifndef WX_PRECOMP +#include +#endif + +#include + +class AchievementsPane : public wxListView { + public: + explicit AchievementsPane(wxWindow* parent); + + void UpdateIndicators(); + + private: + std::vector achievement_names_; +}; + +#endif /* end of include guard: ACHIEVEMENTS_PANE_H_C320D0B8 */ \ No newline at end of file diff --git a/src/ap_state.cpp b/src/ap_state.cpp index 8a3aaf9..0f2246b 100644 --- a/src/ap_state.cpp +++ b/src/ap_state.cpp @@ -45,8 +45,11 @@ struct APState { bool connected = false; bool has_connection_result = false; + std::list tracked_data_storage_keys; + std::map inventory; std::set checked_locations; + std::map data_storage; std::map, int64_t> ap_id_by_location_id; std::map ap_id_by_item_name; @@ -78,6 +81,11 @@ struct APState { } }).detach(); + for (int panel_id : GD_GetAchievementPanels()) { + tracked_data_storage_keys.push_back( + "Achievement|" + GD_GetPanel(panel_id).achievement_name); + } + initialized = true; } @@ -104,6 +112,7 @@ struct APState { inventory.clear(); checked_locations.clear(); + data_storage.clear(); door_shuffle_mode = kNO_DOORS; color_shuffle = false; painting_shuffle = false; @@ -162,6 +171,31 @@ struct APState { RefreshTracker(); }); + 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")); + } + } + + RefreshTracker(); + }); + + 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 + " set to " + + (value.get() ? "true" : "false")); + + RefreshTracker(); + } + }); + apclient->set_slot_connected_handler([this]( const nlohmann::json& slot_data) { tracker_frame->SetStatusMessage("Connected to Archipelago!"); @@ -187,6 +221,9 @@ struct APState { has_connection_result = true; RefreshTracker(); + + apclient->Get(tracked_data_storage_keys); + apclient->SetNotify(tracked_data_storage_keys); }); apclient->set_slot_refused_handler( @@ -325,6 +362,11 @@ struct APState { } } + bool HasAchievement(const std::string& name) { + std::string key = "Achievement|" + name; + return data_storage.count(key) && data_storage.at(key); + } + void RefreshTracker() { TrackerLog("Refreshing display..."); @@ -386,3 +428,7 @@ const std::map AP_GetPaintingMapping() { int AP_GetMasteryRequirement() { return GetState().mastery_requirement; } bool AP_IsReduceChecks() { return GetState().reduce_checks; } + +bool AP_HasAchievement(const std::string& achievement_name) { + return GetState().HasAchievement(achievement_name); +} diff --git a/src/ap_state.h b/src/ap_state.h index f0dcadb..a9edd9e 100644 --- a/src/ap_state.h +++ b/src/ap_state.h @@ -32,4 +32,6 @@ int AP_GetMasteryRequirement(); bool AP_IsReduceChecks(); +bool AP_HasAchievement(const std::string& achievement_name); + #endif /* end of include guard: AP_STATE_H_664A4180 */ diff --git a/src/game_data.cpp b/src/game_data.cpp index f21bc3d..351f515 100644 --- a/src/game_data.cpp +++ b/src/game_data.cpp @@ -177,11 +177,10 @@ struct GameData { } if (panel_it.second["achievement"]) { - panel_obj.achievement = panel_it.second["achievement"].as(); + panel_obj.achievement = true; + panel_obj.achievement_name = panel_it.second["achievement"].as(); - if (panel_obj.achievement) { - achievement_panels_.push_back(panel_id); - } + achievement_panels_.push_back(panel_id); } if (panel_it.second["exclude_reduce"]) { diff --git a/src/game_data.h b/src/game_data.h index 7348809..672d8a4 100644 --- a/src/game_data.h +++ b/src/game_data.h @@ -29,6 +29,7 @@ struct Panel { bool check = false; bool exclude_reduce = false; bool achievement = false; + std::string achievement_name; }; struct ProgressiveRequirement { diff --git a/src/tracker_frame.cpp b/src/tracker_frame.cpp index 0308886..49f947f 100644 --- a/src/tracker_frame.cpp +++ b/src/tracker_frame.cpp @@ -1,10 +1,12 @@ #include "tracker_frame.h" +#include #include #include #include +#include "achievements_pane.h" #include "ap_state.h" #include "connection_dialog.h" #include "tracker_config.h" @@ -50,8 +52,18 @@ TrackerFrame::TrackerFrame() Bind(STATE_CHANGED, &TrackerFrame::OnStateChanged, this); Bind(STATUS_CHANGED, &TrackerFrame::OnStatusChanged, this); + wxChoicebook *choicebook = new wxChoicebook(this, wxID_ANY); + achievements_pane_ = new AchievementsPane(this); + choicebook->AddPage(achievements_pane_, "Achievements"); + tracker_panel_ = new TrackerPanel(this); + wxBoxSizer *top_sizer = new wxBoxSizer(wxHORIZONTAL); + top_sizer->Add(choicebook, wxSizerFlags().Expand().Proportion(1)); + top_sizer->Add(tracker_panel_, wxSizerFlags().Expand().Proportion(3)); + + SetSizerAndFit(top_sizer); + if (!GetTrackerConfig().asked_to_check_for_updates) { GetTrackerConfig().asked_to_check_for_updates = true; @@ -113,6 +125,7 @@ void TrackerFrame::OnCheckForUpdates(wxCommandEvent &event) { void TrackerFrame::OnStateChanged(wxCommandEvent &event) { tracker_panel_->UpdateIndicators(); + achievements_pane_->UpdateIndicators(); Refresh(); } diff --git a/src/tracker_frame.h b/src/tracker_frame.h index f3470fd..85cc7c3 100644 --- a/src/tracker_frame.h +++ b/src/tracker_frame.h @@ -7,6 +7,7 @@ #include #endif +class AchievementsPane; class TrackerPanel; wxDECLARE_EVENT(STATE_CHANGED, wxCommandEvent); @@ -32,6 +33,7 @@ class TrackerFrame : public wxFrame { void CheckForUpdates(bool manual); TrackerPanel *tracker_panel_; + AchievementsPane *achievements_pane_; }; #endif /* end of include guard: TRACKER_FRAME_H_86BD8DFB */ -- cgit 1.4.1