⇅
public class ShopKeeperDisplay : MonoBehaviour
{
[SerializeField] private ShopInventorySlotUI _shopSlotInventoryPrefab;
[SerializeField] private ShoppingCartItemUI _shoppingCartItemPrefab;
[SerializeField] private Button _buyTabButton;
[SerializeField] private Button _sellTabButton;
[Header("Shopping Cart:")]
[SerializeField] private TextMeshProUGUI _priceTotalText;
[SerializeField] private TextMeshProUGUI _playerGoldText;
[SerializeField] private TextMeshProUGUI _shopGoldText;
[Space(10)]
[SerializeField] private Button _buySellButton;
[SerializeField] private TextMeshProUGUI _buySellButtonText;
[Header("Item Preview Section:")]
[SerializeField] private Image _itemPreviewSprite;
[SerializeField] private TextMeshProUGUI _itemPreviewName;
[SerializeField] private TextMeshProUGUI _itemPreviewDescription;
[SerializeField] private GameObject _itemListContentPanel;
[SerializeField] private GameObject _shoppingCartContentPanel;
private ShopSystem _shopSystem;
private PlayerInventory _playerInventory;
private Dictionary<InventoryItemData, int> _shoppingCart = new Dictionary<InventoryItemData, int>();
private Dictionary<InventoryItemData, ShoppingCartItemUI> _shoppingCartUI = new Dictionary<InventoryItemData, ShoppingCartItemUI>();
private int _priceTotal;
private bool _isSelling;
public void DisplayShopWindow(ShopSystem shopSystem, PlayerInventory playerInventory)
{
_shopSystem = shopSystem;
_playerInventory = playerInventory;
RefreshShopDisplay();
}
private void RefreshShopDisplay()
{
if (_buySellButton != null)
{
_buySellButtonText.text = _isSelling ? "Sell" : "Buy";
_buySellButton.onClick?.RemoveAllListeners();
if (_isSelling)
{
_buySellButton.onClick.AddListener(SellItems);
}
else
{
_buySellButton.onClick.AddListener(BuyItems);
}
}
ClearShopInventorySlots();
ClearItemPreview();
_priceTotalText.enabled = false;
_buySellButton.gameObject.SetActive(false);
_priceTotal = 0;
_playerGoldText.text = $"Player Gold: {_playerInventory.PrimaryInventorySystem.Gold}G";
_shopGoldText.text = $"Shop Gold: {_shopSystem.AvailableGold}G";
if (_isSelling) DisplayPlayerInventory();
else DisplayShopInventory();
}
private void BuyItems()
{
if (_playerInventory.PrimaryInventorySystem.Gold < _priceTotal) return;
if (!_playerInventory.PrimaryInventorySystem.HasAvailableInventorySlots(_shoppingCart)) return;
foreach (var kvp in _shoppingCart)
{
_shopSystem.BuyItem(kvp.Key, kvp.Value);
for (int i = 0; i < kvp.Value; i++)
{
_playerInventory.PrimaryInventorySystem.AddItemToInventory(kvp.Key, 1);
}
}
_shopSystem.GetGold(_priceTotal);
_playerInventory.PrimaryInventorySystem.UseGold(_priceTotal);
RefreshShopDisplay();
}
private void SellItems()
{
if (_shopSystem.AvailableGold < _priceTotal) return;
foreach (var kvp in _shoppingCart)
{
int finalPrice = GetModifiedPrice(kvp.Key, kvp.Value, _shopSystem.SellMarkUp);
_shopSystem.SellItem(kvp.Key, kvp.Value, finalPrice);
_playerInventory.PrimaryInventorySystem.GetGold(finalPrice);
_playerInventory.PrimaryInventorySystem.RemoveItemsFromInventory(kvp.Key, kvp.Value);
}
RefreshShopDisplay();
}
private void ClearShopInventorySlots()
{
_shoppingCart = new Dictionary<InventoryItemData, int>();
_shoppingCartUI = new Dictionary<InventoryItemData, ShoppingCartItemUI>();
foreach (var item in _itemListContentPanel.transform.Cast<Transform>())
{
Destroy(item.gameObject);
}
foreach (var item in _shoppingCartContentPanel.transform.Cast<Transform>())
{
Destroy(item.gameObject);
}
}
private void DisplayShopInventory()
{
foreach (var slot in _shopSystem.ShopInventory)
{
if (slot.InventoryItemData == null)
{
continue;
}
ShopInventorySlotUI shopInventorySlotUI = Instantiate(_shopSlotInventoryPrefab, _itemListContentPanel.transform);
shopInventorySlotUI.Initialize(slot, _shopSystem.BuyMarkUp);
}
}
private void DisplayPlayerInventory()
{
foreach (var item in _playerInventory.PrimaryInventorySystem.GetAllInventoryItems())
{
ShopInventorySlot tempShopInventorySlot = new ShopInventorySlot();
tempShopInventorySlot.AssignItemData(item.Key, item.Value);
ShopInventorySlotUI shopInventorySlotUI = Instantiate(_shopSlotInventoryPrefab, _itemListContentPanel.transform);
shopInventorySlotUI.Initialize(tempShopInventorySlot, _shopSystem.SellMarkUp);
}
}
public void AddShopItemToCart(ShopInventorySlotUI shopInventorySlotUI)
{
InventoryItemData inventoryItemData = shopInventorySlotUI.AssignedShopInventorySlot.InventoryItemData;
UpdateItemPreview(shopInventorySlotUI);
int finalPrice = GetModifiedPrice(inventoryItemData, 1, shopInventorySlotUI.Markup);
// item already in cart - increase amount
if (_shoppingCart.ContainsKey(inventoryItemData))
{
_shoppingCart[inventoryItemData]++;
string previewItemData = $"{inventoryItemData.Name} - {finalPrice}G - x{_shoppingCart[inventoryItemData]}";
_shoppingCartUI[inventoryItemData].SetItemPreviewText(previewItemData);
}
// item not in cart - add item to cart
else
{
_shoppingCart.Add(inventoryItemData, 1);
ShoppingCartItemUI shoppingCartItemUI = Instantiate(_shoppingCartItemPrefab, _shoppingCartContentPanel.transform);
string previewItemData = $"{inventoryItemData.Name} - {finalPrice}G - x1";
shoppingCartItemUI.SetItemPreviewText(previewItemData);
_shoppingCartUI.Add(inventoryItemData, shoppingCartItemUI);
}
// set total price of all items
_priceTotal += finalPrice;
_priceTotalText.text = $"Total: {_priceTotal}G";
if (_priceTotal > 0 && !_priceTotalText.IsActive())
{
_priceTotalText.enabled = true;
_buySellButton.gameObject.SetActive(true);
}
HasAvailableGold();
}
public void RemoveShopItemFromCart(ShopInventorySlotUI shopInventorySlotUI)
{
InventoryItemData inventoryItemData = shopInventorySlotUI.AssignedShopInventorySlot.InventoryItemData;
int finalPrice = GetModifiedPrice(inventoryItemData, 1, shopInventorySlotUI.Markup);
// item already in cart - decrease amount
if (_shoppingCart.ContainsKey(inventoryItemData))
{
_shoppingCart[inventoryItemData]--;
string previewItemData = $"{inventoryItemData.Name} - {finalPrice}G - x{_shoppingCart[inventoryItemData]}";
_shoppingCartUI[inventoryItemData].SetItemPreviewText(previewItemData);
if (_shoppingCart[inventoryItemData] <= 0)
{
_shoppingCart.Remove(inventoryItemData);
GameObject shoppingCartItemUI = _shoppingCartUI[inventoryItemData].gameObject;
_shoppingCartUI.Remove(inventoryItemData);
Destroy(shoppingCartItemUI);
}
}
_priceTotal -= finalPrice;
_priceTotalText.text = $"Total: {_priceTotal}G";
if (_priceTotal <= 0 && _priceTotalText.IsActive())
{
_priceTotalText.enabled = false;
_buySellButton.gameObject.SetActive(false);
ClearItemPreview();
return;
}
HasAvailableGold();
}
private void UpdateItemPreview(ShopInventorySlotUI shopInventorySlotUI)
{
InventoryItemData inventoryItemData = shopInventorySlotUI.AssignedShopInventorySlot.InventoryItemData;
_itemPreviewSprite.sprite = inventoryItemData.Sprite;
_itemPreviewSprite.color = Color.white;
_itemPreviewName.text = inventoryItemData.Name;
_itemPreviewDescription.text = inventoryItemData.Description;
}
private void ClearItemPreview()
{
_itemPreviewSprite.sprite = null;
_itemPreviewSprite.color = Color.clear;
_itemPreviewName.text = "";
_itemPreviewDescription.text = "";
}
public static int GetModifiedPrice(InventoryItemData inventoryItemData, int amount, float markup)
{
int basePrice = inventoryItemData.GoldValue * amount;
return Mathf.FloorToInt(basePrice + basePrice * markup);
}
private void HasAvailableGold()
{
int availableGold = _isSelling ? _shopSystem.AvailableGold : _playerInventory.PrimaryInventorySystem.Gold;
_priceTotalText.color = _priceTotal > availableGold ? Color.red : Color.white;
if (_isSelling || _playerInventory.PrimaryInventorySystem.HasAvailableInventorySlots(_shoppingCart)) return;
_priceTotalText.text = "Not enough space in Inventory!";
_priceTotalText.color = Color.red;
}
public void OnBuyTabPressed()
{
_isSelling = false;
RefreshShopDisplay();
}
public void OnSellTabPressed()
{
_isSelling = true;
RefreshShopDisplay();
}
}