using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;
using TMPro;
using System;
///
/// UI for selecting spells to cast in battle
///
public class SpellSelectionUI : MonoBehaviour
{
[Header("UI References")]
public Canvas selectionCanvas;
public Transform spellListContainer;
public GameObject spellButtonPrefab;
public Button cancelButton;
public TextMeshProUGUI titleText;
[Header("Settings")]
public int maxSpellsToShow = 6;
private Character currentCharacter;
private List spellButtons = new List();
// Events
public event Action OnSpellSelected;
public event Action OnSelectionCancelled;
void Awake()
{
if (selectionCanvas == null)
selectionCanvas = GetComponentInChildren();
SetVisible(false);
}
void Start()
{
if (cancelButton != null)
{
cancelButton.onClick.AddListener(() =>
{
OnSelectionCancelled?.Invoke();
HideSelection();
});
}
}
void Update()
{
if (selectionCanvas.gameObject.activeInHierarchy)
{
if (Input.GetKeyDown(KeyCode.Escape))
{
OnSelectionCancelled?.Invoke();
HideSelection();
}
}
}
public void ShowSpellSelection(Character character)
{
currentCharacter = character;
if (titleText != null)
titleText.text = $"{character.CharacterName} - Select Spell";
PopulateSpellList();
SetVisible(true);
Debug.Log($"✨ Spell selection shown for {character.CharacterName}");
}
public void HideSelection()
{
SetVisible(false);
ClearSpellList();
currentCharacter = null;
Debug.Log("✨ Spell selection hidden");
}
private void PopulateSpellList()
{
ClearSpellList();
var spells = GetCharacterSpells();
for (int i = 0; i < spells.Count && i < maxSpellsToShow; i++)
{
CreateSpellButton(spells[i], i);
}
}
private List GetCharacterSpells()
{
// Placeholder implementation - return sample spells
// TODO: Get actual spells from character's spell list/class abilities
return new List
{
new SpellData {
name = "Magic Missile",
description = "Deals 15 magic damage to target",
manaCost = 5,
requiresTarget = true,
isAoE = false,
icon = null
},
new SpellData {
name = "Heal",
description = "Restores 25 HP to target",
manaCost = 8,
requiresTarget = true,
isAoE = false,
icon = null
},
new SpellData {
name = "Fireball",
description = "Explosive fire damage in area",
manaCost = 12,
requiresTarget = true,
isAoE = true,
icon = null
},
new SpellData {
name = "Shield",
description = "Increases AC by 2 for 5 turns",
manaCost = 6,
requiresTarget = false,
isAoE = false,
icon = null
},
new SpellData {
name = "Lightning Bolt",
description = "Chain lightning hits multiple enemies",
manaCost = 10,
requiresTarget = true,
isAoE = true,
icon = null
},
new SpellData {
name = "Cure Disease",
description = "Removes negative effects",
manaCost = 7,
requiresTarget = true,
isAoE = false,
icon = null
}
};
}
private void CreateSpellButton(SpellData spell, int index)
{
GameObject buttonObj = Instantiate(spellButtonPrefab, spellListContainer);
// Get or create components
Button button = buttonObj.GetComponent();
if (button == null)
button = buttonObj.AddComponent();
// Find or create text components
TextMeshProUGUI nameText = buttonObj.transform.Find("SpellName")?.GetComponent();
TextMeshProUGUI descText = buttonObj.transform.Find("Description")?.GetComponent();
TextMeshProUGUI costText = buttonObj.transform.Find("ManaCost")?.GetComponent();
Image iconImage = buttonObj.transform.Find("Icon")?.GetComponent();
// Create text components if they don't exist
if (nameText == null)
{
GameObject nameObj = new GameObject("SpellName");
nameObj.transform.SetParent(buttonObj.transform, false);
nameText = nameObj.AddComponent();
RectTransform nameRect = nameText.GetComponent();
nameRect.anchorMin = new Vector2(0.1f, 0.7f);
nameRect.anchorMax = new Vector2(0.7f, 0.9f);
nameRect.offsetMin = Vector2.zero;
nameRect.offsetMax = Vector2.zero;
nameText.fontSize = 14;
nameText.fontStyle = FontStyles.Bold;
nameText.alignment = TextAlignmentOptions.Left;
}
if (descText == null)
{
GameObject descObj = new GameObject("Description");
descObj.transform.SetParent(buttonObj.transform, false);
descText = descObj.AddComponent();
RectTransform descRect = descText.GetComponent();
descRect.anchorMin = new Vector2(0.1f, 0.3f);
descRect.anchorMax = new Vector2(0.9f, 0.7f);
descRect.offsetMin = Vector2.zero;
descRect.offsetMax = Vector2.zero;
descText.fontSize = 10;
descText.alignment = TextAlignmentOptions.Left;
descText.color = Color.gray;
}
if (costText == null)
{
GameObject costObj = new GameObject("ManaCost");
costObj.transform.SetParent(buttonObj.transform, false);
costText = costObj.AddComponent();
RectTransform costRect = costText.GetComponent();
costRect.anchorMin = new Vector2(0.7f, 0.7f);
costRect.anchorMax = new Vector2(0.9f, 0.9f);
costRect.offsetMin = Vector2.zero;
costRect.offsetMax = Vector2.zero;
costText.fontSize = 12;
costText.alignment = TextAlignmentOptions.Right;
costText.color = Color.cyan;
}
// Set content
nameText.text = spell.name;
descText.text = spell.description;
costText.text = $"{spell.manaCost} MP";
// Add spell type indicators
if (spell.isAoE)
{
nameText.text += " (AoE)";
}
if (spell.requiresTarget)
{
descText.text += " [Requires Target]";
}
if (iconImage != null && spell.icon != null)
iconImage.sprite = spell.icon;
// Check if character can cast this spell (placeholder)
bool canCast = CanCharacterCastSpell(spell);
button.interactable = canCast;
if (!canCast)
{
// Dim the button for unusable spells
var colors = button.colors;
colors.normalColor = Color.gray;
colors.disabledColor = Color.gray;
button.colors = colors;
nameText.color = Color.gray;
descText.color = Color.gray;
costText.color = Color.gray;
}
// Setup button click
button.onClick.AddListener(() =>
{
if (canCast)
{
OnSpellSelected?.Invoke(spell.name);
HideSelection();
}
});
spellButtons.Add(buttonObj);
}
private bool CanCharacterCastSpell(SpellData spell)
{
// Placeholder logic - check if character has enough mana, knows spell, etc.
// TODO: Implement actual spell casting requirements
if (currentCharacter == null)
return false;
// For now, assume character can cast if they have enough "mana"
// (We'll need to add a mana system to characters later)
return true;
}
private void ClearSpellList()
{
foreach (var button in spellButtons)
{
if (button != null)
DestroyImmediate(button);
}
spellButtons.Clear();
}
private void SetVisible(bool visible)
{
if (selectionCanvas != null)
selectionCanvas.gameObject.SetActive(visible);
}
[System.Serializable]
private class SpellData
{
public string name;
public string description;
public int manaCost;
public bool requiresTarget;
public bool isAoE;
public Sprite icon;
}
}