canto/Assets/Scripts/Interaction/IInteractable.cs
2025-07-19 23:42:43 -04:00

87 lines
No EOL
3 KiB
C#

using System;
using KitsuneCafe.System;
using UnityEngine;
namespace KitsuneCafe.Interaction
{
public enum InteractionErrorCode
{
None,
Locked,
MissingItem,
RequiresSwitch,
Generic
}
[Serializable]
public readonly struct InteractionError : IEquatable<InteractionError>
{
public readonly InteractionErrorCode Code;
public readonly string Message;
private InteractionError(InteractionErrorCode code, string message)
{
Code = code;
Message = message;
}
public static InteractionError None => new(InteractionErrorCode.None, string.Empty);
public static InteractionError Locked(string message = "The door is locked.") => new(InteractionErrorCode.Locked, message);
public static InteractionError MissingItem(string message = "This requires a key.") => new(InteractionErrorCode.MissingItem, message);
public static InteractionError RequiresSwitch(string message = "This is unlocked from somewhere else.") => new(InteractionErrorCode.RequiresSwitch, message);
public static InteractionError Generic(string message = "An unknown interaction error occurred.") => new(InteractionErrorCode.Generic, message);
public static implicit operator InteractionError(InteractionErrorCode code)
{
return code switch
{
InteractionErrorCode.None => None,
InteractionErrorCode.Locked => Locked(),
InteractionErrorCode.MissingItem => MissingItem(),
InteractionErrorCode.RequiresSwitch => RequiresSwitch(),
InteractionErrorCode.Generic => Generic(),
_ => throw new ArgumentOutOfRangeException()
};
}
public bool Equals(InteractionError other)
{
return Code == other.Code;
}
public override bool Equals(object obj)
{
return obj is InteractionError other && Equals(other);
}
public override int GetHashCode()
{
return HashCode.Combine(Code);
}
public override string ToString()
{
return $"[{Code}] {Message}";
}
}
public interface IInteractor : IGameObject
{
GameObject Root { get; }
}
public interface IInteractable : IGameObject
{
public static class Result
{
public static IResult<Unit, InteractionError> Ok() => System.Result.Ok<Unit, InteractionError>(default);
public static IResult<Unit, InteractionError> Err(InteractionError error) => System.Result.Err<Unit, InteractionError>(error);
public static IResult<Unit, InteractionError> Err(InteractionErrorCode error) => System.Result.Err<Unit, InteractionError>(error);
}
bool IsInteractable { get; }
virtual void Target(IInteractor interactor) { }
IResult<Unit, InteractionError> Interact(IInteractor interactor);
}
}