extends Area2D enum TEAM {WHITE, BLACK, NEUTRAL} enum KIND {KING, QUEEN, ROOK, BISHOP, KNIGHT, PAWN} @export var dragging: bool = false @export var grid_size: Vector2i = Vector2i(1, 1) @export var grid_pos: Vector2i = Vector2i(0, 0) @export var kind: KIND = KIND.PAWN @export var team: TEAM = TEAM.NEUTRAL signal moved(piece: Area2D, old_pos: Vector2i, new_pos: Vector2i) # Called when the node enters the scene tree for the first time. func _ready(): position = grid_to_pos(grid_pos) setup() func setup(): pass # Called every frame. 'delta' is the elapsed time since the previous frame. func _process(delta): pass func _on_input_event(viewport, event, shape_idx): if event.is_pressed(): dragging = true position = viewport.get_mouse_position(); func _unhandled_input(event): if dragging and event is InputEventMouseButton and not event.pressed: dragging = false var grid_x = floor(position.x / grid_size.x) var grid_y = floor(position.y / grid_size.y) if check_move(Vector2i(grid_x, grid_y)): moved.emit(self, grid_pos, Vector2i(grid_x, grid_y)) grid_pos = Vector2i(grid_x, grid_y) position = grid_to_pos(grid_pos) if self.dragging and event is InputEventMouseMotion: position += event.relative func make_black(): team = TEAM.BLACK func make_white(): team = TEAM.WHITE func make_neutral(): team = TEAM.NEUTRAL func is_black() -> bool: return team == TEAM.BLACK func is_white() -> bool: return team == TEAM.WHITE func is_pawn() -> bool: return kind == KIND.PAWN func is_king() -> bool: return kind == KIND.KING func grid_to_pos(grid_p: Vector2i) -> Vector2: var new_x = grid_p.x * grid_size.x + grid_size.x / 2 var new_y = grid_p.y * grid_size.y + grid_size.y / 2 return Vector2(new_x, new_y) func get_board_state() -> Dictionary: return get_parent().board_state func path_empty(destination: Vector2i) -> bool: var board_state = get_board_state() var dx = destination.x - grid_pos.x var dy = destination.y - grid_pos.y if dx == 0: if dy < 0: for y in range(destination.y + 1, grid_pos.y): if board_state.has(Vector2i(grid_pos.x, y)): return false elif dy > 0: for y in range(grid_pos.y + 1, destination.y): if board_state.has(Vector2i(grid_pos.x, y)): return false else: # no movement return false elif dy == 0: if dx < 0: for x in range(destination.x + 1, grid_pos.x): if board_state.has(Vector2i(x, grid_pos.y)): return false elif dx > 0: for x in range(grid_pos.x + 1, destination.x): if board_state.has(Vector2i(x, grid_pos.y)): return false else: # impossible return false elif abs(dx) == abs(dy): if dx < 0: if dy < 0: for d in range(1, abs(dx)): if board_state.has(Vector2i(grid_pos.x - d, grid_pos.y - d)): return false elif dy > 0: for d in range(1, abs(dx)): if board_state.has(Vector2i(grid_pos.x - d, grid_pos.y + d)): return false else: # impossible return false elif dx > 0: if dy < 0: for d in range(1, abs(dx)): if board_state.has(Vector2i(grid_pos.x + d, grid_pos.y - d)): return false elif dy > 0: for d in range(1, abs(dx)): if board_state.has(Vector2i(grid_pos.x + d, grid_pos.y + d)): return false else: # impossible return false else: # impossible return false else: # not a legal move return false return true func check_move(destination: Vector2i) -> bool: return true