193 lines
6.7 KiB
C#
193 lines
6.7 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using UnityEngine;
|
|
using Sirenix.OdinInspector;
|
|
|
|
namespace DDD
|
|
{
|
|
public static class RestaurantInteractionSubsystems
|
|
{
|
|
public static Dictionary<InteractionType, Type> TypeToSubsystem = new()
|
|
{
|
|
{InteractionType.RestaurantOrder, typeof(RestaurantOrderInteractionSubsystem)},
|
|
{InteractionType.RestaurantManagement, typeof(RestaurantManagementInteractionSubsystem)}
|
|
};
|
|
}
|
|
|
|
|
|
public class RestaurantInteractionComponent : MonoBehaviour, IInteractable, IInteractionSubsystemOwner
|
|
{
|
|
// Single interaction type
|
|
[ValueDropdown("GetAllInteractionTypes")]
|
|
[SerializeField] protected InteractionType _interactionType = InteractionType.None;
|
|
[SerializeField] protected InteractionExecutionParameters _executionParameters = new InteractionExecutionParameters(1f);
|
|
[SerializeField] protected InteractionDisplayParameters _displayParameters = new InteractionDisplayParameters("");
|
|
[SerializeField] protected GameFlowState _interactionAvailableFlows;
|
|
[SerializeField] private Transform[] _aiInteractionPoints;
|
|
[SerializeField] private bool autoInitialize = true;
|
|
|
|
private Dictionary<InteractionType, IInteractionSubsystemObject> _subsystems = new();
|
|
|
|
private void Start()
|
|
{
|
|
if (autoInitialize)
|
|
{
|
|
InitializeInteraction(_interactionType);
|
|
}
|
|
}
|
|
|
|
private static IEnumerable GetAllInteractionTypes()
|
|
{
|
|
return System.Enum.GetValues(typeof(InteractionType))
|
|
.Cast<InteractionType>()
|
|
.Where(x => x != InteractionType.All); // All은 제외
|
|
}
|
|
|
|
public virtual bool CanInteract()
|
|
{
|
|
bool isInteractionVisible = !IsInteractionHidden();
|
|
bool hasValidSubsystem = true;
|
|
if (HasSubsystem(_interactionType))
|
|
{
|
|
hasValidSubsystem = GetSubsystem(_interactionType).CanInteract();
|
|
}
|
|
return isInteractionVisible && hasValidSubsystem;
|
|
}
|
|
|
|
public virtual bool IsInteractionHidden()
|
|
{
|
|
var currentGameFlowState = GameFlowManager.Instance.GameFlowDataSo.CurrentGameState;
|
|
var flowDisabled = (currentGameFlowState & _interactionAvailableFlows) == 0;
|
|
return flowDisabled;
|
|
}
|
|
|
|
public virtual bool OnInteracted(IInteractor interactor, ScriptableObject causerPayload = null)
|
|
{
|
|
if (CanInteract() == false)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
bool interactionResult = RestaurantInteractionEvents.RestaurantInteraction.RequestInteraction(interactor.GetInteractorGameObject(),
|
|
GetInteractableGameObject(), GetInteractionType(), causerPayload, GetPayload(), true);
|
|
if (HasSubsystem(_interactionType))
|
|
{
|
|
interactionResult &= GetSubsystem(_interactionType).OnInteracted(interactor, causerPayload);
|
|
}
|
|
return interactionResult;
|
|
}
|
|
|
|
public virtual InteractionType GetInteractionType()
|
|
{
|
|
return _interactionType;
|
|
}
|
|
|
|
public GameObject GetInteractableGameObject()
|
|
{
|
|
return gameObject;
|
|
}
|
|
|
|
public virtual void InitializeInteraction(InteractionType interactionType)
|
|
{
|
|
_interactionType = interactionType;
|
|
|
|
InitializeSubsystems();
|
|
}
|
|
|
|
private void InitializeSubsystems()
|
|
{
|
|
// Initialize Interaction Subsystems
|
|
bool hasSubsystemType = RestaurantInteractionSubsystems.TypeToSubsystem.TryGetValue(_interactionType, out var subsystemType);
|
|
if (!hasSubsystemType) return;
|
|
|
|
var subsystem = gameObject.GetComponent(subsystemType) as IInteractionSubsystemObject;
|
|
if (subsystem == null)
|
|
{
|
|
subsystem = gameObject.AddComponent(subsystemType) as IInteractionSubsystemObject;
|
|
}
|
|
_subsystems.Add(_interactionType, subsystem);
|
|
subsystem?.InitializeSubsystem();
|
|
}
|
|
|
|
private bool HasSubsystem(InteractionType interactionType)
|
|
{
|
|
return _subsystems.ContainsKey(interactionType);
|
|
}
|
|
|
|
private IInteractionSubsystemObject GetSubsystem(InteractionType interactionType)
|
|
{
|
|
return _subsystems.GetValueOrDefault(interactionType) as IInteractionSubsystemObject;
|
|
}
|
|
|
|
private bool TryGetSubsystem(InteractionType interactionType, out IInteractionSubsystemObject subsystem)
|
|
{
|
|
return _subsystems.TryGetValue(interactionType, out subsystem);
|
|
}
|
|
|
|
// 새로운 스트럭트 기반 메서드들
|
|
public virtual InteractionExecutionParameters GetExecutionParameters()
|
|
{
|
|
return _executionParameters;
|
|
}
|
|
|
|
public virtual InteractionDisplayParameters GetDisplayParameters()
|
|
{
|
|
return _displayParameters;
|
|
}
|
|
|
|
// 하위 호환성을 위한 기존 메서드들
|
|
public float GetRequiredHoldTime()
|
|
{
|
|
return _executionParameters.HoldTime;
|
|
}
|
|
|
|
public string GetInteractionMessageKey()
|
|
{
|
|
return _displayParameters.MessageKey;
|
|
}
|
|
|
|
public Vector3[] GetInteractionPoints()
|
|
{
|
|
if (_aiInteractionPoints == null || _aiInteractionPoints.Length == 0)
|
|
{
|
|
return new Vector3[] { transform.position };
|
|
}
|
|
|
|
Vector3[] positions = new Vector3[_aiInteractionPoints.Length];
|
|
for (int i = 0; i < _aiInteractionPoints.Length; i++)
|
|
{
|
|
if (_aiInteractionPoints[i] != null)
|
|
{
|
|
positions[i] = _aiInteractionPoints[i].position;
|
|
}
|
|
else
|
|
{
|
|
positions[i] = transform.position;
|
|
}
|
|
}
|
|
return positions;
|
|
}
|
|
|
|
public ScriptableObject GetPayload()
|
|
{
|
|
return TryGetSubsystem(_interactionType, out var subsystem) ? subsystem.GetPayload() : null;
|
|
}
|
|
|
|
public bool TryGetSubsystemObject<T>(out IInteractionSubsystemObject<T> subsystemObject) where T : Enum
|
|
{
|
|
foreach (var interactionSubsystemObject in _subsystems.Values)
|
|
{
|
|
if (interactionSubsystemObject is IInteractionSubsystemObject<T> subsystem)
|
|
{
|
|
subsystemObject = subsystem;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
subsystemObject = null;
|
|
return false;
|
|
}
|
|
}
|
|
} |