185 lines
5.4 KiB
C#
185 lines
5.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
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.Managers.Player.Data;
|
|
using BriarQueen.Framework.Services.Puzzles.Base;
|
|
using Cysharp.Threading.Tasks;
|
|
using MemoryPack;
|
|
using UnityEngine;
|
|
|
|
namespace BriarQueen.Game.Puzzles.ChapterOne.Fountain
|
|
{
|
|
[Serializable]
|
|
[MemoryPackable]
|
|
public partial struct FountainGemPuzzleState
|
|
{
|
|
public bool IsCompleted;
|
|
public string[] InputtedGemIDs;
|
|
}
|
|
|
|
public class FountainGemBasePuzzle : BasePuzzle, IPuzzleStateful
|
|
{
|
|
[SerializeField]
|
|
private FountainGemSlot _fountainGemSlot;
|
|
|
|
public override string PuzzleID => PuzzleIdentifiers.AllPuzzles[PuzzleKey.FountainGemPuzzle];
|
|
public override string LevelName => "Hole in the side of a Fountain";
|
|
public override Dictionary<int, BaseHint> Hints { get; } = new();
|
|
|
|
private readonly List<ItemDataSo> _inputtedGems = new();
|
|
private readonly List<string> _inputtedGemIDs = new();
|
|
|
|
private readonly string[] _correctSequence =
|
|
{
|
|
ItemIDs.Get(ItemKey.Sapphire),
|
|
ItemIDs.Get(ItemKey.Emerald),
|
|
ItemIDs.Get(ItemKey.Ruby)
|
|
};
|
|
|
|
private bool _isCompleted;
|
|
public bool IsCompleted => _isCompleted;
|
|
|
|
protected override UniTask PostActivateInternal()
|
|
{
|
|
TutorialService.DisplayTutorial(TutorialPopupID.ResetPuzzles);
|
|
return UniTask.CompletedTask;
|
|
}
|
|
|
|
protected void Start()
|
|
{
|
|
if (_fountainGemSlot != null)
|
|
_fountainGemSlot.Initialize(this);
|
|
}
|
|
|
|
internal bool TryInsertGem(ItemDataSo item)
|
|
{
|
|
if (_isCompleted || item == null)
|
|
return false;
|
|
|
|
var itemID = item.UniqueID;
|
|
if (string.IsNullOrWhiteSpace(itemID))
|
|
return false;
|
|
|
|
_inputtedGems.Add(item);
|
|
_inputtedGemIDs.Add(itemID);
|
|
|
|
ConsumePlayerGem(item);
|
|
|
|
if (_inputtedGemIDs.Count < _correctSequence.Length)
|
|
return true;
|
|
|
|
if (IsCorrectSequence())
|
|
{
|
|
CompletePuzzle().Forget();
|
|
return true;
|
|
}
|
|
|
|
AudioManager.Play(AudioNameIdentifiers.Get(SFXKey.PuzzleIncorrect));
|
|
ResetPuzzleState();
|
|
return false;
|
|
}
|
|
|
|
public override UniTask CompletePuzzle()
|
|
{
|
|
if (_isCompleted)
|
|
return UniTask.CompletedTask;
|
|
|
|
_isCompleted = true;
|
|
|
|
SaveManager.SetLevelFlag(LevelFlag.StreetGateOpen, true);
|
|
SaveManager.SetPuzzleCompleted(PuzzleKey.FountainGemPuzzle, true);
|
|
AudioManager.Play(AudioNameIdentifiers.Get(SFXKey.GateOpening));
|
|
EventCoordinator.Publish(new UnlockAchievementEvent(AchievementID.FountainGemPuzzleSolved));
|
|
|
|
return UniTask.CompletedTask;
|
|
}
|
|
|
|
public UniTask<byte[]> CaptureState()
|
|
{
|
|
var state = new FountainGemPuzzleState
|
|
{
|
|
IsCompleted = _isCompleted,
|
|
InputtedGemIDs = _inputtedGemIDs.ToArray()
|
|
};
|
|
|
|
return UniTask.FromResult(MemoryPackSerializer.Serialize(state));
|
|
}
|
|
|
|
public UniTask RestoreState(byte[] state)
|
|
{
|
|
_inputtedGems.Clear();
|
|
_inputtedGemIDs.Clear();
|
|
_isCompleted = false;
|
|
|
|
if (state == null || state.Length == 0)
|
|
{
|
|
_isCompleted = SaveManager.GetLevelFlag(LevelFlag.StreetGateOpen);
|
|
return UniTask.CompletedTask;
|
|
}
|
|
|
|
var restoredState = MemoryPackSerializer.Deserialize<FountainGemPuzzleState>(state);
|
|
|
|
_isCompleted = restoredState.IsCompleted;
|
|
|
|
if (restoredState.InputtedGemIDs != null)
|
|
_inputtedGemIDs.AddRange(restoredState.InputtedGemIDs);
|
|
|
|
if (_isCompleted)
|
|
{
|
|
SaveManager.SetLevelFlag(LevelFlag.StreetGateOpen, true, false);
|
|
SaveManager.SetPuzzleCompleted(PuzzleKey.FountainGemPuzzle, true, false);
|
|
}
|
|
|
|
return UniTask.CompletedTask;
|
|
}
|
|
|
|
public void ResetPuzzleState()
|
|
{
|
|
if (_isCompleted)
|
|
return;
|
|
|
|
for (int i = 0; i < _inputtedGems.Count; i++)
|
|
{
|
|
var gem = _inputtedGems[i];
|
|
if (gem != null)
|
|
PlayerManager.CollectItem(gem);
|
|
}
|
|
|
|
_inputtedGems.Clear();
|
|
_inputtedGemIDs.Clear();
|
|
}
|
|
|
|
public void OnResetButtonPressed()
|
|
{
|
|
AudioManager.Play(AudioNameIdentifiers.Get(SFXKey.ResetPuzzle));
|
|
ResetPuzzleState();
|
|
}
|
|
|
|
private bool IsCorrectSequence()
|
|
{
|
|
if (_inputtedGemIDs.Count != _correctSequence.Length)
|
|
return false;
|
|
|
|
for (int i = 0; i < _correctSequence.Length; i++)
|
|
{
|
|
if (_inputtedGemIDs[i] != _correctSequence[i])
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
private void ConsumePlayerGem(ItemDataSo item)
|
|
{
|
|
if (item == null)
|
|
return;
|
|
|
|
PlayerManager.RemoveItem(item);
|
|
}
|
|
}
|
|
} |