Minor reset fixes

This commit is contained in:
Michal Pikulski
2025-11-05 20:36:13 +01:00
committed by Michal Pikulski
parent 717deee0cd
commit 0204c11560
4 changed files with 69 additions and 10 deletions

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
@@ -242,6 +242,35 @@ namespace Core.SaveLoad
return currentSaveData.unlockedMinigames.AsReadOnly();
}
/// <summary>
/// Clears all save data for a specific level/scene.
/// Removes all participant states that belong to the specified scene.
/// Useful for "restart level" functionality to wipe progress.
/// </summary>
/// <param name="sceneName">The name of the scene to clear data for</param>
public void ClearLevelData(string sceneName)
{
if (string.IsNullOrEmpty(sceneName))
{
Logging.Warning("[SaveLoadManager] Cannot clear level data - scene name is null or empty");
return;
}
if (currentSaveData == null || currentSaveData.participantStates == null)
{
Logging.Warning("[SaveLoadManager] Cannot clear level data - no save data loaded");
return;
}
// SaveId format is "SceneName/ObjectName/ComponentType"
// Remove all entries that start with "sceneName/"
string scenePrefix = $"{sceneName}/";
int removedCount = currentSaveData.participantStates.RemoveAll(entry =>
entry.saveId.StartsWith(scenePrefix));
Logging.Debug($"[SaveLoadManager] Cleared {removedCount} save entries for level: {sceneName}");
}
#endregion
#region State Restoration

View File

@@ -283,9 +283,9 @@ namespace Core
// Tracks the currently loaded gameplay scene (not persistent/bootstrapper)
public string CurrentGameplayScene { get; set; } = "AppleHillsOverworld";
public async Task ReloadCurrentScene(IProgress<float> progress = null, bool autoHideLoadingScreen = true)
public async Task ReloadCurrentScene(IProgress<float> progress = null, bool autoHideLoadingScreen = true, bool skipSave = false)
{
await SwitchSceneAsync(CurrentGameplayScene, progress, autoHideLoadingScreen);
await SwitchSceneAsync(CurrentGameplayScene, progress, autoHideLoadingScreen, skipSave);
}
/// <summary>
@@ -294,7 +294,8 @@ namespace Core
/// <param name="newSceneName">Name of the scene to load</param>
/// <param name="progress">Optional progress reporter</param>
/// <param name="autoHideLoadingScreen">Whether to automatically hide the loading screen when complete. If false, caller must hide it manually.</param>
public async Task SwitchSceneAsync(string newSceneName, IProgress<float> progress = null, bool autoHideLoadingScreen = true)
/// <param name="skipSave">If true, skips saving scene data during transition. Useful for level restart to prevent re-saving cleared data.</param>
public async Task SwitchSceneAsync(string newSceneName, IProgress<float> progress = null, bool autoHideLoadingScreen = true, bool skipSave = false)
{
string oldSceneName = CurrentGameplayScene;
@@ -309,8 +310,8 @@ namespace Core
LogDebugMessage($"Broadcasting OnSceneUnloading for: {oldSceneName}");
LifecycleManager.Instance?.BroadcastSceneUnloading(oldSceneName);
// PHASE 3: Save scene-specific data via SaveLoadManager
if (SaveLoadManager.Instance != null)
// PHASE 3: Save scene-specific data via SaveLoadManager (unless skipSave is true)
if (!skipSave && SaveLoadManager.Instance != null)
{
var debugSettings = DeveloperSettingsProvider.Instance.GetSettings<DebugSettings>();
if (debugSettings.useSaveLoadSystem)
@@ -319,6 +320,10 @@ namespace Core
SaveLoadManager.Instance.SaveSceneData();
}
}
else if (skipSave)
{
LogDebugMessage($"Skipping save for: {oldSceneName} (skipSave=true)");
}
// PHASE 5: Remove all AstarPath (A* Pathfinder) singletons before loading the new scene
var astarPaths = FindObjectsByType<AstarPath>(FindObjectsSortMode.None);
@@ -364,7 +369,7 @@ namespace Core
LifecycleManager.Instance?.BroadcastSceneReady(newSceneName);
// PHASE 11: Restore scene-specific data via SaveLoadManager
if (SaveLoadManager.Instance != null)
if (!skipSave && SaveLoadManager.Instance != null)
{
var debugSettings = DeveloperSettingsProvider.Instance.GetSettings<DebugSettings>();
if (debugSettings.useSaveLoadSystem)
@@ -373,6 +378,10 @@ namespace Core
SaveLoadManager.Instance.RestoreSceneData();
}
}
else if (skipSave)
{
LogDebugMessage($"Skipping restore for: {newSceneName} (skipSave=true)");
}
// PHASE 12: Only hide the loading screen if autoHideLoadingScreen is true
if (autoHideLoadingScreen && _loadingScreen != null)

View File

@@ -128,8 +128,16 @@ namespace Levels
private async void OnRestartSelected()
{
// TODO: Restart level here
await OnLevelSelected();
// Clear all save data for the target level before reloading
if (Core.SaveLoad.SaveLoadManager.Instance != null && !string.IsNullOrEmpty(switchData?.targetLevelSceneName))
{
Core.SaveLoad.SaveLoadManager.Instance.ClearLevelData(switchData.targetLevelSceneName);
Logging.Debug($"[LevelSwitch] Cleared save data for level: {switchData.targetLevelSceneName}");
}
// Now reload the level with fresh state - skipSave=true prevents re-saving cleared data
var progress = new Progress<float>(p => Logging.Debug($"Loading progress: {p * 100:F0}%"));
await SceneManagerService.Instance.SwitchSceneAsync(switchData.targetLevelSceneName, progress, autoHideLoadingScreen: true, skipSave: true);
}
private void OnMenuCancel()

View File

@@ -1,5 +1,6 @@
using System;
using Core;
using Core.SaveLoad;
using UnityEngine;
using UnityEngine.SceneManagement;
using UI.Core;
@@ -294,8 +295,20 @@ namespace UI
public async void ReloadLevel()
{
// Clear all save data for the current gameplay level before reloading
if (SaveLoadManager.Instance != null && SceneManagerService.Instance != null)
{
string currentLevel = SceneManagerService.Instance.CurrentGameplayScene;
if (!string.IsNullOrEmpty(currentLevel))
{
SaveLoadManager.Instance.ClearLevelData(currentLevel);
Logging.Debug($"[PauseMenu] Cleared save data for current level: {currentLevel}");
}
}
// Now reload the current scene with fresh state - skipSave=true prevents re-saving cleared data
var progress = new Progress<float>(p => Logging.Debug($"Loading progress: {p * 100:F0}%"));
await SceneManagerService.Instance.ReloadCurrentScene(progress);
await SceneManagerService.Instance.ReloadCurrentScene(progress, autoHideLoadingScreen: true, skipSave: true);
}
/// <summary>