First commit for private source control. Older commits available on Github.
This commit is contained in:
BIN
Assets/Scripts/Framework/Services/Puzzles/.DS_Store
vendored
Normal file
BIN
Assets/Scripts/Framework/Services/Puzzles/.DS_Store
vendored
Normal file
Binary file not shown.
3
Assets/Scripts/Framework/Services/Puzzles/Base.meta
Normal file
3
Assets/Scripts/Framework/Services/Puzzles/Base.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 833a26bf9c2c446e8c738a8b377956a0
|
||||
timeCreated: 1773830388
|
||||
50
Assets/Scripts/Framework/Services/Puzzles/Base/BasePuzzle.cs
Normal file
50
Assets/Scripts/Framework/Services/Puzzles/Base/BasePuzzle.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
// ==============================
|
||||
// PuzzleBase.cs (updated)
|
||||
// ==============================
|
||||
|
||||
using System.Collections.Generic;
|
||||
using BriarQueen.Framework.Assets;
|
||||
using BriarQueen.Framework.Coordinators.Events;
|
||||
using BriarQueen.Framework.Managers.Audio;
|
||||
using BriarQueen.Framework.Managers.Hints.Data;
|
||||
using BriarQueen.Framework.Managers.IO;
|
||||
using BriarQueen.Framework.Managers.Levels.Data;
|
||||
using BriarQueen.Framework.Registries;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using VContainer;
|
||||
|
||||
namespace BriarQueen.Framework.Services.Puzzles.Base
|
||||
{
|
||||
public abstract class BasePuzzle : BaseLevel
|
||||
{
|
||||
protected AddressableManager AddressableManager;
|
||||
protected AssetRegistry AssetRegistry;
|
||||
protected AudioManager AudioManager;
|
||||
protected ItemRegistry ItemRegistry;
|
||||
protected PuzzleService PuzzleService;
|
||||
|
||||
public abstract string PuzzleID { get; }
|
||||
|
||||
public override bool IsPuzzleLevel => true;
|
||||
|
||||
// BaseLevel still requires these.
|
||||
public abstract override string LevelName { get; }
|
||||
public abstract override Dictionary<int, BaseHint> Hints { get; }
|
||||
|
||||
public abstract UniTask CompletePuzzle();
|
||||
|
||||
[Inject]
|
||||
public void Construct(EventCoordinator eventCoordinator, AudioManager audioManager,
|
||||
SaveManager saveManager, ItemRegistry itemRegistry, AddressableManager addressableManager,
|
||||
AssetRegistry assetRegistry, PuzzleService puzzleService)
|
||||
{
|
||||
EventCoordinator = eventCoordinator;
|
||||
AudioManager = audioManager;
|
||||
SaveManager = saveManager;
|
||||
ItemRegistry = itemRegistry;
|
||||
AddressableManager = addressableManager;
|
||||
AssetRegistry = assetRegistry;
|
||||
PuzzleService = puzzleService;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2f7dc618c5084940a094037aab5f4e8b
|
||||
timeCreated: 1769876583
|
||||
@@ -0,0 +1,15 @@
|
||||
using Cysharp.Threading.Tasks;
|
||||
|
||||
namespace BriarQueen.Framework.Services.Puzzles.Base
|
||||
{
|
||||
public interface IPuzzleStateful
|
||||
{
|
||||
/// <summary>If true, manager can mark the puzzle completed (and optionally clear state).</summary>
|
||||
bool IsCompleted { get; }
|
||||
|
||||
UniTask<byte[]> CaptureState();
|
||||
|
||||
/// <summary>Restore the puzzle from a previously captured serialized blob.</summary>
|
||||
UniTask RestoreState(byte[] state);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e05bb678cdfe40f6acffd77fceb3faba
|
||||
timeCreated: 1769878647
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace BriarQueen.Framework.Services.Puzzles.Base
|
||||
{
|
||||
public interface IPuzzleWorldStateSync
|
||||
{
|
||||
void SyncWorldStateToSave();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 120766eb18204d1593aad20a292f305c
|
||||
timeCreated: 1774453311
|
||||
134
Assets/Scripts/Framework/Services/Puzzles/PuzzleService.cs
Normal file
134
Assets/Scripts/Framework/Services/Puzzles/PuzzleService.cs
Normal file
@@ -0,0 +1,134 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using BriarQueen.Data.IO.Saves;
|
||||
using BriarQueen.Framework.Managers.IO;
|
||||
using BriarQueen.Framework.Services.Puzzles.Base;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using VContainer;
|
||||
|
||||
namespace BriarQueen.Framework.Services.Puzzles
|
||||
{
|
||||
public class PuzzleService : IDisposable
|
||||
{
|
||||
private readonly SaveManager _saveManager;
|
||||
|
||||
private BasePuzzle _currentBasePuzzle;
|
||||
private bool _isWritingState;
|
||||
|
||||
[Inject]
|
||||
public PuzzleService(SaveManager saveManager)
|
||||
{
|
||||
_saveManager = saveManager;
|
||||
_saveManager.OnBeforeSaveRequestedAsync += OnBeforeSaveRequestedAsync;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_saveManager.OnBeforeSaveRequestedAsync -= OnBeforeSaveRequestedAsync;
|
||||
}
|
||||
|
||||
public async UniTask LoadPuzzle(BasePuzzle basePuzzle)
|
||||
{
|
||||
_currentBasePuzzle = basePuzzle;
|
||||
if (_currentBasePuzzle == null)
|
||||
return;
|
||||
|
||||
await TryRestorePuzzleState(_currentBasePuzzle);
|
||||
}
|
||||
|
||||
public async UniTask SavePuzzle(BasePuzzle basePuzzle)
|
||||
{
|
||||
if (basePuzzle == null)
|
||||
return;
|
||||
|
||||
if (_currentBasePuzzle != null && basePuzzle != _currentBasePuzzle)
|
||||
return;
|
||||
|
||||
await SavePuzzleState(basePuzzle, flushToDisk: true);
|
||||
_currentBasePuzzle = null;
|
||||
}
|
||||
|
||||
private async UniTask OnBeforeSaveRequestedAsync()
|
||||
{
|
||||
if (_currentBasePuzzle == null)
|
||||
return;
|
||||
|
||||
await SavePuzzleState(_currentBasePuzzle, flushToDisk: false);
|
||||
}
|
||||
|
||||
private async UniTask TryRestorePuzzleState(BasePuzzle basePuzzle)
|
||||
{
|
||||
if (basePuzzle == null || _saveManager.CurrentSave == null)
|
||||
return;
|
||||
|
||||
if (basePuzzle is not IPuzzleStateful stateful)
|
||||
return;
|
||||
|
||||
var save = _saveManager.CurrentSave;
|
||||
var entry = save.PuzzleStates?.FirstOrDefault(x => x != null && x.PuzzleID == basePuzzle.PuzzleID);
|
||||
var stateBlob = entry?.State;
|
||||
|
||||
try
|
||||
{
|
||||
await stateful.RestoreState(stateBlob);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogWarning($"[PuzzleService] Failed to restore state for '{basePuzzle.PuzzleID}': {ex}");
|
||||
}
|
||||
}
|
||||
|
||||
private async UniTask SavePuzzleState(BasePuzzle basePuzzle, bool flushToDisk)
|
||||
{
|
||||
if (basePuzzle == null || _saveManager.CurrentSave == null)
|
||||
return;
|
||||
|
||||
if (basePuzzle is not IPuzzleStateful stateful)
|
||||
return;
|
||||
|
||||
if (_isWritingState)
|
||||
return;
|
||||
|
||||
_isWritingState = true;
|
||||
|
||||
try
|
||||
{
|
||||
if (basePuzzle is IPuzzleWorldStateSync worldStateSync)
|
||||
worldStateSync.SyncWorldStateToSave();
|
||||
|
||||
var save = _saveManager.CurrentSave;
|
||||
save.PuzzleStates ??= new List<PuzzleStateSaveData>();
|
||||
|
||||
byte[] blob;
|
||||
try
|
||||
{
|
||||
blob = await stateful.CaptureState() ?? Array.Empty<byte>();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogWarning($"[PuzzleService] Failed to capture state for '{basePuzzle.PuzzleID}': {ex}");
|
||||
return;
|
||||
}
|
||||
|
||||
var existing = save.PuzzleStates.FirstOrDefault(x => x != null && x.PuzzleID == basePuzzle.PuzzleID);
|
||||
if (existing == null)
|
||||
{
|
||||
existing = new PuzzleStateSaveData { PuzzleID = basePuzzle.PuzzleID };
|
||||
save.PuzzleStates.Add(existing);
|
||||
}
|
||||
|
||||
existing.State = blob;
|
||||
existing.Completed = stateful.IsCompleted;
|
||||
|
||||
if (flushToDisk)
|
||||
await _saveManager.SaveGameDataLatest();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_isWritingState = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6475266033724d2db5366ba6e56cf8a1
|
||||
timeCreated: 1769720489
|
||||
Reference in New Issue
Block a user