Laxley Grandfather Clock puzzle artwork done.
This commit is contained in:
@@ -1,7 +1,171 @@
|
||||
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
|
||||
{
|
||||
public class LaxleyClockBasePuzzle
|
||||
[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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,192 @@
|
||||
using BriarQueen.Data.Identifiers;
|
||||
using BriarQueen.Framework.Events.UI;
|
||||
using BriarQueen.Framework.Managers.Levels.Data;
|
||||
using BriarQueen.Framework.Managers.Player.Data;
|
||||
using BriarQueen.Framework.Managers.UI;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace BriarQueen.Game.Puzzles.ChapterOne.LaxleyHouse.Clock
|
||||
{
|
||||
public class LaxleyClockFace
|
||||
public class LaxleyClockFace : BaseItem
|
||||
{
|
||||
|
||||
[Header("Hands")]
|
||||
[SerializeField]
|
||||
private LaxleyClockHand _hourHand;
|
||||
|
||||
[SerializeField]
|
||||
private LaxleyClockHand _minuteHand;
|
||||
|
||||
[SerializeField]
|
||||
private Image _hub;
|
||||
|
||||
private LaxleyClockBasePuzzle _owningPuzzle;
|
||||
private bool _locked;
|
||||
|
||||
public bool HourHandPlaced => _hourHand != null && _hourHand.Placed;
|
||||
public bool MinuteHandPlaced => _minuteHand != null && _minuteHand.Placed;
|
||||
|
||||
public int HourHandRotationStep => _hourHand != null ? _hourHand.CurrentRotationStep : 0;
|
||||
public int MinuteHandRotationStep => _minuteHand != null ? _minuteHand.CurrentRotationStep : 0;
|
||||
|
||||
public override string InteractableName => "Clock Face";
|
||||
public override UICursorService.CursorStyle ApplicableCursorStyle => UICursorService.CursorStyle.Interact;
|
||||
|
||||
public void Initialise(LaxleyClockBasePuzzle owningPuzzle)
|
||||
{
|
||||
_owningPuzzle = owningPuzzle;
|
||||
_locked = false;
|
||||
|
||||
gameObject.SetActive(true);
|
||||
|
||||
if (_hub != null)
|
||||
_hub.gameObject.SetActive(true);
|
||||
|
||||
_hourHand?.Initialise(this, _owningPuzzle);
|
||||
_minuteHand?.Initialise(this, _owningPuzzle);
|
||||
|
||||
RefreshInteractionState();
|
||||
}
|
||||
|
||||
public override async UniTask OnInteract(ItemDataSo item = null)
|
||||
{
|
||||
if (!IsInteractable())
|
||||
return;
|
||||
|
||||
if (item == null)
|
||||
{
|
||||
string message = string.Empty;
|
||||
|
||||
if (!HourHandPlaced && !MinuteHandPlaced)
|
||||
{
|
||||
message = InteractEventIDs.Get(EnvironmentInteractKey.LaxleyGrandfatherClockMissingBothHands);
|
||||
}
|
||||
else if (!HourHandPlaced && MinuteHandPlaced)
|
||||
{
|
||||
message = InteractEventIDs.Get(EnvironmentInteractKey.LaxleyGrandfatherClockMissingHourHand);
|
||||
}
|
||||
else if (HourHandPlaced && !MinuteHandPlaced)
|
||||
{
|
||||
message = InteractEventIDs.Get(EnvironmentInteractKey.LaxleyGrandfatherClockMissingMinuteHand);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(message))
|
||||
EventCoordinator.Publish(new DisplayInteractEvent(message));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
bool isHourHandItem = item.UniqueID == ItemIDs.Get(ItemKey.LaxleyClockHourHand);
|
||||
bool isMinuteHandItem = item.UniqueID == ItemIDs.Get(ItemKey.LaxleyClockMinuteHand);
|
||||
|
||||
if (!isHourHandItem && !isMinuteHandItem)
|
||||
{
|
||||
EventCoordinator.Publish(new DisplayInteractEvent(InteractEventIDs.Get(ItemInteractKey.CantUseItem)));
|
||||
return;
|
||||
}
|
||||
|
||||
await PlaceHand(item);
|
||||
}
|
||||
|
||||
public bool AreBothHandsPlaced()
|
||||
{
|
||||
return HourHandPlaced && MinuteHandPlaced;
|
||||
}
|
||||
|
||||
public void LockHands()
|
||||
{
|
||||
_locked = true;
|
||||
_hourHand?.Lock();
|
||||
_minuteHand?.Lock();
|
||||
RefreshInteractionState();
|
||||
}
|
||||
|
||||
public void HideMechanism()
|
||||
{
|
||||
_locked = true;
|
||||
|
||||
_hourHand?.Hide();
|
||||
_minuteHand?.Hide();
|
||||
|
||||
if (_hub != null)
|
||||
_hub.gameObject.SetActive(false);
|
||||
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
public void RestoreState(
|
||||
bool hourPlaced,
|
||||
bool minutePlaced,
|
||||
int hourRotationStep,
|
||||
int minuteRotationStep,
|
||||
bool solved)
|
||||
{
|
||||
_locked = solved;
|
||||
gameObject.SetActive(!solved);
|
||||
|
||||
if (solved)
|
||||
{
|
||||
_hourHand?.RestoreState(hourPlaced, hourRotationStep, true);
|
||||
_minuteHand?.RestoreState(minutePlaced, minuteRotationStep, true);
|
||||
HideMechanism();
|
||||
return;
|
||||
}
|
||||
|
||||
if (_hub != null)
|
||||
_hub.gameObject.SetActive(true);
|
||||
|
||||
_hourHand?.RestoreState(hourPlaced, hourRotationStep, false);
|
||||
_minuteHand?.RestoreState(minutePlaced, minuteRotationStep, false);
|
||||
|
||||
RefreshInteractionState();
|
||||
}
|
||||
|
||||
internal async UniTask NotifyHandChanged()
|
||||
{
|
||||
RefreshInteractionState();
|
||||
|
||||
if (_owningPuzzle != null)
|
||||
await _owningPuzzle.NotifyClockStateChanged();
|
||||
}
|
||||
|
||||
private async UniTask PlaceHand(ItemDataSo item)
|
||||
{
|
||||
if (item.UniqueID == ItemIDs.Get(ItemKey.LaxleyClockHourHand))
|
||||
{
|
||||
await _hourHand.Place();
|
||||
}
|
||||
else if (item.UniqueID == ItemIDs.Get(ItemKey.LaxleyClockMinuteHand))
|
||||
{
|
||||
await _minuteHand.Place();
|
||||
}
|
||||
|
||||
PlayerManager.RemoveItem(item);
|
||||
|
||||
RefreshInteractionState();
|
||||
|
||||
if (_owningPuzzle != null)
|
||||
await _owningPuzzle.NotifyClockStateChanged();
|
||||
}
|
||||
|
||||
private void RefreshInteractionState()
|
||||
{
|
||||
bool bothPlaced = AreBothHandsPlaced();
|
||||
bool canPlaceHands = !_locked && !bothPlaced;
|
||||
|
||||
if (CanvasGroup != null)
|
||||
{
|
||||
CanvasGroup.blocksRaycasts = canPlaceHands;
|
||||
CanvasGroup.interactable = canPlaceHands;
|
||||
}
|
||||
|
||||
_hourHand?.SetCanRotate(!_locked && bothPlaced);
|
||||
_minuteHand?.SetCanRotate(!_locked && bothPlaced);
|
||||
}
|
||||
|
||||
private bool IsInteractable()
|
||||
{
|
||||
return !_locked && !AreBothHandsPlaced();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,316 @@
|
||||
using System.Threading;
|
||||
using BriarQueen.Framework.Managers.Levels.Data;
|
||||
using BriarQueen.Framework.Managers.Player.Data;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using PrimeTween;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BriarQueen.Game.Puzzles.ChapterOne.LaxleyHouse.Clock
|
||||
{
|
||||
public class LaxleyClockHand
|
||||
public class LaxleyClockHand : BaseItem
|
||||
{
|
||||
|
||||
[Header("State")]
|
||||
[SerializeField]
|
||||
private bool _placed;
|
||||
|
||||
[SerializeField]
|
||||
[Range(0, 11)]
|
||||
private int _currentRotationStep;
|
||||
|
||||
[SerializeField]
|
||||
private bool _locked;
|
||||
|
||||
[SerializeField]
|
||||
private bool _isRotating;
|
||||
|
||||
[SerializeField]
|
||||
private bool _canRotate;
|
||||
|
||||
[Header("Rotation")]
|
||||
[SerializeField]
|
||||
private float[] _rotationSteps = new float[12]
|
||||
{
|
||||
0f, // 12
|
||||
-30f, // 1
|
||||
-60f, // 2
|
||||
-90f, // 3
|
||||
-120f, // 4
|
||||
-150f, // 5
|
||||
-180f, // 6
|
||||
-210f, // 7
|
||||
-240f, // 8
|
||||
-270f, // 9
|
||||
-300f, // 10
|
||||
-330f // 11
|
||||
};
|
||||
|
||||
[SerializeField]
|
||||
private float _rotateDuration = 0.15f;
|
||||
|
||||
[SerializeField]
|
||||
private Ease _rotateEase = Ease.Linear;
|
||||
|
||||
[Header("Placement")]
|
||||
[SerializeField]
|
||||
private float _placeDuration = 0.2f;
|
||||
|
||||
[SerializeField]
|
||||
private Ease _placeEase = Ease.OutSine;
|
||||
|
||||
[Header("Components")]
|
||||
[SerializeField]
|
||||
private GameObject _parentPivot;
|
||||
|
||||
[SerializeField]
|
||||
private CanvasGroup _parentCanvasGroup;
|
||||
|
||||
[Header("Placement Behaviour")]
|
||||
[SerializeField]
|
||||
private bool _randomiseRotationOnFirstPlace = true;
|
||||
|
||||
private Sequence _placeSequence;
|
||||
private Sequence _rotateSequence;
|
||||
|
||||
private CancellationTokenSource _placeCTS;
|
||||
private CancellationTokenSource _rotateCTS;
|
||||
|
||||
private LaxleyClockFace _clockFace;
|
||||
|
||||
public bool Placed => _placed;
|
||||
public int CurrentRotationStep => _currentRotationStep;
|
||||
|
||||
public void Initialise(LaxleyClockFace clockFace, LaxleyClockBasePuzzle owningPuzzle)
|
||||
{
|
||||
_clockFace = clockFace;
|
||||
_canRotate = false;
|
||||
|
||||
if (_placed)
|
||||
{
|
||||
if (_parentPivot != null)
|
||||
_parentPivot.SetActive(true);
|
||||
|
||||
if (_parentCanvasGroup != null)
|
||||
_parentCanvasGroup.alpha = 1f;
|
||||
|
||||
ApplyRotationImmediate(_currentRotationStep);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_parentPivot != null)
|
||||
_parentPivot.SetActive(false);
|
||||
|
||||
if (_parentCanvasGroup != null)
|
||||
_parentCanvasGroup.alpha = 0f;
|
||||
}
|
||||
|
||||
RefreshVisualState();
|
||||
}
|
||||
|
||||
public override async UniTask OnInteract(ItemDataSo item = null)
|
||||
{
|
||||
if (!IsInteractable())
|
||||
return;
|
||||
|
||||
await RotateToNextStep();
|
||||
await _clockFace.NotifyHandChanged();
|
||||
}
|
||||
|
||||
public async UniTask Place()
|
||||
{
|
||||
if (_placed)
|
||||
return;
|
||||
|
||||
_placed = true;
|
||||
_locked = false;
|
||||
_canRotate = false;
|
||||
|
||||
CancelPlaceTween();
|
||||
|
||||
_placeCTS = new CancellationTokenSource();
|
||||
|
||||
if (_randomiseRotationOnFirstPlace)
|
||||
_currentRotationStep = Random.Range(0, _rotationSteps.Length);
|
||||
|
||||
if (_parentPivot != null)
|
||||
_parentPivot.SetActive(true);
|
||||
|
||||
ApplyRotationImmediate(_currentRotationStep);
|
||||
|
||||
if (_parentCanvasGroup != null)
|
||||
{
|
||||
_parentCanvasGroup.alpha = 0f;
|
||||
_parentCanvasGroup.blocksRaycasts = false;
|
||||
_parentCanvasGroup.interactable = false;
|
||||
}
|
||||
|
||||
_placeSequence.Stop();
|
||||
_placeSequence = Sequence.Create()
|
||||
.Group(Tween.Alpha(_parentCanvasGroup, 1f, _placeDuration, _placeEase));
|
||||
|
||||
try
|
||||
{
|
||||
await _placeSequence.ToUniTask(cancellationToken: _placeCTS.Token);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
RefreshVisualState();
|
||||
}
|
||||
|
||||
public void RestoreState(bool placed, int rotationStep, bool locked)
|
||||
{
|
||||
CancelPlaceTween();
|
||||
CancelRotateTween();
|
||||
|
||||
_placed = placed;
|
||||
_locked = locked;
|
||||
_isRotating = false;
|
||||
_canRotate = false;
|
||||
_currentRotationStep = Mathf.Clamp(rotationStep, 0, 11);
|
||||
|
||||
if (_parentPivot != null)
|
||||
_parentPivot.SetActive(_placed);
|
||||
|
||||
if (_placed)
|
||||
{
|
||||
ApplyRotationImmediate(_currentRotationStep);
|
||||
|
||||
if (_parentCanvasGroup != null)
|
||||
_parentCanvasGroup.alpha = 1f;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_parentCanvasGroup != null)
|
||||
_parentCanvasGroup.alpha = 0f;
|
||||
}
|
||||
|
||||
RefreshVisualState();
|
||||
}
|
||||
|
||||
public void SetCanRotate(bool canRotate)
|
||||
{
|
||||
_canRotate = canRotate;
|
||||
RefreshVisualState();
|
||||
}
|
||||
|
||||
public void Lock()
|
||||
{
|
||||
_locked = true;
|
||||
_canRotate = false;
|
||||
RefreshVisualState();
|
||||
}
|
||||
|
||||
public void Hide()
|
||||
{
|
||||
CancelPlaceTween();
|
||||
CancelRotateTween();
|
||||
|
||||
_canRotate = false;
|
||||
_isRotating = false;
|
||||
|
||||
if (_parentCanvasGroup != null)
|
||||
{
|
||||
_parentCanvasGroup.blocksRaycasts = false;
|
||||
_parentCanvasGroup.interactable = false;
|
||||
_parentCanvasGroup.alpha = 0f;
|
||||
}
|
||||
|
||||
if (_parentPivot != null)
|
||||
_parentPivot.SetActive(false);
|
||||
}
|
||||
|
||||
private async UniTask RotateToNextStep()
|
||||
{
|
||||
if (!IsInteractable())
|
||||
return;
|
||||
|
||||
_isRotating = true;
|
||||
RefreshVisualState();
|
||||
|
||||
CancelRotateTween();
|
||||
_rotateCTS = new CancellationTokenSource();
|
||||
|
||||
_currentRotationStep = (_currentRotationStep + 1) % 12;
|
||||
|
||||
Vector3 targetEuler = _parentPivot.transform.localEulerAngles;
|
||||
targetEuler.z = _rotationSteps[_currentRotationStep];
|
||||
|
||||
_rotateSequence.Stop();
|
||||
_rotateSequence = Sequence.Create()
|
||||
.Group(
|
||||
Tween.LocalRotation(
|
||||
_parentPivot.transform,
|
||||
Quaternion.Euler(targetEuler),
|
||||
_rotateDuration,
|
||||
_rotateEase));
|
||||
|
||||
try
|
||||
{
|
||||
await _rotateSequence.ToUniTask(cancellationToken: _rotateCTS.Token);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
_isRotating = false;
|
||||
RefreshVisualState();
|
||||
}
|
||||
|
||||
private void ApplyRotationImmediate(int step)
|
||||
{
|
||||
if (_parentPivot == null)
|
||||
return;
|
||||
|
||||
Vector3 euler = _parentPivot.transform.localEulerAngles;
|
||||
euler.z = _rotationSteps[Mathf.Clamp(step, 0, 11)];
|
||||
_parentPivot.transform.localEulerAngles = euler;
|
||||
}
|
||||
|
||||
private void RefreshVisualState()
|
||||
{
|
||||
bool interactable = IsInteractable();
|
||||
|
||||
if (_parentCanvasGroup != null)
|
||||
{
|
||||
_parentCanvasGroup.blocksRaycasts = interactable;
|
||||
_parentCanvasGroup.interactable = interactable;
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsInteractable()
|
||||
{
|
||||
return _placed && !_locked && !_isRotating && _canRotate;
|
||||
}
|
||||
|
||||
private void CancelPlaceTween()
|
||||
{
|
||||
_placeSequence.Stop();
|
||||
|
||||
if (_placeCTS != null)
|
||||
{
|
||||
_placeCTS.Cancel();
|
||||
_placeCTS.Dispose();
|
||||
_placeCTS = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void CancelRotateTween()
|
||||
{
|
||||
_rotateSequence.Stop();
|
||||
|
||||
if (_rotateCTS != null)
|
||||
{
|
||||
_rotateCTS.Cancel();
|
||||
_rotateCTS.Dispose();
|
||||
_rotateCTS = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
CancelPlaceTween();
|
||||
CancelRotateTween();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,18 +4,18 @@ using System.Linq;
|
||||
using AYellowpaper.SerializedCollections;
|
||||
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 BriarQueen.Game.Levels.ChapterOne.LaxleyHouse.FireplaceLockbox;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using MemoryPack;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
namespace BriarQueen.Game.Levels.ChapterOne.LaxleyHouse
|
||||
namespace BriarQueen.Game.Puzzles.ChapterOne.LaxleyHouse.Fireplace.LockboxPuzzle
|
||||
{
|
||||
[Serializable]
|
||||
[MemoryPackable]
|
||||
@@ -94,6 +94,7 @@ namespace BriarQueen.Game.Levels.ChapterOne.LaxleyHouse
|
||||
AudioManager.Play(AudioNameIdentifiers.Get(SFXKey.LockboxOpening));
|
||||
|
||||
await OpenLockbox();
|
||||
EventCoordinator.Publish(new UnlockAchievementEvent(AchievementID.FireplaceLockboxPuzzleBoxSolved));
|
||||
|
||||
EventCoordinator.Publish(new FadeEvent(true, 0.5f));
|
||||
}
|
||||
@@ -103,10 +104,10 @@ namespace BriarQueen.Game.Levels.ChapterOne.LaxleyHouse
|
||||
if (_backgroundImage != null)
|
||||
_backgroundImage.sprite = _lockBoxOpenSprite;
|
||||
|
||||
await GenerateLockboxItems();
|
||||
await UnlockLockboxItems();
|
||||
}
|
||||
|
||||
private async UniTask GenerateLockboxItems()
|
||||
private async UniTask UnlockLockboxItems()
|
||||
{
|
||||
foreach (var item in _lockboxItems)
|
||||
{
|
||||
@@ -119,10 +120,6 @@ namespace BriarQueen.Game.Levels.ChapterOne.LaxleyHouse
|
||||
item.CanvasGroup.blocksRaycasts = true;
|
||||
item.CanvasGroup.interactable = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
await DestructionService.Destroy(item.gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ using PrimeTween;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace BriarQueen.Game.Levels.ChapterOne.LaxleyHouse.FireplaceLockbox
|
||||
namespace BriarQueen.Game.Puzzles.ChapterOne.LaxleyHouse.Fireplace.LockboxPuzzle
|
||||
{
|
||||
public class LockboxSlot : BaseItem
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user