192 lines
5.9 KiB
C#
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();
|
|
}
|
|
}
|
|
} |