extends "res://Systems/StateMachine/ChessGameState.gd" var moves_remaining = {} var multiMoving = "" var last_selected = null func _ready() -> void: print("Movement state ready") func _setup_movement_modifiers() -> void: for piece_id in game.deckManager.attached_cards: var card = game.deckManager.attached_cards[piece_id] if card.effectType == Card.EffectType.MOVEMENT_MODIFIER: var effects = card.modify_moves() moves_remaining[piece_id] = effects.get("extra_moves", 0) + 1 func enter(_previous: String, _data := {}) -> void: print("ENTERING STATE ", Constants.MOVEMENT, " ", game.currentPlayer) last_selected = null _setup_movement_modifiers() if !game.boardContainer.is_connected("tile_pressed", handleMovement): game.boardContainer.connect("tile_pressed", handleMovement) if game.selectedNode != "": game.getMovableAreas() else: game.resetHighlights() moves_remaining.clear() multiMoving = "" for piece_id in game.deckManager.attached_cards: var card = game.deckManager.attached_cards[piece_id] 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 if game.currentPlayer == game.BLACK and game.stockfishController: var move = game.stockfishController.getGeneratedMove() print("GENERATED MOVE ", move) if move: var move_str = move.move # e.g., "e2e4" if "," in move_str: move_str = move.move.split(",")[0] var source_square = move_str.substr(0, 2) # "e2" var target_square = move_str.substr(2, 2) # "e4" # First select the piece var source_location = Utils.convert_algebraic_to_location(source_square, game.boardYSize) game.selectedNode = source_location print("source_location ", source_location) # Then make the move var target_location = Utils.convert_algebraic_to_location(target_square, game.boardYSize) print("target_location ", target_location) handleMovement(target_location, true) return func exit() -> void: if game.boardContainer.is_connected("tile_pressed", handleMovement): game.boardContainer.disconnect("tile_pressed", handleMovement) func pieceItemColourTurnMatch(colour): #0 white, 1 black return ((colour == 0) and (game.currentPlayer == game.WHITE)) || ((colour == 1) and (game.currentPlayer == game.BLACK)) func handleMovement(location: String, generated: bool = false) -> void: # we need to prevent swapping of focus between peices after the double move process has started # maybe once u start nmoving a peice global stat var is set # and any moving peice needs ot match that var node = game.get_node("Flow/" + location) as PieceContainer print("HANDLING MOVEMENT ", location, " | ", last_selected, " | ", game.selectedNode) if node.has_piece(): print(node.get_piece()) var prev_last_selected = last_selected if !generated : if last_selected == null: last_selected = location else: if game.selectedNode == location: last_selected = null var moves = { "regular_moves": game.areas, "special_moves": game.specialArea } # areas = moves.regular_moves # specialArea = moves.special_moves # Only try to get piece if we have a selected node if game.selectedNode == "": # print("No Node") # If no node is selected, we might want to select this one if it has a piece var piece = node.get_piece() if piece != null && pieceItemColourTurnMatch(piece.Item_Color): game.selectedNode = location game.getMovableAreas() last_selected = location return # else: # moves = (game.get_node("Flow/" + game.selectedNode) as PieceContainer).get_piece().getValidMoves(game.boardContainer, location) var sourcePiece = node.get_piece() # if sourcePiece: # moves = sourcePiece.getValidMoves(game.boardContainer, location) # if !(location == game.selectedNode): # print("Valid Choice ", moves) # Now we know we have a selected node, get its piece var sourceContainer = game.get_node("Flow/" + game.selectedNode) as PieceContainer var piece = sourceContainer.get_piece() if piece == null: print("No Piece") return else: print("Selected ", piece.name) # print("SColor ", sourcePiece.Item_Color, " tColor ", piece.Item_Color) var piece_id = piece.get_instance_id() var is_multi_moving = piece_id in moves_remaining and moves_remaining[piece_id] > 1 if !generated and moves != null and !moves.regular_moves.has(location) and !moves.special_moves.has(location) and !(game.selectedNode == location and location == prev_last_selected): last_selected = prev_last_selected print("Invalid Choice ", moves) if isReselectMove(node): if !is_multi_moving and multiMoving == "": print("RESELECT SELECTION*************") game.selectedNode = location game.getMovableAreas() return if !generated and game.selectedNode == location and location == prev_last_selected: # print("CAN CLEAR SELECTION************* ", multiMoving, " !is_multi_moving ", !is_multi_moving) if !is_multi_moving and multiMoving == "": print("CLEAR SELECTION*************") game.clearSelection() return return if multiMoving.length() > 0: if node.get_piece() != null and is_instance_valid(node.get_piece()): var attempting_piece = node.get_piece() # print("Checking Str comp ", str(attempting_piece.get_instance_id()), " ", multiMoving) # Only block if it's a different piece of the same color if str(attempting_piece.get_instance_id()) != multiMoving and pieceItemColourTurnMatch(attempting_piece.Item_Color): print("early return - can't select different piece of same color during multi-move") return if game.selectedNode == "": # print("No Node 2") if node.get_piece() != null && pieceItemColourTurnMatch(node.get_piece().Item_Color): # print("SELECTED NODE ", location) game.selectedNode = location game.getMovableAreas() return # print(moves_remaining, " | ", piece_id, " | ",is_multi_moving) var consumeMove = true; if is_multi_moving: moves_remaining[piece_id] -= 1 consumeMove = false; else: # No more moves remaining, end turn if piece_id in moves_remaining: moves_remaining.erase(piece_id) # finished.emit(Constants.POST_MOVE) if moves != null and !moves.regular_moves.has(game.selectedNode) and !moves.special_moves.has(game.selectedNode): if sourcePiece and sourcePiece.Item_Color == piece.Item_Color: # print("Set Location*************") game.selectedNode = location game.getMovableAreas() return print("Movemnet ", moves) if isCastlingMove(node, location): handleCastling(node, generated) finished.emit(Constants.POST_MOVE) # En Passant elif isEnPassantMove(node, location): handleEnPassant(node, generated) # Reselect piece elif isReselectMove(node): if !is_multi_moving and multiMoving == "": print("RESELECT SELECTION*************") game.selectedNode = location game.getMovableAreas() # Capture piece elif isCaptureMove(node): handleCapture(node, generated) finished.emit(Constants.POST_MOVE) # Regular move # elif isRegularMove(node): # handleRegularMove(node) # finished.emit(Constants.POST_MOVE) else: if game.isValidMove(location) || generated: # executeMove(location) handleRegularMove(node, consumeMove, generated) if consumeMove: multiMoving = "" game.clearSelection() print("Consuming move") finished.emit(Constants.POST_MOVE) elif is_multi_moving: game.selectedNode = location # Keep the piece selected for another move multiMoving = str(piece_id) # game.selectedNode = "" print("ANOTHER MOVE") game.resetHighlights() if game.selectedNode != "": if game.isPlayerTurn(): game.tileManager.apply_tile_effect(game.selectedNode) game.getMovableAreas() if game.areas.size() == 0 and game.specialArea.size() == 0: print("Consuming move because no valid moves left") game.resolveMoveEffects() multiMoving = "" game.clearSelection() if piece_id in moves_remaining: moves_remaining.erase(piece_id) finished.emit(Constants.POST_MOVE) else: game.currentlyMovingPiece = null # game.applyTileEffects() # finished.emit(Constants.POST_MOVE) func isCastlingMove(node: PieceContainer, location: String) -> bool: return game.selectedNode != "" && node.get_piece() != null && pieceItemColourTurnMatch(node.get_piece().Item_Color) && node.get_piece().name == "Rook" func isEnPassantMove(node: PieceContainer, location: String) -> bool: return game.selectedNode != "" && node.get_piece() != null && !pieceItemColourTurnMatch(node.get_piece().Item_Color) && \ node.get_piece().name == "Pawn" && game.specialArea.size() != 0 && game.specialArea[0] == node.name && \ node.get_piece().get("En_Passant") == true func isReselectMove(node: PieceContainer) -> bool: return game.selectedNode != "" && node.get_piece() != null && pieceItemColourTurnMatch(node.get_piece().Item_Color) func isCaptureMove(node: PieceContainer) -> bool: return game.selectedNode != "" && node.get_piece() != null && !pieceItemColourTurnMatch(node.get_piece().Item_Color) func isRegularMove(node: PieceContainer) -> bool: return game.selectedNode != "" && node.get_piece() != null func handleCastling(node: PieceContainer, generated: bool = false) -> void: print("handleCastling") if generated: castleMovement(node) return for i in game.areas: if i == node.name: castleMovement(node) func castleMovement(node: PieceContainer) -> void: var kingContainer = game.get_node("Flow/" + game.selectedNode) as PieceContainer var rookContainer = node as PieceContainer var kingTargetContainer = game.get_node("Flow/" + game.specialArea[1]) as PieceContainer var rookTargetContainer = game.get_node("Flow/" + game.specialArea[0]) as PieceContainer var king = kingContainer.get_piece() var rook = rookContainer.get_piece() # kingContainer.remove_piece(true) # rookContainer.remove_piece(true) # kingTargetContainer.set_piece(king) # rookTargetContainer.set_piece(rook) kingTargetContainer.animate_movement(kingContainer, king); rookTargetContainer.animate_movement(rookContainer, rook); game.currentlyMovingPiece = king game.resolveMoveEffects() func handleEnPassant(node: PieceContainer, generated: bool = false) -> void: print("handleEnPassant") if generated: handleEnPassantMovement(node) return for i in game.areas: if i == node.name: handleEnPassantMovement(node) func handleEnPassantMovement(node: PieceContainer) -> void: var targetContainer = game.get_node("Flow/" + game.selectedNode) as PieceContainer var pawn = (game.get_node("Flow/" + game.selectedNode) as PieceContainer).get_piece() # node.remove_piece() # targetContainer.set_piece(pawn) game.currentlyMovingPiece = pawn targetContainer.animate_movement(node, pawn); game.resolveMoveEffects() func handleCapture(node: PieceContainer, generated: bool = false) -> void: print("handleCapture") if generated: handleCaptureMovement(node) return for i in game.areas: if i == node.name: handleCaptureMovement(node) func handleCaptureMovement(node: PieceContainer) -> void: var source_container = game.get_node("Flow/" + game.selectedNode) as PieceContainer print("handleCaptureMovement") var moving_piece = source_container.get_piece() var captured_piece = node.get_piece() if moving_piece && captured_piece: print("handleCapturingMovement") # await game.animatePieceCapture(captured_piece) game.updatePointsAndCapture(captured_piece, true) node.animate_movement(source_container, moving_piece); var tile = game.tileManager.get_tile(node.name) if tile: tile.apply_effect(moving_piece) game.currentlyMovingPiece = moving_piece game.resolveMoveEffects() func handleRegularMove(node: PieceContainer, consume: bool, generated: bool = false) -> void: print("handleRegularMove", node, game.selectedNode) if generated: moveAndConsume(node, consume) return for i in game.areas: if i == node.name: moveAndConsume(node, consume) func moveAndConsume(node: PieceContainer, consume: bool) -> void: var sourceContainer = game.get_node("Flow/" + game.selectedNode) as PieceContainer var piece = sourceContainer.get_piece() # print("Removing Piece 1") node.animate_movement(sourceContainer, piece); game.currentlyMovingPiece = piece if consume: game.resolveMoveEffects() else: game.togglePieceChessEffect() func executeMove(targetLocation: String) -> void: print("executeMove ", targetLocation) var targetContainer = game.get_node("Flow/" + targetLocation) as PieceContainer var sourceContainer = game.get_node("Flow/" + game.selectedNode) as PieceContainer var piece = sourceContainer.get_piece() # Handle capture if there's a piece in the target location if targetContainer.has_piece(): var capturedPiece = targetContainer.get_piece() if game.currentPlayer == game.WHITE: game.p1Points += capturedPiece.Points game.p1String.text = str(game.p1Points) else: game.p2Points += capturedPiece.Points game.p2String.text = str(game.p2Points) targetContainer.remove_piece() # This will handle freeing the captured piece # Move piece to new location sourceContainer.remove_piece(true) targetContainer.set_piece(piece) game.currentlyMovingPiece = piece game.resetHighlights()