working updates

This commit is contained in:
2026-01-26 16:14:57 -05:00
parent b1e99fa952
commit c8228f200d
8055 changed files with 142307 additions and 867 deletions

View File

@@ -166,7 +166,15 @@ func get_card_texture(card: CardData) -> Texture2D:
if card.image_path.is_empty():
return null
var texture_path = "res://assets/cards/" + card.image_path
# Try source-cards directory first (primary location for card images)
var texture_path = "res://source-cards/" + card.image_path
if ResourceLoader.exists(texture_path):
var texture = load(texture_path)
_card_textures[card.id] = texture
return texture
# Fallback to assets/cards directory
texture_path = "res://assets/cards/" + card.image_path
if ResourceLoader.exists(texture_path):
var texture = load(texture_path)
_card_textures[card.id] = texture
@@ -175,25 +183,53 @@ func get_card_texture(card: CardData) -> Texture2D:
return null
## Create a list of card IDs for a deck (for testing)
func create_test_deck(_player_index: int) -> Array[String]:
## Player 0 gets Fire/Ice deck, Player 1 gets Wind/Lightning deck
func create_test_deck(player_index: int) -> Array[String]:
var deck: Array[String] = []
# Get all cards and create a 50-card deck
var all_cards = get_all_cards()
# Define element pairs for each player
var primary_element: Enums.Element
var secondary_element: Enums.Element
# Add 3 copies of each card until we have 50
for card in all_cards:
if deck.size() >= 50:
break
# Add up to 3 copies
if player_index == 0:
primary_element = Enums.Element.FIRE
secondary_element = Enums.Element.ICE
else:
primary_element = Enums.Element.WIND
secondary_element = Enums.Element.LIGHTNING
# Get cards by element
var primary_cards = get_cards_by_element(primary_element)
var secondary_cards = get_cards_by_element(secondary_element)
# Add 3 copies of each primary element card
for card in primary_cards:
for i in range(3):
if deck.size() >= 50:
break
deck.append(card.id)
if deck.size() < 50:
deck.append(card.id)
# Fill remaining slots if needed
while deck.size() < 50 and all_cards.size() > 0:
deck.append(all_cards[0].id)
# Add 3 copies of each secondary element card
for card in secondary_cards:
for i in range(3):
if deck.size() < 50:
deck.append(card.id)
# If we still need cards, add from Earth/Water
if deck.size() < 50:
var filler_element = Enums.Element.EARTH if player_index == 0 else Enums.Element.WATER
var filler_cards = get_cards_by_element(filler_element)
for card in filler_cards:
for i in range(3):
if deck.size() < 50:
deck.append(card.id)
# Final fallback: add any cards
if deck.size() < 50:
var all_cards = get_all_cards()
for card in all_cards:
for i in range(3):
if deck.size() < 50:
deck.append(card.id)
return deck

View File

@@ -84,6 +84,7 @@ func start_new_game() -> void:
func _connect_game_signals() -> void:
game_state.game_ended.connect(_on_game_ended)
game_state.card_played.connect(_on_card_played)
game_state.summon_cast.connect(_on_summon_cast)
game_state.damage_dealt.connect(_on_damage_dealt)
game_state.forward_broken.connect(_on_forward_broken)
game_state.attack_declared.connect(_on_attack_declared)
@@ -147,14 +148,19 @@ func try_play_card(card: CardInstance) -> bool:
message.emit(play_error)
return false
# Determine target zone
# Handle summons differently
if card.is_summon():
return _try_cast_summon(player_index, card)
# Determine target zone for Forwards/Backups
var to_zone = Enums.ZoneType.FIELD_FORWARDS if card.is_forward() else Enums.ZoneType.FIELD_BACKUPS
# Try to play
if game_state.play_card(player_index, card):
# Record for undo
# Try to play (returns CP spent dict)
var cp_spent = game_state.play_card(player_index, card)
if not cp_spent.is_empty():
# Record for undo with actual CP spent
if undo_system:
undo_system.record_play_card(player_index, card, to_zone, {})
undo_system.record_play_card(player_index, card, to_zone, cp_spent)
message.emit("Played " + card.get_display_name())
return true
@@ -164,6 +170,18 @@ func try_play_card(card: CardInstance) -> bool:
message.emit("Failed to play " + card.get_display_name() + " (internal error)")
return false
## Try to cast a summon
func _try_cast_summon(player_index: int, card: CardInstance) -> bool:
if game_state.cast_summon(player_index, card):
# Note: Summons cannot be undone as they have immediate effects
message.emit("Cast " + card.get_display_name() + "!")
# TODO: Implement effect resolution system
# For now, summons just go to break zone with no effect
return true
else:
message.emit("Failed to cast " + card.get_display_name() + " (internal error)")
return false
## Check play restrictions and return error message, or empty string if playable
func _check_play_restrictions(player: Player, card: CardInstance) -> String:
# Check if card is in hand
@@ -175,11 +193,11 @@ func _check_play_restrictions(player: Player, card: CardInstance) -> String:
if player.field_backups.get_count() >= Player.MAX_BACKUPS:
return "Cannot play: Maximum 5 Backups allowed!"
# Check unique name restriction (non-generic cards)
# Check unique name restriction (non-generic cards can't share names across entire field)
if not card.card_data.is_generic:
if card.is_forward() and player.field_forwards.has_card_with_name(card.card_data.name):
if player.field_forwards.has_card_with_name(card.card_data.name):
return "Cannot play: You already have " + card.card_data.name + " on the field!"
if card.is_backup() and player.field_backups.has_card_with_name(card.card_data.name):
if player.field_backups.has_card_with_name(card.card_data.name):
return "Cannot play: You already have " + card.card_data.name + " on the field!"
# Check Light/Dark restriction
@@ -194,6 +212,11 @@ func discard_card_for_cp(card: CardInstance) -> bool:
if not game_state or not is_game_active:
return false
# Check Light/Dark restriction before attempting
if card.is_light_or_dark():
message.emit("Cannot discard Light/Dark cards for CP!")
return false
var player_index = card.owner_index
var element = card.get_element()
@@ -239,9 +262,11 @@ func _check_pending_action() -> void:
return
if player.cp_pool.can_afford_card(selected_card.card_data):
# Can now afford - try to play
try_play_card(selected_card)
clear_selection()
# Per FF-TCG rules: CP is generated to pay for a specific card
# Auto-play when we have enough CP
var card_to_play = selected_card
clear_selection() # Clear first to avoid re-entry
try_play_card(card_to_play)
## Declare an attack
func declare_attack(card: CardInstance) -> bool:
@@ -356,6 +381,12 @@ func _on_card_played(card: CardInstance, _player_index: int) -> void:
"type": Enums.card_type_to_string(card.card_data.type)
})
func _on_summon_cast(card: CardInstance, _player_index: int) -> void:
card_played.emit({
"name": card.get_display_name(),
"type": "Summon"
})
func _on_damage_dealt(player_index: int, amount: int, _cards: Array) -> void:
var player_name = game_state.get_player(player_index).player_name
damage_dealt.emit(player_name, amount)