Files
A-Fairytale-Gone-Bad-Briar-…/Assets/Scripts/Game/Puzzles/ChapterOne/LaxleyHouse/Clock/LaxleyClockBasePuzzle.cs

171 lines
5.3 KiB
C#

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<BaseItem> _clockItems;
public override string PuzzleID => PuzzleIdentifiers.AllPuzzles[PuzzleKey.LaxleyClock];
public override string LevelName => "Grandfather Clock";
public override Dictionary<int, BaseHint> 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<byte[]> 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<LaxleyClockPuzzleState>(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;
}
}
}