343 lines
13 KiB
GDScript
343 lines
13 KiB
GDScript
extends "res://Systems/StateMachine/ChessGameState.gd"
|
|
|
|
var moves_remaining = {}
|
|
var multiMoving = ""
|
|
|
|
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)
|
|
|
|
|
|
_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"
|
|
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.selectedNode = source_location
|
|
print("source_location ", source_location)
|
|
|
|
# Then make the move
|
|
var target_location = Utils.convert_algebraic_to_location(target_square)
|
|
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 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
|
|
print("HANDLING MOVEMENT ", location, " | ", multiMoving, " | ", game.selectedNode)
|
|
var node = game.get_node("Flow/" + location) as PieceContainer
|
|
|
|
# Only try to get piece if we have a selected node
|
|
if game.selectedNode == "":
|
|
# 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 && piece.Item_Color == game.Turn:
|
|
game.selectedNode = location
|
|
game.getMovableAreas()
|
|
return
|
|
|
|
var sourcePiece = node.get_piece()
|
|
var moves = null;
|
|
if sourcePiece:
|
|
moves = sourcePiece.getValidMoves(game.boardContainer, location)
|
|
|
|
# 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:
|
|
return
|
|
# 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 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 attempting_piece.Item_Color == game.Turn:
|
|
print("early return - can't select different piece of same color during multi-move")
|
|
return
|
|
if game.selectedNode == "":
|
|
if node.get_piece() != null && node.get_piece().Item_Color == game.Turn:
|
|
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 game.selectedNode == location:
|
|
if !is_multi_moving and multiMoving == "":
|
|
print("CLEAR SELECTION*************")
|
|
game.clearSelection()
|
|
elif 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:
|
|
game.selectedNode = location
|
|
game.getMovableAreas()
|
|
return
|
|
return
|
|
elif 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 != "":
|
|
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.hasMoved = false
|
|
game.currentlyMovingPiece = null
|
|
# game.applyTileEffects()
|
|
# finished.emit(Constants.POST_MOVE)
|
|
|
|
|
|
|
|
|
|
|
|
func isCastlingMove(node: PieceContainer, location: String) -> bool:
|
|
return game.selectedNode != "" && node.get_piece() != null && node.get_piece().Item_Color == game.Turn && node.get_piece().name == "Rook"
|
|
|
|
func isEnPassantMove(node: PieceContainer, location: String) -> bool:
|
|
return game.selectedNode != "" && node.get_piece() != null && node.get_piece().Item_Color != game.Turn && \
|
|
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 && node.get_piece().Item_Color == game.Turn
|
|
|
|
func isCaptureMove(node: PieceContainer) -> bool:
|
|
return game.selectedNode != "" && node.get_piece() != null && node.get_piece().Item_Color != game.Turn
|
|
|
|
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
|
|
|
|
|
|
var moving_piece = source_container.get_piece()
|
|
var captured_piece = node.get_piece()
|
|
|
|
if moving_piece && captured_piece:
|
|
await game.animatePieceCapture(captured_piece)
|
|
game.updatePointsAndCapture(captured_piece, false)
|
|
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.Turn == 0:
|
|
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.hasMoved = true
|
|
game.currentlyMovingPiece = piece
|
|
game.resetHighlights()
|