159 lines
4.7 KiB
C#
159 lines
4.7 KiB
C#
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<CustomerNPC> line = new List<CustomerNPC>();
|
|
private CustomerNPC customerAtTill;
|
|
private List<GameObject> spawnedItems = new List<GameObject>();
|
|
|
|
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<ItemData> 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<Collider>()) 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.");
|
|
}
|
|
|
|
ClearCounter();
|
|
|
|
// Customer leaves
|
|
line.Remove(customerAtTill);
|
|
customerAtTill.FinishCheckoutAndLeave();
|
|
customerAtTill = null;
|
|
|
|
if (UIManager.Instance != null)
|
|
{
|
|
UIManager.Instance.CloseAllMenus();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|