From 2c2d9e9f39ea780b5a04159f9c62fd5540471b86 Mon Sep 17 00:00:00 2001 From: Star Rauchenberger Date: Wed, 28 Feb 2024 11:40:26 -0500 Subject: Fix pilgrimage detection for vanilla doors Also add new pilgrimage options. --- src/tracker_state.cpp | 83 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 69 insertions(+), 14 deletions(-) (limited to 'src/tracker_state.cpp') 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() { return *instance; } +class StateCalculator; + struct StateCalculatorOptions { std::string start = "Menu"; bool pilgrimage = false; + StateCalculator* parent = nullptr; }; class StateCalculator { @@ -136,15 +139,43 @@ class StateCalculator { const std::set& GetReachableRooms() const { return reachable_rooms_; } + const std::map& GetDoorDecisions() const { return door_decisions_; } + const std::set& GetSolveablePanels() const { return solveable_panels_; } private: - Decision IsDoorReachable(int door_id) { + Decision IsNonGroupedDoorReachable(const Door& door_obj) { + bool has_item = AP_HasItem(door_obj.ap_item_id); + + if (!has_item) { + for (const ProgressiveRequirement& prog_req : door_obj.progressives) { + if (AP_HasItem(prog_req.ap_item_id, prog_req.quantity)) { + has_item = true; + break; + } + } + } + + return has_item ? kYes : kNo; + } + + Decision IsDoorReachable_Helper(int door_id) { const Door& door_obj = GD_GetDoor(door_id); - if (!AP_IsPilgrimageEnabled() && - door_obj.item_name == "Pilgrim Room - Sun Painting") { + if (!AP_IsPilgrimageEnabled() && door_obj.type == DoorType::kSunPainting) { return AP_HasItem(door_obj.ap_item_id) ? kYes : kNo; + } else if (door_obj.type == DoorType::kSunwarp) { + switch (AP_GetSunwarpAccess()) { + case kSUNWARP_ACCESS_NORMAL: + return kYes; + case kSUNWARP_ACCESS_DISABLED: + return kNo; + case kSUNWARP_ACCESS_UNLOCK: + return AP_HasItem(door_obj.group_ap_item_id) ? kYes : kNo; + case kSUNWARP_ACCESS_INDIVIDUAL: + case kSUNWARP_ACCESS_PROGRESSIVE: + return IsNonGroupedDoorReachable(door_obj); + } } else if (AP_GetDoorShuffleMode() == kNO_DOORS || door_obj.skip_item) { if (!reachable_rooms_.count(door_obj.room)) { return kMaybe; @@ -161,19 +192,25 @@ class StateCalculator { !door_obj.group_name.empty()) { return AP_HasItem(door_obj.group_ap_item_id) ? kYes : kNo; } else { - bool has_item = AP_HasItem(door_obj.ap_item_id); + return IsNonGroupedDoorReachable(door_obj); + } + } - if (!has_item) { - for (const ProgressiveRequirement& prog_req : door_obj.progressives) { - if (AP_HasItem(prog_req.ap_item_id, prog_req.quantity)) { - has_item = true; - break; - } - } - } + Decision IsDoorReachable(int door_id) { + if (options_.parent) { + return options_.parent->IsDoorReachable(door_id); + } - return has_item ? kYes : kNo; + if (door_decisions_.count(door_id)) { + return door_decisions_.at(door_id); } + + Decision result = IsDoorReachable_Helper(door_id); + if (result != kMaybe) { + door_decisions_[door_id] = result; + } + + return result; } Decision IsPanelReachable(int panel_id) { @@ -258,6 +295,15 @@ class StateCalculator { return kNo; } + if (AP_GetSunwarpAccess() != kSUNWARP_ACCESS_NORMAL) { + for (int door_id : GD_GetSunwarpDoors()) { + Decision sub_decision = IsDoorReachable(door_id); + if (sub_decision != kYes) { + return sub_decision; + } + } + } + static const std::vector> pilgrimage_pairs = { {"Crossroads", "Hot Crusts Area"}, @@ -268,7 +314,7 @@ class StateCalculator { for (const auto& [from_room, to_room] : pilgrimage_pairs) { StateCalculator pilgrimage_calculator( - {.start = from_room, .pilgrimage = true}); + {.start = from_room, .pilgrimage = true, .parent = this}); pilgrimage_calculator.Calculate(); if (!pilgrimage_calculator.GetReachableRooms().count( @@ -285,6 +331,14 @@ class StateCalculator { room_exit.type == EntranceType::kSunwarp) { return kNo; } + if (room_exit.type == EntranceType::kCrossroadsRoofAccess && + !AP_DoesPilgrimageAllowRoofAccess()) { + return kNo; + } + if (room_exit.type == EntranceType::kPainting && + !AP_DoesPilgrimageAllowPaintings()) { + return kNo; + } } if (room_exit.type == EntranceType::kSunwarp) { @@ -305,6 +359,7 @@ class StateCalculator { StateCalculatorOptions options_; std::set reachable_rooms_; + std::map door_decisions_; std::set solveable_panels_; }; -- cgit 1.4.1