141 lines
3.4 KiB
GDScript
141 lines
3.4 KiB
GDScript
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
|