using System.Collections.Generic; using UnityEngine; namespace MedievalShopkeeper { public class ShopTill : Interactable { [Header("Queue Settings")] [Tooltip("Where the first customer stands (typically directly in front of the counter).")] public Transform queueStartPoint; [Tooltip("How far apart customers stand in line.")] public float queueSpacing = 1.5f; [Header("Counter Settings")] [Tooltip("Where the physical item models will spawn when a customer is checking out.")] public Transform counterTopSpot; // Queue Management private List line = new List(); private CustomerNPC customerAtTill; private List spawnedItems = new List(); public override string InteractionPrompt { get { if (customerAtTill != null) return "Serve Customer"; return "Till (No customers waiting)"; } } public void JoinQueue(CustomerNPC npc) { if (!line.Contains(npc)) { line.Add(npc); } } public void LeaveQueue(CustomerNPC npc) { line.Remove(npc); if (customerAtTill == npc) { ClearCounter(); customerAtTill = null; } } public bool IsFrontOfQueue(CustomerNPC npc) { return line.Count > 0 && line[0] == npc; } public Vector3 GetQueuePosition(CustomerNPC npc) { int index = line.IndexOf(npc); if (index == -1) index = 0; // Fallback if (queueStartPoint != null) { // Queue extends backwards along the local Z axis return queueStartPoint.position - (queueStartPoint.forward * (index * queueSpacing)); } return transform.position - (transform.forward * (1f + (index * queueSpacing))); } public void PlaceItemsOnCounter(CustomerNPC npc, List items) { customerAtTill = npc; ClearCounter(); if (counterTopSpot == null) return; foreach (var item in items) { if (item != null && item.displayPrefab != null) { // Add a tiny random offset so items pile up naturally Vector3 randomOffset = new Vector3( Random.Range(-0.2f, 0.2f), 0, Random.Range(-0.2f, 0.2f) ); GameObject vis = Instantiate(item.displayPrefab, counterTopSpot.position + randomOffset, Quaternion.identity); // Strip colliders from the spawned visuals foreach (var col in vis.GetComponentsInChildren()) Destroy(col); spawnedItems.Add(vis); } } } private void ClearCounter() { foreach (var vis in spawnedItems) { if (vis != null) Destroy(vis); } spawnedItems.Clear(); } public override void Interact(PlayerController player) { base.Interact(player); if (customerAtTill != null && customerAtTill.GetBasket().Count > 0) { if (UIManager.Instance != null) { UIManager.Instance.OpenTillMenu(this, customerAtTill.GetBasket()); } else { // Fallback if no UI ChargeCustomer(); } } else { Debug.Log("[ShopTill] No customer is ready at the till."); } } public void ChargeCustomer() { if (customerAtTill == null) return; int totalCost = 0; foreach (var item in customerAtTill.GetBasket()) { if (item != null) totalCost += item.sellPrice; } if (GameManager.Instance != null) { GameManager.Instance.AddMoney(totalCost); Debug.Log($"[ShopTill] Charged customer {totalCost} G."); } if (AudioManager.Instance != null) { AudioManager.Instance.PlaySale(); } ClearCounter(); // Customer leaves line.Remove(customerAtTill); customerAtTill.FinishCheckoutAndLeave(); customerAtTill = null; if (UIManager.Instance != null) { UIManager.Instance.CloseAllMenus(); } } } }