Files
FFCardGame/scripts/game/Zone.gd
2026-01-26 16:14:57 -05:00

161 lines
4.0 KiB
GDScript

class_name Zone
extends RefCounted
## Zone - Container for cards in a specific game area
var zone_type: Enums.ZoneType
var owner_index: int # Player who owns this zone (-1 for shared zones like stack)
var _cards: Array[CardInstance] = []
# Signals (these would need to be connected via the parent)
# In GDScript, RefCounted can't have signals, so we'll use callbacks
var on_card_added: Callable = func(_card): pass
var on_card_removed: Callable = func(_card): pass
func _init(type: Enums.ZoneType, owner: int = -1) -> void:
zone_type = type
owner_index = owner
## Add a card to this zone
## Returns true if successful, false if card was already in zone
func add_card(card: CardInstance, at_top: bool = true) -> bool:
if card in _cards:
push_warning("Card already in zone: " + str(card))
return false
card.zone_type = zone_type
if at_top:
_cards.append(card)
else:
_cards.insert(0, card)
on_card_added.call(card)
return true
## Remove a card from this zone
func remove_card(card: CardInstance) -> bool:
var index = _cards.find(card)
if index >= 0:
_cards.remove_at(index)
on_card_removed.call(card)
return true
return false
## Get all cards in this zone
func get_cards() -> Array[CardInstance]:
return _cards.duplicate()
## Get card count
func get_count() -> int:
return _cards.size()
## Check if zone contains a card
func has_card(card: CardInstance) -> bool:
return card in _cards
## Get card at index
func get_card_at(index: int) -> CardInstance:
if index >= 0 and index < _cards.size():
return _cards[index]
return null
## Get top card (last added)
func get_top_card() -> CardInstance:
if _cards.size() > 0:
return _cards[_cards.size() - 1]
return null
## Remove and return top card
func pop_top_card() -> CardInstance:
if _cards.size() > 0:
var card = _cards.pop_back()
on_card_removed.call(card)
return card
return null
## Get bottom card (first added)
func get_bottom_card() -> CardInstance:
if _cards.size() > 0:
return _cards[0]
return null
## Check if zone is empty
func is_empty() -> bool:
return _cards.size() == 0
## Shuffle the zone (for decks)
func shuffle() -> void:
_cards.shuffle()
## Clear all cards from zone
func clear() -> Array[CardInstance]:
var removed = _cards.duplicate()
_cards.clear()
for card in removed:
on_card_removed.call(card)
return removed
## Get all Forwards in zone
func get_forwards() -> Array[CardInstance]:
var forwards: Array[CardInstance] = []
for card in _cards:
if card.is_forward():
forwards.append(card)
return forwards
## Get all Backups in zone
func get_backups() -> Array[CardInstance]:
var backups: Array[CardInstance] = []
for card in _cards:
if card.is_backup():
backups.append(card)
return backups
## Get all active cards
func get_active_cards() -> Array[CardInstance]:
var active: Array[CardInstance] = []
for card in _cards:
if card.is_active():
active.append(card)
return active
## Get all dull cards
func get_dull_cards() -> Array[CardInstance]:
var dull: Array[CardInstance] = []
for card in _cards:
if card.is_dull():
dull.append(card)
return dull
## Find cards by name
func find_cards_by_name(card_name: String) -> Array[CardInstance]:
var found: Array[CardInstance] = []
for card in _cards:
if card.card_data and card.card_data.name == card_name:
found.append(card)
return found
## Find cards by element
func find_cards_by_element(element: Enums.Element) -> Array[CardInstance]:
var found: Array[CardInstance] = []
for card in _cards:
if element in card.get_elements():
found.append(card)
return found
## Check if zone has a card with specific name
## Note: The non-generic check should be on the card being played, not the field card
func has_card_with_name(card_name: String) -> bool:
for card in _cards:
if card.card_data and card.card_data.name == card_name:
return true
return false
## Check if zone has any Light or Dark card
func has_light_or_dark() -> bool:
for card in _cards:
if card.is_light_or_dark():
return true
return false