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 | ||