Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 24 additions & 9 deletions S1API/Internal/Patches/GenericSaveables.Patches.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,14 @@ private static void SaveManager_Save_Postfix(string saveFolderPath)
}
}

private static string lastLoadedGameFolderPath = null;
private static bool sameSession = false;

/// <summary>
/// Loads saveables marked with BeforeBaseGame load order BEFORE base game loaders run.
/// This runs as a prefix to LoadManager.QueueLoadRequest on the first LoadRequest creation,
/// which happens right before base game loaders start processing.
/// Uses the LoadedGameFolderPath to detect new load cycles.
/// before base game loaders start processing.
/// Uses an internal sameSession flag to detect new load cycles. sameSession is reset by
/// onLoadComplete so subsequent load cycles can be detected.
/// </summary>
[HarmonyPatch(typeof(S1Persistence.LoadManager), nameof(S1Persistence.LoadManager.QueueLoadRequest))]
[HarmonyPrefix]
Expand All @@ -89,12 +90,9 @@ private static void BeforeBaseLoaders(S1Persistence.LoadRequest request)
if (lm == null || string.IsNullOrEmpty(lm.LoadedGameFolderPath))
return;

// Only run once per load cycle by checking if the folder path has changed
if (lastLoadedGameFolderPath == lm.LoadedGameFolderPath)
return;

lastLoadedGameFolderPath = lm.LoadedGameFolderPath;

// QueueLoadRequest may be called multiple times before loading into a save
// this flag makes sure we only load once - it's cleared by onLoadComplete
if (sameSession) return;
string basePath = Path.Combine(lm.LoadedGameFolderPath, "Modded", "Saveables");

foreach (var saveable in SaveableAutoRegistry.GetRegisteredSaveables())
Expand Down Expand Up @@ -129,6 +127,23 @@ void InitializeOnLoadComplete()
EventHelper.AddListener(InitializeOnLoadComplete, lm.onLoadComplete);
}
}

// Lock subsequent calls to this prefix until load completes to avoid loading multiple times in the same session
sameSession = true;
// Clear the lock once the game is loaded to allow loading again in future sessions without restarting the game
void ClearLockOnLoadComplete()
{
try
{
EventHelper.RemoveListener(ClearLockOnLoadComplete, lm.onLoadComplete);
sameSession = false;
}
catch (Exception e)
{
try { MelonLoader.MelonLogger.Warning($"[Saveables] ClearLockOnLoadComplete failed: {e.Message}\n{e.StackTrace}"); } catch { }
}
}
EventHelper.AddListener(ClearLockOnLoadComplete, lm.onLoadComplete);
}
catch (Exception e)
{
Expand Down
Loading