124 lines
4.4 KiB
C#
124 lines
4.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using JetBrains.Annotations;
|
|
using UnityEngine;
|
|
using static CustomerController;
|
|
using Random = UnityEngine.Random;
|
|
|
|
|
|
public class CustomerManager : MonoBehaviour {
|
|
public static CustomerManager Instance { get; private set; }
|
|
|
|
|
|
[SerializeField] private GameObject _customerPrefab;
|
|
[SerializeField] private Transform _customerSpawnPoint;
|
|
|
|
[SerializeField] private float _timeToNextCustomerMin = 5;
|
|
[SerializeField] private float _timeToNextCustomerMax = 10;
|
|
|
|
private List<SellCounter> _sellCounters = new List<SellCounter>();
|
|
private List<SellCounter> AvailableCounters { get; } = new List<SellCounter>();
|
|
|
|
private readonly List<CustomerController> _customers = new List<CustomerController>();
|
|
|
|
private int _newCustomerNeeded; // 0 = no new ones needed, > 0 = new one needed
|
|
private float _timeToNextCustomer;
|
|
|
|
|
|
//Args for the event
|
|
public class OnCustomerLeftArgs : EventArgs {
|
|
public bool Angry;
|
|
}
|
|
|
|
public event EventHandler<OnCustomerLeftArgs> OnCustomerLeft;
|
|
|
|
// Start is called before the first frame update
|
|
private void Start() {
|
|
// Find all sellingCounters in the scene
|
|
|
|
if (Instance != null) {
|
|
Debug.LogError("What? 2 CustomerManagers crazy!!!");
|
|
}
|
|
|
|
Instance = this;
|
|
|
|
var sellCounters = FindObjectsOfType<SellCounter>();
|
|
foreach (var sellCounter in sellCounters) {
|
|
sellCounter.OnCounterStartSelling += CounterStartedSelling;
|
|
_sellCounters?.Add(sellCounter);
|
|
}
|
|
|
|
|
|
}
|
|
|
|
private void CounterStartedSelling(object sender, [NotNull] SellCounter.OnCounterStartSellingArgs e) {
|
|
if (e == null) throw new ArgumentNullException(nameof(e));
|
|
// Spawn a customer at the spawn point
|
|
_newCustomerNeeded += 1;
|
|
AvailableCounters.Add(e.SellCounter);
|
|
}
|
|
|
|
private void SpawnCustomer(SellCounter target) {
|
|
var customer = Instantiate(_customerPrefab, _customerSpawnPoint.position, Quaternion.identity);
|
|
var customerController = customer.GetComponent<CustomerController>();
|
|
|
|
customerController.SetTargetCounter(target);
|
|
customerController.SetExitPosition(_customerSpawnPoint.position);
|
|
|
|
customerController.OnCustomerLeft += CustomerLeft;
|
|
_customers.Add(customerController);
|
|
}
|
|
|
|
private void CustomerLeft(SellCounter sellCounter, CustomerController customerController) {
|
|
if (customerController.State == Customer.MoodState.Angry) {
|
|
//Customer left angry, should dispach a new customer to the counter
|
|
_newCustomerNeeded += 1;
|
|
if (!AvailableCounters.Contains(sellCounter)) {
|
|
AvailableCounters.Add(sellCounter);
|
|
}
|
|
else {
|
|
Debug.LogError("This should not happen, the counter is already in the available list");
|
|
}
|
|
}
|
|
OnCustomerLeft?.Invoke(this, new OnCustomerLeftArgs { Angry = customerController.State == Customer.MoodState.Angry });
|
|
}
|
|
|
|
|
|
// Update is called once per frame
|
|
private void Update() {
|
|
if(AvailableCounters.Count == 0) return;
|
|
if (_newCustomerNeeded > 0) {
|
|
_timeToNextCustomer -= Time.deltaTime;
|
|
if (_timeToNextCustomer <= 0) {
|
|
_newCustomerNeeded--;
|
|
_timeToNextCustomer = Random.Range(_timeToNextCustomerMin, _timeToNextCustomerMax);
|
|
|
|
SellCounter target = AvailableCounters[Random.Range(0, AvailableCounters.Count)];
|
|
SpawnCustomer(target);
|
|
|
|
AvailableCounters.Remove(target);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void StoppedSelling(SellCounter sellCounter) {
|
|
if (AvailableCounters.Contains(sellCounter)) {
|
|
AvailableCounters.Remove(sellCounter);
|
|
}
|
|
|
|
//Check if any customer has this counter as an target
|
|
foreach (var customerController in _customers) {
|
|
if (customerController.TargetCounter != sellCounter) continue;
|
|
|
|
customerController.SetDestination(_customerSpawnPoint.position);
|
|
customerController.SetState(CustomerState.WalkingToExit);
|
|
}
|
|
}
|
|
|
|
public void CustomerDies([NotNull] CustomerController customerController) {
|
|
if (customerController == null) return;
|
|
if (_customers.Contains(customerController)) {
|
|
_customers.Remove(customerController);
|
|
}
|
|
}
|
|
} |