using System; using System.Collections.Generic; using System.Linq; using BriarQueen.Data.Identifiers; using BriarQueen.Data.IO.Saves; using BriarQueen.Framework.Events.Progression; using BriarQueen.Framework.Events.UI; using BriarQueen.Framework.Managers.Hints.Data; using BriarQueen.Framework.Managers.Levels.Data; using BriarQueen.Framework.Services.Puzzles.Base; using Cysharp.Threading.Tasks; using MemoryPack; using UnityEngine; using UnityEngine.UI; namespace BriarQueen.Game.Puzzles.ChapterOne.LaxleyHouse.Clock { [Serializable] [MemoryPackable] public partial struct LaxleyClockPuzzleState { public bool HourHandPlaced; public bool MinuteHandPlaced; public int HourHandRotationStep; public int MinuteHandRotationStep; public bool IsSolved; } public class LaxleyClockBasePuzzle : BasePuzzle, IPuzzleStateful { private const int SolvedHourStep = 6; private const int SolvedMinuteStep = 1; [Header("Clock Face")] [SerializeField] private LaxleyClockFace _clockFace; [Header("Puzzle State")] [SerializeField] private Image _background; [SerializeField] private Sprite _clockOpenSprite; [SerializeField] private List _clockItems; public override string PuzzleID => PuzzleIdentifiers.AllPuzzles[PuzzleKey.LaxleyClock]; public override string LevelName => "Grandfather Clock"; public override Dictionary Hints { get; } public bool IsCompleted => SaveManager.GetLevelFlag(LevelFlag.LaxleyClockSolved); protected override async UniTask PostLoadInternal() { _clockFace.Initialise(this); if (SaveManager.GetLevelFlag(LevelFlag.LaxleyClockSolved)) { _clockFace.LockHands(); await OpenClock(false); } } public async UniTask NotifyClockStateChanged() { if (IsCompleted) return; if (!_clockFace.AreBothHandsPlaced()) return; if (_clockFace.HourHandRotationStep == SolvedHourStep && _clockFace.MinuteHandRotationStep == SolvedMinuteStep) { await CompletePuzzle(); } } public override async UniTask CompletePuzzle() { if (IsCompleted) return; SaveManager.SetLevelFlag(LevelFlag.LaxleyClockSolved, true); SaveManager.SetPuzzleCompleted(PuzzleKey.LaxleyClock, true); EventCoordinator.Publish(new FadeEvent(false, 0.5f)); await UniTask.Delay(TimeSpan.FromSeconds(0.5f)); _clockFace.HideMechanism(); _clockFace.LockHands(); await OpenClock(true); EventCoordinator.Publish(new UnlockAchievementEvent(AchievementID.LaxleyGrandfatherClockPuzzleSolved)); EventCoordinator.Publish(new FadeEvent(true, 0.5f)); await UniTask.Delay(TimeSpan.FromSeconds(0.5f)); } public UniTask CaptureState() { var state = new LaxleyClockPuzzleState { HourHandPlaced = _clockFace.HourHandPlaced, MinuteHandPlaced = _clockFace.MinuteHandPlaced, HourHandRotationStep = _clockFace.HourHandRotationStep, MinuteHandRotationStep = _clockFace.MinuteHandRotationStep, IsSolved = IsCompleted }; byte[] data = MemoryPackSerializer.Serialize(state); return UniTask.FromResult(data); } public async UniTask RestoreState(byte[] state) { _clockFace.Initialise(this); if (state == null || state.Length == 0) { if (SaveManager.GetLevelFlag(LevelFlag.LaxleyClockSolved)) { _clockFace.LockHands(); await OpenClock(false); } return; } LaxleyClockPuzzleState restored = MemoryPackSerializer.Deserialize(state); _clockFace.RestoreState( restored.HourHandPlaced, restored.MinuteHandPlaced, restored.HourHandRotationStep, restored.MinuteHandRotationStep, restored.IsSolved); if (restored.IsSolved || SaveManager.GetLevelFlag(LevelFlag.LaxleyClockSolved)) { _clockFace.LockHands(); await OpenClock(false); } } private async UniTask OpenClock(bool playAudio = false) { _background.sprite = _clockOpenSprite; if (playAudio) AudioManager.Play(AudioNameIdentifiers.Get(SFXKey.ClockOpening)); await UnlockItems(); } private UniTask UnlockItems() { foreach (var item in _clockItems) { if (SaveManager.CurrentSave.CollectedItems.All(x => x.UniqueIdentifier != item.ItemData.UniqueID)) { item.CanvasGroup.blocksRaycasts = true; item.CanvasGroup.interactable = true; item.CanvasGroup.alpha = 1; } } return UniTask.CompletedTask; } } }