using System; using System.Collections.Generic; using System.Linq; using UnityEngine; namespace AppleHills.Data.CardSystem { /// /// Manages the player's collection of cards and booster packs /// [Serializable] public class CardInventory { // Dictionary of collected cards indexed by definition ID + rarity (e.g., "Pikachu_Normal", "Pikachu_Rare") [SerializeField] private Dictionary collectedCards = new Dictionary(); /// /// Generate a unique key for a card based on definition ID and rarity /// private string GetCardKey(string definitionId, CardRarity rarity) { return $"{definitionId}_{rarity}"; } // Number of unopened booster packs the player has [SerializeField] private int boosterPackCount; // Additional lookup dictionaries (not serialized) [NonSerialized] private Dictionary> cardsByZone = new Dictionary>(); [NonSerialized] private Dictionary> cardsByRarity = new Dictionary>(); // Properties with public getters public Dictionary CollectedCards => collectedCards; public int BoosterPackCount { get => boosterPackCount; set => boosterPackCount = value; } // Constructor initializes empty dictionaries public CardInventory() { // Initialize dictionaries for all enum values so we never have to check for null foreach (CardZone zone in Enum.GetValues(typeof(CardZone))) { cardsByZone[zone] = new List(); } foreach (CardRarity rarity in Enum.GetValues(typeof(CardRarity))) { cardsByRarity[rarity] = new List(); } } /// /// Get all cards in the player's collection as a list /// public List GetAllCards() { return collectedCards.Values.ToList(); } /// /// Clears all cards from the inventory /// Primarily used for testing /// public void ClearAllCards() { collectedCards.Clear(); // Clear lookup dictionaries foreach (var zone in cardsByZone.Keys) { cardsByZone[zone].Clear(); } foreach (var rarity in cardsByRarity.Keys) { cardsByRarity[rarity].Clear(); } } /// /// Get cards filtered by zone /// public List GetCardsByZone(CardZone zone) { return new List(cardsByZone[zone]); } /// /// Get cards filtered by rarity /// public List GetCardsByRarity(CardRarity rarity) { return new List(cardsByRarity[rarity]); } /// /// Add a card to the inventory (or increase the copies if already owned) /// public void AddCard(CardData card) { if (card == null) return; string key = GetCardKey(card.DefinitionId, card.Rarity); if (collectedCards.TryGetValue(key, out CardData existingCard)) { // Increase copies of existing card existingCard.CopiesOwned++; } else { // Add new card to collection var newCard = new CardData(card); collectedCards[key] = newCard; // Add to lookup dictionaries cardsByZone[newCard.Zone].Add(newCard); cardsByRarity[newCard.Rarity].Add(newCard); } } /// /// Update card zone and rarity indexes when a card changes /// public void UpdateCardProperties(CardData card, CardZone oldZone, CardRarity oldRarity) { // Only needed if the card's zone or rarity actually changed if (oldZone != card.Zone) { cardsByZone[oldZone].Remove(card); cardsByZone[card.Zone].Add(card); } if (oldRarity != card.Rarity) { cardsByRarity[oldRarity].Remove(card); cardsByRarity[card.Rarity].Add(card); } } /// /// Get a specific card from the collection by definition ID and rarity /// public CardData GetCard(string definitionId, CardRarity rarity) { string key = GetCardKey(definitionId, rarity); return collectedCards.TryGetValue(key, out CardData card) ? card : null; } /// /// Check if the player has a specific card at a specific rarity /// public bool HasCard(string definitionId, CardRarity rarity) { string key = GetCardKey(definitionId, rarity); return collectedCards.ContainsKey(key); } /// /// Get total number of unique cards in collection /// public int GetUniqueCardCount() { return collectedCards.Count; } /// /// Get total number of cards including copies /// public int GetTotalCardCount() { return collectedCards.Values.Sum(card => card.CopiesOwned); } /// /// Get number of cards in a specific zone /// public int GetZoneCardCount(CardZone zone) { return cardsByZone[zone].Count; } /// /// Get number of cards of a specific rarity /// public int GetRarityCardCount(CardRarity rarity) { return cardsByRarity[rarity].Count; } /// /// Get cards sorted by collection index (for album view) /// public List GetCardsSortedByIndex() { return collectedCards.Values .OrderBy(card => card.CollectionIndex) .ToList(); } /// /// Check if there's a complete collection for a specific zone /// public bool IsZoneCollectionComplete(CardZone zone, List allAvailableCards) { int availableInZone = allAvailableCards.Count(card => card.Zone == zone); int collectedInZone = cardsByZone[zone].Count; return availableInZone > 0 && collectedInZone >= availableInZone; } /// /// Adds booster packs to the inventory /// public void AddBoosterPacks(int count) { boosterPackCount += count; } /// /// Use a single booster pack (returns true if successful) /// public bool UseBoosterPack() { if (boosterPackCount <= 0) return false; boosterPackCount--; return true; } } }