Files
MedievalShopkeeper/Assets/Scripts/ShopInventory.cs

138 lines
4.7 KiB
C#
Raw Normal View History

2026-09-03 16:35:05 +01:00
using System;
using System.Collections.Generic;
using UnityEngine;
namespace MedievalShopkeeper
{
public class ShopInventory : MonoBehaviour
{
public static ShopInventory Instance { get; private set; }
// Tracks how many of each item are in the virtual "backroom" storage
private Dictionary<ItemData, int> stock = new Dictionary<ItemData, int>();
public event Action OnInventoryUpdated;
[Header("Prefabs")]
[Tooltip("The crate/box prefab spawned when taking stock out to carry. Attach a StockBox component to it!")]
[SerializeField] private GameObject defaultStockBoxPrefab;
private void Awake()
{
if (Instance != null && Instance != this)
{
Destroy(gameObject);
return;
}
Instance = this;
}
public int GetStockCount(ItemData item)
{
if (item == null) return 0;
return stock.TryGetValue(item, out int count) ? count : 0;
}
public bool BuyStock(ItemData item, int quantity)
{
if (item == null || quantity <= 0) return false;
int totalCost = item.buyPrice * quantity;
if (GameManager.Instance != null && GameManager.Instance.TrySpendMoney(totalCost))
{
AddStock(item, quantity);
Debug.Log($"[ShopInventory] Bought {quantity}x {item.itemName}. Cost: {totalCost}");
return true;
}
Debug.LogWarning($"[ShopInventory] Cannot afford {quantity}x {item.itemName}. Need: {totalCost}");
return false;
}
public void AddStock(ItemData item, int quantity)
{
if (item == null || quantity <= 0) return;
if (stock.ContainsKey(item))
stock[item] += quantity;
else
stock[item] = quantity;
OnInventoryUpdated?.Invoke();
}
public bool RemoveStock(ItemData item, int quantity)
{
if (item == null || quantity <= 0) return false;
if (stock.ContainsKey(item) && stock[item] >= quantity)
{
stock[item] -= quantity;
if (stock[item] == 0)
{
stock.Remove(item); // Clean up empty entries
}
OnInventoryUpdated?.Invoke();
return true;
}
return false;
}
/// <summary>
/// Spawns a physical StockBox in the player's hands from the backroom inventory.
/// </summary>
public void WithdrawToPlayer(ItemData item, int quantity, PlayerController player)
{
if (player == null || player.IsCarryingItem)
{
Debug.LogWarning("[ShopInventory] Player is already carrying something or is null!");
return;
}
// Verify we actually have enough stock
if (GetStockCount(item) < quantity)
{
Debug.LogWarning($"[ShopInventory] Not enough {item.itemName} in stock to withdraw {quantity}. Max available: {GetStockCount(item)}");
// Auto-adjust to max available instead of failing? Let's just fail for safety/feedback.
return;
}
// Spawn the box
GameObject boxObj = null;
if (defaultStockBoxPrefab != null)
{
boxObj = Instantiate(defaultStockBoxPrefab);
}
else
{
// Fallback cube if no prefab assigned
boxObj = GameObject.CreatePrimitive(PrimitiveType.Cube);
boxObj.transform.localScale = new Vector3(0.5f, 0.5f, 0.5f);
boxObj.name = "Fallback Crate";
Destroy(boxObj.GetComponent<Collider>()); // prevent physical collisions while carried
// Give it a brown color
var rend = boxObj.GetComponent<Renderer>();
if (rend != null) rend.material.color = new Color(0.5f, 0.3f, 0.1f);
}
// Attach and configure StockBox component
StockBox stockBox = boxObj.GetComponent<StockBox>();
if (stockBox == null)
{
stockBox = boxObj.AddComponent<StockBox>();
}
stockBox.Initialize(item, quantity);
// Deduct from virtual storage
RemoveStock(item, quantity);
// Physically carry it
player.CarryItem(boxObj);
Debug.Log($"[ShopInventory] Player withdrew {quantity}x {item.itemName}. Remaining in storage: {GetStockCount(item)}");
}
}
}