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

192 lines
5.9 KiB
C#

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 : 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();
}
}
}