class_name Deck extends RefCounted ## Deck - Data model for a player's deck signal deck_changed const MIN_CARDS: int = 50 const MAX_CARDS: int = 50 const MAX_COPIES: int = 3 var name: String = "New Deck" var cards: Dictionary = {} # card_id -> count ## Add a card to the deck ## Returns empty string on success, error message on failure func add_card(card_id: String) -> String: var current_count = cards.get(card_id, 0) if current_count >= MAX_COPIES: return "Maximum %d copies allowed" % MAX_COPIES var total = get_total_cards() if total >= MAX_CARDS: return "Deck is full (%d cards)" % MAX_CARDS cards[card_id] = current_count + 1 deck_changed.emit() return "" ## Remove a card from the deck ## Returns true if successful func remove_card(card_id: String) -> bool: if not cards.has(card_id): return false cards[card_id] -= 1 if cards[card_id] <= 0: cards.erase(card_id) deck_changed.emit() return true ## Set card count directly func set_card_count(card_id: String, count: int) -> void: if count <= 0: cards.erase(card_id) else: cards[card_id] = mini(count, MAX_COPIES) deck_changed.emit() ## Get total number of cards in deck func get_total_cards() -> int: var total = 0 for count in cards.values(): total += count return total ## Get count for a specific card func get_card_count(card_id: String) -> int: return cards.get(card_id, 0) ## Get all unique card IDs in deck func get_card_ids() -> Array[String]: var ids: Array[String] = [] for card_id in cards.keys(): ids.append(card_id) return ids ## Validate the deck ## Returns array of error messages (empty if valid) func validate() -> Array[String]: var errors: Array[String] = [] var total = get_total_cards() if total < MIN_CARDS: errors.append("Deck needs %d more cards" % (MIN_CARDS - total)) elif total > MAX_CARDS: errors.append("Deck has %d too many cards" % (total - MAX_CARDS)) for card_id in cards: if cards[card_id] > MAX_COPIES: var card_data = CardDatabase.get_card(card_id) var card_name = card_data.name if card_data else card_id errors.append("%s has too many copies (%d)" % [card_name, cards[card_id]]) return errors ## Check if deck is valid func is_valid() -> bool: return validate().size() == 0 ## Convert deck to array of card IDs (for gameplay) func to_card_array() -> Array[String]: var result: Array[String] = [] for card_id in cards: for i in range(cards[card_id]): result.append(card_id) return result ## Clear the deck func clear() -> void: cards.clear() deck_changed.emit() ## Get deck statistics func get_stats() -> Dictionary: var stats = { "total": get_total_cards(), "unique": cards.size(), "elements": {}, "types": {}, "cost_curve": {} } for card_id in cards: var count = cards[card_id] var card_data = CardDatabase.get_card(card_id) if not card_data: continue # Element breakdown for element in card_data.elements: var elem_name = Enums.element_to_string(element) stats.elements[elem_name] = stats.elements.get(elem_name, 0) + count # Type breakdown var type_name = Enums.card_type_to_string(card_data.type) stats.types[type_name] = stats.types.get(type_name, 0) + count # Cost curve var cost_key = str(card_data.cost) stats.cost_curve[cost_key] = stats.cost_curve.get(cost_key, 0) + count return stats ## Serialize deck to dictionary (for saving) func to_dict() -> Dictionary: return { "name": name, "cards": cards.duplicate(), "version": "1.0" } ## Load deck from dictionary func from_dict(data: Dictionary) -> void: name = data.get("name", "Unnamed Deck") cards = data.get("cards", {}).duplicate() deck_changed.emit() func _to_string() -> String: return "[Deck: %s (%d cards)]" % [name, get_total_cards()]