138 lines
4.7 KiB
C#
138 lines
4.7 KiB
C#
|
|
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)}");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|