using System; using System.Collections; using BlueWater.Interfaces; using BlueWater.Npcs.Crews; using BlueWater.Npcs.Crews.Server; using BlueWater.Npcs.Customers; using BlueWater.Utility; using UnityEngine; using UnityEngine.Serialization; namespace BlueWater.Tycoons { public class ServingTable : InteractionFurniture, ICrewInteraction { [FormerlySerializedAs("_cocktailGlassImage")] [SerializeField] protected SpriteRenderer CocktailGlassImage; // 서빙 테이블 기준 아이템이 있는지 없는지 private IPickup _currentPickupItem; public IPickup CurrentPickupItem { get => _currentPickupItem; set { _currentPickupItem = value; if (_currentPickupItem != null) { Utils.StartUniqueCoroutine(this, ref _findCustomerMatchingItemInstance, FindCustomerMatchingItem()); } else { if (_findCustomerMatchingItemInstance != null) { StopCoroutine(_findCustomerMatchingItemInstance); _findCustomerMatchingItemInstance = null; } if (_findServerCrewInstance != null) { StopCoroutine(_findServerCrewInstance); _findServerCrewInstance = null; } } } } protected Customer OrderedCustomer; private Material _originalCocktailGlassMaterial; private Coroutine _findCustomerMatchingItemInstance; private Coroutine _findServerCrewInstance; public event Action OnInteractionCompleted; protected override void Awake() { base.Awake(); _originalCocktailGlassMaterial = CocktailGlassImage.material; } public override void Interaction() { // 테이블의 칵테일을 가져가는 경우 if (CurrentPickupItem != null) { CurrentTycoonPlayer.TycoonPickupHandler.PickupItem(CurrentPickupItem); CurrentTycoonPlayer.InteractionCanvas.BalloonUi.SetItemImage(CurrentPickupItem); CocktailGlassImage.enabled = false; InteractionCanvas.BalloonUi.DiscardItem(); CurrentPickupItem = null; OrderedCustomer = null; } // 테이블에 칵테일을 놓는 경우 else { EventManager.InvokePlaceOnServingTable(); CurrentPickupItem = CurrentTycoonPlayer.TycoonPickupHandler.GetCurrentPickupItem(); InteractionCanvas.BalloonUi.SetItemImage(CurrentPickupItem); CurrentTycoonPlayer.TycoonPickupHandler.DiscardItem(); CurrentTycoonPlayer.InteractionCanvas.BalloonUi.DiscardItem(); CocktailGlassImage.enabled = true; } } public override bool CanInteraction() { // 1. 테이블에 칵테일이 있고, 플레이어가 칵테일을 들고 있지 않은 경우 // 2. 테이블에 칵테일이 없고, 플레이어가 칵테일을 들고 있는 경우 (정상적인 칵테일만) return (CurrentPickupItem != null && !CurrentTycoonPlayer.TycoonPickupHandler.IsPickedUpCocktail()) || (CurrentPickupItem == null && CurrentTycoonPlayer.TycoonPickupHandler.IsServablePickupItem()); } public override void ShowInteractionUi() { InteractionMessage = CurrentPickupItem != null ? "음료 들기" : "음료 내려놓기"; base.ShowInteractionUi(); CocktailGlassImage.material = OutlineMaterial; } public override void HideInteractionUi() { base.HideInteractionUi(); CocktailGlassImage.material = _originalCocktailGlassMaterial; } public void InteractionCrew(Crew crew) { // 종업원이 테이블의 칵테일을 가져가는 경우 if (CurrentPickupItem != null) { var serverCrew = (ServerCrew)crew; serverCrew.TakeFromServingTable(CurrentPickupItem, OrderedCustomer); CocktailGlassImage.enabled = false; InteractionCanvas.BalloonUi.DiscardItem(); CurrentPickupItem = null; OrderedCustomer = null; } // 종업원이 테이블에 칵테일을 놓는 경우 else { var serverCrew = (ServerCrew)crew; CurrentPickupItem = serverCrew.CurrentPickupItem; CocktailGlassImage.enabled = true; InteractionCanvas.BalloonUi.SetItemImage(CurrentPickupItem); serverCrew.ResetMission(); } } public void CancelInteractionCrew() { throw new NotImplementedException(); } public virtual bool CanInteractionCrew(Crew crew = null) { var servingCrew = (ServerCrew)crew; if (!servingCrew) { throw new Exception("상호작용 오브젝트 오류"); } return (servingCrew.CurrentActionType == ActionType.TakeCocktail && CurrentPickupItem != null && OrderedCustomer) || servingCrew.CurrentActionType == ActionType.PlaceOnServingTable && CurrentPickupItem == null; } private IEnumerator FindCustomerMatchingItem() { var waitTime = new WaitForSeconds(2f); while (true) { OrderedCustomer = TycoonManager.Instance.CustomerController.FindCustomerMatchingItem(_currentPickupItem); if (OrderedCustomer && OrderedCustomer.CanInteractionCrew()) { var crewController = TycoonManager.Instance.CrewController; Utils.StartUniqueCoroutine(this, ref _findServerCrewInstance, crewController.FindClosestCrewCoroutine(CenterTransform.position, crewController.ServerCrews, crew => crew.OnMission(this, OrderedCustomer, ActionType.TakeCocktail))); } yield return waitTime; } } } }