using UnityEngine; using System.Collections.Generic; using System.Linq; public enum ShopType { Weapons, Armor, Potions, General, Magic, Tools } [System.Serializable] public class TownShop : TownBuilding { [Header("Shop Configuration")] public ShopType shopType = ShopType.General; public string shopkeeperName = "Merchant"; public float profitMargin = 1.2f; // 20% markup on base item prices public float sellbackRate = 0.6f; // Player gets 60% of base price when selling [Header("Shop Inventory")] public List baseInventory = new List(); public int maxInventorySize = 20; public bool restockDaily = true; [Header("Shop Filters")] public List acceptedItemTypes = new List(); public List acceptedRarities = new List(); public List currentInventory = new List(); private System.DateTime lastRestockTime; protected override void Start() { base.Start(); buildingType = BuildingType.Shop; InitializeShop(); } private void InitializeShop() { // Set default accepted item types based on shop type if (acceptedItemTypes.Count == 0) { switch (shopType) { case ShopType.Weapons: acceptedItemTypes.Add(ItemType.Weapon); break; case ShopType.Armor: acceptedItemTypes.Add(ItemType.Armor); acceptedItemTypes.Add(ItemType.Accessory); break; case ShopType.Potions: acceptedItemTypes.Add(ItemType.Consumable); break; case ShopType.General: acceptedItemTypes.AddRange(System.Enum.GetValues(typeof(ItemType)).Cast()); break; case ShopType.Tools: acceptedItemTypes.Add(ItemType.Tool); acceptedItemTypes.Add(ItemType.Miscellaneous); break; } } // Initialize inventory RestockInventory(); // Set building colors based on shop type switch (shopType) { case ShopType.Weapons: buildingColor = new Color(0.8f, 0.2f, 0.2f); // Red break; case ShopType.Armor: buildingColor = new Color(0.2f, 0.2f, 0.8f); // Blue break; case ShopType.Potions: buildingColor = new Color(0.2f, 0.8f, 0.2f); // Green break; case ShopType.General: buildingColor = new Color(0.6f, 0.4f, 0.2f); // Brown break; default: buildingColor = Color.gray; break; } } public void RestockInventory() { currentInventory.Clear(); // Add base inventory items with markup foreach (var item in baseInventory) { if (item != null) { var shopItem = new ShopInventoryItem(item, profitMargin); currentInventory.Add(shopItem); } } // Add some random items based on shop type AddRandomItems(); lastRestockTime = System.DateTime.Now; Debug.Log($"{buildingName} restocked with {currentInventory.Count} items"); } private void AddRandomItems() { // Get all items of appropriate types from Resources var allItems = Resources.LoadAll("Items"); var filteredItems = allItems.Where(item => acceptedItemTypes.Contains(item.itemType) && (acceptedRarities.Count == 0 || acceptedRarities.Contains(item.rarity)) ).ToList(); // Add 3-5 random items int randomItemCount = Random.Range(3, 6); for (int i = 0; i < randomItemCount && currentInventory.Count < maxInventorySize; i++) { if (filteredItems.Count > 0) { var randomItem = filteredItems[Random.Range(0, filteredItems.Count)]; var shopItem = new ShopInventoryItem(randomItem, profitMargin); currentInventory.Add(shopItem); } } } public List GetInventory() { // Check if restock is needed if (restockDaily && (System.DateTime.Now - lastRestockTime).TotalDays >= 1) { RestockInventory(); } return new List(currentInventory); } public bool CanBuyItem(Item item) { return acceptedItemTypes.Contains(item.itemType) && (acceptedRarities.Count == 0 || acceptedRarities.Contains(item.rarity)); } public int GetSellPrice(Item item) { if (!CanBuyItem(item)) return 0; int basePrice = item.goldCost * 100 + item.silverCost * 10 + item.copperCost; return Mathf.RoundToInt(basePrice * sellbackRate); } public void SellItemToShop(Item item, TeamCharacter seller) { if (!CanBuyItem(item)) return; int sellPrice = GetSellPrice(item); // Convert copper to gold/silver/copper int gold = sellPrice / 100; sellPrice %= 100; int silver = sellPrice / 10; int copper = sellPrice % 10; // Add money to seller seller.gold += gold; seller.silver += silver; seller.copper += copper; // Normalize currency (convert excess copper/silver) if (seller.copper >= 10) { seller.silver += seller.copper / 10; seller.copper %= 10; } if (seller.silver >= 10) { seller.gold += seller.silver / 10; seller.silver %= 10; } Debug.Log($"Sold {item.itemName} to {buildingName} for {gold}g {silver}s {copper}c"); } /// /// Update shop names after initialization (called by TownShopManager) /// public void UpdateNames(string newBuildingName, string newShopkeeperName) { this.buildingName = newBuildingName; this.shopkeeperName = newShopkeeperName; Debug.Log($"TownShop: Updated names to '{this.buildingName}' run by '{this.shopkeeperName}'"); } } [System.Serializable] public class ShopInventoryItem { public Item item; public int markupGold; public int markupSilver; public int markupCopper; public int quantity; public bool isUnlimited; public ShopInventoryItem(Item baseItem, float profitMargin, int qty = 1, bool unlimited = false) { item = baseItem; quantity = qty; isUnlimited = unlimited; // Calculate markup prices int baseCopperPrice = baseItem.goldCost * 100 + baseItem.silverCost * 10 + baseItem.copperCost; int markupCopperPrice = Mathf.RoundToInt(baseCopperPrice * profitMargin); markupGold = markupCopperPrice / 100; markupCopperPrice %= 100; markupSilver = markupCopperPrice / 10; markupCopper = markupCopperPrice % 10; } public bool CanAfford(TeamCharacter customer) { if (customer == null || quantity <= 0) return false; int totalCopperCost = markupGold * 100 + markupSilver * 10 + markupCopper; int totalCopperAvailable = customer.gold * 100 + customer.silver * 10 + customer.copper; return totalCopperAvailable >= totalCopperCost; } public void Purchase(TeamCharacter customer) { if (!CanAfford(customer) || quantity <= 0) return; // Deduct money int totalCopperCost = markupGold * 100 + markupSilver * 10 + markupCopper; int totalCopperAvailable = customer.gold * 100 + customer.silver * 10 + customer.copper; int remainingCopper = totalCopperAvailable - totalCopperCost; customer.gold = remainingCopper / 100; remainingCopper %= 100; customer.silver = remainingCopper / 10; customer.copper = remainingCopper % 10; // Add item to customer inventory // This will be handled by the shop UI // Reduce quantity if (!isUnlimited) quantity--; Debug.Log($"Purchased {item.itemName} for {markupGold}g {markupSilver}s {markupCopper}c"); } public string GetPriceString() { string price = ""; if (markupGold > 0) price += $"{markupGold}g "; if (markupSilver > 0) price += $"{markupSilver}s "; if (markupCopper > 0) price += $"{markupCopper}c"; return price.Trim(); } }