canto/Assets/Scripts/Interaction/Gate.cs
2025-07-14 22:22:25 -04:00

95 lines
2.5 KiB
C#

using KitsuneCafe.ItemSystem;
using KitsuneCafe.System;
using NaughtyAttributes;
using UnityEngine;
using UnityEngine.Events;
namespace KitsuneCafe.Interaction
{
using Result = IInteractable.Result;
public class Gate : MonoBehaviour, IInteractable
{
public enum Requirement
{
None,
Key,
Switch
}
[SerializeField]
private bool isOpen;
[SerializeField]
private bool isLocked;
[SerializeField, ShowIf("isLocked")]
private Requirement requirement;
[SerializeField, ShowIf("requirement", Requirement.Key)]
private Item key;
[SerializeField, ShowIf("requirement", Requirement.Key)]
private bool consumeKey;
[SerializeField]
private UnityEvent opened = default;
public bool IsInteractable => true;
public bool IsOpen => isOpen;
public bool IsLocked => isLocked;
public IResult<Unit, InteractionError> Interact(IInteractor interactor)
{
return TryOpen(interactor);
}
private IResult<Unit, InteractionError> TryOpen(IInteractor interactor)
{
if (isOpen)
{
return Result.Ok();
}
else if (!isLocked)
{
opened.Invoke();
return Result.Ok();
}
else if (requirement == Requirement.None)
{
return Result.Err(InteractionErrorCode.Locked);
}
else if (requirement == Requirement.Switch)
{
return Result.Err(InteractionErrorCode.RequiresSwitch);
}
else if (requirement == Requirement.Key && interactor.TryGetComponent<IInventory<InventoryItem>>(out var inventory))
{
if (inventory.Has(key))
{
if (consumeKey)
{
inventory.Remove(key);
}
ForceOpen();
return Result.Ok();
}
else
{
return Result.Err(InteractionErrorCode.MissingItem);
}
}
else
{
return Result.Err(InteractionErrorCode.MissingItem);
}
}
private void ForceOpen()
{
isOpen = true;
opened.Invoke();
}
}
}