using System.Collections; using System.Collections.Generic; using System.Linq; using BlueWater.Npcs.Crews; using BlueWater.Npcs.Crews.Bartender; using BlueWater.Npcs.Crews.Cleaner; using BlueWater.Npcs.Crews.Server; using BlueWater.Npcs.Customers; using BlueWater.Utility; using Sirenix.OdinInspector; using UnityEngine; namespace BlueWater.Tycoons { public class CrewController : MonoBehaviour { [Title("Crew 프리팹")] [SerializeField] private CleanerCrew _cleanerCrewPrefab; [SerializeField] private ServerCrew _servingCrewPrefab; [SerializeField] private BartenderCrew _bartenderCrewPrefab; [Title("Crew 생성 변수")] [SerializeField] private Transform _cleanerCrewSpawnTransform; [SerializeField] private Transform _servingCrewSpawnTransform; [SerializeField] private List _bartenderCrewSpawnTransforms = new(5); [field: Title("실시간 데이터")] [field: SerializeField] public List Crews { get; private set; } [field: SerializeField] public List CleanerCrews { get; private set; } [field: SerializeField] public List ServerCrews { get; private set; } [field: SerializeField] public List BartenderCrews { get; private set; } private void Start() { EventManager.OnCreateCleanerCrew += CreateCleanerCrew; EventManager.OnCreateServerCrew += CreateServerCrew; EventManager.OnCreateBartenderCrew += CreateBartenderCrew; EventManager.OnOrderedCocktail += FindBartenderCrew; } private void OnDestroy() { EventManager.OnCreateCleanerCrew -= CreateCleanerCrew; EventManager.OnCreateServerCrew -= CreateServerCrew; EventManager.OnCreateBartenderCrew -= CreateBartenderCrew; EventManager.OnOrderedCocktail -= FindBartenderCrew; } public CleanerCrew CreateCleanerCrew() { var newCrew = Instantiate(_cleanerCrewPrefab, _cleanerCrewSpawnTransform.position, _cleanerCrewPrefab.transform.rotation); Utils.RegisterList(CleanerCrews, newCrew); Utils.RegisterList(Crews, newCrew); newCrew.Initialize(); EventManager.InvokeUpdateCrewUi(BartenderCrews.Count, ServerCrews.Count, CleanerCrews.Count); return newCrew; } public ServerCrew CreateServerCrew() { var newCrew = Instantiate(_servingCrewPrefab, _servingCrewSpawnTransform.position, _servingCrewPrefab.transform.rotation); Utils.RegisterList(ServerCrews, newCrew); Utils.RegisterList(Crews, newCrew); newCrew.Initialize(); EventManager.InvokeUpdateCrewUi(BartenderCrews.Count, ServerCrews.Count, CleanerCrews.Count); return newCrew; } public BartenderCrew CreateBartenderCrew() { int randomIndex = Random.Range(0, _bartenderCrewSpawnTransforms.Count); Transform spawnTransform = _bartenderCrewSpawnTransforms[randomIndex]; _bartenderCrewSpawnTransforms.Remove(spawnTransform); var newCrew = Instantiate(_bartenderCrewPrefab, spawnTransform.position, _bartenderCrewPrefab.transform.rotation); Utils.RegisterList(BartenderCrews, newCrew); Utils.RegisterList(Crews, newCrew); newCrew.SetBartenderTable(spawnTransform.GetComponentInParent()); newCrew.Initialize(); EventManager.InvokeUpdateCrewUi(BartenderCrews.Count, ServerCrews.Count, CleanerCrews.Count); return newCrew; } public T FindClosestAvailableCrew(Vector3 position, List crews) where T : Crew { if (crews == null || crews.Count == 0) return null; var availableCrews = crews.Where(crew => !crew.IsOnMission).ToList(); if (availableCrews.Count == 0) return null; return availableCrews .OrderBy(crew => Vector3.Distance(crew.transform.position, position)) .FirstOrDefault(); } public IEnumerator FindClosestCrewCoroutine(Vector3 position, List crews, System.Action onCrewFoundEvent) where T : Crew { var waitTime = new WaitForSeconds(2f); while (true) { var closestCrew = FindClosestAvailableCrew(position, crews); if (closestCrew != null) { onCrewFoundEvent?.Invoke(closestCrew); yield break; } yield return waitTime; } } private void FindBartenderCrew(Customer orderedCustomer) { StartCoroutine(FindBartenderCrewCoroutine(orderedCustomer)); } private IEnumerator FindBartenderCrewCoroutine(Customer orderedCustomer) { var waitTime = new WaitForSeconds(2f); var tycoonManager = TycoonManager.Instance; var tycoonIngredientController = tycoonManager.TycoonIngredientController; var orderedCocktailData = orderedCustomer.OrderedCocktailData; yield return new WaitForSeconds(0.5f); while (true) { var orderedCount = tycoonManager.CustomerController.OrderedCocktailCount(orderedCocktailData.Idx); if (!tycoonManager.TycoonStageController.CanMakingCocktail(orderedCocktailData.Idx, orderedCount)) { yield return waitTime; continue; } foreach (var element in BartenderCrews) { if (element.MyBartenderTable.CurrentPickupItem != null || element.IsOnMission) continue; var orderedCocktailIngredients = orderedCocktailData.ValidIngredients; if (!tycoonIngredientController.IsMakingCocktail(orderedCocktailIngredients)) break; if (orderedCustomer.IsReceivedItem || orderedCustomer.IsMatchedServer) yield break; element.SetOrderedCustomer(orderedCustomer); tycoonIngredientController.ConsumeMakingCocktailIngredient(orderedCocktailIngredients); yield break; } yield return waitTime; } } } }