2025-10-10 14:31:51 +02:00
|
|
|
|
using System;
|
|
|
|
|
|
using AppleHills.Data.CardSystem;
|
2025-10-14 15:53:58 +02:00
|
|
|
|
using Core;
|
2025-10-10 14:31:51 +02:00
|
|
|
|
using TMPro;
|
|
|
|
|
|
using UnityEditor;
|
2025-10-21 12:10:16 +02:00
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
using UnityEngine.UI;
|
2025-10-10 14:31:51 +02:00
|
|
|
|
|
2025-10-21 12:10:16 +02:00
|
|
|
|
namespace UI.CardSystem
|
2025-10-10 14:31:51 +02:00
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Handles displaying and interacting with a single card in the UI.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public class CardUIElement : MonoBehaviour
|
|
|
|
|
|
{
|
|
|
|
|
|
[Header("UI Elements")]
|
|
|
|
|
|
[SerializeField] private TextMeshProUGUI cardNameText;
|
|
|
|
|
|
[SerializeField] private Image cardImage;
|
|
|
|
|
|
[SerializeField] private Image frameImage;
|
|
|
|
|
|
[SerializeField] private Image backgroundImage;
|
|
|
|
|
|
[SerializeField] private Image backgroundShape;
|
|
|
|
|
|
|
|
|
|
|
|
[Header("Card Data")]
|
|
|
|
|
|
[SerializeField] private CardDefinition cardDefinition;
|
|
|
|
|
|
[SerializeField] private CardData cardData;
|
|
|
|
|
|
|
|
|
|
|
|
[Header("Visual Settings")]
|
|
|
|
|
|
[SerializeField] private CardVisualConfig visualConfig;
|
|
|
|
|
|
|
|
|
|
|
|
// Events
|
|
|
|
|
|
public event Action<CardUIElement> OnCardClicked;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Sets up the card UI with the given card data
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public void SetupCard(CardData cardData)
|
|
|
|
|
|
{
|
2025-10-14 15:53:58 +02:00
|
|
|
|
Logging.Debug($"[CardUIElement] Setting up card with data: {cardData}");
|
2025-10-10 14:31:51 +02:00
|
|
|
|
|
|
|
|
|
|
this.cardData = cardData;
|
|
|
|
|
|
|
|
|
|
|
|
if (cardData == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.LogError("[CardUIElement] Attempted to setup card with null data");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
UpdateCardVisuals();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Updates the card visuals based on the current card data
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private void UpdateCardVisuals()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (cardData == null) return;
|
|
|
|
|
|
|
|
|
|
|
|
// Set basic text information
|
|
|
|
|
|
if (cardNameText != null) cardNameText.text = cardData.Name;
|
|
|
|
|
|
|
|
|
|
|
|
// Set the card image
|
|
|
|
|
|
if (cardImage != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (cardData.CardImage != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
cardImage.sprite = cardData.CardImage;
|
|
|
|
|
|
cardImage.enabled = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
cardImage.sprite = null;
|
|
|
|
|
|
cardImage.enabled = false;
|
|
|
|
|
|
// Don't log warnings for missing images - this is expected for new cards
|
|
|
|
|
|
// and causes console spam in the editor
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Update frame color based on rarity
|
|
|
|
|
|
UpdateFrameByRarity(cardData.Rarity);
|
|
|
|
|
|
|
|
|
|
|
|
// Update background color and shape based on zone
|
|
|
|
|
|
UpdateBackgroundByZone(cardData.Zone);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Updates the frame color based on card rarity
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private void UpdateFrameByRarity(CardRarity rarity)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (frameImage == null) return;
|
|
|
|
|
|
|
|
|
|
|
|
// Get color from config if available, otherwise use default colors
|
|
|
|
|
|
Color frameColor = visualConfig != null
|
|
|
|
|
|
? visualConfig.GetRarityColor(rarity)
|
|
|
|
|
|
: GetDefaultRarityColor(rarity);
|
|
|
|
|
|
|
|
|
|
|
|
frameImage.color = frameColor;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Updates the background color and shape based on card zone
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private void UpdateBackgroundByZone(CardZone zone)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Update background color
|
|
|
|
|
|
if (backgroundImage != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
Color bgColor = visualConfig != null
|
|
|
|
|
|
? visualConfig.GetZoneColor(zone)
|
|
|
|
|
|
: GetDefaultZoneColor(zone);
|
|
|
|
|
|
|
|
|
|
|
|
backgroundImage.color = bgColor;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Update background shape
|
|
|
|
|
|
if (backgroundShape != null && visualConfig != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
Sprite shapeSprite = visualConfig.GetZoneShape(zone);
|
|
|
|
|
|
if (shapeSprite != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
backgroundShape.sprite = shapeSprite;
|
|
|
|
|
|
backgroundShape.gameObject.SetActive(true);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
backgroundShape.gameObject.SetActive(false);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Returns default color for rarity if no config is available
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private Color GetDefaultRarityColor(CardRarity rarity)
|
|
|
|
|
|
{
|
|
|
|
|
|
switch (rarity)
|
|
|
|
|
|
{
|
|
|
|
|
|
case CardRarity.Common:
|
|
|
|
|
|
return Color.gray;
|
|
|
|
|
|
case CardRarity.Uncommon:
|
|
|
|
|
|
return Color.green;
|
|
|
|
|
|
case CardRarity.Rare:
|
|
|
|
|
|
return Color.blue;
|
|
|
|
|
|
case CardRarity.Epic:
|
|
|
|
|
|
return new Color(0.5f, 0, 0.5f); // Purple
|
|
|
|
|
|
case CardRarity.Legendary:
|
|
|
|
|
|
return Color.yellow;
|
|
|
|
|
|
default:
|
|
|
|
|
|
return Color.white;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Returns default color for zone if no config is available
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private Color GetDefaultZoneColor(CardZone zone)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Default zone colors from CardDefinition
|
|
|
|
|
|
switch (zone)
|
|
|
|
|
|
{
|
|
|
|
|
|
case CardZone.AppleHills:
|
|
|
|
|
|
return new Color(0.8f, 0.9f, 0.8f); // Light green
|
|
|
|
|
|
case CardZone.Quarry:
|
|
|
|
|
|
return new Color(0.85f, 0.8f, 0.7f); // Sandy brown
|
|
|
|
|
|
case CardZone.Forest:
|
|
|
|
|
|
return new Color(0.6f, 0.8f, 0.6f); // Forest green
|
|
|
|
|
|
case CardZone.Mountain:
|
|
|
|
|
|
return new Color(0.7f, 0.7f, 0.9f); // Bluish
|
|
|
|
|
|
case CardZone.Beach:
|
|
|
|
|
|
return new Color(0.9f, 0.85f, 0.7f); // Sandy yellow
|
|
|
|
|
|
default:
|
|
|
|
|
|
return Color.white;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Called when the card is clicked
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public void OnClick()
|
|
|
|
|
|
{
|
|
|
|
|
|
OnCardClicked?.Invoke(this);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Returns the card data associated with this UI element
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public CardData GetCardData()
|
|
|
|
|
|
{
|
|
|
|
|
|
return cardData;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Animation methods that can be called from UI events
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Called when the card is revealed from a booster pack
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public void OnShowAnimation()
|
|
|
|
|
|
{
|
|
|
|
|
|
// Stub for card reveal animation
|
2025-10-14 15:53:58 +02:00
|
|
|
|
Logging.Debug($"[CardUIElement] Showing card: {cardData?.Name}");
|
2025-10-10 14:31:51 +02:00
|
|
|
|
// Could add animation code or call Animation Trigger here
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Called when the card moves to the backpack after being revealed
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public void OnMoveToBackpackAnimation()
|
|
|
|
|
|
{
|
|
|
|
|
|
// Stub for animation when card moves to backpack
|
2025-10-14 15:53:58 +02:00
|
|
|
|
Logging.Debug($"[CardUIElement] Moving card to backpack: {cardData?.Name}");
|
2025-10-10 14:31:51 +02:00
|
|
|
|
// Could add animation code or call Animation Trigger here
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Create card data from definition and update the UI
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public void CreateFromDefinition()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (cardDefinition == null)
|
|
|
|
|
|
{
|
2025-10-14 15:53:58 +02:00
|
|
|
|
Logging.Warning("[CardUIElement] Cannot create card data: No card definition assigned");
|
2025-10-10 14:31:51 +02:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
cardData = cardDefinition.CreateCardData();
|
|
|
|
|
|
UpdateCardVisuals();
|
|
|
|
|
|
|
2025-10-14 15:53:58 +02:00
|
|
|
|
Logging.Debug($"[CardUIElement] Created card from definition: {cardData.Name}");
|
2025-10-10 14:31:51 +02:00
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
|
|
[CustomEditor(typeof(CardUIElement))]
|
2025-10-27 14:00:37 +01:00
|
|
|
|
public class CardUIElementEditor : UnityEditor.Editor
|
2025-10-10 14:31:51 +02:00
|
|
|
|
{
|
|
|
|
|
|
public override void OnInspectorGUI()
|
|
|
|
|
|
{
|
|
|
|
|
|
DrawDefaultInspector();
|
|
|
|
|
|
|
|
|
|
|
|
CardUIElement cardUI = (CardUIElement)target;
|
|
|
|
|
|
|
|
|
|
|
|
EditorGUILayout.Space();
|
|
|
|
|
|
if (GUILayout.Button("Create From Definition"))
|
|
|
|
|
|
{
|
|
|
|
|
|
cardUI.CreateFromDefinition();
|
|
|
|
|
|
EditorUtility.SetDirty(cardUI);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
}
|