171 lines
5.3 KiB
C#
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;
|
|
}
|
|
}
|
|
} |