using System; using BlueWater.Audios; using BlueWater.Interfaces; using BlueWater.Npcs.Crews; using BlueWater.Npcs.Crews.Cleaner; using BlueWater.Uis; using BlueWater.Utility; using Sirenix.OdinInspector; using UnityEngine; namespace BlueWater.Tycoons { [Serializable] public class TableSeat : InteractionFurniture, ICrewInteraction { [field: SerializeField] public BalloonUi MenuBalloonUi { get; private set; } [SerializeField] private PayMoneyUi _payMoneyUiObject; [SerializeField] private Vector3 _offset = new(0f, 1.5f, 0f); [field: SerializeField] public bool IsOccupied { get; private set; } [field: SerializeField] public bool IsReserved { get; private set; } [field: SerializeField] public bool IsCleaned { get; private set; } = true; [field: SerializeField] public Transform SeatTransform { get; private set; } [field: SerializeField] public SpriteRenderer Food { get; private set; } [field: SerializeField] public Vector3 TableDirection; [field: SerializeField] public int TableNumber; [SerializeField] private Sprite _fullBeerGlass; [SerializeField] private Sprite _emptyBeerGlass; [SerializeField] private float _playerHoldingTime = 3f; [SerializeField] private float _crewHoldingTime = 9f; [SerializeField] private string _cleaningSfxName = "CleaningTable"; [Title("연출")] [SerializeField] private Color _originalColor = Color.white; [SerializeField] private Color _mismatchedColor = Color.gray; private LevelData _currentLevelData; private Coroutine _findCleanerCrewInstance; private bool _isPlayerInteracting; private bool _isCrewInteracting; public event Action OnInteractionCompleted; protected override void OnEnable() { base.OnEnable(); Initialize(); } protected override void Start() { base.Start(); EventManager.OnCleaningAll += Cleaning; EventManager.OnChangedPickupItem += ChangeMenuColor; } private void Update() { if (InteractionCanvas.BalloonUi.IsWaitTimeOver()) { var damageable = GameManager.Instance.CurrentTycoonPlayer.GetComponent(); damageable?.TakeDamage(1); EventManager.InvokeCleaningResult(false); CleanTable(); } if (IsCleaned) return; if (IsShowing) { EventManager.InvokeHoldInteracting(HoldingElapsedTime); } if (HoldingElapsedTime >= 1f) { if (_isPlayerInteracting) { if (TycoonManager.Instance.TycoonStatus.CurrentPassiveCard == PassiveCard.CleaningBonus) { TycoonManager.Instance.TycoonStageController.CleaningBonus(); } var tip = (int)(_currentLevelData.Gold * TycoonManager.Instance.TycoonStatus.TipMultiplier); if (tip > 0) { var payMoneyUi = Instantiate(_payMoneyUiObject, transform.position + _offset, Quaternion.identity, TycoonUiManager.Instance.WorldCanvas.transform); payMoneyUi.Initialize(tip, true); } } if (_isCrewInteracting) { OnInteractionCompleted?.Invoke(); OnInteractionCompleted = null; } EventManager.InvokeCleaningResult(true); CleanTable(); } if (_isPlayerInteracting) { InteractionCanvas.BalloonUi.PauseTween(); HoldingElapsedTime += Time.deltaTime / _playerHoldingTime; } if (_isCrewInteracting) { InteractionCanvas.BalloonUi.PauseTween(); HoldingElapsedTime += Time.deltaTime / (_crewHoldingTime - TycoonManager.Instance.TycoonStatus.CleanerCleaningReduction); } if (!_isPlayerInteracting && !_isCrewInteracting) { InteractionCanvas.BalloonUi.ResumeTween(); if (HoldingElapsedTime > 0f) { HoldingElapsedTime -= Time.deltaTime; } } } private void OnDestroy() { EventManager.OnCleaningAll -= Cleaning; EventManager.OnChangedPickupItem -= ChangeMenuColor; } public void Initialize() { UnreserveSeat(); VacateSeat(); CleanTable(); Food.sprite = null; Food.enabled = false; } public void SetTableNumber(int number) => TableNumber = number; public void SetFood(Sprite cocktailSprite) { Food.sprite = cocktailSprite; Food.enabled = true; } public override void Interaction() { GameManager.Instance.CurrentTycoonPlayer.IsCleaningTable = true; _isPlayerInteracting = true; AudioManager.Instance.PlaySfx(_cleaningSfxName); } public override void CancelInteraction() { GameManager.Instance.CurrentTycoonPlayer.IsCleaningTable = false; _isPlayerInteracting = false; AudioManager.Instance.StopSfx(_cleaningSfxName); } public override bool CanInteraction() { return !GameManager.Instance.CurrentTycoonPlayer.TycoonPickupHandler.IsPickedUpAnything() && !IsCleaned; } public void ReserveSeat() => IsReserved = true; public void UnreserveSeat() => IsReserved = false; public void OccupySeat() => IsOccupied = true; public void VacateSeat() => IsOccupied = false; public void CleanTable() { Food.sprite = null; Food.enabled = false; IsCleaned = true; _isPlayerInteracting = false; _isCrewInteracting = false; InteractionCanvas.BalloonUi.DiscardItem(); MenuBalloonUi.DiscardItem(); HoldingElapsedTime = 0f; } public void DirtyTable() { _currentLevelData = TycoonManager.Instance.GetCurrentLevelData(); Food.sprite = _emptyBeerGlass; Food.enabled = true; InteractionCanvas.BalloonUi.OrderItem(DataManager.Instance.SpriteDataSo.Cleaning, 0, TycoonManager.Instance.TycoonStageController.StageDataSo.DirtyTableWaitTime); IsCleaned = false; var crewController = TycoonManager.Instance.CrewController; Utils.StartUniqueCoroutine(this, ref _findCleanerCrewInstance, crewController.FindClosestCrewCoroutine(CenterTransform.position, crewController.CleanerCrews, crew => crew.OnMission(this))); } public void Purify() { if (IsCleaned) { Food.sprite = null; Food.enabled = false; } UnreserveSeat(); VacateSeat(); } public void InteractionCrew(Crew crew) { _isCrewInteracting = true; ((CleanerCrew)crew).SetIsCleaningTable(true); } public void CancelInteractionCrew() { _isCrewInteracting = false; } public bool CanInteractionCrew(Crew crew = null) { return !IsCleaned; } public void Cleaning() { if (IsCleaned) return; CleanTable(); } public void OrderCocktail(string itemIdx, float waitTime, float hurryTime, bool isReverse = false) { MenuBalloonUi.OrderItem(itemIdx, waitTime, hurryTime, isReverse); ChangeMenuColor(GameManager.Instance.CurrentTycoonPlayer.TycoonPickupHandler.CurrentPickupItem?.Idx); } public void ChangeMenuColor(string idx) { if (MenuBalloonUi.gameObject.activeInHierarchy) { if (idx == null || (MenuBalloonUi.IsWaitServing() && MenuBalloonUi.OrderCocktailData?.Idx == idx)) { ChangeMenuOriginalColor(); } else { MenuBalloonUi.SetColor(_mismatchedColor); } } } public void ChangeMenuOriginalColor() { MenuBalloonUi.SetColor(_originalColor); } } }