about summary refs log tree commit diff stats
path: root/src/ap_state.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ap_state.cpp')
-rw-r--r--src/ap_state.cpp62
1 files changed, 43 insertions, 19 deletions
diff --git a/src/ap_state.cpp b/src/ap_state.cpp index 1e5621d..8ba6633 100644 --- a/src/ap_state.cpp +++ b/src/ap_state.cpp
@@ -10,6 +10,7 @@
10#include <any> 10#include <any>
11#include <apclient.hpp> 11#include <apclient.hpp>
12#include <apuuid.hpp> 12#include <apuuid.hpp>
13#include <bitset>
13#include <chrono> 14#include <chrono>
14#include <exception> 15#include <exception>
15#include <filesystem> 16#include <filesystem>
@@ -37,6 +38,10 @@ constexpr int ITEM_HANDLING = 7; // <- all
37constexpr int CONNECTION_TIMEOUT = 50000; // 50 seconds 38constexpr int CONNECTION_TIMEOUT = 50000; // 50 seconds
38constexpr int CONNECTION_BACKOFF_INTERVAL = 100; 39constexpr int CONNECTION_BACKOFF_INTERVAL = 100;
39 40
41constexpr int PANEL_COUNT = 803;
42constexpr int PANEL_BITFIELD_LENGTH = 48;
43constexpr int PANEL_BITFIELDS = 17;
44
40namespace { 45namespace {
41 46
42const std::set<long> kNonProgressionItems = { 47const std::set<long> kNonProgressionItems = {
@@ -79,6 +84,7 @@ struct APState {
79 std::set<int64_t> checked_locations; 84 std::set<int64_t> checked_locations;
80 std::map<std::string, std::any> data_storage; 85 std::map<std::string, std::any> data_storage;
81 std::optional<std::tuple<int, int>> player_pos; 86 std::optional<std::tuple<int, int>> player_pos;
87 std::bitset<PANEL_COUNT> solved_panels;
82 88
83 DoorShuffleMode door_shuffle_mode = kNO_DOORS; 89 DoorShuffleMode door_shuffle_mode = kNO_DOORS;
84 bool group_doors = false; 90 bool group_doors = false;
@@ -142,6 +148,7 @@ struct APState {
142 checked_locations.clear(); 148 checked_locations.clear();
143 data_storage.clear(); 149 data_storage.clear();
144 player_pos = std::nullopt; 150 player_pos = std::nullopt;
151 solved_panels.reset();
145 victory_data_storage_key.clear(); 152 victory_data_storage_key.clear();
146 door_shuffle_mode = kNO_DOORS; 153 door_shuffle_mode = kNO_DOORS;
147 group_doors = false; 154 group_doors = false;
@@ -216,18 +223,15 @@ struct APState {
216 return checked_locations.count(location_id); 223 return checked_locations.count(location_id);
217 } 224 }
218 225
219 bool HasCheckedHuntPanel(int location_id) {
220 std::lock_guard state_guard(state_mutex);
221
222 std::string key =
223 fmt::format("{}Hunt|{}", data_storage_prefix, location_id);
224 return data_storage.count(key) && std::any_cast<bool>(data_storage.at(key));
225 }
226
227 bool HasItem(int item_id, int quantity) { 226 bool HasItem(int item_id, int quantity) {
228 return inventory.count(item_id) && inventory.at(item_id) >= quantity; 227 return inventory.count(item_id) && inventory.at(item_id) >= quantity;
229 } 228 }
230 229
230 bool HasItemSafe(int item_id, int quantity) {
231 std::lock_guard state_guard(state_mutex);
232 return HasItem(item_id, quantity);
233 }
234
231 bool HasAchievement(const std::string& name) { 235 bool HasAchievement(const std::string& name) {
232 std::lock_guard state_guard(state_mutex); 236 std::lock_guard state_guard(state_mutex);
233 237
@@ -283,6 +287,12 @@ struct APState {
283 30; // CLIENT_GOAL 287 30; // CLIENT_GOAL
284 } 288 }
285 289
290 bool IsPanelSolved(int solve_index) {
291 std::lock_guard state_guard(state_mutex);
292
293 return solved_panels.test(solve_index);
294 }
295
286 private: 296 private:
287 void Initialize() { 297 void Initialize() {
288 if (!initialized) { 298 if (!initialized) {
@@ -295,11 +305,8 @@ struct APState {
295 "Achievement|{}", GD_GetPanel(panel_id).achievement_name)); 305 "Achievement|{}", GD_GetPanel(panel_id).achievement_name));
296 } 306 }
297 307
298 for (const MapArea& map_area : GD_GetMapAreas()) { 308 for (int i = 0; i < PANEL_BITFIELDS; i++) {
299 for (const Location& location : map_area.locations) { 309 tracked_data_storage_keys.push_back(fmt::format("Panels_{}", i));
300 tracked_data_storage_keys.push_back(
301 fmt::format("Hunt|{}", location.ap_location_id));
302 }
303 } 310 }
304 311
305 tracked_data_storage_keys.push_back("PlayerPos"); 312 tracked_data_storage_keys.push_back("PlayerPos");
@@ -605,8 +612,6 @@ struct APState {
605 612
606 if (key.find("Achievement|") != std::string::npos) { 613 if (key.find("Achievement|") != std::string::npos) {
607 state_update.achievements = true; 614 state_update.achievements = true;
608 } else if (key.find("Hunt|") != std::string::npos) {
609 state_update.hunt_panels = true;
610 } 615 }
611 } else if (value.is_number()) { 616 } else if (value.is_number()) {
612 data_storage[key] = value.get<int>(); 617 data_storage[key] = value.get<int>();
@@ -615,6 +620,21 @@ struct APState {
615 620
616 if (key == victory_data_storage_key) { 621 if (key == victory_data_storage_key) {
617 state_update.cleared_locations = true; 622 state_update.cleared_locations = true;
623 } else if (key.find("Panels_") != std::string::npos) {
624 int bitfield_num =
625 std::stoi(key.substr(data_storage_prefix.size() + 7));
626 uint64_t bitfield_value = value.get<uint64_t>();
627 for (int i = 0; i < PANEL_BITFIELD_LENGTH; i++) {
628 if ((bitfield_value & (1LL << i)) != 0) {
629 int solve_index = bitfield_num * PANEL_BITFIELD_LENGTH + i;
630
631 if (!solved_panels.test(solve_index)) {
632 state_update.panels.insert(solve_index);
633 }
634
635 solved_panels.set(solve_index);
636 }
637 }
618 } 638 }
619 } else if (value.is_object()) { 639 } else if (value.is_object()) {
620 if (key.ends_with("PlayerPos")) { 640 if (key.ends_with("PlayerPos")) {
@@ -715,14 +735,14 @@ bool AP_HasCheckedGameLocation(int location_id) {
715 return GetState().HasCheckedGameLocation(location_id); 735 return GetState().HasCheckedGameLocation(location_id);
716} 736}
717 737
718bool AP_HasCheckedHuntPanel(int location_id) {
719 return GetState().HasCheckedHuntPanel(location_id);
720}
721
722bool AP_HasItem(int item_id, int quantity) { 738bool AP_HasItem(int item_id, int quantity) {
723 return GetState().HasItem(item_id, quantity); 739 return GetState().HasItem(item_id, quantity);
724} 740}
725 741
742bool AP_HasItemSafe(int item_id, int quantity) {
743 return GetState().HasItemSafe(item_id, quantity);
744}
745
726std::string AP_GetItemName(int item_id) { 746std::string AP_GetItemName(int item_id) {
727 return GetState().GetItemName(item_id); 747 return GetState().GetItemName(item_id);
728} 748}
@@ -883,3 +903,7 @@ std::optional<std::tuple<int, int>> AP_GetPlayerPosition() {
883 903
884 return GetState().player_pos; 904 return GetState().player_pos;
885} 905}
906
907bool AP_IsPanelSolved(int solve_index) {
908 return GetState().IsPanelSolved(solve_index);
909}