diff --git a/Systems/DeckManager.gd b/Systems/DeckManager.gd index 085f7ed..c298655 100644 --- a/Systems/DeckManager.gd +++ b/Systems/DeckManager.gd @@ -5,6 +5,7 @@ var deck: Array = [] var hand: Array = [] var discard: Array = [] var attached_cards: Dictionary = {} # piece_id: card +var attached_effects: Dictionary = {} # piece_id: [card] var hand_size: int = 5 # Card costs for shop @@ -72,6 +73,57 @@ func playCard(card: Card, target_piece: Pawn, board_flow = null, game_state = nu # print("Failed Play Card 2") return false + +func playEffect(card: Card, target_piece: Pawn, board_flow = null, game_state = null): + + var key = target_piece.get_instance_id(); + if !attached_effects.has(key): + attached_effects[key] = [] + else: + for existing_card in attached_effects[key]: + if existing_card.cardName == card.cardName: + # Card already exists, don't add it again + return false + + if card.apply_effect(target_piece, board_flow, game_state): + if card.duration > 0: + attached_effects[key].append(card) + + + return true + # print("Failed Play Card 2") + return false + +func updateEffectDurations(): + var expired_entries = [] # Store [piece_id, card_id] pairs to remove + + for piece_id in attached_effects: + var cards_to_remove = [] # Track which cards to remove from this piece's array + + for card in attached_effects[piece_id]: + card.update_duration() + if card.remaining_turns <= 0: + cards_to_remove.append(card) + else: + var piece_node = instance_from_id(piece_id) + if is_instance_valid(piece_node): + piece_node.update_appearance() + + # Remove expired cards from this piece's array + for card in cards_to_remove: + attached_effects[piece_id].erase(card) + + # If no cards left for this piece, mark the piece_id for removal + if attached_effects[piece_id].is_empty(): + expired_entries.append(piece_id) + var piece_node = instance_from_id(piece_id) + if is_instance_valid(piece_node): + piece_node.update_appearance() + + # Remove empty entries + for piece_id in expired_entries: + attached_effects.erase(piece_id) + func updateCardDurations(): var expired_cards = [] for piece_id in attached_cards: diff --git a/Systems/StateMachine/GameStates/Movement.gd b/Systems/StateMachine/GameStates/Movement.gd index bb2c3c8..981b3c1 100644 --- a/Systems/StateMachine/GameStates/Movement.gd +++ b/Systems/StateMachine/GameStates/Movement.gd @@ -23,6 +23,15 @@ func enter(_previous: String, _data := {}) -> void: if card.effectType == Card.EffectType.MOVEMENT_MODIFIER: var effects = card.modify_moves() moves_remaining[piece_id] = effects.get("extra_moves", 0) + 1 + for piece_id in game.deckManager.attached_effects: + for effect in game.deckManager.attached_effects[piece_id]: + if effect.effectType == Card.EffectType.MOVEMENT_MODIFIER: + var effects = effect.modify_moves() + # Add to existing moves if already present, otherwise set new value + if piece_id in moves_remaining: + moves_remaining[piece_id] += effects.get("extra_moves", 0) + else: + moves_remaining[piece_id] = effects.get("extra_moves", 0) + 1 func exit() -> void: if game.boardContainer.is_connected("tile_pressed", handleMovement): diff --git a/Systems/Tiles/DoubleMovement.gd b/Systems/Tiles/DoubleMovement.gd index 599b413..3639a21 100644 --- a/Systems/Tiles/DoubleMovement.gd +++ b/Systems/Tiles/DoubleMovement.gd @@ -12,18 +12,9 @@ func _init(button: Button, is_white: bool, d: int) -> void: func apply_effect(piece: Pawn = null) -> void: if piece && is_effect_active(): var deck_manager = game.deckManager - - # Check for and remove any existing card - var piece_id = piece.get_instance_id() - if deck_manager.attached_cards.has(piece_id): - var existing_card = deck_manager.attached_cards[piece_id] - existing_card.remove_effect() - deck_manager.attached_cards.erase(piece_id) - - # Add double movement effect to the piece var double_time = DoubleTimeCard.new() double_time.duration = 2 - deck_manager.playCard(double_time, piece, null, null, true) + deck_manager.playEffect(double_time, piece, null, null) piece.on_card_effect_changed() func update_appearance() -> void: diff --git a/Systems/Tiles/PawnBoost.gd b/Systems/Tiles/PawnBoost.gd index 07e1192..f05f824 100644 --- a/Systems/Tiles/PawnBoost.gd +++ b/Systems/Tiles/PawnBoost.gd @@ -30,7 +30,7 @@ func apply_effect(piece: Pawn = null) -> void: # Add double movement effect var double_time = DoubleTimeCard.new() double_time.duration = 1 # Just for this turn - game.deckManager.playCard(double_time, pawn, null, game, true) + game.deckManager.playEffect(double_time, pawn, null, game) pawn.on_card_effect_changed() boosted_pawns.append(pawn_id) diff --git a/addons/Chess/Scripts/Pawn.gd b/addons/Chess/Scripts/Pawn.gd index 845fc45..b6a18aa 100644 --- a/addons/Chess/Scripts/Pawn.gd +++ b/addons/Chess/Scripts/Pawn.gd @@ -11,121 +11,125 @@ class_name Pawn @export var Points = 1 -var attached_card_label: Label var duration_label: Label var Temp_Color = 0 var Double_Start = true var En_Passant = false const BASE_SIZE = Vector2(40, 40) -const EFFECT_TINT_COLOR = Color(0.3, 0.8, 0.3, 0.5) # Green tint for card effects +const CARD_TINT_COLOR = Color(0.3, 0.8, 0.3, 0.5) # Green tint for card effects +const EFFECT_TINT_COLOR = Color(0.8, 0.2, 0.2, 0.5) var id: String = Utils.generate_guid() func _ready(): - modulate = Color.WHITE if Item_Color == 0 else Color.BLACK + modulate = Color.WHITE if Item_Color == 0 else Color.BLACK func _init() -> void: - self.texture = load("res://addons/Chess/Textures/WPawn.svg") - var background_style = StyleBoxFlat.new() - background_style.bg_color = Color.WHITE - background_style.corner_radius_top_left = 2 - background_style.corner_radius_top_right = 2 - background_style.corner_radius_bottom_left = 2 - background_style.corner_radius_bottom_right = 2 - background_style.content_margin_left = 2 - background_style.content_margin_right = 2 - background_style.content_margin_top = 1 - background_style.content_margin_bottom = 1 - duration_label = Label.new() - duration_label.add_theme_stylebox_override("normal", background_style) - duration_label.add_theme_color_override("font_color", Color.BLACK) - duration_label.position = Vector2(-20, -20) # Position above the piece - add_child(duration_label) - duration_label.hide() + self.texture = load("res://addons/Chess/Textures/WPawn.svg") + var background_style = StyleBoxFlat.new() + background_style.bg_color = Color.WHITE + background_style.corner_radius_top_left = 2 + background_style.corner_radius_top_right = 2 + background_style.corner_radius_bottom_left = 2 + background_style.corner_radius_bottom_right = 2 + background_style.content_margin_left = 2 + background_style.content_margin_right = 2 + background_style.content_margin_top = 1 + background_style.content_margin_bottom = 1 + duration_label = Label.new() + duration_label.add_theme_stylebox_override("normal", background_style) + duration_label.add_theme_color_override("font_color", Color.BLACK) + duration_label.position = Vector2(-20, -20) # Position above the piece + add_child(duration_label) + duration_label.hide() func update_appearance() -> void: - # print("update_appearance") - if !is_instance_valid(get_tree()) || !get_tree().get_root().has_node("Board"): - return - - var chess_game = get_tree().get_root().get_node("Board") - if !chess_game.deckManager: - return - - var deck_manager = chess_game.deckManager - var has_card = deck_manager.attached_cards.has(get_instance_id()) + # print("update_appearance") + if !is_instance_valid(get_tree()) || !get_tree().get_root().has_node("Board"): + return + + var chess_game = get_tree().get_root().get_node("Board") + if !chess_game.deckManager: + return + + var deck_manager = chess_game.deckManager + var has_card = deck_manager.attached_cards.has(get_instance_id()) + var has_effect = deck_manager.attached_effects.has(get_instance_id()) + + if has_card: + # Apply tint while keeping the piece color + var base_color = Color.WHITE if Item_Color == 0 else Color.BLACK + modulate = base_color * CARD_TINT_COLOR + + if has_effect: + modulate = base_color * CARD_TINT_COLOR * EFFECT_TINT_COLOR + + # Update duration display + var card = deck_manager.attached_cards[get_instance_id()] + if is_instance_valid(duration_label): + duration_label.text = str(card.remaining_turns) + duration_label.show() + else: + # Reset to normal color + modulate = Color.WHITE if Item_Color == 0 else Color.BLACK + if is_instance_valid(duration_label): + duration_label.hide() - if has_card: - # Apply tint while keeping the piece color - var base_color = Color.WHITE if Item_Color == 0 else Color.BLACK - modulate = base_color * EFFECT_TINT_COLOR - - # Update duration display - var card = deck_manager.attached_cards[get_instance_id()] - if is_instance_valid(duration_label): - duration_label.text = str(card.remaining_turns) - duration_label.show() - else: - # Reset to normal color - modulate = Color.WHITE if Item_Color == 0 else Color.BLACK - if is_instance_valid(duration_label): - duration_label.hide() - func on_card_effect_changed() -> void: - update_appearance() + update_appearance() # Movement interface method that all pieces will implement # In Pawn.gd func getValidMoves(board_flow, current_location: String) -> Dictionary: - var moves = { - "regular_moves": [], - "special_moves": [] - } + var moves = { + "regular_moves": [], + "special_moves": [] + } - var loc = current_location.split("-") - var x = int(loc[0]) - var y = int(loc[1]) + var loc = current_location.split("-") + var x = int(loc[0]) + var y = int(loc[1]) - # Movement direction based on color - var direction = -1 if Item_Color == 0 else 1 + # Movement direction based on color + var direction = -1 if Item_Color == 0 else 1 - # Forward movement - var forward = str(x) + "-" + str(y + direction) - if is_valid_cell(board_flow, forward) && can_move_to_cell(board_flow, forward): - moves.regular_moves.append(forward) - - # Double move on first turn - var double_forward = str(x) + "-" + str(y + (direction * 2)) - if Double_Start && is_valid_cell(board_flow, double_forward) && can_move_to_cell(board_flow, double_forward): - moves.regular_moves.append(double_forward) + # Forward movement + var forward = str(x) + "-" + str(y + direction) + if is_valid_cell(board_flow, forward) && can_move_to_cell(board_flow, forward): + moves.regular_moves.append(forward) + + # Double move on first turn + var double_forward = str(x) + "-" + str(y + (direction * 2)) + if Double_Start && is_valid_cell(board_flow, double_forward) && can_move_to_cell(board_flow, double_forward): + moves.regular_moves.append(double_forward) - # Diagonal captures - for dx in [-1, 1]: - var capture = str(x + dx) + "-" + str(y + direction) - if is_valid_cell(board_flow, capture) && can_move_to_cell(board_flow, capture, true): - moves.regular_moves.append(capture) - - # En Passant - var adjacent = str(x + dx) + "-" + str(y) - if is_valid_cell(board_flow, adjacent) && is_valid_cell(board_flow, capture): - var adjacent_cell = board_flow.get_node(adjacent) as PieceContainer - if adjacent_cell.get_piece() != null: - var adjacent_piece = adjacent_cell.get_piece() - if adjacent_piece.name == "Pawn" && adjacent_piece.En_Passant && adjacent_piece.Item_Color != self.Item_Color: - moves.special_moves.append([adjacent, capture]) + # Diagonal captures + for dx in [-1, 1]: + var capture = str(x + dx) + "-" + str(y + direction) + if is_valid_cell(board_flow, capture) && can_move_to_cell(board_flow, capture, true): + moves.regular_moves.append(capture) + + # En Passant + var adjacent = str(x + dx) + "-" + str(y) + if is_valid_cell(board_flow, adjacent) && is_valid_cell(board_flow, capture): + var adjacent_cell = board_flow.get_node(adjacent) as PieceContainer + if adjacent_cell.get_piece() != null: + var adjacent_piece = adjacent_cell.get_piece() + if adjacent_piece.name == "Pawn" && adjacent_piece.En_Passant && adjacent_piece.Item_Color != self.Item_Color: + moves.special_moves.append([adjacent, capture]) - return moves + return moves # Helper method for all pieces func is_valid_cell(board_flow, location: String) -> bool: - var node = board_flow.get_node_or_null(location) - return node != null + var node = board_flow.get_node_or_null(location) + return node != null # Helper for checking if cell is empty or contains enemy func can_move_to_cell(board_flow, location: String, is_capture: bool = false) -> bool: - var container = board_flow.get_node(location) as PieceContainer - if is_capture: - var piece = container.get_piece() - return piece != null && piece.Item_Color != self.Item_Color - return !container.has_piece() \ No newline at end of file + var container = board_flow.get_node(location) as PieceContainer + if is_capture: + var piece = container.get_piece() + return piece != null && piece.Item_Color != self.Item_Color + return !container.has_piece() \ No newline at end of file