// Filename : NPCShopDetailPanel.cs // Creator : Converted from C++ EC_Shop // Date : 2024 using UnityEngine; using UnityEngine.UI; using TMPro; using BrewMonster.Scripts; using BrewMonster.Network; using CSNetwork.C2SCommand; public class NPCShopDetailPanel : MonoBehaviour { [Header("UI Components")] public TextOutlet itemDescriptionText; public Image itemIconImage; //public TextMeshProUGUI itemPriceText; [Header("Action Buttons")] public Button closeButton; public Button buyButton; private GShopItem currentItem; private NPCShopUIManager shopManager; private int shopItemIndex; void Start() { SetupEventListeners(); } void SetupEventListeners() { if (closeButton != null) closeButton.onClick.AddListener(OnCloseClicked); if (buyButton != null) buyButton.onClick.AddListener(OnBuyButtonClicked); } public void SetupDetailPanel(GShopItem item, NPCShopUIManager manager, int index) { currentItem = item; shopManager = manager; shopItemIndex = index; UpdateDisplay(); } void UpdateDisplay() { if (currentItem.id == 0) { Debug.LogWarning("[NPCShopDetailPanel] Current item ID is 0, skipping display update"); return; } // Set item description if (itemDescriptionText != null) { string description = GetItemDescription((int)currentItem.id); itemDescriptionText.Set(description); } // Set price (use first available price) uint price = 0; if (currentItem.buy != null && currentItem.buy.Length > 0) { for (int i = 0; i < currentItem.buy.Length; i++) { if (currentItem.buy[i].price > 0) { price = currentItem.buy[i].price; break; } } } // if (itemPriceText != null) // itemPriceText.text = price > 0 ? $"Price: {price}" : "Price: N/A"; // Load icon if (itemIconImage != null) { LoadItemIcon(itemIconImage, (int)currentItem.id); } } void LoadItemIcon(Image iconImage, int itemId) { if (itemId <= 0 || iconImage == null) return; // Ensure the Image component is enabled and properly configured iconImage.enabled = true; iconImage.preserveAspect = true; iconImage.type = Image.Type.Simple; // Use the existing icon loading system from EC_IvtrItemUtils Sprite iconSprite = EC_IvtrItemUtils.Instance.ResolveItemIconSprite(itemId); if (iconSprite != null) { iconImage.sprite = iconSprite; iconImage.color = Color.white; } else { iconImage.sprite = null; } } string GetItemDescription(int itemId) { // First check if description is already in the item data if (!string.IsNullOrEmpty(currentItem.desc)) { return currentItem.desc; } // Try to use EC_IvtrEquip description for equipment items (like EC_InventoryUI does) try { // Create EC_IvtrEquip for equipment items - this will work for weapons and armor EC_IvtrEquip equipment = (EC_IvtrEquip)EC_IvtrItem.CreateItem(itemId, 0, 1); // For NPC shop items, we typically have static data only // Try to get description using GetNormalDesc() which works with base stats string equipDesc = equipment.GetDesc(); if (!string.IsNullOrEmpty(equipDesc)) { // Replace C++ style "\r" line separators with real newlines for TMP return equipDesc.Replace("\\r", "\n"); } } catch (System.Exception ex) { // If EC_IvtrEquip fails, fall through to EC_IvtrItem method Debug.LogWarning($"[NPCShopDetailPanel] Failed to get equipment description for item {itemId}: {ex.Message}"); } // Fallback: build description using EC_IvtrItem (for non-equipment items) try { EC_IvtrItem item = EC_IvtrItem.CreateItem(itemId, 0, 1); if (item != null) { // For NPC shop, we typically have static data only, so load from local DB item.GetDetailDataFromLocal(); string description = item.GetDesc(); if (!string.IsNullOrEmpty(description)) { return description.Replace("\\r", "\n"); } } } catch (System.Exception ex) { Debug.LogWarning($"[NPCShopDetailPanel] Failed to get description for item {itemId}: {ex.Message}"); } return "No description available."; } void OnCloseClicked() { gameObject.SetActive(false); } void OnBuyButtonClicked() { if (currentItem.id == 0) { Debug.LogWarning("[NPCShopDetailPanel] Cannot buy item with ID 0"); return; } // Get price from item uint price = 0; if (currentItem.buy != null && currentItem.buy.Length > 0) { for (int i = 0; i < currentItem.buy.Length; i++) { if (currentItem.buy[i].price > 0) { price = currentItem.buy[i].price; break; } } } // Server requires SEVNPC_HELLO with NPC id before buy, and the correct shop slot index if (shopManager != null && shopManager.CurrentNPCID != 0) UnityGameSession.c2s_CmdNPCSevHello((int)shopManager.CurrentNPCID); // Create npc_trade_item: tid = template ID, index = shop slot (server validates this), count = quantity npc_trade_item[] items = new npc_trade_item[1]; items[0] = new npc_trade_item { tid = (int)currentItem.id, index = (uint)shopItemIndex, count = 1 }; UnityGameSession.c2s_CmdNPCSevBuy(1, items); Debug.Log($"[NPCShopDetailPanel] Sent buy command for item {currentItem.id}, price {price}"); } void OnDestroy() { // Clean up event listeners if (closeButton != null) closeButton.onClick.RemoveListener(OnCloseClicked); if (buyButton != null) buyButton.onClick.RemoveListener(OnBuyButtonClicked); } // === Text Outlet Helper === [System.Serializable] public class TextOutlet { [SerializeField] public Text legacy; [SerializeField] public TMPro.TextMeshProUGUI tmp; public void Set(string value) { if (legacy != null) { legacy.text = EC_Utility.FormatForLegacyText(value ?? string.Empty); } if (tmp != null) { tmp.text = EC_Utility.FormatForTextMeshPro(value ?? string.Empty); } } } }