diff options
| author | Star Rauchenberger <fefferburbia@gmail.com> | 2023-05-02 21:00:00 -0400 |
|---|---|---|
| committer | Star Rauchenberger <fefferburbia@gmail.com> | 2023-05-02 21:00:00 -0400 |
| commit | 1ec273825497fd6feda19079fa8006096777b11d (patch) | |
| tree | 6b705070cde43de5dbf167f636bd13428e26b3a0 | |
| parent | a3eaefcd38f5f92dc342a2a43d37b6571d2a7a6d (diff) | |
| download | lingo-ap-tracker-1ec273825497fd6feda19079fa8006096777b11d.tar.gz lingo-ap-tracker-1ec273825497fd6feda19079fa8006096777b11d.tar.bz2 lingo-ap-tracker-1ec273825497fd6feda19079fa8006096777b11d.zip | |
Support door shuffle
| -rw-r--r-- | ap_state.cpp | 24 | ||||
| -rw-r--r-- | ap_state.h | 9 | ||||
| -rw-r--r-- | game_data.cpp | 5 | ||||
| -rw-r--r-- | game_data.h | 3 | ||||
| -rw-r--r-- | tracker_state.cpp | 34 |
5 files changed, 47 insertions, 28 deletions
| diff --git a/ap_state.cpp b/ap_state.cpp index 9df487f..910feb7 100644 --- a/ap_state.cpp +++ b/ap_state.cpp | |||
| @@ -17,11 +17,6 @@ constexpr int AP_REVISION = 0; | |||
| 17 | 17 | ||
| 18 | constexpr int ITEM_HANDLING = 7; // <- all | 18 | constexpr int ITEM_HANDLING = 7; // <- all |
| 19 | 19 | ||
| 20 | NLOHMANN_JSON_SERIALIZE_ENUM(DoorShuffleMode, | ||
| 21 | {{DoorShuffleMode::kNone, "none"}, | ||
| 22 | {DoorShuffleMode::kSimple, "simple"}, | ||
| 23 | {DoorShuffleMode::kComplex, "complex"}}); | ||
| 24 | |||
| 25 | APState::APState() { | 20 | APState::APState() { |
| 26 | std::thread([this]() { | 21 | std::thread([this]() { |
| 27 | for (;;) { | 22 | for (;;) { |
| @@ -178,6 +173,17 @@ void APState::Connect(std::string server, std::string player, | |||
| 178 | } | 173 | } |
| 179 | } | 174 | } |
| 180 | 175 | ||
| 176 | for (const Door& door : GetGameData().GetDoors()) { | ||
| 177 | if (!door.skip_item) { | ||
| 178 | ap_id_by_item_name_[door.item_name] = GetItemId(door.item_name); | ||
| 179 | |||
| 180 | if (!door.group_name.empty() && | ||
| 181 | !ap_id_by_item_name_.count(door.group_name)) { | ||
| 182 | ap_id_by_item_name_[door.group_name] = GetItemId(door.group_name); | ||
| 183 | } | ||
| 184 | } | ||
| 185 | } | ||
| 186 | |||
| 181 | ap_id_by_color_[LingoColor::kBlack] = GetItemId("Black"); | 187 | ap_id_by_color_[LingoColor::kBlack] = GetItemId("Black"); |
| 182 | ap_id_by_color_[LingoColor::kRed] = GetItemId("Red"); | 188 | ap_id_by_color_[LingoColor::kRed] = GetItemId("Red"); |
| 183 | ap_id_by_color_[LingoColor::kBlue] = GetItemId("Blue"); | 189 | ap_id_by_color_[LingoColor::kBlue] = GetItemId("Blue"); |
| @@ -212,6 +218,14 @@ bool APState::HasColorItem(LingoColor color) const { | |||
| 212 | } | 218 | } |
| 213 | } | 219 | } |
| 214 | 220 | ||
| 221 | bool APState::HasItem(const std::string& item) const { | ||
| 222 | if (ap_id_by_item_name_.count(item)) { | ||
| 223 | return inventory_.count(ap_id_by_item_name_.at(item)); | ||
| 224 | } else { | ||
| 225 | return false; | ||
| 226 | } | ||
| 227 | } | ||
| 228 | |||
| 215 | void APState::RefreshTracker() { | 229 | void APState::RefreshTracker() { |
| 216 | GetTrackerState().CalculateState(); | 230 | GetTrackerState().CalculateState(); |
| 217 | tracker_frame_->UpdateIndicators(); | 231 | tracker_frame_->UpdateIndicators(); |
| diff --git a/ap_state.h b/ap_state.h index d818b40..d815f93 100644 --- a/ap_state.h +++ b/ap_state.h | |||
| @@ -11,7 +11,7 @@ | |||
| 11 | #include "game_data.h" | 11 | #include "game_data.h" |
| 12 | #include "tracker_frame.h" | 12 | #include "tracker_frame.h" |
| 13 | 13 | ||
| 14 | enum class DoorShuffleMode { kNone, kSimple, kComplex }; | 14 | enum DoorShuffleMode { kNO_DOORS = 0, kSIMPLE_DOORS = 1, kCOMPLEX_DOORS = 2 }; |
| 15 | 15 | ||
| 16 | class APState { | 16 | class APState { |
| 17 | public: | 17 | public: |
| @@ -27,6 +27,8 @@ class APState { | |||
| 27 | 27 | ||
| 28 | bool HasColorItem(LingoColor color) const; | 28 | bool HasColorItem(LingoColor color) const; |
| 29 | 29 | ||
| 30 | bool HasItem(const std::string& item) const; | ||
| 31 | |||
| 30 | DoorShuffleMode GetDoorShuffleMode() const { return door_shuffle_mode_; } | 32 | DoorShuffleMode GetDoorShuffleMode() const { return door_shuffle_mode_; } |
| 31 | 33 | ||
| 32 | bool IsColorShuffle() const { return color_shuffle_; } | 34 | bool IsColorShuffle() const { return color_shuffle_; } |
| @@ -46,11 +48,10 @@ class APState { | |||
| 46 | std::set<int64_t> checked_locations_; | 48 | std::set<int64_t> checked_locations_; |
| 47 | 49 | ||
| 48 | std::map<std::tuple<int, int>, int64_t> ap_id_by_location_id_; | 50 | std::map<std::tuple<int, int>, int64_t> ap_id_by_location_id_; |
| 49 | std::map<int, int64_t> ap_id_by_door_id_; | 51 | std::map<std::string, int64_t> ap_id_by_item_name_; |
| 50 | std::map<int, int64_t> ap_id_by_door_group_id_; | ||
| 51 | std::map<LingoColor, int64_t> ap_id_by_color_; | 52 | std::map<LingoColor, int64_t> ap_id_by_color_; |
| 52 | 53 | ||
| 53 | DoorShuffleMode door_shuffle_mode_ = DoorShuffleMode::kNone; | 54 | DoorShuffleMode door_shuffle_mode_ = kNO_DOORS; |
| 54 | bool color_shuffle_ = false; | 55 | bool color_shuffle_ = false; |
| 55 | }; | 56 | }; |
| 56 | 57 | ||
| diff --git a/game_data.cpp b/game_data.cpp index af5f665..b1504de 100644 --- a/game_data.cpp +++ b/game_data.cpp | |||
| @@ -183,8 +183,13 @@ GameData::GameData() { | |||
| 183 | door_obj.skip_location = door_it.second["skip_location"].as<bool>(); | 183 | door_obj.skip_location = door_it.second["skip_location"].as<bool>(); |
| 184 | } | 184 | } |
| 185 | 185 | ||
| 186 | if (door_it.second["skip_item"]) { | ||
| 187 | door_obj.skip_item = door_it.second["skip_item"].as<bool>(); | ||
| 188 | } | ||
| 189 | |||
| 186 | if (door_it.second["event"]) { | 190 | if (door_it.second["event"]) { |
| 187 | door_obj.skip_location = door_it.second["event"].as<bool>(); | 191 | door_obj.skip_location = door_it.second["event"].as<bool>(); |
| 192 | door_obj.skip_item = door_it.second["event"].as<bool>(); | ||
| 188 | } | 193 | } |
| 189 | 194 | ||
| 190 | if (door_it.second["item_name"]) { | 195 | if (door_it.second["item_name"]) { |
| diff --git a/game_data.h b/game_data.h index ec3e94d..3c50b68 100644 --- a/game_data.h +++ b/game_data.h | |||
| @@ -36,6 +36,7 @@ struct Door { | |||
| 36 | std::string item_name; | 36 | std::string item_name; |
| 37 | std::string group_name; | 37 | std::string group_name; |
| 38 | bool skip_location = false; | 38 | bool skip_location = false; |
| 39 | bool skip_item = false; | ||
| 39 | std::vector<int> panels; | 40 | std::vector<int> panels; |
| 40 | bool exclude_reduce = true; | 41 | bool exclude_reduce = true; |
| 41 | }; | 42 | }; |
| @@ -79,6 +80,8 @@ class GameData { | |||
| 79 | 80 | ||
| 80 | const Room& GetRoom(int room_id) const { return rooms_.at(room_id); } | 81 | const Room& GetRoom(int room_id) const { return rooms_.at(room_id); } |
| 81 | 82 | ||
| 83 | const std::vector<Door>& GetDoors() const { return doors_; } | ||
| 84 | |||
| 82 | const Door& GetDoor(int door_id) const { return doors_.at(door_id); } | 85 | const Door& GetDoor(int door_id) const { return doors_.at(door_id); } |
| 83 | 86 | ||
| 84 | const Panel& GetPanel(int panel_id) const { return panels_.at(panel_id); } | 87 | const Panel& GetPanel(int panel_id) const { return panels_.at(panel_id); } |
| diff --git a/tracker_state.cpp b/tracker_state.cpp index 62e4612..a84dd6e 100644 --- a/tracker_state.cpp +++ b/tracker_state.cpp | |||
| @@ -42,26 +42,23 @@ bool IsPanelReachable_Helper(int panel_id, | |||
| 42 | bool IsDoorReachable_Helper(int door_id, const std::set<int>& reachable_rooms) { | 42 | bool IsDoorReachable_Helper(int door_id, const std::set<int>& reachable_rooms) { |
| 43 | const Door& door_obj = GetGameData().GetDoor(door_id); | 43 | const Door& door_obj = GetGameData().GetDoor(door_id); |
| 44 | 44 | ||
| 45 | switch (GetAPState().GetDoorShuffleMode()) { | 45 | if (GetAPState().GetDoorShuffleMode() == kNO_DOORS || door_obj.skip_item) { |
| 46 | case DoorShuffleMode::kNone: { | 46 | if (!reachable_rooms.count(door_obj.room)) { |
| 47 | if (!reachable_rooms.count(door_obj.room)) { | 47 | return false; |
| 48 | return false; | 48 | } |
| 49 | } | ||
| 50 | 49 | ||
| 51 | for (int panel_id : door_obj.panels) { | 50 | for (int panel_id : door_obj.panels) { |
| 52 | if (!IsPanelReachable_Helper(panel_id, reachable_rooms)) { | 51 | if (!IsPanelReachable_Helper(panel_id, reachable_rooms)) { |
| 53 | return false; | 52 | return false; |
| 54 | } | ||
| 55 | } | 53 | } |
| 56 | |||
| 57 | return true; | ||
| 58 | } | ||
| 59 | case DoorShuffleMode::kSimple: { | ||
| 60 | break; | ||
| 61 | } | ||
| 62 | case DoorShuffleMode::kComplex: { | ||
| 63 | break; | ||
| 64 | } | 54 | } |
| 55 | |||
| 56 | return true; | ||
| 57 | } else if (GetAPState().GetDoorShuffleMode() == kSIMPLE_DOORS && | ||
| 58 | !door_obj.group_name.empty()) { | ||
| 59 | return GetAPState().HasItem(door_obj.group_name); | ||
| 60 | } else { | ||
| 61 | return GetAPState().HasItem(door_obj.item_name); | ||
| 65 | } | 62 | } |
| 66 | } | 63 | } |
| 67 | 64 | ||
| @@ -88,8 +85,7 @@ void TrackerState::CalculateState() { | |||
| 88 | if (room_exit.door.has_value()) { | 85 | if (room_exit.door.has_value()) { |
| 89 | if (IsDoorReachable_Helper(*room_exit.door, reachable_rooms)) { | 86 | if (IsDoorReachable_Helper(*room_exit.door, reachable_rooms)) { |
| 90 | valid_transition = true; | 87 | valid_transition = true; |
| 91 | } else if (GetAPState().GetDoorShuffleMode() == | 88 | } else if (GetAPState().GetDoorShuffleMode() == kNO_DOORS) { |
| 92 | DoorShuffleMode::kNone) { | ||
| 93 | new_boundary.push_back(room_exit); | 89 | new_boundary.push_back(room_exit); |
| 94 | } | 90 | } |
| 95 | } else { | 91 | } else { |
