442 lines
14 KiB
C#
442 lines
14 KiB
C#
using BrewMonster.Network;
|
|
using NUnit.Framework;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using TMPro;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
|
|
public class ShopDetailPanel : MonoBehaviour
|
|
{
|
|
[Header("UI Components")]
|
|
public TextMeshProUGUI itemNameText;
|
|
public TextMeshProUGUI itemDescriptionText;
|
|
public Image itemIconImage;
|
|
public TextMeshProUGUI itemPriceText;
|
|
public TextMeshProUGUI itemQuantityText;
|
|
public TextMeshProUGUI itemGiftText;
|
|
|
|
[Header("Buy Options")]
|
|
public Button[] buyOptionButtons; // Up to 4 buy options
|
|
public TextMeshProUGUI[] buyOptionPriceTexts;
|
|
public TextMeshProUGUI[] buyOptionStatusTexts;
|
|
|
|
[Header("Action Buttons")]
|
|
public Button buyButton;
|
|
public Button closeButton;
|
|
|
|
private GShopItem currentItem;
|
|
private ShopUIManager shopManager;
|
|
|
|
void Start()
|
|
{
|
|
SetupEventListeners();
|
|
}
|
|
|
|
void SetupEventListeners()
|
|
{
|
|
if (buyButton != null)
|
|
buyButton.onClick.AddListener(OnBuyClicked);
|
|
|
|
if (closeButton != null)
|
|
closeButton.onClick.AddListener(OnCloseClicked);
|
|
|
|
// Setup buy option buttons
|
|
for (int i = 0; i < buyOptionButtons.Length; i++)
|
|
{
|
|
int optionIndex = i; // Capture for closure
|
|
if (buyOptionButtons[i] != null)
|
|
{
|
|
buyOptionButtons[i].onClick.AddListener(() => OnBuyOptionSelected(optionIndex));
|
|
}
|
|
}
|
|
}
|
|
|
|
public void SetupDetailPanel(GShopItem item, ShopUIManager manager)
|
|
{
|
|
Debug.Log($"[ShopDetailPanel] SetupDetailPanel called with item ID: {item.id}, Name: '{item.name}', Icon: '{item.icon}'");
|
|
|
|
currentItem = item;
|
|
shopManager = manager;
|
|
|
|
UpdateDisplay();
|
|
}
|
|
|
|
void UpdateDisplay()
|
|
{
|
|
Debug.Log($"[ShopDetailPanel] UpdateDisplay called for item ID: {currentItem.id}");
|
|
|
|
if (currentItem.id == 0)
|
|
{
|
|
Debug.LogWarning("[ShopDetailPanel] Current item ID is 0, skipping display update");
|
|
return;
|
|
}
|
|
|
|
// Set basic item info
|
|
if (itemNameText != null)
|
|
itemNameText.text = currentItem.name;
|
|
|
|
if (itemDescriptionText != null)
|
|
{
|
|
RemoveCaretColor(itemDescriptionText.text = ConvertColorCodeOfText(currentItem.desc));
|
|
}
|
|
|
|
if (itemQuantityText != null)
|
|
itemQuantityText.text = $"Quantity: {currentItem.num}";
|
|
|
|
// Load icon
|
|
Debug.Log($"[ShopDetailPanel] About to load icon. itemIconImage is null: {itemIconImage == null}");
|
|
Debug.Log($"[ShopDetailPanel] Current item icon field: '{currentItem.icon}'");
|
|
|
|
if (itemPriceText != null)
|
|
{
|
|
itemPriceText.text = currentItem.buy[0].price.ToString();
|
|
LayoutRebuilder.ForceRebuildLayoutImmediate(itemPriceText.transform as RectTransform);
|
|
}
|
|
|
|
if (itemIconImage != null)
|
|
{
|
|
LoadItemIcon(itemIconImage, currentItem.icon);
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError("[ShopDetailPanel] itemIconImage is null! Make sure it's assigned in the inspector.");
|
|
}
|
|
|
|
// Update buy options
|
|
UpdateBuyOptions();
|
|
|
|
// Update gift info
|
|
UpdateGiftInfo();
|
|
}
|
|
struct ColorText
|
|
{
|
|
public string hex;
|
|
public string content;
|
|
}
|
|
private string ConvertColorCodeOfText(string input)
|
|
{
|
|
/*string returnValue = "";
|
|
List<ColorText> colorTexts = new List<ColorText>();
|
|
ColorText currentColorText = new ColorText();
|
|
currentColorText.hex = "ffffff";
|
|
currentColorText.content = "";
|
|
for (int i = 0; i < input.Length; i++)
|
|
{
|
|
if (input[i] == '^' && i + 6 < input.Length)
|
|
{
|
|
// Store the current segment before changing color
|
|
colorTexts.Add(currentColorText);
|
|
|
|
// Start a new color segment
|
|
currentColorText = new ColorText();
|
|
currentColorText.hex = input.Substring(i + 1, 6);
|
|
currentColorText.content = "";
|
|
i += 6;
|
|
}
|
|
else
|
|
{
|
|
currentColorText.content += input[i];
|
|
}
|
|
}
|
|
foreach ( var ct in colorTexts)
|
|
{
|
|
if (ct.hex.ToLower() != "ffffff")
|
|
{
|
|
returnValue += $"<color=#{ct.hex}>{ct.content}</color>";
|
|
}
|
|
else
|
|
{
|
|
returnValue += ct.content;
|
|
}
|
|
Debug.Log($"[ShopDetailPanel] Processed ColorText: Hex='{ct.hex}', Content='{ct.content}'");
|
|
}
|
|
|
|
return returnValue;*/
|
|
|
|
|
|
if (string.IsNullOrEmpty(input))
|
|
return input;
|
|
|
|
input = input.Replace("\\r\\n", "\n");
|
|
input = input.Replace("\\r", "\n");
|
|
input = input.Replace("\\n", "\n");
|
|
|
|
input = input.Replace("\r\n", "\n");
|
|
input = input.Replace("\r", "\n");
|
|
input = input.Replace("\n", "\n");
|
|
|
|
System.Text.StringBuilder sb = new System.Text. StringBuilder();
|
|
for (int i = 0; i < input.Length; i++)
|
|
{
|
|
|
|
if (input[i] == '^' && i + 6 < input.Length)
|
|
{
|
|
string hex = input.Substring(i + 1, 6);
|
|
if (hex.ToLower() != "ffffff")
|
|
{
|
|
sb.Append($"<color=#{hex}>");
|
|
}
|
|
i += 6;
|
|
}
|
|
else
|
|
{
|
|
sb.Append(input[i]);
|
|
}
|
|
}
|
|
|
|
sb.Append("</color>");
|
|
return sb.ToString();
|
|
}
|
|
|
|
public static string RemoveCaretColor(string input)
|
|
{
|
|
return System.Text.RegularExpressions.Regex.Replace(input, @"\^[0-9a-fA-F]{6}", "");
|
|
}
|
|
|
|
|
|
|
|
void UpdateBuyOptions()
|
|
{
|
|
for (int i = 0; i < buyOptionButtons.Length && i < currentItem.buy.Length; i++)
|
|
{
|
|
var buyOption = currentItem.buy[i];
|
|
|
|
// Show/hide buy option based on price
|
|
bool hasValidPrice = buyOption.price > 0;
|
|
if (buyOptionButtons[i] != null)
|
|
{
|
|
buyOptionButtons[i].gameObject.SetActive(hasValidPrice);
|
|
}
|
|
|
|
if (hasValidPrice)
|
|
{
|
|
// Set price text
|
|
if (i < buyOptionPriceTexts.Length && buyOptionPriceTexts[i] != null)
|
|
{
|
|
buyOptionPriceTexts[i].text = buyOption.price.ToString();
|
|
}
|
|
|
|
// Set status text
|
|
if (i < buyOptionStatusTexts.Length && buyOptionStatusTexts[i] != null)
|
|
{
|
|
string statusText = GetStatusText(buyOption.status);
|
|
buyOptionStatusTexts[i].text = statusText;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
string GetStatusText(uint status)
|
|
{
|
|
switch (status)
|
|
{
|
|
case 0: return "";
|
|
case 1: return "HOT";
|
|
case 2: return "NEW";
|
|
case 3: return "RECOMMENDED";
|
|
case 4: return "10% OFF";
|
|
case 5: return "20% OFF";
|
|
case 6: return "30% OFF";
|
|
case 7: return "40% OFF";
|
|
case 8: return "50% OFF";
|
|
case 9: return "60% OFF";
|
|
case 10: return "70% OFF";
|
|
case 11: return "80% OFF";
|
|
case 12: return "90% OFF";
|
|
case 13: return "SOLD OUT";
|
|
default: return "";
|
|
}
|
|
}
|
|
|
|
void UpdateGiftInfo()
|
|
{
|
|
if (itemGiftText != null)
|
|
{
|
|
if (currentItem.idGift > 0)
|
|
{
|
|
itemGiftText.text = $"Gift: {currentItem.giftNum}x (ID: {currentItem.idGift})";
|
|
itemGiftText.gameObject.SetActive(true);
|
|
}
|
|
else
|
|
{
|
|
itemGiftText.gameObject.SetActive(false);
|
|
}
|
|
}
|
|
}
|
|
|
|
void LoadItemIcon(Image iconImage, string itemIcon)
|
|
{
|
|
Debug.Log($"[ShopDetailPanel] LoadItemIcon called with itemIcon: '{itemIcon}'");
|
|
|
|
if (string.IsNullOrEmpty(itemIcon))
|
|
{
|
|
Debug.LogWarning("[ShopDetailPanel] Item icon path is null or empty");
|
|
return;
|
|
}
|
|
|
|
// Extract filename from path (e.g., "surfaces/.../... .dds" -> "... .dds")
|
|
string fileName = ExtractFileNameFromPath(itemIcon);
|
|
Debug.Log($"[ShopDetailPanel] Extracted filename: '{fileName}' from path: '{itemIcon}'");
|
|
|
|
// Load sprite from DDSAtlas using the same system as inventory items
|
|
Sprite iconSprite = LoadSpriteFromDDSAtlas(fileName);
|
|
|
|
if (iconSprite != null)
|
|
{
|
|
iconImage.sprite = iconSprite;
|
|
Debug.Log($"[ShopDetailPanel] Successfully loaded icon: {fileName}");
|
|
}
|
|
else
|
|
{
|
|
Debug.LogWarning($"[ShopDetailPanel] Failed to load icon from DDSAtlas: {fileName}");
|
|
iconImage.sprite = null;
|
|
}
|
|
}
|
|
|
|
private string ExtractFileNameFromPath(string iconPath)
|
|
{
|
|
if (string.IsNullOrEmpty(iconPath))
|
|
return string.Empty;
|
|
|
|
try
|
|
{
|
|
// Replace backslashes with forward slashes for consistency
|
|
string normalizedPath = iconPath.Replace('\\', '/');
|
|
|
|
// Get the filename from the path
|
|
string fileName = System.IO.Path.GetFileName(normalizedPath);
|
|
|
|
if (string.IsNullOrEmpty(fileName))
|
|
fileName = normalizedPath;
|
|
|
|
// Remove extension (.dds/.tga/.png) to get the sprite name
|
|
string spriteName = System.IO.Path.GetFileNameWithoutExtension(fileName);
|
|
|
|
if (string.IsNullOrEmpty(spriteName))
|
|
spriteName = fileName;
|
|
|
|
return spriteName.Trim();
|
|
}
|
|
catch (System.Exception ex)
|
|
{
|
|
Debug.LogError($"Error extracting filename from path '{iconPath}': {ex.Message}");
|
|
return string.Empty;
|
|
}
|
|
}
|
|
|
|
private Sprite LoadSpriteFromDDSAtlas(string spriteName)
|
|
{
|
|
Debug.Log($"[ShopDetailPanel] LoadSpriteFromDDSAtlas called with spriteName: '{spriteName}'");
|
|
|
|
if (string.IsNullOrEmpty(spriteName))
|
|
{
|
|
Debug.LogWarning("[ShopDetailPanel] Sprite name is null or empty");
|
|
return null;
|
|
}
|
|
|
|
try
|
|
{
|
|
// Load the DDSAtlas sprites if not already loaded
|
|
var atlasSprites = UnityEngine.Resources.LoadAll<Sprite>("UI/MallItemImg/DDSAtlas");
|
|
|
|
Debug.Log($"[ShopDetailPanel] Loaded {atlasSprites?.Length ?? 0} sprites from Resources/UI/MallItemImg/DDSAtlas");
|
|
|
|
if (atlasSprites == null || atlasSprites.Length == 0)
|
|
{
|
|
Debug.LogWarning("[ShopDetailPanel] Failed to load DDSAtlas sprites from Resources/UI/MallItemImg/DDSAtlas");
|
|
return null;
|
|
}
|
|
|
|
// Log first few sprite names for debugging
|
|
for (int i = 0; i < Mathf.Min(5, atlasSprites.Length); i++)
|
|
{
|
|
if (atlasSprites[i] != null)
|
|
{
|
|
Debug.Log($"[ShopDetailPanel] Atlas sprite {i}: '{atlasSprites[i].name}'");
|
|
}
|
|
}
|
|
|
|
// Try to find sprite by exact name match (case insensitive)
|
|
foreach (var sprite in atlasSprites)
|
|
{
|
|
if (sprite != null && string.Equals(sprite.name, spriteName, System.StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
Debug.Log($"[ShopDetailPanel] Found exact match for sprite: '{spriteName}'");
|
|
return sprite;
|
|
}
|
|
}
|
|
|
|
// Try lowercase/uppercase variants as fallback
|
|
foreach (var sprite in atlasSprites)
|
|
{
|
|
if (sprite != null && (string.Equals(sprite.name, spriteName.ToLowerInvariant(), System.StringComparison.OrdinalIgnoreCase) ||
|
|
string.Equals(sprite.name, spriteName.ToUpperInvariant(), System.StringComparison.OrdinalIgnoreCase)))
|
|
{
|
|
Debug.Log($"[ShopDetailPanel] Found case variant match for sprite: '{spriteName}'");
|
|
return sprite;
|
|
}
|
|
}
|
|
|
|
Debug.LogWarning($"[ShopDetailPanel] Sprite '{spriteName}' not found in DDSAtlas. Available sprites: {string.Join(", ", System.Array.ConvertAll(atlasSprites, s => s?.name ?? "null"))}");
|
|
return null;
|
|
}
|
|
catch (System.Exception ex)
|
|
{
|
|
Debug.LogError($"[ShopDetailPanel] Error loading sprite '{spriteName}' from DDSAtlas: {ex.Message}");
|
|
return null;
|
|
}
|
|
}
|
|
|
|
void OnBuyOptionSelected(int optionIndex)
|
|
{
|
|
if (currentItem.buy == null || optionIndex >= currentItem.buy.Length)
|
|
return;
|
|
|
|
var selectedOption = currentItem.buy[optionIndex];
|
|
|
|
if (selectedOption.price > 0 && selectedOption.status != 13) // Not sold out
|
|
{
|
|
// TODO: Implement purchase with specific buy option
|
|
Debug.Log($"Selected buy option {optionIndex}: Price={selectedOption.price}, Status={selectedOption.status}");
|
|
|
|
// Update main price display
|
|
if (itemPriceText != null)
|
|
itemPriceText.text = $"Price: {selectedOption.price}";
|
|
}
|
|
}
|
|
|
|
void OnBuyClicked()
|
|
{
|
|
// TODO: Implement purchase logic
|
|
Debug.Log($"Attempting to buy item: ID {currentItem.id} (Index: {currentItem.itemIndex})");
|
|
UnityGameSession.Instance.RequestMallShopping(1, Convert.ToInt32(currentItem.id), currentItem.itemIndex, 0);
|
|
// Close panel after purchase attempt
|
|
OnCloseClicked();
|
|
}
|
|
|
|
void OnCloseClicked()
|
|
{
|
|
gameObject.SetActive(false);
|
|
}
|
|
|
|
void OnDestroy()
|
|
{
|
|
// Clean up event listeners
|
|
if (buyButton != null)
|
|
buyButton.onClick.RemoveListener(OnBuyClicked);
|
|
|
|
if (closeButton != null)
|
|
closeButton.onClick.RemoveListener(OnCloseClicked);
|
|
|
|
for (int i = 0; i < buyOptionButtons.Length; i++)
|
|
{
|
|
if (buyOptionButtons[i] != null)
|
|
{
|
|
int optionIndex = i; // Capture for closure
|
|
buyOptionButtons[i].onClick.RemoveListener(() => OnBuyOptionSelected(optionIndex));
|
|
}
|
|
}
|
|
}
|
|
}
|