121 lines
3.2 KiB
C#
121 lines
3.2 KiB
C#
using System;
|
|
using KitsuneCafe.ItemSystem;
|
|
using KitsuneCafe.Sys;
|
|
using KitsuneCafe.Sys.Attributes;
|
|
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;
|
|
|
|
[SerializeField]
|
|
private UnityEvent closed = default;
|
|
|
|
public bool IsInteractable => true;
|
|
public bool IsOpen => isOpen;
|
|
public bool IsLocked => isLocked;
|
|
|
|
public IResult<Unit, InteractionError> Interact(IInteractor interactor)
|
|
{
|
|
return isOpen switch
|
|
{
|
|
true => TryClose(interactor),
|
|
false => TryOpen(interactor),
|
|
};
|
|
}
|
|
|
|
private IResult<Unit, InteractionError> TryClose(IInteractor interactor)
|
|
{
|
|
if (!isOpen)
|
|
{
|
|
return Result.Ok();
|
|
}
|
|
|
|
return ForceClosed();
|
|
}
|
|
|
|
private IResult<Unit, InteractionError> TryOpen(IInteractor interactor)
|
|
{
|
|
return requirement switch
|
|
{
|
|
_ when isOpen => Result.Ok(),
|
|
_ when !isLocked => ForceOpen(),
|
|
Requirement.None => Result.Err(InteractionErrorCode.Locked),
|
|
Requirement.Key => TryOpenWithKey(interactor),
|
|
Requirement.Switch => Result.Err(InteractionErrorCode.RequiresSwitch),
|
|
var x => throw new ArgumentException($"{gameObject.name} requested invalid requirement type {x}")
|
|
};
|
|
}
|
|
|
|
private IResult<Unit, InteractionError> TryOpenWithKey(IInteractor interactor)
|
|
{
|
|
if (interactor.TryGetComponent<IInventory<InventoryItem>>(out var inventory) && inventory.Has(key))
|
|
{
|
|
if (consumeKey)
|
|
{
|
|
inventory.Remove(key);
|
|
}
|
|
|
|
isLocked = false;
|
|
ForceOpen();
|
|
return Result.Ok();
|
|
}
|
|
else
|
|
{
|
|
return Result.Err(InteractionErrorCode.MissingItem);
|
|
}
|
|
}
|
|
|
|
public void ForceClosedAndForget()
|
|
{
|
|
isOpen = false;
|
|
closed.Invoke();
|
|
}
|
|
|
|
public IResult<Unit, InteractionError> ForceClosed()
|
|
{
|
|
ForceClosedAndForget();
|
|
return Result.Ok();
|
|
}
|
|
|
|
public void ForceOpenAndForget()
|
|
{
|
|
isOpen = true;
|
|
opened.Invoke();
|
|
}
|
|
|
|
public IResult<Unit, InteractionError> ForceOpen()
|
|
{
|
|
ForceOpenAndForget();
|
|
return Result.Ok();
|
|
}
|
|
}
|
|
}
|