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 stock = new Dictionary(); 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; } /// /// Spawns a physical StockBox in the player's hands from the backroom inventory. /// 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()); // prevent physical collisions while carried // Give it a brown color var rend = boxObj.GetComponent(); if (rend != null) rend.material.color = new Color(0.5f, 0.3f, 0.1f); } // Attach and configure StockBox component StockBox stockBox = boxObj.GetComponent(); if (stockBox == null) { stockBox = boxObj.AddComponent(); } 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)}"); } } }