diff options
| author | Star Rauchenberger <fefferburbia@gmail.com> | 2024-02-28 11:40:26 -0500 |
|---|---|---|
| committer | Star Rauchenberger <fefferburbia@gmail.com> | 2024-02-28 11:40:26 -0500 |
| commit | 2c2d9e9f39ea780b5a04159f9c62fd5540471b86 (patch) | |
| tree | ee77e44a683cdc656196f4a04a643fed72de7ad5 /src/tracker_state.cpp | |
| parent | b2b60f8ade218920dc3eb5304e7abb7dfa9f3a8d (diff) | |
| download | lingo-ap-tracker-2c2d9e9f39ea780b5a04159f9c62fd5540471b86.tar.gz lingo-ap-tracker-2c2d9e9f39ea780b5a04159f9c62fd5540471b86.tar.bz2 lingo-ap-tracker-2c2d9e9f39ea780b5a04159f9c62fd5540471b86.zip | |
Fix pilgrimage detection for vanilla doors
Also add new pilgrimage options.
Diffstat (limited to 'src/tracker_state.cpp')
| -rw-r--r-- | src/tracker_state.cpp | 83 |
1 files changed, 69 insertions, 14 deletions
| diff --git a/src/tracker_state.cpp b/src/tracker_state.cpp index cc941ef..5a99254 100644 --- a/src/tracker_state.cpp +++ b/src/tracker_state.cpp | |||
| @@ -24,9 +24,12 @@ TrackerState& GetState() { | |||
| 24 | return *instance; | 24 | return *instance; |
| 25 | } | 25 | } |
| 26 | 26 | ||
| 27 | class StateCalculator; | ||
| 28 | |||
| 27 | struct StateCalculatorOptions { | 29 | struct StateCalculatorOptions { |
| 28 | std::string start = "Menu"; | 30 | std::string start = "Menu"; |
| 29 | bool pilgrimage = false; | 31 | bool pilgrimage = false; |
| 32 | StateCalculator* parent = nullptr; | ||
| 30 | }; | 33 | }; |
| 31 | 34 | ||
| 32 | class StateCalculator { | 35 | class StateCalculator { |
| @@ -136,15 +139,43 @@ class StateCalculator { | |||
| 136 | 139 | ||
| 137 | const std::set<int>& GetReachableRooms() const { return reachable_rooms_; } | 140 | const std::set<int>& GetReachableRooms() const { return reachable_rooms_; } |
| 138 | 141 | ||
| 142 | const std::map<int, Decision>& GetDoorDecisions() const { return door_decisions_; } | ||
| 143 | |||
| 139 | const std::set<int>& GetSolveablePanels() const { return solveable_panels_; } | 144 | const std::set<int>& GetSolveablePanels() const { return solveable_panels_; } |
| 140 | 145 | ||
| 141 | private: | 146 | private: |
| 142 | Decision IsDoorReachable(int door_id) { | 147 | Decision IsNonGroupedDoorReachable(const Door& door_obj) { |
| 148 | bool has_item = AP_HasItem(door_obj.ap_item_id); | ||
| 149 | |||
| 150 | if (!has_item) { | ||
| 151 | for (const ProgressiveRequirement& prog_req : door_obj.progressives) { | ||
| 152 | if (AP_HasItem(prog_req.ap_item_id, prog_req.quantity)) { | ||
| 153 | has_item = true; | ||
| 154 | break; | ||
| 155 | } | ||
| 156 | } | ||
| 157 | } | ||
| 158 | |||
| 159 | return has_item ? kYes : kNo; | ||
| 160 | } | ||
| 161 | |||
| 162 | Decision IsDoorReachable_Helper(int door_id) { | ||
| 143 | const Door& door_obj = GD_GetDoor(door_id); | 163 | const Door& door_obj = GD_GetDoor(door_id); |
| 144 | 164 | ||
| 145 | if (!AP_IsPilgrimageEnabled() && | 165 | if (!AP_IsPilgrimageEnabled() && door_obj.type == DoorType::kSunPainting) { |
| 146 | door_obj.item_name == "Pilgrim Room - Sun Painting") { | ||
| 147 | return AP_HasItem(door_obj.ap_item_id) ? kYes : kNo; | 166 | return AP_HasItem(door_obj.ap_item_id) ? kYes : kNo; |
| 167 | } else if (door_obj.type == DoorType::kSunwarp) { | ||
| 168 | switch (AP_GetSunwarpAccess()) { | ||
| 169 | case kSUNWARP_ACCESS_NORMAL: | ||
| 170 | return kYes; | ||
| 171 | case kSUNWARP_ACCESS_DISABLED: | ||
| 172 | return kNo; | ||
| 173 | case kSUNWARP_ACCESS_UNLOCK: | ||
| 174 | return AP_HasItem(door_obj.group_ap_item_id) ? kYes : kNo; | ||
| 175 | case kSUNWARP_ACCESS_INDIVIDUAL: | ||
| 176 | case kSUNWARP_ACCESS_PROGRESSIVE: | ||
| 177 | return IsNonGroupedDoorReachable(door_obj); | ||
| 178 | } | ||
| 148 | } else if (AP_GetDoorShuffleMode() == kNO_DOORS || door_obj.skip_item) { | 179 | } else if (AP_GetDoorShuffleMode() == kNO_DOORS || door_obj.skip_item) { |
| 149 | if (!reachable_rooms_.count(door_obj.room)) { | 180 | if (!reachable_rooms_.count(door_obj.room)) { |
| 150 | return kMaybe; | 181 | return kMaybe; |
| @@ -161,19 +192,25 @@ class StateCalculator { | |||
| 161 | !door_obj.group_name.empty()) { | 192 | !door_obj.group_name.empty()) { |
| 162 | return AP_HasItem(door_obj.group_ap_item_id) ? kYes : kNo; | 193 | return AP_HasItem(door_obj.group_ap_item_id) ? kYes : kNo; |
| 163 | } else { | 194 | } else { |
| 164 | bool has_item = AP_HasItem(door_obj.ap_item_id); | 195 | return IsNonGroupedDoorReachable(door_obj); |
| 196 | } | ||
| 197 | } | ||
| 165 | 198 | ||
| 166 | if (!has_item) { | 199 | Decision IsDoorReachable(int door_id) { |
| 167 | for (const ProgressiveRequirement& prog_req : door_obj.progressives) { | 200 | if (options_.parent) { |
| 168 | if (AP_HasItem(prog_req.ap_item_id, prog_req.quantity)) { | 201 | return options_.parent->IsDoorReachable(door_id); |
| 169 | has_item = true; | 202 | } |
| 170 | break; | ||
| 171 | } | ||
| 172 | } | ||
| 173 | } | ||
| 174 | 203 | ||
| 175 | return has_item ? kYes : kNo; | 204 | if (door_decisions_.count(door_id)) { |
| 205 | return door_decisions_.at(door_id); | ||
| 176 | } | 206 | } |
| 207 | |||
| 208 | Decision result = IsDoorReachable_Helper(door_id); | ||
| 209 | if (result != kMaybe) { | ||
| 210 | door_decisions_[door_id] = result; | ||
| 211 | } | ||
| 212 | |||
| 213 | return result; | ||
| 177 | } | 214 | } |
| 178 | 215 | ||
| 179 | Decision IsPanelReachable(int panel_id) { | 216 | Decision IsPanelReachable(int panel_id) { |
| @@ -258,6 +295,15 @@ class StateCalculator { | |||
| 258 | return kNo; | 295 | return kNo; |
| 259 | } | 296 | } |
| 260 | 297 | ||
| 298 | if (AP_GetSunwarpAccess() != kSUNWARP_ACCESS_NORMAL) { | ||
| 299 | for (int door_id : GD_GetSunwarpDoors()) { | ||
| 300 | Decision sub_decision = IsDoorReachable(door_id); | ||
| 301 | if (sub_decision != kYes) { | ||
| 302 | return sub_decision; | ||
| 303 | } | ||
| 304 | } | ||
| 305 | } | ||
| 306 | |||
| 261 | static const std::vector<std::tuple<std::string, std::string>> | 307 | static const std::vector<std::tuple<std::string, std::string>> |
| 262 | pilgrimage_pairs = { | 308 | pilgrimage_pairs = { |
| 263 | {"Crossroads", "Hot Crusts Area"}, | 309 | {"Crossroads", "Hot Crusts Area"}, |
| @@ -268,7 +314,7 @@ class StateCalculator { | |||
| 268 | 314 | ||
| 269 | for (const auto& [from_room, to_room] : pilgrimage_pairs) { | 315 | for (const auto& [from_room, to_room] : pilgrimage_pairs) { |
| 270 | StateCalculator pilgrimage_calculator( | 316 | StateCalculator pilgrimage_calculator( |
| 271 | {.start = from_room, .pilgrimage = true}); | 317 | {.start = from_room, .pilgrimage = true, .parent = this}); |
| 272 | pilgrimage_calculator.Calculate(); | 318 | pilgrimage_calculator.Calculate(); |
| 273 | 319 | ||
| 274 | if (!pilgrimage_calculator.GetReachableRooms().count( | 320 | if (!pilgrimage_calculator.GetReachableRooms().count( |
| @@ -285,6 +331,14 @@ class StateCalculator { | |||
| 285 | room_exit.type == EntranceType::kSunwarp) { | 331 | room_exit.type == EntranceType::kSunwarp) { |
| 286 | return kNo; | 332 | return kNo; |
| 287 | } | 333 | } |
| 334 | if (room_exit.type == EntranceType::kCrossroadsRoofAccess && | ||
| 335 | !AP_DoesPilgrimageAllowRoofAccess()) { | ||
| 336 | return kNo; | ||
| 337 | } | ||
| 338 | if (room_exit.type == EntranceType::kPainting && | ||
| 339 | !AP_DoesPilgrimageAllowPaintings()) { | ||
| 340 | return kNo; | ||
| 341 | } | ||
| 288 | } | 342 | } |
| 289 | 343 | ||
| 290 | if (room_exit.type == EntranceType::kSunwarp) { | 344 | if (room_exit.type == EntranceType::kSunwarp) { |
| @@ -305,6 +359,7 @@ class StateCalculator { | |||
| 305 | StateCalculatorOptions options_; | 359 | StateCalculatorOptions options_; |
| 306 | 360 | ||
| 307 | std::set<int> reachable_rooms_; | 361 | std::set<int> reachable_rooms_; |
| 362 | std::map<int, Decision> door_decisions_; | ||
| 308 | std::set<int> solveable_panels_; | 363 | std::set<int> solveable_panels_; |
| 309 | }; | 364 | }; |
| 310 | 365 | ||
