using System.Collections; using System.Collections.Generic; using UnityEngine; namespace MedievalShopkeeper { public class NPCManager : MonoBehaviour { [Header("Prefabs")] [Tooltip("List of visually different NPC prefabs to spawn.")] public List npcPrefabs; [Tooltip("Where the NPCs spawn when they arrive.")] public Transform spawnPoint; [Header("Spawning Settings")] [Tooltip("Base minimum time between spawns when shop is open.")] public float minSpawnDelay = 10f; [Tooltip("Base maximum time between spawns when shop is open.")] public float maxSpawnDelay = 25f; [Header("Demand & Items")] [Tooltip("List of all items currently available in the game that NPCs might want to buy.")] public List allAvailableItems; private float spawnTimer; private void Start() { ResetSpawnTimer(); } private void Update() { if (GameManager.Instance == null || !GameManager.Instance.IsShopOpen) return; spawnTimer -= Time.deltaTime; if (spawnTimer <= 0) { SpawnNPC(); ResetSpawnTimer(); } } private void ResetSpawnTimer() { float delay = Random.Range(minSpawnDelay, maxSpawnDelay); if (GameManager.Instance != null && GameManager.Instance.IsNightTime) { // Night time has fewer customers, so multiply the wait time delay *= 2.5f; } spawnTimer = delay; } private void SpawnNPC() { if (npcPrefabs == null || npcPrefabs.Count == 0) { Debug.LogWarning("[NPCManager] No NPC Prefabs assigned!"); return; } Vector3 spawnPos = spawnPoint != null ? spawnPoint.position : (ShopDoor.Instance != null ? ShopDoor.Instance.transform.position : Vector3.zero); GameObject prefabToSpawn = npcPrefabs[Random.Range(0, npcPrefabs.Count)]; GameObject spawnedObj = Instantiate(prefabToSpawn, spawnPos, Quaternion.identity); CustomerNPC npc = spawnedObj.GetComponent(); if (npc != null) { NPCIntention intent = RollForIntention(); List shoppingList = GenerateShoppingList(intent); npc.Initialize(intent, shoppingList); Debug.Log($"[NPCManager] Spawned {npc.npcName} with intention: {intent}."); } } private NPCIntention RollForIntention() { float shoplifterChance = 5f; float raiderChance = 2f; if (GameManager.Instance != null && GameManager.Instance.IsNightTime) { // Massive risk increase at night shoplifterChance = 20f; raiderChance = 10f; } float roll = Random.Range(0f, 100f); if (roll < raiderChance) return NPCIntention.Raider; if (roll < raiderChance + shoplifterChance) return NPCIntention.Shoplifter; return NPCIntention.Shopper; } private List GenerateShoppingList(NPCIntention intent) { List list = new List(); // Raiders don't care about shopping lists if (intent == NPCIntention.Raider) return list; if (allAvailableItems == null || allAvailableItems.Count == 0) return list; int itemsWanted = Random.Range(1, 4); for (int i = 0; i < itemsWanted; i++) { ItemData randomItem = allAvailableItems[Random.Range(0, allAvailableItems.Count)]; list.Add(randomItem); } return list; } } }