Files
TheAuction-GS/Assets/Customer/CustomerManager.cs

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);
}
}
}