online multiplayer chess game (note server currently down)
type strengthening + general fixes
58 files changed, 1068 insertions, 620 deletions
diff --git a/Debug.gd b/Debug.gd new file mode 100644 index 0000000..79578f1 --- /dev/null +++ b/Debug.gd @@ -0,0 +1,75 @@ +extends Node2D + +var refs := [] # = [[ node : object, variable : string, (code : string) ]] +var style: StyleBox = load("res://ui/theme/transblack.tres") +var font: Font = load("res://ui/verdana.tres") +var debug := false +var timer := Timer.new() +var expr := Expression.new() + +const offset := Vector2(10, 10) +const vertical := 15 + + +static func is_debug() -> bool: + var args := Utils.get_args() + if "debug" in args: + return bool(args.debug) + return false or OS.is_debug_build() + + +func _ready() -> void: + z_index = 5 # put on top + add_child(timer) + timer.connect("timeout", self, "update") + timer.start(.1) # only redraw every .1 seconds + font = font.duplicate() + font.size = vertical * 0.8 + debug = is_debug() + visible = debug + + +func monitor(node: Node, what: String, code := "") -> void: # code doesnt really work well with ternarys + refs.append([node, what, code] if code else [node, what]) + calculate_size() + + +func calculate_size() -> Rect2: + var xminsize := 0.0 + for set in refs: # find the chonkiest text + var tmp := font.get_string_size(get_string(set)).x + xminsize = tmp if tmp > xminsize else xminsize + return Rect2(Vector2.ZERO, Vector2(xminsize + offset.x, (refs.size()) * vertical) + offset) + + +func update() -> void: + timer.start(.1) + .update() + + +func _draw() -> void: + if !debug: + return + draw_style_box(style, calculate_size()) + var i = len(refs) + while i >= 0: + i -= 1 + var pos := Vector2(offset.x, (i + 1) * vertical) + draw_string(font, pos, get_string(refs[i])) + + +func get_string(set: Array) -> String: + var node: Node = set[0] + if !is_instance_valid(node): + refs.remove(refs.find(set)) + return "invalid!" + var what: String = set[1] + var gotten = node.get(what) + var val: String = str(gotten) if typeof(gotten) != TYPE_DICTIONARY else to_json(gotten) + if len(set) == 3: + var err := expr.parse(set[2]) + if err != OK: + Log.err(expr.get_error_text()) + return "" + val = str(expr.execute([], node, true)) + return "%s: %s" % [what, val] @@ -1,8 +1,8 @@ extends Node -var __nosethalfmove = false -var pawns = [] # PoolPawnArray -var team = true +var __nosethalfmove := false +var pawns := [] # PoolPawnArray +var team := true var grid: Grid = null var network: Network = null var piece_set := "california" @@ -12,8 +12,8 @@ var in_check := false var checking_piece: Piece = null var board_color1: Color = Color(0.870588, 0.890196, 0.901961) var board_color2: Color = Color(0.54902, 0.635294, 0.678431) -var white_king: King -var black_king: King +var white_king: King = null +var black_king: King = null var turn := true # true for white, false for black # true cuz white goes first @@ -41,10 +41,6 @@ func pack_vars() -> Dictionary: } -func get_var(key): - return self.get(key) - - func turns() -> int: return fullmove @@ -63,8 +59,19 @@ func add_turn() -> void: else: halfmove += 1 turn = not turn + Log.debug("Turn over signal emmited") Events.emit_signal("turn_over") +func get_turn(flip := false) -> String: + if flip: + return "black" if turn else "white" + return "white" if turn else "black" + + func _ready() -> void: VisualServer.set_default_clear_color(Color.black) + Debug.monitor(self, "fullmove") + Debug.monitor(self, "halfmove") + Debug.monitor(self, "in_check") + Debug.monitor(self, "turn", "get_turn()") @@ -1,17 +1,17 @@ extends Node2D class_name Grid -const topper_header = "┏━━━┳━━━┳━━━┳━━━┳━━━┳━━━┳━━━┳━━━┳━━━┓" -const middle_header = "┣━━━╋━━━╋━━━╋━━━╋━━━╋━━━╋━━━╋━━━╋━━━┫" -const middish_heads = "┗━━━╋━━━╋━━━╋━━━╋━━━╋━━━╋━━━╋━━━╋━━━┫" -const bottom_header = "┗━━━┻━━━┻━━━┻━━━┻━━━┻━━━┻━━━┻━━━┻━━━┛" -const smaller_heads = " ┗━━━┻━━━┻━━━┻━━━┻━━━┻━━━┻━━━┻━━━┛" -const letter_header = " ┃ a ┃ b ┃ c ┃ d ┃ e ┃ f ┃ g ┃ h ┃" -const ender = " ┃ " # for pretty prints -const Piece = preload("res://Piece.tscn") -const Square = preload("res://Square.tscn") -const BottomLeftLabel = preload("res://ui/BottomLeftLabel.tscn") -const TopRightLabel = preload("res://ui/TopRightLabel.tscn") +const topper_header := "┏━━━┳━━━┳━━━┳━━━┳━━━┳━━━┳━━━┳━━━┳━━━┓" +const middle_header := "┣━━━╋━━━╋━━━╋━━━╋━━━╋━━━╋━━━╋━━━╋━━━┫" +const middish_heads := "┗━━━╋━━━╋━━━╋━━━╋━━━╋━━━╋━━━╋━━━╋━━━┫" +const bottom_header := "┗━━━┻━━━┻━━━┻━━━┻━━━┻━━━┻━━━┻━━━┻━━━┛" +const smaller_heads := " ┗━━━┻━━━┻━━━┻━━━┻━━━┻━━━┻━━━┻━━━┛" +const letter_header := " ┃ a ┃ b ┃ c ┃ d ┃ e ┃ f ┃ g ┃ h ┃" +const ender := " ┃ " # for pretty prints +const Piece := preload("res://Piece.tscn") +const Square := preload("res://Square.tscn") +const BottomLeftLabel := preload("res://ui/BottomLeftLabel.tscn") +const TopRightLabel := preload("res://ui/TopRightLabel.tscn") const piece_size := Vector2(100, 100) const default_metadata := { @@ -30,22 +30,22 @@ export(Color) var clockrunninglow := Color(0.47451, 0.172549, 0.164706) export(Color) var clocklow := Color(0.313726, 0.156863, 0.14902) var matrix := [] -var promoting = null +var stop_input := false var background_matrix := [] var history_matrixes := {} var last_clicked: Piece = null -var flipped = false +var flipped := false -var labels = {"letters": [], "numbers": []} +var labels := {"letters": [], "numbers": []} onready var background := $Background onready var ASSETS_PATH: String = "res://assets/pieces/%s/" % Globals.piece_set onready var foreground := $Foreground onready var pieces := $Pieces -onready var status_label := $"../UI/Holder/Back/VBox/Status" +onready var ui := $"../UI" -func _init(): +func _init() -> void: Globals.grid = self @@ -56,32 +56,36 @@ func _ready() -> void: Events.connect("turn_over", self, "_on_turn_over") # listen for turn_over events Events.connect("outoftime", self, "_on_outoftime") # listen for timeout events + Debug.monitor(self, "last_clicked") + Debug.monitor(self, "matrix", "matrix[8]") + Debug.monitor(self, "highest value in 3fold", "threefoldrepetition()") + func _exit_tree() -> void: Globals.grid = null # reset the globals grid when leaving tree -func _input(event) -> void: # input +func _input(event: InputEvent) -> void: # input if event.is_action_released("debug"): # if debug print_matrix_pretty(matrix) # print the matrix -static func print_matrix_pretty(mat) -> void: # print the matrix +static func print_matrix_pretty(mat: Array) -> void: # print the matrix for j in range(8): # for each row var r: Array = mat[j] # get the row if j == 0: - Log.info(topper_header) # print the top border + print(topper_header) # print the top border else: - Log.info(middle_header) # print the middle border - var row = "┃ %s ┃ " % str(8 - j) # init the string + print(middle_header) # print the middle border + var row := "┃ %s ┃ " % str(8 - j) # init the string for i in range(8): # for each column - var c = r[i] # get the column + var c: Piece = r[i] # get the column if c: # if there is a piece row += c.mininame + ender # add the shortname else: # if there is no piece row += " " + ender - Log.info(row) # print the string - Log.info("%s\n%s\n%s" % [middish_heads, letter_header, smaller_heads]) + print(row) # print the string + print("%s\n%s\n%s" % [middish_heads, letter_header, smaller_heads]) func reload_sprites() -> void: @@ -94,30 +98,22 @@ func reload_sprites() -> void: func flip_pieces() -> void: for i in range(8): for j in range(8): - var spot = matrix[i][j] + var spot: Piece = matrix[i][j] if spot: spot.sprite.flip_v = flipped spot.sprite.flip_h = flipped - # spot.tween.interpolate_property( - # spot.sprite, "rotation_degrees", spot.sprite.rotation_degrees, degree, .5 - # ) - # spot.tween.start() func flip_labels() -> void: for i in range(8): - var numlabel = labels.numbers[i].get_node("Label") - var letlabel = labels.letters[i].get_node("Label") - var number: int - if flipped: - number = i + 1 - else: - number = 8 - i + var numlabel: Label = labels.numbers[i].get_node("Label") + var letlabel: Label = labels.letters[i].get_node("Label") + var number := i + 1 if flipped else 8 - i numlabel.text = str(number) letlabel.text = "hgfedcba"[number - 1] -func flip_board(): +func flip_board() -> void: if global_position == Vector2(800, 800): flipped = false global_position = Vector2(0, 0) @@ -135,33 +131,31 @@ func flip_board(): func init_labels() -> void: for i in range(8): labels.letters.append(init_label(BottomLeftLabel, i, Vector2(i, 7), "abcdefgh"[i])) - labels.numbers.append(init_label(TopRightLabel, i, Vector2(7, i), str(8 - i))) func init_label(labelscene: PackedScene, i: int, position: Vector2, text: String) -> Control: - var labelholder = labelscene.instance() + var labelholder: Control = labelscene.instance() labelholder.rect_size = piece_size labelholder.rect_position = position * piece_size - var label = labelholder.get_node("Label") + var label: Label = labelholder.get_node("Label") label.text = text label.add_color_override("font_color", Globals.board_color1 if i % 2 == 0 else Globals.board_color2) foreground.add_child(labelholder) return labelholder -func threefoldrepetition() -> bool: - for i in history_matrixes.values(): - if i >= 3: - return true - return false +func threefoldrepetition() -> int: + if !history_matrixes.values(): + return 0 + return history_matrixes.values().max() -func mat2str(mat = matrix) -> String: +func mat2str(mat: Array = matrix) -> String: var string := "" for y in range(8): for x in range(8): - var spot = mat[y][x] + var spot: Piece = mat[y][x] if spot: string += spot.mininame else: @@ -172,29 +166,27 @@ func mat2str(mat = matrix) -> String: return string -func drawed() -> void: - return # TODO: make gameovers work again - # Events.emit_signal("game_over") - # SoundFx.play("Draw") - # yield(get_tree().create_timer(5), "timeout") - # Events.emit_signal("go_back") - # SoundFx.play("Victory") +func drawed(reason := "") -> void: + ui.set_status("draw by " + reason) + Events.emit_signal("game_over") + SoundFx.play("Draw") + yield(get_tree().create_timer(5), "timeout") + Events.emit_signal("go_back") -func win(_winner) -> void: - return # TODO: make gameovers work again - # Events.emit_signal("game_over") - # Log.info([winner, " won the game in ", Globals.turns(), " turns!"]) - # SoundFx.play("Victory") - # yield(get_tree().create_timer(5), "timeout") - # Events.emit_signal("go_back") - # SoundFx.play("Victory") +func win(winner: bool, reason := "") -> void: + ui.set_status("%s won the game by %s" % ["white" if winner else "black", reason]) # black won the game by checkmate + Events.emit_signal("game_over") + Log.info("%s won the game in %s turns!" % ["white" if winner else "black", Globals.turns()]) + SoundFx.play("Victory") + yield(get_tree().create_timer(5), "timeout") + Events.emit_signal("go_back") -func check_in_check(prin = false) -> bool: # check if in_check +func check_in_check(prin := false) -> bool: # check if in_check for i in range(0, 8): # for each row for j in range(0, 8): # for each column - var spot = matrix[i][j] # get the square + var spot: Piece = matrix[i][j] # get the square if spot and spot.white != Globals.turn: # enemie if spot.can_attack_piece(Globals.white_king if Globals.turn else Globals.black_king): # if it can take the king # control never flows here @@ -210,7 +202,7 @@ func check_in_check(prin = false) -> bool: # check if in_check func can_move() -> bool: for i in range(0, 8): # for each row for j in range(0, 8): # for each column - var spot = matrix[i][j] # get the square + var spot: Piece = matrix[i][j] # get the square if spot and spot.white != Globals.team: # enemie: checking for our enemys if spot.can_move(): return true @@ -228,7 +220,7 @@ func init_matrix() -> void: # create the matrix func make_piece(position: Vector2, script: String, white: bool = true) -> void: # make peace var piece := Piece.instance() # create a piece - piece.script = load(script) # set the script + piece.script = load("res://pieces/%s.gd" % script) # set the script piece.real_position = position # set the real position piece.global_position = position * piece_size # set the global position piece.white = white # set its team @@ -261,39 +253,39 @@ func add_pieces() -> void: # add the pieces func add_pawns() -> void: for i in range(8): - make_piece(Vector2(i, 1), "res://pieces/Pawn.gd", false) - make_piece(Vector2(i, 6), "res://pieces/Pawn.gd", true) + make_piece(Vector2(i, 1), "Pawn", false) + make_piece(Vector2(i, 6), "Pawn", true) func add_rooks() -> void: - make_piece(Vector2(0, 0), "res://pieces/Rook.gd", false) - make_piece(Vector2(7, 0), "res://pieces/Rook.gd", false) - make_piece(Vector2(0, 7), "res://pieces/Rook.gd", true) - make_piece(Vector2(7, 7), "res://pieces/Rook.gd", true) + make_piece(Vector2(0, 0), "Rook", false) + make_piece(Vector2(7, 0), "Rook", false) + make_piece(Vector2(0, 7), "Rook", true) + make_piece(Vector2(7, 7), "Rook", true) func add_knights() -> void: - make_piece(Vector2(1, 0), "res://pieces/Knight.gd", false) - make_piece(Vector2(6, 0), "res://pieces/Knight.gd", false) - make_piece(Vector2(1, 7), "res://pieces/Knight.gd", true) - make_piece(Vector2(6, 7), "res://pieces/Knight.gd", true) + make_piece(Vector2(1, 0), "Knight", false) + make_piece(Vector2(6, 0), "Knight", false) + make_piece(Vector2(1, 7), "Knight", true) + make_piece(Vector2(6, 7), "Knight", true) func add_bishops() -> void: - make_piece(Vector2(2, 0), "res://pieces/Bishop.gd", false) - make_piece(Vector2(5, 0), "res://pieces/Bishop.gd", false) - make_piece(Vector2(2, 7), "res://pieces/Bishop.gd", true) - make_piece(Vector2(5, 7), "res://pieces/Bishop.gd", true) + make_piece(Vector2(2, 0), "Bishop", false) + make_piece(Vector2(5, 0), "Bishop", false) + make_piece(Vector2(2, 7), "Bishop", true) + make_piece(Vector2(5, 7), "Bishop", true) func add_queens() -> void: - make_piece(Vector2(3, 0), "res://pieces/Queen.gd", false) - make_piece(Vector2(3, 7), "res://pieces/Queen.gd", true) + make_piece(Vector2(3, 0), "Queen", false) + make_piece(Vector2(3, 7), "Queen", true) func add_kings() -> void: - make_piece(Vector2(4, 0), "res://pieces/King.gd", false) - make_piece(Vector2(4, 7), "res://pieces/King.gd", true) + make_piece(Vector2(4, 0), "King", false) + make_piece(Vector2(4, 7), "King", true) Globals.white_king = matrix[7][4] # set the white king Globals.black_king = matrix[0][4] # set the black king @@ -304,24 +296,26 @@ func check_for_circle(position: Vector2) -> bool: # check for a circle, validat func check_for_frame(position: Vector2) -> bool: # check for a frame, validating taking if !is_instance_valid(matrix[position.y][position.x]): # if there is no piece - return false # return false + return false # there is no frame return matrix[position.y][position.x].frameon # return if the frame is on func square_clicked(position: Vector2) -> void: # square clicked Log.debug(Utils.to_algebraic(position) + " clicked") - if promoting != null: + if stop_input: return if Globals.turn != Globals.team: return - var spot = matrix[position.y][position.x] # get the spot + var spot: Piece = matrix[position.y][position.x] # get the spot if !spot or spot.white != Globals.team: if !is_instance_valid(last_clicked): return if check_for_frame(position): # takeable handle_take(position) + stop_input = true elif check_for_circle(position): # see if theres a circle at the position handle_move(position) # move + stop_input = true last_clicked.clear_clicked() # remove the circles last_clicked = null # set it to null elif last_clicked != spot: # we got a new piece (or pawn) clicked @@ -331,17 +325,16 @@ func square_clicked(position: Vector2) -> void: # square clicked spot.clicked() # tell the piece shit happeend -func handle_take(position) -> void: +func handle_take(position: Vector2) -> void: if Utils.is_pawn(last_clicked): # if its a pawn - var pawn = last_clicked - if check_promote(pawn, position, "take"): + if check_promote(last_clicked, position, "take"): return Globals.network.send_move_packet( PoolVector2Array([last_clicked.real_position, position]), Network.MOVEHEADERS.move ) # piece taking piece -func handle_move(position) -> void: +func handle_move(position: Vector2) -> void: if Utils.is_king(last_clicked) and last_clicked.can_castle: for i in range(len(last_clicked.can_castle)): var castle_data = last_clicked.can_castle[i] @@ -359,7 +352,7 @@ func handle_move(position) -> void: return if Utils.is_pawn(last_clicked): - var pawn = last_clicked + var pawn: Pawn = last_clicked if pawn.enpassant: for i in range(len(pawn.enpassant)): var en_passant_data = pawn.enpassant[i] @@ -370,7 +363,7 @@ func handle_move(position) -> void: Network.MOVEHEADERS.passant ) return - if check_promote(pawn, position): + elif check_promote(pawn, position): return Globals.network.send_move_packet( PoolVector2Array([last_clicked.real_position, position]), Network.MOVEHEADERS.move @@ -380,7 +373,6 @@ func handle_move(position) -> void: func check_promote(pawn, position, calltype: String = "move") -> bool: if pawn.can_promote(position): pawn.promote(position, calltype) - promoting = position return true return false @@ -388,25 +380,27 @@ func check_promote(pawn, position, calltype: String = "move") -> bool: func clear_fx() -> void: # clear the circles for i in range(8): # for each row for j in range(8): # for each column - var square = background_matrix[i][j] # get the square + var square: ColorRect = background_matrix[i][j] # get the square square.set_circle(false) # set the circle to false - var piece = matrix[i][j] # get the piece + var piece: Piece = matrix[i][j] # get the piece if piece: # if there is a piece piece.set_frame(false) # clear the frame -func _on_outoftime(who) -> void: - if who == "white": - win("black") - else: - win("white") +func _on_outoftime(who: bool) -> void: + win(who, "time") func _on_turn_over() -> void: - var matstr: String = mat2str() - if !history_matrixes.has(matstr): + stop_input = false + Log.debug("turn over. new turn: " + Globals.get_turn()) + var matstr := mat2str() + Log.debug("matstr: " + matstr) + if !matstr in history_matrixes: + Log.debug("new matrix entry") history_matrixes[matstr] = 1 else: + Log.debug(["matrix entry = ", history_matrixes[matstr], "+ 1"]) history_matrixes[matstr] += 1 Globals.checking_piece = null # reset checking_piece Globals.in_check = false # reset in_check @@ -415,12 +409,8 @@ func _on_turn_over() -> void: check_in_check(true) # check if in_check if !can_move(): if Globals.in_check: - var winner := "black" if Globals.turn else "white" - status_label.text("%s won the game by checkmate" % winner) - win(winner) + win(!Globals.turn, "checkmate") else: - status_label.text("stalemate") - drawed() - elif threefoldrepetition(): - status_label.text("draw by threefold repetition") - drawed() + drawed("stalemate") + elif threefoldrepetition() >= 3: + drawed("threefold repetition") @@ -0,0 +1,27 @@ +extends Node + + +static func info(information) -> void: # logs the input string + print("[i] " + to_str(information)) + + +static func debug(information) -> void: # logs the input string on debug builds + if Debug.debug: + print("[d] " + to_str(information)) + + +static func err(information) -> void: # logs the input string to stderr + printerr("[E]" + to_str(information)) + + +static func to_str(arg) -> String: + if typeof(arg) == TYPE_ARRAY: + return arr2str(arg) + return str(arg) + + +static func arr2str(arr: Array) -> String: + var string := "" + for i in arr: + string += str(i) + " " + return string @@ -1,7 +1,6 @@ extends ColorRect var real_position := Vector2() -var algebraic_string := "" var circle_on := false onready var area := $Squarea @@ -17,7 +16,6 @@ func _ready() -> void: circle.visible = false areacollisionshape.global_position += Globals.grid.piece_size / 2 areacollisionshape.shape.extents = Vector2(rect_size.x / 2, rect_size.y / 2) - algebraic_string = Utils.to_algebraic(real_position) func _on_Squarea_input_event(_viewport: Node, _event: InputEvent, _shape_idx: int) -> void: @@ -25,11 +23,6 @@ func _on_Squarea_input_event(_viewport: Node, _event: InputEvent, _shape_idx: in emit_signal("clicked", real_position) -func get_string() -> String: - return algebraic_string - - -func set_circle(boolean: bool, real = true) -> void: +func set_circle(boolean: bool) -> void: circle_on = boolean - if real: - circle.visible = boolean + circle.visible = boolean @@ -5,12 +5,43 @@ signal newfen(fen) var turn_moves: PoolStringArray = [] var turns_moves: PoolStringArray = [] -var internet = false +var internet := false var counter := 0 +var fen := "" + + +func get_args() -> Dictionary: + var arguments := {} + for argument in OS.get_cmdline_args(): + var key_value = argument.split("=") + if len(key_value) == 2: + arguments[key_value[0].lstrip("--")] = key_value[1] + else: + arguments[key_value[0].lstrip("--")] = "true" + return arguments func _ready() -> void: + internet_available() Events.connect("turn_over", self, "_on_turn_over") + if "help" in get_args(): + print("usage: ./chess%s [debug | help]" % exec_ext()) + print("run with command debug to enable debug mode") + print("run with command help to show this help") + get_tree().quit() # dont wait + Debug.monitor(self, "fen") + + +static func exec_ext() -> String: + if OS.has_feature("Windows"): + return ".exe" + elif OS.has_feature("OSX"): + return ".app/Contents/MacOS/chess" + elif OS.has_feature("X11"): + return ".x86_64" + elif OS.has_feature("web"): + return ".html" + return "" static func is_pawn(inode) -> bool: @@ -21,33 +52,29 @@ static func is_king(inode) -> bool: return inode is King -func add_move(move) -> void: +func add_move(move: String) -> void: if turn_moves.size() == 0: - turn_moves.append(str(Globals.fullmove) + ". " + move) + turn_moves.append("%s. %s" % [Globals.fullmove, move]) else: turn_moves.append(move) emit_signal("newmove", move) -static func flip_int(i: int) -> int: - return int(abs(7 - i)) - - func reset_vars() -> void: turn_moves.resize(0) turns_moves.resize(0) counter = 0 -static func to_algebraic(real_position) -> String: - return char(65 + (real_position.x)).to_lower() + str(8 - real_position.y) +static func to_algebraic(pos: Vector2) -> String: + return "abcdefgh"[pos.x] + str(round(8 - pos.y)) static func from_algebraic(algebraic_position: String) -> Vector2: return Vector2(ord(algebraic_position[0]) - ord("a"), 8 - int(algebraic_position[1])) -static func get_node_name(node) -> Array: +static func get_node_name(node: Node) -> Array: if is_pawn(node): return ["♙", "p"] if node.white else ["♟", "p"] elif node is King: @@ -65,16 +92,16 @@ static func get_node_name(node) -> Array: func internet_available() -> bool: - var http = HTTPRequest.new() + var http := HTTPRequest.new() add_child(http) - var httpurl = "https://1.1.1.1" - var returnable = http.request(httpurl) == OK + var httpurl := "https://1.1.1.1" + var returnable := http.request(httpurl) == OK http.queue_free() internet = returnable return returnable -func walk_dir(path = "res://assets/pieces") -> PoolStringArray: # walk the directory, finding the asset packs +func walk_dir(path := "res://assets/pieces") -> PoolStringArray: # walk the directory, finding the asset packs var folders: PoolStringArray = [] # init the folders var dir := Directory.new() # init the directory if dir.open(path) == OK: # open the directory @@ -90,12 +117,12 @@ func walk_dir(path = "res://assets/pieces") -> PoolStringArray: # walk the dire func format_seconds(time: float, use_milliseconds: bool = false) -> String: - var format_string = "%02d:%04.1f" if use_milliseconds else "%02d:%02d" - return format_string % [time / 60, fmod(time, 60)] + return "%02d:%04.1f" if use_milliseconds else "%02d:%02d" % [time / 60, fmod(time, 60)] func _on_turn_over() -> void: - var fen = fen() + fen = get_fen() + Log.info("fen: " + fen) emit_signal("newfen", fen) counter += 1 if counter >= 2: @@ -104,12 +131,12 @@ func _on_turn_over() -> void: turn_moves.resize(0) -func fen() -> String: - var pieces = "" +func get_fen() -> String: + var pieces := "" for rank in range(8): - var empty = 0 + var empty := 0 for file in range(8): - var spot = Globals.grid.matrix[rank][file] + var spot: Piece = Globals.grid.matrix[rank][file] if spot == null: empty += 1 if len(pieces) > 0 and str(empty - 1) == pieces[-1]: @@ -122,39 +149,35 @@ func fen() -> String: if rank != 7: pieces += "/" # handle castling checks - var whitecastling = PoolStringArray(Globals.white_king.castleing(true)).join(" ") - var blackcastling = PoolStringArray(Globals.black_king.castleing(true)).join(" ") - var castlingrights = "" + var whitecastling := PoolStringArray(Globals.white_king.castleing(true)).join("") + var blackcastling := PoolStringArray(Globals.black_king.castleing(true)).join("") + var castlingrights := "" if blackcastling and whitecastling: - castlingrights += "K" if "K" in whitecastling else "" - castlingrights += "Q" if "Q" in whitecastling else "" - castlingrights += "k" if "K" in blackcastling else "" - castlingrights += "q" if "Q" in blackcastling else "" + castlingrights = whitecastling.to_upper() + blackcastling.to_lower() else: castlingrights = "-" - var enpassants = "" + var enpassants := "" for pawn in Globals.pawns: if pawn.twostepfirstmove and pawn.just_set: enpassants += to_algebraic(pawn.real_position + (Vector2.DOWN * pawn.whiteint)) - var fen = ( + return ( "%s %s %s %s %s %s" % [ pieces, - "w" if Globals.team else "b", + "w" if Globals.turn else "b", castlingrights, enpassants if enpassants else "-", Globals.halfmove, Globals.fullmove, ] ) # pos # turn # castling # enpassant # halfmove # fullmove - return fen func _notification(what: int) -> void: if what == MainLoop.NOTIFICATION_WM_QUIT_REQUEST or what == MainLoop.NOTIFICATION_WM_GO_BACK_REQUEST: if get_tree().get_root().has_node("Board"): - Globals.network.send_packet(Globals.network.game_code, Globals.network.HEADERS.stopgame) + Globals.network.send_packet(Globals.network.game_code, Network.HEADERS.stopgame) yield(get_tree(), "idle_frame") # wait for the packet to send - Log.info("Bye!") + Log.debug("Bye!") get_tree().quit() diff --git a/assets/ui/check.png b/assets/ui/check.png new file mode 100644 index 0000000..fbb40ae --- /dev/null +++ b/assets/ui/check.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:32270febf5a2080aca7f10215fe06302b3520c600645850837ddc5543eddfa12 +size 1097 diff --git a/assets/ui/check.png.import b/assets/ui/check.png.import new file mode 100644 index 0000000..7303460 --- /dev/null +++ b/assets/ui/check.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/check.png-e8b14fcbaaa1bc4bede83522bb1efa68.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/ui/check.png" +dest_files=[ "res://.import/check.png-e8b14fcbaaa1bc4bede83522bb1efa68.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=false +svg/scale=1.0 diff --git a/assets/ui/close.png b/assets/ui/close.png index 225ad17..db35ea2 100644 --- a/assets/ui/close.png +++ b/assets/ui/close.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e81d7cc66b21f36b18db7bc29f0646a188e3791f69fc297bb38ac8144ed57da1 -size 772 +oid sha256:5700d25d0887b794e34f255085d6067bdb05437b296ea22ba38c85db1a23c915 +size 690 diff --git a/assets/ui/draw.png b/assets/ui/draw.png new file mode 100644 index 0000000..5c1cae7 --- /dev/null +++ b/assets/ui/draw.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:938a831facef14c00c2cfd69898cf62aef52c3f33a9e3353322a21d13682e388 +size 644 diff --git a/assets/ui/draw.png.import b/assets/ui/draw.png.import new file mode 100644 index 0000000..d7f1480 --- /dev/null +++ b/assets/ui/draw.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/draw.png-fd0668639e07dc0335699f2521885008.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/ui/draw.png" +dest_files=[ "res://.import/draw.png-fd0668639e07dc0335699f2521885008.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=false +svg/scale=1.0 diff --git a/assets/ui/svg/check.svg b/assets/ui/svg/check.svg new file mode 100644 index 0000000..c3f9212 --- /dev/null +++ b/assets/ui/svg/check.svg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7d8a54ed133465e82e0fa6d65faf1ccddad619a1f5836d5305f4fbb232c4bc91 +size 1295 diff --git a/assets/ui/svg/close.svg b/assets/ui/svg/close.svg index 3a3ae7a..458c6f8 100644 --- a/assets/ui/svg/close.svg +++ b/assets/ui/svg/close.svg @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:37345ed189fdb6b6fc1997538a6f9637b1c1d36c488925d029018b3662a5c6e6 -size 1306 +oid sha256:f73660d7c7961b25560a25cc9f2f73e680f146c66818c205aa6b2e2eead6b842 +size 1369 diff --git a/assets/ui/svg/draw.svg b/assets/ui/svg/draw.svg new file mode 100644 index 0000000..03d3856 --- /dev/null +++ b/assets/ui/svg/draw.svg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bd31ea0b66b7ae2d32ca3ee53d3edf4a2e37397bccd146cf2b7e89da026745d0 +size 3440 diff --git a/networking/Network.gd b/networking/Network.gd index d5d845e..e6fb242 100644 --- a/networking/Network.gd +++ b/networking/Network.gd @@ -4,7 +4,7 @@ class_name Network var ws := WebSocketClient.new() var game_code := "" -var connected = false +var connected := false const HEADERS := { "move": "M", @@ -13,6 +13,7 @@ const HEADERS := { "stopgame": "K", "ping": "P", "startgame": "S", + "request": "R" } const MOVEHEADERS := { @@ -23,6 +24,8 @@ const MOVEHEADERS := { "promote": "Q", } +const REQUESTHEADERS := {"takeback": "T", "draw": "D", "resign": "R"} # not really a request, but... + var notation := "" signal start_game @@ -30,19 +33,21 @@ signal move_data(data) signal host_result(result) signal join_result(result) signal game_over(problem, isok) +signal request_result(result) +signal request(request) signal connection_established const url := "wss://gd-chess-server.herokuapp.com/" func _ready() -> void: + yield(get_tree(), "idle_frame") # wait a frame ws.connect("connection_established", self, "_connection_established") ws.connect("connection_closed", self, "_connection_closed") ws.connect("connection_error", self, "_connection_error") ws.connect("data_received", self, "_data_recieved") - Log.debug("Connecting to server %s..." % url) ws.connect_to_url(url) - var t = Timer.new() + var t := Timer.new() add_child(t) t.wait_time = 1 t.start(1) @@ -53,14 +58,14 @@ func ping() -> void: send_packet("ping", HEADERS.ping) -func close(): +func close() -> void: ws.disconnect_from_host(0, "Close") func _connection_established(_protocol) -> void: connected = true emit_signal("connection_established") - Log.info("Connection established") + Log.debug("Connected to server %s..." % url) func _connection_closed(_was_clean_closed) -> void: @@ -75,12 +80,19 @@ func _connection_error() -> void: emit_signal("game_over", "Connection error", false) +func send_request_answer_packet(request_type: String, answer: bool) -> void: + var data := {"answering": true, "type": request_type, "gamecode": game_code, "answer": answer} + send_packet(data, HEADERS.request) + + +func send_request_packet(request_type: String, prompt: String) -> void: + var data := {"answering": false, "type": request_type, "gamecode": game_code, "question": prompt} + send_packet(data, HEADERS.request) + + func send_move_packet(positions, header: String) -> void: var packet := {"movetype": header, "gamecode": game_code, "positions": positions} - Globals.add_turn() - var globals = Globals.pack_vars() - for variable in globals: - packet[variable] = globals[variable] + Log.debug("sending move packet: %s" % packet) send_packet(packet, HEADERS.move) # your move will wait till the server relays back :> @@ -96,18 +108,25 @@ func _data_recieved() -> void: HEADERS.joinrequest: emit_signal("join_result", text) HEADERS.stopgame: - if PacketHandler.leaving: - PacketHandler.leaving = false - else: # dont emit the signal if its a stophost thing (HACK) - emit_signal("game_over", "your opponent requested stop", true) + if !PacketHandler.leaving: # dont emit the signal if its a stophost thing (HACK) + emit_signal("game_over", text, true) + PacketHandler.leaving = false HEADERS.startgame: emit_signal("start_game") + PacketHandler.emit_signal("set_visible", false) + HEADERS.request: + if text.answering: + emit_signal("request_result", text) + else: + emit_signal("request", text) HEADERS.ping: pass + _: + Log.err("unknown header %s" % header) -func _process(_delta) -> void: - var wsstatus = ws.get_connection_status() +func _process(_delta: float) -> void: + var wsstatus := ws.get_connection_status() if wsstatus == ws.CONNECTION_CONNECTING or wsstatus == ws.CONNECTION_CONNECTED: ws.poll() diff --git a/networking/PacketHandler.gd b/networking/PacketHandler.gd index 571091a..ca0da6d 100644 --- a/networking/PacketHandler.gd +++ b/networking/PacketHandler.gd @@ -1,7 +1,7 @@ extends Node class_name NetManager -### for the ui +### for the lobby ui signal set_buttons(enabled) signal set_status(status, err, isok) signal set_visible(visibility) @@ -10,23 +10,23 @@ signal hosting(newhosting) signal game_over signal game_started -var hosting = false setget set_hosting -var leaving = false +var hosting := false setget set_hosting +var leaving := false -var status = ["", true, false] +var status := ["", true, false] -func set_buttons(enabled): +func set_buttons(enabled: bool) -> void: status[2] = enabled emit_signal("set_buttons", enabled) -func set_hosting(newhosting): +func set_hosting(newhosting: bool) -> void: hosting = newhosting emit_signal("hosting", newhosting) -func return(): +func return() -> void: # return to the void if hosting: leaving = true Globals.network.send_packet(Globals.network.game_code, Network.HEADERS.stopgame) # stop hosting @@ -35,10 +35,10 @@ func return(): set_status("", true) -func _ready(): +func _ready() -> void: get_tree().set_auto_accept_quit(false) - if Utils.internet_available(): - var net = Network.new() + if Utils.internet: + var net := Network.new() set_status("Connecting", true) Events.connect("go_back", self, "_handle_game_over") net.connect("move_data", self, "_on_data") @@ -51,22 +51,22 @@ func _ready(): Globals.network = net -func requestjoin(): +func requestjoin() -> void: set_buttons(false) Globals.network.send_packet(Globals.network.game_code, Globals.network.HEADERS.joinrequest) -func requesthost(): +func requesthost() -> void: set_buttons(false) Globals.network.send_packet(Globals.network.game_code, Globals.network.HEADERS.hostrequest) -func network_ready(): +func network_ready() -> void: set_status("", true) set_buttons(true) -func set_status(text, isok): +func set_status(text: String, isok: bool) -> void: status[0] = text status[1] = isok emit_signal("set_status", text, isok) @@ -74,6 +74,7 @@ func set_status(text, isok): func _on_join_result(accepted: String) -> void: if handle_result(accepted, "Joined!", false): + emit_signal("set_visible", false) Globals.network.send_packet(Globals.network.game_code, Globals.network.HEADERS.startgame) @@ -81,8 +82,8 @@ func _on_host_result(accepted: String) -> void: set_hosting(handle_result(accepted, "Hosted!")) -func handle_result(accepted: String, resultstring: String, team: bool = true) -> bool: - Globals.team = team +func handle_result(accepted: String, resultstring: String, team := true) -> bool: + Globals.team = team # what am i doing here??? if accepted == "Y": set_status(resultstring, true) return true @@ -91,61 +92,54 @@ func handle_result(accepted: String, resultstring: String, team: bool = true) -> return false -func _handle_game_over(error = "game over", isok = true) -> void: +func _handle_game_over(error := "game over", isok := true) -> void: + Globals.network.send_packet({"gamecode": Globals.network.game_code, "reason": error}, Network.HEADERS.stopgame) Globals.reset_vars() if get_tree().get_root().has_node("Board"): get_tree().get_root().get_node("Board").queue_free() set_status(error, isok) emit_signal("set_visible", true) + set_buttons(true) emit_signal("game_over") func _start_game() -> void: set_hosting(false) - var board = load("res://Board.tscn").instance() + var board: Node2D = load("res://Board.tscn").instance() get_tree().get_root().add_child(board) emit_signal("set_visible", false) emit_signal("game_started") set_buttons(false) -static func add_turn() -> void: - Events.emit_signal("just_before_turn_over") - Globals.add_turn() - Globals.turn = not Globals.turn - Events.emit_signal("turn_over") - - func _on_data(data: Dictionary) -> void: + Globals.add_turn() Log.debug([data, " recieved"]) - Globals.fullmove = data["fullmove"] - Globals.turn = data["turn"] - Globals.halfmove = data["halfmove"] Events.emit_signal("data_recieved") match data["movetype"]: Network.MOVEHEADERS.passant: # en passant - var end_pos = dict2vec(data["positions"][1]) - var start_piece = Piece.at_pos(dict2vec(data["positions"][0])) + var end_pos := dict2vec(data["positions"][1]) + var start_piece := Piece.at_pos(dict2vec(data["positions"][0])) Piece.at_pos(dict2vec(data["positions"][2])).took() # kill the unfortunate start_piece.passant(end_pos) Network.MOVEHEADERS.move: - var start_piece = Piece.at_pos(dict2vec(data["positions"][0])) - var end_pos = dict2vec(data["positions"][1]) - var end_piece = Piece.at_pos(end_pos) + var start_piece := Piece.at_pos(dict2vec(data["positions"][0])) + var end_pos := dict2vec(data["positions"][1]) + var end_piece := Piece.at_pos(end_pos) if end_piece != null: start_piece.take(end_piece) else: start_piece.moveto(end_pos) Network.MOVEHEADERS.castle: - var king = Piece.at_pos(dict2vec(data["positions"]["king"])) - var rook = Piece.at_pos(dict2vec(data["positions"]["rook"])) + var king := Piece.at_pos(dict2vec(data["positions"]["king"])) + var rook := Piece.at_pos(dict2vec(data["positions"]["rook"])) rook.moveto(dict2vec(data["positions"]["rookdestination"]), true, false, true) Utils.add_move(king.castle(dict2vec(data["positions"]["kingdestination"]))) Network.MOVEHEADERS.promote: - var dict_data = data["positions"] # positions is a dict for readability sometimes - var pawn = Piece.at_pos(dict2vec(dict_data["start_position"])) - var dest = dict2vec(dict_data["destination"]) + var dict_data: Dictionary = data["positions"] # positions is a dict for readability sometimes + var pawn: Pawn = Piece.at_pos(dict2vec(dict_data["start_position"])) + var dest := dict2vec(dict_data["destination"]) if Piece.at_pos(dest) != null: Piece.at_pos(dest).took() # move the pawn to the new place, killing if necessary pawn.clear_clicked() diff --git a/pieces/Bishop.gd b/pieces/Bishop.gd index ad2a3c8..18029fb 100644 --- a/pieces/Bishop.gd +++ b/pieces/Bishop.gd @@ -2,5 +2,6 @@ extends Piece class_name Bishop, "res://assets/pieces/california/wB.png" -func get_moves(no_enemys = false, check_spots_check = true) -> Array: - return traverse(all_dirs().slice(4, 8), no_enemys, check_spots_check) +func get_moves(no_enemys := false, check_spots_check := true) -> PoolVector2Array: + var dirs = PoolVector2Array(Array(all_dirs()).slice(4, 8)) + return traverse(dirs, no_enemys, check_spots_check) diff --git a/pieces/King.gd b/pieces/King.gd index aeb1477..7360054 100644 --- a/pieces/King.gd +++ b/pieces/King.gd @@ -9,10 +9,10 @@ func _ready() -> void: Events.connect("just_before_turn_over", self, "just_before_over") -func get_moves(no_enemys = false, check_spots_check = true) -> Array: - var moves := [] +func get_moves(no_enemys := false, check_spots_check := true) -> PoolVector2Array: + var moves: PoolVector2Array = [] for i in all_dirs(): - var spot: Vector2 = pos_around(i) + var spot := pos_around(i) if is_on_board(spot): if no_enemys and at_pos(spot): continue @@ -40,7 +40,7 @@ func just_before_over() -> void: # assign metadata for threefold repetition dra Globals.grid.matrix[8].bccr = true -func castleing(justcheckrooks = false) -> Array: +func castleing(justcheckrooks := false) -> Array: if has_moved: return [] var moves := [] @@ -51,7 +51,7 @@ func castleing(justcheckrooks = false) -> Array: for i in range(len(rooks)): if !is_on_board(rooks[i]): continue - var rook = at_pos(rooks[i]) + var rook: Piece = at_pos(rooks[i]) if !rook is Rook: continue if rook.has_moved: @@ -60,8 +60,8 @@ func castleing(justcheckrooks = false) -> Array: moves.append(labels[i]) continue var direction: Vector2 = king_moveto_spots[i] - var posx2: Vector2 = pos_around(direction * 2) - var pos: Vector2 = pos_around(direction) + var posx2 := pos_around(direction * 2) + var pos := pos_around(direction) if at_pos(posx2) or at_pos(pos) or checkcheck(posx2) or checkcheck(pos): continue if i == 1: # 3x check for O-O-O @@ -70,11 +70,13 @@ func castleing(justcheckrooks = false) -> Array: continue can_castle.append([posx2, rook, rook_motion[i], "O-O-O" if i == 1 else "O-O"]) moves.append(posx2) + if justcheckrooks: + moves.sort() return moves -func castle(position) -> String: - var return_string = "" +func castle(position: Vector2) -> String: + var return_string := "" if can_castle.size() == 1: return_string = can_castle[0][3] else: @@ -89,13 +91,13 @@ func castle(position) -> String: func can_move() -> bool: # checks if you can legally move castle_check = false - var can: bool = .can_move() + var can := .can_move() castle_check = true return can -func get_attacks(check_spots_check = true) -> Array: +func get_attacks(check_spots_check := true) -> PoolVector2Array: castle_check = false - var final: Array = .get_attacks(check_spots_check) + var final := .get_attacks(check_spots_check) castle_check = true return final diff --git a/pieces/Knight.gd b/pieces/Knight.gd index b9e91e5..dfb05c8 100644 --- a/pieces/Knight.gd +++ b/pieces/Knight.gd @@ -2,8 +2,8 @@ extends Piece class_name Knight, "res://assets/pieces/california/wN.png" -func get_moves(no_enemys = false, check_spots_check = true) -> Array: - var moves := [ +func get_moves(no_enemys := false, check_spots_check := true) -> PoolVector2Array: + var moves: PoolVector2Array = [ pos_around(Vector2(-2, -1)), pos_around(Vector2(-2, 1)), pos_around(Vector2(2, -1)), @@ -13,7 +13,7 @@ func get_moves(no_enemys = false, check_spots_check = true) -> Array: pos_around(Vector2(-1, 2)), pos_around(Vector2(1, 2)) ] - var final := [] + var final: PoolVector2Array = [] for i in moves: if is_on_board(i): if no_enemys and at_pos(i): diff --git a/pieces/Pawn.gd b/pieces/Pawn.gd index 43ecc09..ab9ea15 100644 --- a/pieces/Pawn.gd +++ b/pieces/Pawn.gd @@ -1,18 +1,18 @@ extends Piece class_name Pawn, "res://assets/pieces/california/wP.png" -const promotables := ["Q.png", "N.png", "R.png", "B.png"] +const promotables := "QNRB" var twostepfirstmove := false var just_set := false -var enpassant := [] +var enpassant: Array = [] var promoteposition := Vector2() var promotetake := false onready var whiteint := 1 if white else -1 onready var sprites := [] -onready var darken = get_node("../../Darken") +onready var darken: ColorRect = $"../../Darken" func _ready() -> void: @@ -21,23 +21,22 @@ func _ready() -> void: Events.connect("just_before_turn_over", self, "_just_before_turn_over") sprite.position = Globals.grid.piece_size / 2 for i in range(0, 4): # add 3 sprites - var newsprite = load("res://ui/ClickableSprite.tscn").instance() + var newsprite: Node2D = load("res://ui/ClickableSprite.tscn").instance() newsprite.position = (sprite.position + Vector2(0, (i * Globals.grid.piece_size.y) * whiteint)) - newsprite.name = "Sprite%s" % str(i) - newsprite.connect("clicked", self, "handle_sprite_input_event") - newsprite.z_index = 5 + newsprite.connect("clicked", self, "handle_sprite_input_event", [newsprite]) + newsprite.z_index = 5 # its not a texturebutton so i can use this newsprite.hide() add_child(newsprite) sprites.append(newsprite) func _exit_tree() -> void: - var find = Globals.pawns.find(self) + var find: int = Globals.pawns.find(self) if find != -1: Globals.pawns.remove(find) -func moveto(position, real = true, take = false, override_moveto = false) -> void: +func moveto(position: Vector2, real := true, take := false, override_moveto := false) -> void: # check if 2 step if real: if !twostepfirstmove and !has_moved: @@ -52,9 +51,9 @@ func moveto(position, real = true, take = false, override_moveto = false) -> voi Globals.reset_halfmove() -func get_moves(_var = false, check_spots_check = true) -> Array: +func get_moves(_var := false, check_spots_check := true) -> PoolVector2Array: var points := [Vector2.UP, Vector2.UP * 2] - var moves := [] + var moves: PoolVector2Array = [] for i in range(len(points)): var point: Vector2 = points[i] point *= whiteint @@ -70,20 +69,18 @@ func get_moves(_var = false, check_spots_check = true) -> Array: return moves -static func can_promote(position) -> bool: - if position.y >= 7 or position.y <= 0: - return true - return false +static func can_promote(position: Vector2) -> bool: + return position.y >= 7 or position.y <= 0 -func passant(position) -> void: - enpassant.clear() +func passant(position: Vector2) -> void: + enpassant.resize(0) moveto(position) -func get_attacks(check_spots_check = true) -> Array: +func get_attacks(check_spots_check := true) -> PoolVector2Array: var points := [Vector2.UP + Vector2.RIGHT, Vector2.UP + Vector2.LEFT] - var moves := [] + var moves: PoolVector2Array = [] for i in range(len(points)): var point: Vector2 = points[i] point *= whiteint @@ -98,13 +95,13 @@ func get_attacks(check_spots_check = true) -> Array: return moves -func en_passant(turncheck = true, check_spots_check = true) -> Array: # in passing +func en_passant(turncheck := true, check_spots_check := true) -> Array: # in passing var passants := [pos_around(Vector2.LEFT), pos_around(Vector2.RIGHT)] var moves := [] for i in passants: if !is_on_board(i) or !at_pos(i): continue - var spot = at_pos(i) + var spot := at_pos(i) if spot.white == white or !Utils.is_pawn(spot): continue if turncheck and white != Globals.turn: @@ -120,27 +117,30 @@ func en_passant(turncheck = true, check_spots_check = true) -> Array: # in pass return moves -func promote(position, type) -> void: +func promote(position: Vector2, type: String) -> void: if type == "take": at_pos(position).hide() move(position) # only move the visuals promoteposition = position darken.show() for i in range(len(promotables)): - sprites[i].sprite.texture = load("%s%s%s" % [Globals.grid.ASSETS_PATH, team.to_lower(), promotables[i]]) + sprites[i].sprite.texture = load( + "%s%s%s.png" % [Globals.grid.ASSETS_PATH, team.to_lower(), promotables[i]] + ) + sprites[i].name = promotables[i] sprites[i].show() -func handle_sprite_input_event(node) -> void: +func handle_sprite_input_event(node: Node2D) -> void: darken.hide() - var promote_to = promotables[sprites.find(node)][0] - var first = ( + var promote_to := node.name + var first := ( algebraic_move_notation(promoteposition) if !promotetake else algebraic_take_notation(promoteposition, real_position) ) - var notation = "%s=%s" % [first, promote_to] - Globals.grid.promoting = null + Log.debug(promote_to) + var notation := "%s=%s" % [first, promote_to] Globals.network.send_move_packet( { "start_position": real_position, @@ -153,18 +153,18 @@ func handle_sprite_input_event(node) -> void: ) -static func piece(string) -> String: +static func piece(string: String) -> String: match string: "Q": - return "res://pieces/Queen.gd" + return "Queen" "N": - return "res://pieces/Knight.gd" + return "Knight" "R": - return "res://pieces/Rook.gd" + return "Rook" "B": - return "res://pieces/Bishop.gd" + return "Bishop" _: - return "res://pieces/Piece.gd" + return "Piece" func _on_turn_over() -> void: diff --git a/pieces/Piece.gd b/pieces/Piece.gd index 9584883..6d9b09f 100644 --- a/pieces/Piece.gd +++ b/pieces/Piece.gd @@ -45,23 +45,20 @@ func clear_clicked() -> void: Globals.grid.clear_fx() -func algebraic_take_notation(position, startpos = real_position) -> String: - var starter := shortname if shortname != "p" else to_algebraic(startpos)[0] - return starter + "x" + to_algebraic(position) +func algebraic_take_notation(position: Vector2, startpos: Vector2 = real_position) -> String: + var starter := shortname if shortname != "p" else Utils.to_algebraic(startpos)[0] + return starter + "x" + Utils.to_algebraic(position) -func algebraic_move_notation(position) -> String: +func algebraic_move_notation(position: Vector2) -> String: var starter := shortname if shortname != "p" else "" - return starter + to_algebraic(position) - - -static func to_algebraic(position) -> String: - return Globals.grid.background_matrix[position.x][position.y].get_string() + return starter + Utils.to_algebraic(position) func move(newpos: Vector2) -> void: # dont use directly; use moveto tween.interpolate_property(self, "position", position, newpos * Globals.grid.piece_size, 0.3, Tween.TRANS_BACK) - var signresult = sign(newpos.x * Globals.grid.piece_size.x - global_position.x) + var signresult := sign(newpos.x * Globals.grid.piece_size.x - global_position.x) + Log.debug("signresult: " + str(signresult)) if signresult == 1: rotate.play("Right") elif signresult == -1: @@ -70,7 +67,7 @@ func move(newpos: Vector2) -> void: # dont use directly; use moveto tween.start() -func moveto(position, real := true, take := false, override_moveto = false) -> void: +func moveto(position: Vector2, real := true, take := false, override_moveto := false) -> void: Globals.grid.matrix[real_position.y][real_position.x] = null Globals.grid.matrix[position.y][position.x] = self if real: @@ -86,7 +83,7 @@ func moveto(position, real := true, take := false, override_moveto = false) -> v "%s moving from %s to %s" % [ shortname + " white" if white else " black", - Utils.to_algebraic(global_position / Globals.grid.piece_size), + Utils.to_algebraic((global_position / Globals.grid.piece_size).snapped(Vector2(1, 1))), Utils.to_algebraic(real_position) ] ) @@ -95,25 +92,27 @@ func moveto(position, real := true, take := false, override_moveto = false) -> v has_moved = true -func pos_around(around_vector) -> Vector2: +func pos_around(around_vector: Vector2) -> Vector2: return real_position + around_vector -static func all_dirs() -> Array: - return [ - Vector2.UP, - Vector2.DOWN, - Vector2.LEFT, - Vector2.RIGHT, - Vector2(1, 1), - Vector2(1, -1), - Vector2(-1, 1), - Vector2(-1, -1) - ] +static func all_dirs() -> PoolVector2Array: + return PoolVector2Array( + [ + Vector2.UP, + Vector2.DOWN, + Vector2.LEFT, + Vector2.RIGHT, + Vector2(1, 1), + Vector2(1, -1), + Vector2(-1, 1), + Vector2(-1, -1) + ] + ) -func traverse(arr := [], no_enemys = false, check_spots_check = true) -> Array: - var circle_array := [] +func traverse(arr: PoolVector2Array = [], no_enemys := false, check_spots_check := true) -> PoolVector2Array: + var circle_array: PoolVector2Array = [] for i in arr: var pos := real_position while true: @@ -134,7 +133,7 @@ func traverse(arr := [], no_enemys = false, check_spots_check = true) -> Array: return circle_array -static func at_pos(vector: Vector2): +static func at_pos(vector: Vector2) -> Piece: if is_instance_valid(Globals.grid): return Globals.grid.matrix[vector.y][vector.x] return null @@ -146,13 +145,13 @@ func can_move() -> bool: # checks if you can legally move return false -func get_moves(_no_enemys = false, _check_spots_check = true) -> Array: # @Override - return [] +func get_moves(_no_enemys := false, _check_spots_check := true) -> PoolVector2Array: # @Override + return PoolVector2Array() -func get_attacks(check_spots_check = true) -> Array: # @Override - var moves: Array = get_moves(false, check_spots_check) # assumes the attacks are same as moves - var final := [] +func get_attacks(check_spots_check := true) -> PoolVector2Array: # @Override + var moves := get_moves(false, check_spots_check) # assumes the attacks are same as moves + var final: PoolVector2Array = [] for i in moves: if at_pos(i) != null: if at_pos(i).white != white: # attack ze enemie @@ -162,24 +161,24 @@ func get_attacks(check_spots_check = true) -> Array: # @Override return final -func can_attack_piece(piece) -> bool: +func can_attack_piece(piece: Piece) -> bool: for pos in get_attacks(false): if at_pos(pos) == piece: return true return false -static func create_move_circles(pos) -> void: +static func create_move_circles(pos: Vector2) -> void: Globals.grid.background_matrix[pos.x][pos.y].set_circle(true) # make the move circle -static func create_take_circles(spot) -> void: # create take circles +static func create_take_circles(spot: Piece) -> void: # create take circles spot.set_frame() # turn on the little take frame on the piece, to show its takeable static func set_circle(positions: Array, type := "move") -> void: for pos in positions: - var spot = at_pos(pos) # get the piece at the position + var spot := at_pos(pos) # get the piece at the position if type == "move": create_move_circles(pos) # create the move circle elif type == "take": @@ -216,6 +215,6 @@ func took() -> void: # called when piece is taken anim.play("Take") -func set_frame(value = true) -> void: +func set_frame(value := true) -> void: frameon = value frame.visible = value diff --git a/pieces/Queen.gd b/pieces/Queen.gd index 0786c96..6143b16 100644 --- a/pieces/Queen.gd +++ b/pieces/Queen.gd @@ -2,5 +2,5 @@ extends Piece class_name Queen, "res://assets/pieces/california/wQ.png" -func get_moves(no_enemys = false, check_spots_check = true) -> Array: +func get_moves(no_enemys := false, check_spots_check := true) -> PoolVector2Array: return traverse(all_dirs(), no_enemys, check_spots_check) diff --git a/pieces/Rook.gd b/pieces/Rook.gd index 51254b4..40150d8 100644 --- a/pieces/Rook.gd +++ b/pieces/Rook.gd @@ -2,5 +2,5 @@ extends Piece class_name Rook, "res://assets/pieces/california/wR.png" -func get_moves(no_enemys = false, check_spots_check = true) -> Array: +func get_moves(no_enemys := false, check_spots_check := true) -> PoolVector2Array: return traverse([Vector2.UP, Vector2.DOWN, Vector2.LEFT, Vector2.RIGHT], no_enemys, check_spots_check) diff --git a/project.godot b/project.godot index 74e6847..1fe7c99 100644 --- a/project.godot +++ b/project.godot @@ -9,7 +9,7 @@ config_version=4 _global_script_classes=[ { -"base": "Control", +"base": "TextureButton", "class": "BarTextureButton", "language": "GDScript", "path": "res://ui/barbutton/BarTextureButton.gd" @@ -34,11 +34,26 @@ _global_script_classes=[ { "language": "GDScript", "path": "res://ui/colorpicker/ColorSelect.gd" }, { +"base": "Control", +"class": "Confirm", +"language": "GDScript", +"path": "res://ui/confirmbar.gd" +}, { +"base": "BarTextureButton", +"class": "DrawButton", +"language": "GDScript", +"path": "res://ui/barbutton/drawbutton.gd" +}, { "base": "LineEdit", "class": "FENLabel", "language": "GDScript", "path": "res://ui/FENlabel.gd" }, { +"base": "BarTextureButton", +"class": "FlipButton", +"language": "GDScript", +"path": "res://ui/barbutton/flipbutton.gd" +}, { "base": "Node2D", "class": "Grid", "language": "GDScript", @@ -99,6 +114,11 @@ _global_script_classes=[ { "language": "GDScript", "path": "res://pieces/Queen.gd" }, { +"base": "BarTextureButton", +"class": "ResignButton", +"language": "GDScript", +"path": "res://ui/barbutton/resignbutton.gd" +}, { "base": "Piece", "class": "Rook", "language": "GDScript", @@ -108,6 +128,11 @@ _global_script_classes=[ { "class": "SaveLoader", "language": "GDScript", "path": "res://saveload.gd" +}, { +"base": "Label", +"class": "StatusLabel", +"language": "GDScript", +"path": "res://ui/Status.gd" } ] _global_script_class_icons={ "BarTextureButton": "", @@ -115,7 +140,10 @@ _global_script_class_icons={ "ColorPickerBetter": "", "ColorPickerButtonBetter": "", "ColorSelect": "", +"Confirm": "", +"DrawButton": "res://assets/ui/draw.png", "FENLabel": "", +"FlipButton": "res://assets/ui/flip_board.png", "Grid": "", "HueSlider": "", "King": "res://assets/pieces/california/wK.png", @@ -128,8 +156,10 @@ _global_script_class_icons={ "Piece": "res://assets/pieces/california/wP.png", "Preview": "", "Queen": "res://assets/pieces/california/wQ.png", +"ResignButton": "res://assets/ui/flag.png", "Rook": "res://assets/pieces/california/wR.png", -"SaveLoader": "" +"SaveLoader": "", +"StatusLabel": "" } [application] @@ -153,6 +183,7 @@ SoundFx="*res://sounds/SoundFX.tscn" SaveLoad="*res://saveload.gd" ColorBack="*res://ui/background/ColorfullBackground.tscn" PacketHandler="*res://networking/PacketHandler.gd" +Debug="*res://Debug.gd" [debug] @@ -166,6 +197,10 @@ window/size/height=800 window/stretch/mode="2d" window/stretch/aspect="keep" +[editor] + +main_run_args="debug" + [editor_plugins] enabled=PoolStringArray( ) diff --git a/saveload.gd b/saveload.gd index 1a710e4..c77f97b 100644 --- a/saveload.gd +++ b/saveload.gd @@ -15,19 +15,19 @@ const default_settings_data = { var files := {"settings": {"file": settings_file, "data": default_settings_data.duplicate(true)}} # file types -func _ready(): +func _ready() -> void: SaveLoad.load_data("settings") -func save(type) -> void: - var file = File.new() +func save(type: String) -> void: + var file := File.new() file.open(files[type]["file"], File.WRITE) file.store_string(var2str(files[type]["data"])) func load_data(type: String) -> Dictionary: if check_file(type): - var file = File.new() + var file := File.new() file.open(files[type]["file"], File.READ) if file.get_as_text().length() > 0: var read_dictionary: Dictionary = str2var(file.get_as_text()) @@ -37,6 +37,6 @@ func load_data(type: String) -> Dictionary: return files[type]["data"] -func check_file(type) -> bool: - var file = File.new() +func check_file(type: String) -> bool: + var file := File.new() return file.file_exists(files[type]["file"]) diff --git a/sounds/SoundFX.gd b/sounds/SoundFX.gd index d86d61f..3e6862c 100644 --- a/sounds/SoundFX.gd +++ b/sounds/SoundFX.gd @@ -1,6 +1,6 @@ extends Node -const soundpath = "res://sounds/" +const soundpath := "res://sounds/" var sounds := { "Check": load(soundpath + "Check.ogg"), @@ -15,7 +15,7 @@ var sounds := { onready var sound_players := get_children() -func play(sound_string, pitch_scale = 1, volume_db = 0) -> void: +func play(sound_string: String, pitch_scale: float = 1, volume_db: float = 0) -> void: for soundPlayer in sound_players: if not soundPlayer.playing: soundPlayer.pitch_scale = pitch_scale diff --git a/ui/ClickableSprite.gd b/ui/ClickableSprite.gd index c99c396..1d16d61 100644 --- a/ui/ClickableSprite.gd +++ b/ui/ClickableSprite.gd @@ -2,25 +2,22 @@ extends Node2D signal clicked -var c = 0 - -onready var sprite = $Sprite +onready var sprite := $Sprite func _ready() -> void: - $Area2D/CollisionShape2D.shape.extents = Globals.grid.piece_size / 2 + if get_parent() != get_viewport(): + $Area2D/CollisionShape2D.shape.extents = Globals.grid.piece_size / 2 func _on_Area2D_input_event(_viewport: Node, _event: InputEvent, _shape_idx: int) -> void: if visible and Input.is_action_just_released("click"): - c += 1 - if c >= 1: - emit_signal("clicked", self) + emit_signal("clicked") func _on_Area2D_mouse_entered() -> void: - sprite.scale = Vector2(1, 1) + sprite.scale = Vector2(1.3, 1.3) func _on_Area2D_mouse_exited() -> void: - sprite.scale = Vector2(1.2, 1.2) + sprite.scale = Vector2(.8, .8) diff --git a/ui/ClickableSprite.tscn b/ui/ClickableSprite.tscn index 1617144..be3e310 100644 --- a/ui/ClickableSprite.tscn +++ b/ui/ClickableSprite.tscn @@ -5,7 +5,6 @@ [sub_resource type="RectangleShape2D" id=1] [node name="ClickableSprite" type="Node2D"] -visible = false script = ExtResource( 1 ) [node name="Sprite" type="Sprite" parent="."] diff --git a/ui/FENlabel.gd b/ui/FENlabel.gd index 1240d25..2dc0c91 100644 --- a/ui/FENlabel.gd +++ b/ui/FENlabel.gd @@ -4,8 +4,7 @@ class_name FENLabel func _ready() -> void: Utils.connect("newfen", self, "on_new_fen") - context_menu_enabled = false -func on_new_fen(fen) -> void: +func on_new_fen(fen: String) -> void: text = fen diff --git a/ui/GameUI.gd b/ui/GameUI.gd new file mode 100644 index 0000000..dd4a737 --- /dev/null +++ b/ui/GameUI.gd @@ -0,0 +1,7 @@ +extends CanvasLayer + +onready var status: StatusLabel = $Holder/Back/VBox/Status + + +func set_status(text: String, length := 5) -> void: + status.set_text(text, length) diff --git a/ui/GameUI.tscn b/ui/GameUI.tscn index 72d58df..dc2112b 100644 --- a/ui/GameUI.tscn +++ b/ui/GameUI.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=18 format=2] +[gd_scene load_steps=24 format=2] [ext_resource path="res://ui/theme/main.tres" type="Theme" id=1] [ext_resource path="res://ui/roboto.tres" type="DynamicFont" id=2] @@ -7,15 +7,21 @@ [ext_resource path="res://ui/Timer.gd" type="Script" id=5] [ext_resource path="res://ui/sandisplay/SanDisplay.tscn" type="PackedScene" id=6] [ext_resource path="res://ui/Status.gd" type="Script" id=7] -[ext_resource path="res://ui/barbutton/resignbutton.gd" type="Script" id=8] -[ext_resource path="res://assets/ui/flag.png" type="Texture" id=9] +[ext_resource path="res://ui/barbutton/drawbutton.gd" type="Script" id=8] +[ext_resource path="res://assets/ui/draw.png" type="Texture" id=9] +[ext_resource path="res://ui/GameUI.gd" type="Script" id=10] +[ext_resource path="res://assets/ui/check.png" type="Texture" id=11] +[ext_resource path="res://assets/ui/close.png" type="Texture" id=12] +[ext_resource path="res://ui/barbutton/resignbutton.gd" type="Script" id=13] +[ext_resource path="res://ui/confirmbar.gd" type="Script" id=14] [ext_resource path="res://ui/FENlabel.gd" type="Script" id=15] [ext_resource path="res://ui/barbutton/BarTextureButton.tscn" type="PackedScene" id=16] [ext_resource path="res://assets/ui/flip_board.png" type="Texture" id=17] -[ext_resource path="res://ui/flipbutton.gd" type="Script" id=18] +[ext_resource path="res://ui/barbutton/flipbutton.gd" type="Script" id=18] +[ext_resource path="res://assets/ui/flag.png" type="Texture" id=19] [sub_resource type="DynamicFont" id=1] -size = 25 +size = 35 font_data = ExtResource( 3 ) [sub_resource type="StyleBoxFlat" id=10] @@ -29,22 +35,24 @@ font_data = ExtResource( 3 ) size = 40 font_data = ExtResource( 3 ) -[node name="UI" type="CanvasLayer"] +[node name="GameUI" type="CanvasLayer"] +script = ExtResource( 10 ) [node name="Holder" type="Control" parent="."] anchor_left = 1.0 anchor_right = 1.0 anchor_bottom = 1.0 -margin_left = -624.0 +margin_left = -622.0 +margin_right = 2.0 theme = ExtResource( 1 ) __meta__ = { -"_edit_group_": true +"_edit_lock_": true } [node name="Back" type="ColorRect" parent="Holder"] anchor_right = 1.0 anchor_bottom = 1.0 -color = Color( 0.141176, 0.141176, 0.141176, 1 ) +color = Color( 0.141176, 0.141176, 0.141176, 0.784314 ) __meta__ = { "_edit_lock_": true } @@ -58,9 +66,10 @@ __meta__ = { } [node name="BlackTime" type="Label" parent="Holder/Back/VBox"] -margin_top = 107.0 +visible = false +margin_top = 218.0 margin_right = 624.0 -margin_bottom = 190.0 +margin_bottom = 301.0 custom_fonts/font = ExtResource( 2 ) text = "00:00.0" align = 1 @@ -79,27 +88,29 @@ margin_left = 72.0 margin_right = -72.0 color = Color( 0, 0, 0, 1 ) +[node name="MovesList" parent="Holder/Back/VBox" instance=ExtResource( 6 )] +margin_top = 239.0 +margin_right = 624.0 +margin_bottom = 439.0 + [node name="Status" type="Label" parent="Holder/Back/VBox"] -visible = false -margin_top = 264.0 -margin_right = 400.0 -margin_bottom = 295.0 +margin_top = 454.0 +margin_right = 624.0 +margin_bottom = 496.0 custom_fonts/font = SubResource( 1 ) -text = "hi there" align = 1 autowrap = true script = ExtResource( 7 ) -[node name="MovesList" parent="Holder/Back/VBox" instance=ExtResource( 6 )] -margin_top = 205.0 -margin_right = 624.0 -margin_bottom = 405.0 - [node name="buttonbarholder" type="Control" parent="Holder/Back/VBox"] -margin_top = 420.0 +margin_top = 511.0 margin_right = 624.0 -margin_bottom = 470.0 +margin_bottom = 561.0 rect_min_size = Vector2( 50, 50 ) +__meta__ = { +"_edit_group_": true, +"_edit_lock_": true +} [node name="Panel" type="Panel" parent="Holder/Back/VBox/buttonbarholder"] anchor_right = 1.0 @@ -113,24 +124,70 @@ custom_constants/separation = 0 alignment = 1 [node name="FlipBoard" parent="Holder/Back/VBox/buttonbarholder/buttonbar" instance=ExtResource( 16 )] +margin_left = 237.0 +margin_right = 287.0 +texture_normal = ExtResource( 17 ) +script = ExtResource( 18 ) + +[node name="DrawButton" parent="Holder/Back/VBox/buttonbarholder/buttonbar" instance=ExtResource( 16 )] margin_left = 287.0 margin_right = 337.0 -margin_bottom = 50.0 -script = ExtResource( 18 ) -texture = ExtResource( 17 ) +texture_normal = ExtResource( 9 ) +script = ExtResource( 8 ) +status = NodePath("../../../Status") +confirmbar = NodePath("../../../confirmbar") [node name="ResignButton" parent="Holder/Back/VBox/buttonbarholder/buttonbar" instance=ExtResource( 16 )] +margin_left = 337.0 +margin_right = 387.0 +texture_normal = ExtResource( 19 ) +script = ExtResource( 13 ) +status = NodePath("../../../Status") +drawbutton = NodePath("../DrawButton") +confirmbar = NodePath("../../../confirmbar") + +[node name="confirmbar" type="Control" parent="Holder/Back/VBox"] visible = false -margin_left = 200.0 -margin_right = 250.0 -margin_bottom = 50.0 -script = ExtResource( 8 ) -texture = ExtResource( 9 ) +margin_top = 490.0 +margin_right = 624.0 +margin_bottom = 590.0 +rect_min_size = Vector2( 0, 100 ) +script = ExtResource( 14 ) +__meta__ = { +"_edit_group_": true, +"_edit_lock_": true +} +status = NodePath("../Status") + +[node name="H" type="HBoxContainer" parent="Holder/Back/VBox/confirmbar"] +anchor_right = 1.0 +anchor_bottom = 1.0 +custom_constants/separation = 0 +alignment = 1 + +[node name="yes" parent="Holder/Back/VBox/confirmbar/H" instance=ExtResource( 16 )] +margin_left = 212.0 +margin_right = 312.0 +margin_bottom = 100.0 +rect_min_size = Vector2( 100, 100 ) +size_flags_horizontal = 4 +size_flags_vertical = 4 +texture_normal = ExtResource( 11 ) + +[node name="no" parent="Holder/Back/VBox/confirmbar/H" instance=ExtResource( 16 )] +margin_left = 312.0 +margin_right = 412.0 +margin_bottom = 100.0 +rect_min_size = Vector2( 100, 100 ) +size_flags_horizontal = 4 +size_flags_vertical = 4 +texture_normal = ExtResource( 12 ) [node name="WhiteTime" type="Label" parent="Holder/Back/VBox"] -margin_top = 485.0 +visible = false +margin_top = 498.0 margin_right = 624.0 -margin_bottom = 568.0 +margin_bottom = 581.0 custom_fonts/font = ExtResource( 2 ) text = "00:00.0" align = 1 @@ -154,16 +211,18 @@ color = Color( 0, 0, 0, 1 ) script = ExtResource( 5 ) [node name="Spacer" type="Control" parent="Holder/Back/VBox"] -margin_top = 583.0 +visible = false +margin_top = 530.0 margin_right = 624.0 -margin_bottom = 603.0 +margin_bottom = 550.0 rect_min_size = Vector2( 0, 20 ) [node name="FENlabel" type="LineEdit" parent="Holder/Back/VBox"] +visible = false margin_left = 58.0 -margin_top = 618.0 +margin_top = 503.0 margin_right = 566.0 -margin_bottom = 692.0 +margin_bottom = 577.0 size_flags_horizontal = 4 custom_colors/font_color_uneditable = Color( 1, 1, 1, 1 ) custom_fonts/font = SubResource( 8 ) @@ -171,6 +230,7 @@ text = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1" align = 1 editable = false expand_to_text_length = true +context_menu_enabled = false placeholder_text = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1" script = ExtResource( 15 ) @@ -190,5 +250,7 @@ anchor_bottom = 1.0 margin_right = -400.0 color = Color( 0, 0, 0, 0.784314 ) -[connection signal="pressed" from="Holder/Back/VBox/buttonbarholder/buttonbar/FlipBoard" to="Holder/Back/VBox/buttonbarholder/buttonbar/FlipBoard" method="_pressed"] -[connection signal="pressed" from="Holder/Back/VBox/buttonbarholder/buttonbar/ResignButton" to="Holder/Back/VBox/buttonbarholder/buttonbar/ResignButton" method="_pressed"] +[connection signal="confirmed" from="Holder/Back/VBox/confirmbar" to="Holder/Back/VBox/buttonbarholder/buttonbar/DrawButton" method="_handle_confirm"] +[connection signal="confirmed" from="Holder/Back/VBox/confirmbar" to="Holder/Back/VBox/buttonbarholder/buttonbar/ResignButton" method="_confirmed"] +[connection signal="pressed" from="Holder/Back/VBox/confirmbar/H/yes" to="Holder/Back/VBox/confirmbar" method="_pressed" binds= [ true ]] +[connection signal="pressed" from="Holder/Back/VBox/confirmbar/H/no" to="Holder/Back/VBox/confirmbar" method="_pressed" binds= [ false ]] diff --git a/ui/Lobby.gd b/ui/Lobby.gd index cca387c..bc8dd3f 100644 --- a/ui/Lobby.gd +++ b/ui/Lobby.gd @@ -1,29 +1,29 @@ extends Control onready var address: LineEdit = find_node("Address") -onready var buttons = find_node("buttons") -onready var status_ok = find_node("StatusOK") -onready var status_fail = find_node("StatusFail") +onready var buttons := find_node("buttons") +onready var status_ok := find_node("StatusOK") +onready var status_fail := find_node("StatusFail") -func toggle(onoff) -> void: - visible = onoff +func toggle(onoff: bool) -> void: + get_parent().visible = onoff -func _ready(): +func _ready() -> void: PacketHandler.connect("set_status", self, "_set_status") PacketHandler.connect("set_buttons", self, "_set_buttons") PacketHandler.connect("set_visible", self, "toggle") PacketHandler.connect("hosting", find_node("stophost"), "set_visible") _set_status(PacketHandler.status[0], PacketHandler.status[1]) - if !Utils.internet_available(): + if !Utils.internet: _set_status("no internet", false) _set_buttons(false) else: _set_buttons(PacketHandler.status[2]) -func _set_status(text, isok) -> void: # Simple way to show status. +func _set_status(text: String, isok: bool) -> void: # Simple way to show status. if isok: status_ok.set_text(text) status_fail.set_text("") @@ -34,7 +34,7 @@ func _set_status(text, isok) -> void: # Simple way to show status. status_fail.visible = len(status_fail.text) > 0 -func _set_buttons(enabled = true) -> void: +func _set_buttons(enabled := true) -> void: for c in buttons.get_children(): c.disabled = !enabled address.editable = enabled @@ -50,8 +50,8 @@ func _on_HostButton_pressed() -> void: PacketHandler.requesthost() -func validate_text(text = address.get_text()) -> String: - var pos = address.caret_position +func validate_text(text := address.get_text()) -> String: + var pos := address.caret_position text = text.strip_edges() text = text.replace(" ", "_") address.text = text @@ -60,7 +60,7 @@ func validate_text(text = address.get_text()) -> String: return text -func _on_Address_text_entered(new_text: String): +func _on_Address_text_entered(new_text: String) -> void: validate_text(new_text) @@ -69,5 +69,5 @@ func _on_tabs_tab_changed(tab: int): PacketHandler.return() -func _on_stophost_pressed(): +func _on_stophost_pressed() -> void: PacketHandler.return() @@ -26,7 +26,7 @@ static func to_str(arg) -> String: static func arr2str(arr: Array) -> String: - var string = "" + var string := "" for i in arr: string += str(i) + " " return string diff --git a/ui/Preview.gd b/ui/Preview.gd index 1ad2fd3..8807498 100644 --- a/ui/Preview.gd +++ b/ui/Preview.gd @@ -2,7 +2,7 @@ tool extends GridContainer class_name Preview -var size = Vector2(5, 4) +var size := Vector2(5, 4) const pieces = [ "R", "N", "B", "Q", "K", @@ -11,14 +11,14 @@ const pieces = [ "K", "Q", "B", "N", "R", ] -func _init(): +func _init() -> void: columns = size.x for x in size.x: for y in size.y: - var clr = ColorRect.new() + var clr := ColorRect.new() clr.name = "%s%s" % [x, y] clr.rect_min_size = Vector2(100, 100) - var tex = TextureRect.new() + var tex := TextureRect.new() tex.rect_min_size = Vector2(100, 100) tex.expand = true tex.name = "Piece" @@ -28,12 +28,12 @@ func _init(): update_preview(Color(0.870588, 0.890196, 0.901961), Color(0.54902, 0.635294, 0.678431), "california") -func update_preview(color1, color2, piece_set): - var squares = get_children() +func update_preview(color1:Color, color2:Color, piece_set:String) -> void: + var squares := get_children() for i in range(size.x * size.y): squares[i].color = color1 if i % 2 == 0 else color2 - var top = (size.x * size.y) / 2 + var top := (size.x * size.y) / 2 for i in size.x * size.y: - var node = squares[i].get_node("Piece") - var things = [piece_set, "b" if i < top else "w", pieces[i]] + var node :TextureRect= squares[i].get_node("Piece") + var things := [piece_set, "b" if i < top else "w", pieces[i]] node.texture = load("res://assets/pieces/%s/%s%s.png" % things) diff --git a/ui/Settings.gd b/ui/Settings.gd index a26afb7..c74c4c3 100644 --- a/ui/Settings.gd +++ b/ui/Settings.gd @@ -11,26 +11,28 @@ onready var board_color2: ColorPickerButtonBetter = find_node("boardcolor2") onready var settings: Dictionary = SaveLoad.files["settings"]["data"] setget set_settings +var ignore_set_settings = false -func set_settings(new_settings) -> void: + +func set_settings(new_settings: Dictionary) -> void: + if ignore_set_settings: + return update_button_visuals(new_settings) settings = new_settings SaveLoad.files["settings"]["data"] = settings SaveLoad.save("settings") -func toggle(onoff) -> void: - visible = onoff - - -func update_button_visuals(set = settings) -> void: +func update_button_visuals(set: Dictionary = settings) -> void: + ignore_set_settings = true vsyncbutton.pressed = set["vsync"] fullscreenbutton.pressed = set["fullscreen"] if is_instance_valid(borderlessbutton): borderlessbutton.pressed = !set["borderless"] board_color1.color = set["board_color1"] board_color2.color = set["board_color2"] - preview.call_deferred("update_preview", set["board_color1"], set["board_color2"], set["piece_set"]) + preview.update_preview(set["board_color1"], set["board_color2"], set["piece_set"]) + ignore_set_settings = false func _ready() -> void: @@ -58,16 +60,7 @@ func update_vars() -> void: SaveLoad.save("settings") -func _input(event) -> void: - if visible and event.is_action_pressed("ui_cancel"): - toggle(false) - - -func _on_BackButton_pressed() -> void: - toggle(false) - - -func _on_PieceSet_item_selected(index) -> void: +func _on_PieceSet_item_selected(index: int) -> void: Globals.piece_set = piece_sets[index] self.settings.piece_set = piece_sets[index] @@ -87,16 +80,16 @@ func _on_Borderless_toggled(button_pressed: bool) -> void: OS.window_borderless = !button_pressed -func _on_boardcolor1_newcolor(color: Color): +func _on_boardcolor1_newcolor(color: Color) -> void: Globals.board_color1 = color self.settings.board_color1 = color -func _on_boardcolor2_newcolor(color: Color): +func _on_boardcolor2_newcolor(color: Color) -> void: Globals.board_color2 = color self.settings.board_color2 = color -func _on_resetbutton_pressed(): +func _on_resetbutton_pressed() -> void: self.settings = SaveLoad.default_settings_data.duplicate(true) update_vars() diff --git a/ui/Settings.tscn b/ui/Settings.tscn index 84ea5b3..f12eddd 100644 --- a/ui/Settings.tscn +++ b/ui/Settings.tscn @@ -23,7 +23,7 @@ alignment = 1 [node name="TabContainer" type="TabContainer" parent="H"] margin_left = 203.0 margin_right = 703.0 -margin_bottom = 530.0 +margin_bottom = 570.0 rect_min_size = Vector2( 500, 0 ) size_flags_vertical = 0 custom_constants/hseparation = 20 @@ -40,25 +40,25 @@ margin_bottom = -30.0 alignment = 1 [node name="boardcolor1" parent="H/TabContainer/colors" instance=ExtResource( 5 )] -margin_left = 77.0 +margin_left = 57.0 margin_top = 26.0 -margin_right = 403.0 +margin_right = 383.0 margin_bottom = 132.0 size_flags_horizontal = 4 text = "boardcolor1" [node name="boardcolor2" parent="H/TabContainer/colors" instance=ExtResource( 5 )] -margin_left = 77.0 +margin_left = 57.0 margin_top = 147.0 -margin_right = 403.0 +margin_right = 383.0 margin_bottom = 253.0 size_flags_horizontal = 4 text = "boardcolor2" [node name="PieceSet" type="OptionButton" parent="H/TabContainer/colors"] -margin_left = 57.0 +margin_left = 37.0 margin_top = 268.0 -margin_right = 423.0 +margin_right = 403.0 margin_bottom = 424.0 focus_mode = 0 size_flags_horizontal = 4 diff --git a/ui/StartMenu.tscn b/ui/StartMenu.tscn index 0c254ca..1b69847 100644 --- a/ui/StartMenu.tscn +++ b/ui/StartMenu.tscn @@ -7,7 +7,7 @@ [ext_resource path="res://assets/ui/verdana-bold.ttf" type="DynamicFontData" id=5] [sub_resource type="DynamicFont" id=1] -size = 300 +size = 400 use_mipmaps = true use_filter = true font_data = ExtResource( 5 ) @@ -20,15 +20,19 @@ theme = ExtResource( 1 ) script = ExtResource( 2 ) [node name="tabs" type="TabContainer" parent="."] -anchor_right = 1.0 -anchor_bottom = 1.0 -margin_left = 24.0 -margin_top = 32.0 -margin_right = -30.0 -margin_bottom = -40.0 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +margin_left = -684.0 +margin_top = -364.0 +margin_right = 684.0 +margin_bottom = 364.0 +mouse_filter = 1 size_flags_horizontal = 0 size_flags_vertical = 0 drag_to_rearrange_enabled = true +use_hidden_tabs_for_min_size = true [node name="Lobby" parent="tabs" instance=ExtResource( 4 )] margin_left = 30.0 @@ -45,10 +49,12 @@ margin_bottom = -30.0 [node name="quit" type="Button" parent="tabs"] visible = false -margin_left = -157.0 -margin_top = 315.0 -margin_right = -15.0 -margin_bottom = 421.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +margin_left = 30.0 +margin_top = 90.0 +margin_right = -30.0 +margin_bottom = -30.0 focus_mode = 0 size_flags_horizontal = 4 size_flags_vertical = 4 diff --git a/ui/Status.gd b/ui/Status.gd index 3988d53..6a68c79 100644 --- a/ui/Status.gd +++ b/ui/Status.gd @@ -1,6 +1,9 @@ extends Label +class_name StatusLabel -func text(newtext) -> void: - show() +func set_text(newtext: String, time := 7) -> void: + print("set to ", newtext) text = newtext + yield(get_tree().create_timer(time), "timeout") + text = "" diff --git a/ui/Timer.gd b/ui/Timer.gd index 86aa8e9..69d3eae 100644 --- a/ui/Timer.gd +++ b/ui/Timer.gd @@ -16,7 +16,7 @@ func _ready() -> void: set_process(false) # disable -func _process(delta) -> void: +func _process(delta: float) -> void: if !enabled: return if Globals.turn: diff --git a/ui/TimerLabels.gd b/ui/TimerLabels.gd index b04e262..a8d8b7c 100644 --- a/ui/TimerLabels.gd +++ b/ui/TimerLabels.gd @@ -3,19 +3,19 @@ extends Label var time: float setget set_time var stop := false -const TIME = 300 +const STARTTIME = 300 export(bool) var white := false onready var colorrect := $ColorRect -func set_time(newtime) -> bool: +func set_time(newtime: float) -> bool: if stop: return false time = newtime if time <= 0.0: - Events.emit_signal("outoftime", "white" if white else "black") + Events.emit_signal("outoftime", white) stop = true text = "00:00.0" return false @@ -25,7 +25,7 @@ func set_time(newtime) -> bool: func _ready() -> void: - set_time(TIME) + set_time(STARTTIME) set_color() colorrect.show_behind_parent = true Events.connect("data_recieved", self, "set_color") diff --git a/ui/background/ColorfullBackground.gd b/ui/background/ColorfullBackground.gd index e4cfcfe..590211d 100644 --- a/ui/background/ColorfullBackground.gd +++ b/ui/background/ColorfullBackground.gd @@ -1,6 +1,6 @@ extends ColorRect -export(Array, Color) var colors = [ +export(PoolColorArray) var colors := [ Color(0.784314, 0.427451, 0.427451, 1), Color(0.913725, 0.847059, 0.403922, 1), Color(0.380392, 0.741176, 0.647059, 1), @@ -12,17 +12,17 @@ export(Array, Color) var colors = [ Color(0.984314, 0.858824, 0.282353, 1), Color(0.164706, 0.0862745, 0.247059, 1) ] -export(float) var length = 2.8 +export(float) var length := 2.8 -var tween = Tween.new() -var timer = Timer.new() +var tween := Tween.new() +var timer := Timer.new() static func rand(clr) -> float: return clamp(clr + rand_range(0, .1) if randi() % 2 else clr - rand_range(0, .1), 0, 1) -func _ready(): +func _ready() -> void: randomize() add_child(timer) add_child(tween) @@ -31,8 +31,8 @@ func _ready(): change_color() -func change_color(): - var clr = colors[randi() % colors.size()] +func change_color() -> void: + var clr: Color = colors[randi() % colors.size()] clr = Color(rand(clr.r), rand(clr.g), rand(clr.b), 1) tween.interpolate_property(self, "color", color, clr, length, Tween.TRANS_ELASTIC) tween.start() diff --git a/ui/barbutton/BarTextureButton.gd b/ui/barbutton/BarTextureButton.gd index fa776a5..6f57340 100644 --- a/ui/barbutton/BarTextureButton.gd +++ b/ui/barbutton/BarTextureButton.gd @@ -1,33 +1,29 @@ -extends Control +extends TextureButton class_name BarTextureButton -signal pressed - -var focused = false - -export(Texture) var texture +var focused: bool export(Color) var normal_color := Color.black -export(Color) var highlight_color := Color(0.243137, 0.129412, 0.129412) -export(Color) var pressed_color := Color(0.227451, 0.270588, 0.301961) +export(Color) var highlight_color := Color(0.670588, 0.352941, 0.352941) +export(Color) var pressed_color := Color(0.356863, 0.572549, 0.647059) +export(Color) var disabled_color := Color(0.501961, 0.501961, 0.501961) -onready var texture_button = $Texture -onready var background = $Background +onready var background := $Background -func _ready(): - texture_button.texture_normal = texture - texture_button.texture_focused = texture - texture_button.texture_pressed = texture - texture_button.texture_hover = texture +func _ready() -> void: + _focused(false) -func _on_Texture_pressed(): - emit_signal("pressed") +func set_disabled(new: bool) -> void: + disabled = new + self_modulate = Color(.1, .1, .1, 0.5) if disabled else Color.white -func _process(_delta): - if texture_button.pressed: +func _process(_delta := 0.0): + if disabled: + background.color = disabled_color + elif pressed: background.color = pressed_color elif focused: background.color = highlight_color @@ -35,11 +31,5 @@ func _process(_delta): background.color = normal_color -func _on_Texture_mouse_entered(): - focused = true - background.color = highlight_color - - -func _on_Texture_mouse_exited(): - focused = false - background.color = normal_color +func _focused(q: bool): + focused = q diff --git a/ui/barbutton/BarTextureButton.tscn b/ui/barbutton/BarTextureButton.tscn index b7091fc..2f22a36 100644 --- a/ui/barbutton/BarTextureButton.tscn +++ b/ui/barbutton/BarTextureButton.tscn @@ -2,23 +2,21 @@ [ext_resource path="res://ui/barbutton/BarTextureButton.gd" type="Script" id=2] -[node name="BarTextureButton" type="Control"] -margin_right = 64.0 -margin_bottom = 64.0 +[node name="BarTextureButton" type="TextureButton"] +margin_right = 50.0 +margin_bottom = 50.0 rect_min_size = Vector2( 50, 50 ) +focus_mode = 1 +enabled_focus_mode = 1 +expand = true script = ExtResource( 2 ) [node name="Background" type="ColorRect" parent="."] +show_behind_parent = true anchor_right = 1.0 anchor_bottom = 1.0 +mouse_filter = 2 +color = Color( 0, 0, 0, 1 ) -[node name="Texture" type="TextureButton" parent="."] -anchor_right = 1.0 -anchor_bottom = 1.0 -focus_mode = 0 -enabled_focus_mode = 0 -expand = true - -[connection signal="mouse_entered" from="Texture" to="." method="_on_Texture_mouse_entered"] -[connection signal="mouse_exited" from="Texture" to="." method="_on_Texture_mouse_exited"] -[connection signal="pressed" from="Texture" to="." method="_on_Texture_pressed"] +[connection signal="mouse_entered" from="." to="." method="_focused" binds= [ true ]] +[connection signal="mouse_exited" from="." to="." method="_focused" binds= [ false ]] diff --git a/ui/barbutton/drawbutton.gd b/ui/barbutton/drawbutton.gd new file mode 100644 index 0000000..c5fb8ef --- /dev/null +++ b/ui/barbutton/drawbutton.gd @@ -0,0 +1,59 @@ +extends BarTextureButton +class_name DrawButton, "res://assets/ui/draw.png" + +export(NodePath) onready var status = get_node(status) as StatusLabel +export(NodePath) onready var confirmbar = get_node(confirmbar) as Confirm + +var waiting_on_answer := false + + +func _ready() -> void: + Globals.network.connect("request", self, "draw_request") + Globals.network.connect("request_result", self, "_on_draw_result") + + +func draw_request(what: Dictionary): + if what.type == Network.REQUESTHEADERS.draw: + if "questions" in what: + Log.err("Draw request without prompt") + return + confirmbar.confirm(self, what.question, 20) + waiting_on_answer = true + + +func drawed() -> GDScriptFunctionState: + return Globals.grid.drawed("mutual agreement") + + +func stoplooking() -> void: + _handle_confirm(false) + + +func _pressed() -> void: + if waiting_on_answer: + _handle_confirm(true) + confirmbar.stop_looking() + else: + disabled = true + Globals.network.send_request_packet( + Network.REQUESTHEADERS.draw, "Your opponent wishes to draw, do you accept?" + ) + status.set_text("Draw request sent") + + +func _on_draw_result(accepted: Dictionary) -> void: # called from _handle_confirm + disabled = false + if accepted.type == Network.REQUESTHEADERS.draw: + if accepted.answer: + drawed() + else: + status.set_text("Your opponent has rejected the draw request.") + + +func _handle_confirm(yes: bool) -> void: # called from confirmbar.confirmed + if waiting_on_answer: + disabled = false + waiting_on_answer = false + Globals.network.send_request_answer_packet(Network.REQUESTHEADERS.draw, yes) + if yes: + drawed() diff --git a/ui/barbutton/flipbutton.gd b/ui/barbutton/flipbutton.gd new file mode 100644 index 0000000..7a6e3ac --- /dev/null +++ b/ui/barbutton/flipbutton.gd @@ -0,0 +1,6 @@ +extends BarTextureButton +class_name FlipButton, "res://assets/ui/flip_board.png" + + +func _pressed() -> void: + Globals.grid.flip_board() diff --git a/ui/barbutton/resignbutton.gd b/ui/barbutton/resignbutton.gd index fb553ad..3ca7490 100644 --- a/ui/barbutton/resignbutton.gd +++ b/ui/barbutton/resignbutton.gd @@ -1,5 +1,41 @@ extends BarTextureButton +class_name ResignButton, "res://assets/ui/flag.png" +export(NodePath) onready var status = get_node(status) as StatusLabel +export(NodePath) onready var drawbutton = get_node(drawbutton) as DrawButton +export(NodePath) onready var confirmbar = get_node(confirmbar) as Confirm -func _pressed(): - pass +var waiting_on_answer = false + + +func _ready() -> void: + Globals.network.connect("request", self, "resigned") + + +func resigned(what: Dictionary): + if what.type == Network.REQUESTHEADERS.resign: + Globals.grid.win(Globals.team, "resignation") + + +func _pressed() -> void: + if waiting_on_answer: + _confirmed(true) + confirmbar.stop_looking() + else: + confirmbar.confirm(self, "Resign?", 20) + waiting_on_answer = true + drawbutton.disabled = true + + +func stoplooking() -> void: + _confirmed(false) + + +func _confirmed(what: bool): + if waiting_on_answer: + waiting_on_answer = false + drawbutton.disabled = what # dont un disable it if the game is over + if what: + Globals.network.send_request_packet(Network.REQUESTHEADERS.resign, "") + Globals.grid.win(!Globals.team, "resignation") + disabled = true diff --git a/ui/colorpicker/ColorPicker.gd b/ui/colorpicker/ColorPicker.gd index 415953c..e4e9303 100644 --- a/ui/colorpicker/ColorPicker.gd +++ b/ui/colorpicker/ColorPicker.gd @@ -6,39 +6,35 @@ var color: Color = Color.white setget set_color signal color_changed(color) signal done(color) -onready var oldcolorview = $Panel/V/H2/OldColorView -onready var newcolorpreview = $Panel/V/H2/NewColorPreview -onready var colorselect = $Panel/V/H/ColorSelect -onready var hueslider = $Panel/V/H/HueSlider +onready var oldcolorview := $V/H2/OldColorView +onready var newcolorpreview := $V/H2/NewColorPreview +onready var colorselect := $V/H/ColorSelect +onready var hueslider := $V/H/HueSlider +onready var closebutton := $V/H2/Close -func open(): - oldcolorview.color = color - update_color() +func open(newcolor: Color) -> void: + oldcolorview.color = newcolor show() + set_color(newcolor) -func _ready(): - if has_node("/root/ColorPicker"): - open() # for testing - - -func update_color(): +func update_color() -> void: newcolorpreview.color = color colorselect.color = color - hueslider.color = color -func set_color(newcolor): +func set_color(newcolor: Color) -> void: color = newcolor update_color() emit_signal("color_changed", newcolor) -func done(): +func done() -> void: + closebutton._focused(false) emit_signal("done", color) -func _color_changed(newcolor: Color): +func _color_changed(newcolor: Color) -> void: if newcolor != color: set_color(newcolor) diff --git a/ui/colorpicker/ColorPicker.tscn b/ui/colorpicker/ColorPicker.tscn index 2e15d4b..db272c0 100644 --- a/ui/colorpicker/ColorPicker.tscn +++ b/ui/colorpicker/ColorPicker.tscn @@ -1,59 +1,49 @@ [gd_scene load_steps=9 format=2] [ext_resource path="res://ui/colorpicker/ColorPicker.gd" type="Script" id=1] +[ext_resource path="res://assets/ui/close.png" type="Texture" id=2] [ext_resource path="res://ui/colorpicker/HueSlider.gd" type="Script" id=6] [ext_resource path="res://ui/colorpicker/ColorSelect.gd" type="Script" id=7] [ext_resource path="res://ui/colorpicker/OldColorView.gd" type="Script" id=9] [ext_resource path="res://ui/colorpicker/huepicker.material" type="Material" id=10] [ext_resource path="res://ui/colorpicker/ColorSelect.material" type="Material" id=11] [ext_resource path="res://ui/barbutton/BarTextureButton.tscn" type="PackedScene" id=12] -[ext_resource path="res://assets/ui/close.png" type="Texture" id=13] [node name="ColorPicker" type="Control"] -margin_right = 145.0 -margin_bottom = 145.0 +margin_right = 125.0 +margin_bottom = 125.0 +rect_min_size = Vector2( 125, 125 ) script = ExtResource( 1 ) __meta__ = { -"_edit_group_": true, -"_edit_lock_": true +"_edit_group_": true } -[node name="Panel" type="Panel" parent="."] -anchor_right = 1.0 -anchor_bottom = 1.0 -__meta__ = { -"_edit_lock_": true -} - -[node name="V" type="VBoxContainer" parent="Panel"] -anchor_right = 1.0 -anchor_bottom = 1.0 -margin_left = 10.0 -margin_top = 10.0 -margin_right = -10.0 -margin_bottom = -8.0 +[node name="V" type="VBoxContainer" parent="."] +margin_right = 125.0 +margin_bottom = 125.0 custom_constants/separation = 5 -[node name="H" type="HBoxContainer" parent="Panel/V"] +[node name="H" type="HBoxContainer" parent="V"] margin_right = 125.0 margin_bottom = 100.0 custom_constants/separation = 5 -[node name="HueSlider" type="Control" parent="Panel/V/H"] +[node name="HueSlider" type="Control" parent="V/H"] margin_right = 20.0 margin_bottom = 100.0 rect_min_size = Vector2( 20, 100 ) size_flags_vertical = 0 script = ExtResource( 6 ) -[node name="ShaderHolder" type="ColorRect" parent="Panel/V/H/HueSlider"] +[node name="ShaderHolder" type="ColorRect" parent="V/H/HueSlider"] show_behind_parent = true material = ExtResource( 10 ) anchor_right = 1.0 anchor_bottom = 1.0 mouse_filter = 2 +color = Color( 1, 0, 0, 1 ) -[node name="ColorSelect" type="Control" parent="Panel/V/H"] +[node name="ColorSelect" type="Control" parent="V/H"] margin_left = 25.0 margin_right = 125.0 margin_bottom = 100.0 @@ -63,51 +53,48 @@ size_flags_horizontal = 0 size_flags_vertical = 0 script = ExtResource( 7 ) -[node name="ShaderHolder" type="ColorRect" parent="Panel/V/H/ColorSelect"] +[node name="ShaderHolder" type="ColorRect" parent="V/H/ColorSelect"] show_behind_parent = true material = ExtResource( 11 ) anchor_right = 1.0 anchor_bottom = 1.0 mouse_filter = 2 -[node name="H2" type="HBoxContainer" parent="Panel/V"] +[node name="H2" type="HBoxContainer" parent="V"] margin_top = 105.0 margin_right = 125.0 margin_bottom = 125.0 custom_constants/separation = 0 -[node name="Close" parent="Panel/V/H2" instance=ExtResource( 12 )] +[node name="Close" parent="V/H2" instance=ExtResource( 12 )] margin_right = 20.0 margin_bottom = 20.0 rect_min_size = Vector2( 20, 0 ) -texture = ExtResource( 13 ) +texture_normal = ExtResource( 2 ) normal_color = Color( 0.145098, 0.145098, 0.164706, 1 ) -highlight_color = Color( 0.1944, 0.3048, 0.36, 1 ) -pressed_color = Color( 0.3216, 0.414, 0.48, 1 ) -[node name="Spacer" type="Control" parent="Panel/V/H2"] +[node name="Spacer" type="Control" parent="V/H2"] margin_left = 20.0 margin_right = 25.0 margin_bottom = 20.0 rect_min_size = Vector2( 5, 0 ) -[node name="OldColorView" type="ColorRect" parent="Panel/V/H2"] +[node name="OldColorView" type="ColorRect" parent="V/H2"] margin_left = 25.0 margin_right = 75.0 margin_bottom = 20.0 rect_min_size = Vector2( 50, 20 ) script = ExtResource( 9 ) -[node name="NewColorPreview" type="ColorRect" parent="Panel/V/H2"] +[node name="NewColorPreview" type="ColorRect" parent="V/H2"] margin_left = 75.0 margin_right = 125.0 margin_bottom = 20.0 rect_min_size = Vector2( 50, 20 ) -[connection signal="color_changed" from="Panel/V/H/HueSlider" to="." method="_color_changed"] -[connection signal="gui_input" from="Panel/V/H/HueSlider" to="Panel/V/H/HueSlider" method="_gui_input"] -[connection signal="color_changed" from="Panel/V/H/ColorSelect" to="." method="_color_changed"] -[connection signal="gui_input" from="Panel/V/H/ColorSelect" to="Panel/V/H/ColorSelect" method="_gui_input"] -[connection signal="pressed" from="Panel/V/H2/Close" to="." method="done"] -[connection signal="color_changed" from="Panel/V/H2/OldColorView" to="." method="_color_changed"] -[connection signal="gui_input" from="Panel/V/H2/OldColorView" to="Panel/V/H2/OldColorView" method="_gui_input"] +[connection signal="hue_changed" from="V/H/HueSlider" to="V/H/ColorSelect" method="_hue_changed"] +[connection signal="color_changed" from="V/H/ColorSelect" to="." method="_color_changed"] +[connection signal="gui_input" from="V/H/ColorSelect" to="V/H/ColorSelect" method="_gui_input"] +[connection signal="pressed" from="V/H2/Close" to="." method="done"] +[connection signal="color_changed" from="V/H2/OldColorView" to="." method="_color_changed"] +[connection signal="gui_input" from="V/H2/OldColorView" to="V/H2/OldColorView" method="_gui_input"] diff --git a/ui/colorpicker/ColorPickerButton.gd b/ui/colorpicker/ColorPickerButton.gd index 7baf17e..a15dc6e 100644 --- a/ui/colorpicker/ColorPickerButton.gd +++ b/ui/colorpicker/ColorPickerButton.gd @@ -1,26 +1,28 @@ extends Control class_name ColorPickerButtonBetter -onready var colorpicker = $"ColorPicker" +onready var popup: Popup = $Popup +onready var colorpicker := $Popup/ColorPicker signal newcolor(color) var color: Color setget set_color -func set_color(newcolor): +func set_color(newcolor: Color) -> void: color = newcolor add_color_override("font_color", color) - colorpicker.color = color -func _ready(): - colorpicker.set_as_toplevel(true) - colorpicker.rect_global_position = $Position.rect_global_position - $Position.queue_free() - - -func _on_ColorPicker_done(newcolor: Color): +func _on_ColorPicker_done(newcolor: Color) -> void: set_color(newcolor) + popup.hide() colorpicker.hide() emit_signal("newcolor", color) + + +func _pressed() -> void: + var rect := popup.get_global_rect() + rect.position = rect_global_position + Vector2(50, 50) + popup.popup(rect) + colorpicker.open(color) diff --git a/ui/colorpicker/ColorPickerButton.tscn b/ui/colorpicker/ColorPickerButton.tscn index 2608dc9..df3ed57 100644 --- a/ui/colorpicker/ColorPickerButton.tscn +++ b/ui/colorpicker/ColorPickerButton.tscn @@ -1,9 +1,16 @@ -[gd_scene load_steps=4 format=2] +[gd_scene load_steps=5 format=2] [ext_resource path="res://ui/theme/main.tres" type="Theme" id=1] [ext_resource path="res://ui/colorpicker/ColorPickerButton.gd" type="Script" id=2] [ext_resource path="res://ui/colorpicker/ColorPicker.tscn" type="PackedScene" id=3] +[sub_resource type="StyleBoxFlat" id=1] +content_margin_left = 10.0 +content_margin_right = 10.0 +content_margin_top = 10.0 +content_margin_bottom = 10.0 +bg_color = Color( 0, 0, 0, 0.784314 ) + [node name="ColorPickerButton" type="Button"] margin_right = 232.0 margin_bottom = 106.0 @@ -13,18 +20,21 @@ enabled_focus_mode = 0 text = "button" script = ExtResource( 2 ) -[node name="ColorPicker" parent="." instance=ExtResource( 3 )] -visible = false -margin_left = 32.0 -margin_top = 32.0 -margin_right = 177.0 -margin_bottom = 177.0 +[node name="Popup" type="PopupPanel" parent="."] +visible = true +margin_left = 50.0 +margin_top = 50.0 +margin_right = 195.0 +margin_bottom = 195.0 +rect_min_size = Vector2( 125, 125 ) +custom_styles/panel = SubResource( 1 ) -[node name="Position" type="Control" parent="."] -margin_left = 32.0 -margin_top = 32.0 -margin_right = 72.0 -margin_bottom = 72.0 +[node name="ColorPicker" parent="Popup" instance=ExtResource( 3 )] +anchor_right = 1.0 +anchor_bottom = 1.0 +margin_left = 10.0 +margin_top = 10.0 +margin_right = -10.0 +margin_bottom = -10.0 -[connection signal="pressed" from="." to="ColorPicker" method="open"] -[connection signal="done" from="ColorPicker" to="." method="_on_ColorPicker_done"] +[connection signal="done" from="Popup/ColorPicker" to="." method="_on_ColorPicker_done"] diff --git a/ui/colorpicker/ColorSelect.gd b/ui/colorpicker/ColorSelect.gd index 4533514..1a8ddfa 100644 --- a/ui/colorpicker/ColorSelect.gd +++ b/ui/colorpicker/ColorSelect.gd @@ -2,38 +2,42 @@ extends Control class_name ColorSelect var color: Color setget set_color +var last_clicked_pos := Vector2.ZERO onready var shader_holder := $ShaderHolder signal color_changed(color) -func set_color(newcolor): +func set_color(newcolor: Color, sig := false) -> void: if newcolor != color: color = newcolor shader_holder.material.set_shader_param("hue", color.h) update() + if sig: + emit_signal("color_changed", color) -func _gui_input(event): +func _gui_input(event: InputEvent) -> void: if Input.is_action_pressed("click") and event is InputEventMouse: - var position = event.position - var saturation = clamp(position.x / rect_size.x, 0, 1) - var value = clamp(1 - (position.y / rect_size.y), 0, 1) - set_color(Color.from_hsv(color.h, saturation, value)) - update() - emit_signal("color_changed", color) + last_clicked_pos = event.position + var saturation := clamp(last_clicked_pos.x / rect_size.x, 0, 1) + var value := clamp(1 - (last_clicked_pos.y / rect_size.y), 0, 1) + set_color(Color.from_hsv(color.h, saturation, value), true) + + +func _draw() -> void: + var draw_color := color.inverted() + var vlinex := clamp(last_clicked_pos.x, 0, rect_size.x) -func _draw(): - var draw_color = color.inverted() + draw_line(Vector2(vlinex, 0), Vector2(vlinex, rect_size.x), draw_color) - var vlinex = color.s * rect_size.x - var vliney = rect_size.y + var hliney = clamp(last_clicked_pos.y, 0, rect_size.y) - draw_line(Vector2(vlinex, 0), Vector2(vlinex, vliney), draw_color) + draw_line(Vector2(0, hliney), Vector2(rect_size.x, hliney), draw_color) - var hlinex = rect_size.x - var hliney = rect_size.y - color.v * rect_size.y - draw_line(Vector2(0, hliney), Vector2(hlinex, hliney), draw_color) +func _hue_changed(hue: float) -> void: + color.h = hue + set_color(color, true) diff --git a/ui/colorpicker/HueSlider.gd b/ui/colorpicker/HueSlider.gd index bbc8234..247c029 100644 --- a/ui/colorpicker/HueSlider.gd +++ b/ui/colorpicker/HueSlider.gd @@ -1,28 +1,25 @@ extends Control class_name HueSlider -signal color_changed(color) +signal hue_changed(hue) -var color: Color setget set_color +var hue: float = 0 -func _gui_input(event): +func _gui_input(event: InputEvent) -> void: if Input.is_action_pressed("click") and event is InputEventMouse: - var position = event.position - var tmphue = clamp(position.y / rect_size.y, 0, 1) - set_color(Color.from_hsv(tmphue, color.s, color.v)) - emit_signal("color_changed", color) + var position: Vector2 = event.position + set_hue(clamp(position.y / rect_size.y, 0, 1)) + emit_signal("hue_changed", hue) -func set_color(newcolor): - if newcolor != color: - color = newcolor +func set_hue(nh: float) -> void: + if nh != hue: + hue = nh update() -func _draw(): - var x = rect_size.x - var y = color.h * rect_size.y - draw_line(Vector2(0, y - 1), Vector2(x, y - 1), Color.black, 1, true) - draw_line(Vector2(0, y), Vector2(x, y), Color.white, 1, true) - draw_line(Vector2(0, y + 1), Vector2(x, y + 1), Color.black, 1, true) +func _draw() -> void: + var y := hue * rect_size.y + var drawclr := Color.from_hsv(wrapf(hue + .5, 0, 1), 1, 1, 1) + draw_line(Vector2(0, y), Vector2(rect_size.x, y), drawclr, 1, true) diff --git a/ui/colorpicker/OldColorView.gd b/ui/colorpicker/OldColorView.gd index c840c2c..f62d54d 100644 --- a/ui/colorpicker/OldColorView.gd +++ b/ui/colorpicker/OldColorView.gd @@ -4,6 +4,6 @@ class_name OldColorView signal color_changed(color) -func _gui_input(event: InputEvent): +func _gui_input(event: InputEvent) -> void: if event is InputEventMouseButton: emit_signal("color_changed", color) diff --git a/ui/confirmbar.gd b/ui/confirmbar.gd new file mode 100644 index 0000000..f378f59 --- /dev/null +++ b/ui/confirmbar.gd @@ -0,0 +1,39 @@ +extends Control +class_name Confirm + +signal confirmed(what) + +export(NodePath) onready var status = get_node(status) as StatusLabel + +var timer := Timer.new() +var looking: Node = null + + +func _ready() -> void: + add_child(timer) + timer.connect("timeout", self, "_pressed", [false]) + + +func _timeout() -> void: + _pressed(false) + + +func stop_looking() -> void: + looking = null + timer.stop() + hide() + + +func confirm(who: Node, what: String, timeout := 5): + if is_instance_valid(looking): + looking.stoplooking() + looking = who + show() + status.set_text(what, timeout) + timer.start(timeout) + + +func _pressed(what: bool): + status.set_text("", 0) + emit_signal("confirmed", what) + stop_looking() diff --git a/ui/flipbutton.gd b/ui/flipbutton.gd index ebfec40..720be19 100644 --- a/ui/flipbutton.gd +++ b/ui/flipbutton.gd @@ -1,5 +1,5 @@ extends BarTextureButton -func _pressed(): +func _pressed() -> void: Globals.grid.flip_board() diff --git a/ui/sandisplay/SanDisplay.gd b/ui/sandisplay/SanDisplay.gd index a26413a..3ecaafe 100644 --- a/ui/sandisplay/SanDisplay.gd +++ b/ui/sandisplay/SanDisplay.gd @@ -1,25 +1,22 @@ extends ScrollContainer -var tween: Tween +var tween := Tween.new() -var number = 1 - -onready var scroll_container = self -onready var scroll_bar = get_v_scrollbar() -onready var sans = $sans +onready var scroll_container := self +onready var scroll_bar := get_v_scrollbar() +onready var sans := $sans func _ready() -> void: - tween = Tween.new() add_child(tween) Utils.connect("newmove", self, "on_new_move") -func create_number_label(num) -> void: - var clr = ColorRect.new() +func create_number_label(num: int) -> void: + var clr := ColorRect.new() clr.color = Color(1, 1, 1, 0.13) clr.rect_min_size = Vector2(70, 30) - var label = Label.new() + var label := Label.new() label.text = " %s." % str(num) label.align = Label.ALIGN_LEFT label.valign = Label.VALIGN_CENTER @@ -27,8 +24,8 @@ func create_number_label(num) -> void: sans.add_child(clr) -func create_san_label(text, alignment = Label.ALIGN_RIGHT) -> void: - var label = Label.new() +func create_san_label(text: String, alignment := Label.ALIGN_RIGHT) -> void: + var label := Label.new() label.text = text label.valign = Label.VALIGN_CENTER label.align = alignment @@ -36,12 +33,11 @@ func create_san_label(text, alignment = Label.ALIGN_RIGHT) -> void: sans.add_child(label) -func on_new_move(move) -> void: - var alignment = Label.ALIGN_RIGHT +func on_new_move(move: String) -> void: + var alignment := Label.ALIGN_RIGHT if !Globals.turn: # black just moved alignment = Label.ALIGN_LEFT create_number_label(Globals.fullmove) - number = 0 create_san_label(move, alignment) tween.interpolate_property( # scrolldown scroll_bar, "value", scroll_bar.value, scroll_bar.max_value, 0.5, Tween.TRANS_BOUNCE, Tween.EASE_IN_OUT diff --git a/ui/theme/main.tres b/ui/theme/main.tres index 5e526c1..333e5d3 100644 --- a/ui/theme/main.tres +++ b/ui/theme/main.tres @@ -45,14 +45,21 @@ bg_color = Color( 0, 0, 0, 0.313726 ) content_margin_left = 10.0 content_margin_right = 10.0 bg_color = Color( 0, 0, 0, 0.313726 ) -border_color = Color( 0, 0, 0, 0 ) -expand_margin_left = 10.0 +border_width_left = 3 +border_width_top = 3 +border_width_right = 3 +border_width_bottom = 1 +border_color = Color( 0, 0, 0, 0.392157 ) [sub_resource type="StyleBoxFlat" id=11] content_margin_left = 10.0 content_margin_right = 10.0 bg_color = Color( 0.188235, 0.188235, 0.188235, 1 ) -border_color = Color( 0, 0, 0, 0 ) +border_width_left = 3 +border_width_top = 3 +border_width_right = 3 +border_width_bottom = 1 +border_color = Color( 0, 0, 0, 0.392157 ) [sub_resource type="StyleBoxEmpty" id=5] diff --git a/ui/theme/transblack.tres b/ui/theme/transblack.tres new file mode 100644 index 0000000..020e585 --- /dev/null +++ b/ui/theme/transblack.tres @@ -0,0 +1,8 @@ +[gd_resource type="StyleBoxFlat" format=2] + +[resource] +content_margin_left = 10.0 +content_margin_right = 10.0 +content_margin_top = 10.0 +content_margin_bottom = 10.0 +bg_color = Color( 0, 0, 0, 0.313726 ) |