using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
/// <summary>
/// GAME 1303 Tier 7 — Sends shoppers into the store. Store Simulator.
///
/// SETUP
/// 1. Empty GameObject at the shop door + this script.
/// 2. Customer Prefabs: one or more CustomerAI prefabs (vary the models so the store
/// doesn't look cloned).
/// 3. Drag in the Register and a Store Exit transform — the spawner passes them to each
/// customer so they don't have to search.
/// 4. Rate: Seconds Between Customers with variance. Max In Store caps the crowd.
/// 5. Scale With Day: on by default — each day the interval shrinks by Rate Improvement
/// Per Day, so the shop gets busier as it grows. That's the progression curve for the
/// whole game, and it's one float.
/// 6. Only Spawn During Day pauses spawning between days.
/// </summary>
public class CustomerSpawner : MonoBehaviour
{
public List<GameObject> customerPrefabs = new List<GameObject>();
public Register register;
public Transform storeExit;
[Header("Rate")]
public float secondsBetweenCustomers = 12f;
public float variance = 4f;
public int maxInStore = 6;
public float startDelay = 5f;
[Header("Growth")]
public bool scaleWithDay = true;
[Tooltip("Seconds shaved off the interval per day.")]
public float rateImprovementPerDay = 0.8f;
public float minimumInterval = 3f;
[Header("Events")]
public UnityEvent<GameObject> OnCustomerSpawned;
private readonly List<GameObject> active = new List<GameObject>();
void Start()
{
if (register == null) register = FindFirstObjectByType<Register>();
StartCoroutine(SpawnLoop());
}
IEnumerator SpawnLoop()
{
yield return new WaitForSeconds(startDelay);
while (true)
{
active.RemoveAll(c => c == null);
if (active.Count < maxInStore) Spawn();
yield return new WaitForSeconds(CurrentInterval());
}
}
float CurrentInterval()
{
float baseInterval = secondsBetweenCustomers;
if (scaleWithDay && StoreEconomy.Instance != null)
baseInterval -= rateImprovementPerDay * (StoreEconomy.Instance.Day - 1);
baseInterval = Mathf.Max(minimumInterval, baseInterval);
return Mathf.Max(0.5f, baseInterval + Random.Range(-variance, variance));
}
public void Spawn()
{
if (customerPrefabs.Count == 0) return;
var prefab = customerPrefabs[Random.Range(0, customerPrefabs.Count)];
if (prefab == null) return;
var customer = Instantiate(prefab, transform.position, transform.rotation);
var ai = customer.GetComponent<CustomerAI>();
if (ai != null)
{
ai.register = register;
ai.storeExit = storeExit != null ? storeExit : transform;
}
active.Add(customer);
OnCustomerSpawned?.Invoke(customer);
}
}