diff options
| author | Garrett Cox <garrettjcox@gmail.com> | 2026-02-09 19:44:04 -0600 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-02-09 19:44:04 -0600 |
| commit | f62f5735b90878ad97556e47341b881c9c81f78b (patch) | |
| tree | 267d5057aed3b760f945276f46d70befe3705ef1 | |
| parent | 889656bf4223313ff38353ebef1b813ec4408d74 (diff) | |
Time logic tweaks (#1541)
* Time logic tweaks
* Update mm/2s2h/Rando/Logic/Logic.cpp
* Update mm/2s2h/Rando/Logic/Logic.h
| -rw-r--r-- | mm/2s2h/Rando/Logic/Logic.cpp | 54 | ||||
| -rw-r--r-- | mm/2s2h/Rando/Logic/Logic.h | 13 | ||||
| -rw-r--r-- | mm/2s2h/Rando/MiscBehavior/OnFileCreate.cpp | 1 |
3 files changed, 52 insertions, 16 deletions
diff --git a/mm/2s2h/Rando/Logic/Logic.cpp b/mm/2s2h/Rando/Logic/Logic.cpp index b72dde87a..737e1cbcd 100644 --- a/mm/2s2h/Rando/Logic/Logic.cpp +++ b/mm/2s2h/Rando/Logic/Logic.cpp @@ -9,8 +9,7 @@ namespace Logic { std::map<RandoRegionId, RandoRegion> Regions = {}; -// Thread-local storage for current region time during check evaluation -thread_local uint64_t gCurrentRegionTime = 0; +uint64_t gCurrentRegionTime = 0; RandoRegionId GetRegionIdFromEntrance(s32 entrance) { static std::map<s32, RandoRegionId> entranceToRegionId; @@ -104,17 +103,29 @@ void FindReachableRegions(RandoRegionId currentRegion, std::set<RandoRegionId>& sourceTimeState.timeSlices = currentTime; } - // Set global time for check evaluation - gCurrentRegionTime = currentTime; - // Explore connections for (auto& [connectedRegionId, condition] : sourceRegion.connections) { - if (reachableRegions.count(connectedRegionId) == 0 && condition.first()) { - reachableRegions.insert(connectedRegionId); + // Set global time for check evaluation + gCurrentRegionTime = currentTime; + if (condition.first()) { auto& targetRegion = Regions[connectedRegionId]; - regionTimeStates[connectedRegionId] = { .timeSlices = currentTime, - .canStayOverTime = targetRegion.canStayOverTime }; + RegionTimeState incomingState = { .timeSlices = currentTime, + .canStayOverTime = targetRegion.canStayOverTime }; + + auto existingIt = regionTimeStates.find(connectedRegionId); + if (existingIt != regionTimeStates.end()) { + // Region already visited - check if we have new time to add + if (TimeStateCovers(existingIt->second, incomingState)) { + continue; // Skip - existing state already covers incoming + } + // Merge time states for re-exploration + existingIt->second = MergeTimeStates(existingIt->second, incomingState); + } else { + // First visit to this region + reachableRegions.insert(connectedRegionId); + regionTimeStates[connectedRegionId] = incomingState; + } FindReachableRegions(connectedRegionId, reachableRegions, regionTimeStates); } @@ -122,13 +133,28 @@ void FindReachableRegions(RandoRegionId currentRegion, std::set<RandoRegionId>& // Explore exits for (auto& [exitId, regionExit] : sourceRegion.exits) { - RandoRegionId connectedRegionId = GetRegionIdFromEntrance(exitId); - if (reachableRegions.count(connectedRegionId) == 0 && regionExit.condition()) { - reachableRegions.insert(connectedRegionId); + // Set global time for check evaluation + gCurrentRegionTime = currentTime; + RandoRegionId connectedRegionId = GetRegionIdFromEntrance(exitId); + if (regionExit.condition()) { auto& targetRegion = Regions[connectedRegionId]; - regionTimeStates[connectedRegionId] = { .timeSlices = currentTime, - .canStayOverTime = targetRegion.canStayOverTime }; + RegionTimeState incomingState = { .timeSlices = currentTime, + .canStayOverTime = targetRegion.canStayOverTime }; + + auto existingIt = regionTimeStates.find(connectedRegionId); + if (existingIt != regionTimeStates.end()) { + // Region already visited - check if we have new time to add + if (TimeStateCovers(existingIt->second, incomingState)) { + continue; // Skip - existing state already covers incoming + } + // Merge time states for re-exploration + existingIt->second = MergeTimeStates(existingIt->second, incomingState); + } else { + // First visit to this region + reachableRegions.insert(connectedRegionId); + regionTimeStates[connectedRegionId] = incomingState; + } FindReachableRegions(connectedRegionId, reachableRegions, regionTimeStates); } diff --git a/mm/2s2h/Rando/Logic/Logic.h b/mm/2s2h/Rando/Logic/Logic.h index 1093e5341..92df13e64 100644 --- a/mm/2s2h/Rando/Logic/Logic.h +++ b/mm/2s2h/Rando/Logic/Logic.h @@ -100,8 +100,7 @@ struct RegionTimeState { bool canStayOverTime; }; -// Thread-local current region time for check evaluation -extern thread_local uint64_t gCurrentRegionTime; +extern uint64_t gCurrentRegionTime; // Helper: Convert runtime game time to TimeSlice enum TimeSlice TimeSliceFromGameTime(s32 day, u16 time); @@ -502,6 +501,16 @@ inline constexpr uint64_t GetHalfDayTimeMask(int halfDayIndex) { return mask; } +// Merge two time states (bitwise OR on time slices) +inline RegionTimeState MergeTimeStates(const RegionTimeState& a, const RegionTimeState& b) { + return { .timeSlices = a.timeSlices | b.timeSlices, .canStayOverTime = a.canStayOverTime || b.canStayOverTime }; +} + +// Check if 'a' covers 'b' (a is a superset - adding b gives nothing new) +inline bool TimeStateCovers(const RegionTimeState& a, const RegionTimeState& b) { + return (a.timeSlices | b.timeSlices) == a.timeSlices; +} + // ============================================================================ // CLOCK ITEM MACROS // ============================================================================ diff --git a/mm/2s2h/Rando/MiscBehavior/OnFileCreate.cpp b/mm/2s2h/Rando/MiscBehavior/OnFileCreate.cpp index 75785b966..f6f1af194 100644 --- a/mm/2s2h/Rando/MiscBehavior/OnFileCreate.cpp +++ b/mm/2s2h/Rando/MiscBehavior/OnFileCreate.cpp @@ -53,6 +53,7 @@ void Rando::MiscBehavior::OnFileCreate(s16 fileNum) { hadInputSeed = false; } + SPDLOG_INFO("Generating new randomizer with seed: {}", inputSeed); uint32_t finalSeed = Ship_Hash(inputSeed); Ship_Random_Seed(finalSeed); |
