86 lines
2.8 KiB
C#
86 lines
2.8 KiB
C#
using AfterHours.Core;
|
|
using AfterHours.Data;
|
|
using AfterHours.Shop;
|
|
using Unity.Netcode;
|
|
using UnityEngine;
|
|
|
|
namespace AfterHours.Customers
|
|
{
|
|
/// <summary>
|
|
/// Erzeugt Kunden abhängig von Uhrzeit und Ruf. Läuft nur auf dem Server.
|
|
/// </summary>
|
|
public sealed class CustomerSpawner : NetworkBehaviour
|
|
{
|
|
public static CustomerSpawner Instance { get; private set; }
|
|
|
|
[SerializeField] private GameObject _customerPrefab;
|
|
[SerializeField] private Transform _entryPoint;
|
|
[SerializeField] private Transform _exitPoint;
|
|
[SerializeField] private CashRegister _register;
|
|
|
|
[Header("Andrang")]
|
|
[SerializeField] private int _maxConcurrent = 20;
|
|
[SerializeField] private float _baseSecondsBetweenSpawns = 8f;
|
|
|
|
[Tooltip("Multiplikator über den Tag: x-Achse 0..24 Uhr, y = Andrang.")]
|
|
[SerializeField] private AnimationCurve _rushCurve = AnimationCurve.Linear(0f, 1f, 24f, 1f);
|
|
|
|
public Transform ExitPoint => _exitPoint;
|
|
|
|
private float _cooldown;
|
|
private int _alive;
|
|
|
|
private void Awake() => Instance = this;
|
|
|
|
public override void OnNetworkDespawn()
|
|
{
|
|
if (Instance == this) Instance = null;
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (!IsServer) return;
|
|
if (GameClock.Instance == null || !GameClock.Instance.IsOpen) return;
|
|
if (_alive >= _maxConcurrent) return;
|
|
|
|
_cooldown -= Time.deltaTime;
|
|
if (_cooldown > 0f) return;
|
|
|
|
Spawn();
|
|
_cooldown = NextInterval();
|
|
}
|
|
|
|
private float NextInterval()
|
|
{
|
|
float rush = Mathf.Max(0.1f, _rushCurve.Evaluate(GameClock.Instance.HourOfDay));
|
|
float reputation = Mathf.Lerp(1.6f, 0.6f, ShopEconomy.Instance.Reputation);
|
|
return _baseSecondsBetweenSpawns / rush * reputation * Random.Range(0.7f, 1.3f);
|
|
}
|
|
|
|
private void Spawn()
|
|
{
|
|
var instance = Instantiate(_customerPrefab, _entryPoint.position, _entryPoint.rotation);
|
|
var netObject = instance.GetComponent<NetworkObject>();
|
|
netObject.Spawn();
|
|
|
|
var categories = (ProductCategory[])System.Enum.GetValues(typeof(ProductCategory));
|
|
|
|
var agent = instance.GetComponent<CustomerAgent>();
|
|
agent.Initialize(
|
|
tolerance: Random.Range(0.15f, 0.95f),
|
|
wantedItems: Random.Range(1, 4),
|
|
wantedCategory: categories[Random.Range(0, categories.Length)],
|
|
register: _register);
|
|
|
|
_alive++;
|
|
}
|
|
|
|
/// <summary>Wird von CustomerAgent kurz vor dem Despawn aufgerufen.</summary>
|
|
public void NotifyCustomerGone()
|
|
{
|
|
if (!IsServer) return;
|
|
_alive = Mathf.Max(0, _alive - 1);
|
|
}
|
|
}
|
|
}
|