summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGarrett Cox <garrettjcox@gmail.com>2026-02-09 19:44:04 -0600
committerGitHub <noreply@github.com>2026-02-09 19:44:04 -0600
commitf62f5735b90878ad97556e47341b881c9c81f78b (patch)
tree267d5057aed3b760f945276f46d70befe3705ef1
parent889656bf4223313ff38353ebef1b813ec4408d74 (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.cpp54
-rw-r--r--mm/2s2h/Rando/Logic/Logic.h13
-rw-r--r--mm/2s2h/Rando/MiscBehavior/OnFileCreate.cpp1
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);