online multiplayer chess game (note server currently down)
spectators
39 files changed, 266 insertions, 243 deletions
@@ -130,34 +130,21 @@ func init_labels() -> void: foreground.offset = rect_global_position for i in range(8): labels.letters.append( - init_label( - i, - Vector2(i, 7), - "abcdefgh"[i], - Label.VALIGN_BOTTOM, - Label.ALIGN_LEFT, - Vector2(10, -10) - ) + init_label(i, Vector2(i, 7), "abcdefgh"[i], Label.VALIGN_BOTTOM, Label.ALIGN_LEFT, Vector2(10, -10)) ) labels.numbers.append( - init_label( - i, Vector2(7, i), str(8 - i), Label.VALIGN_TOP, Label.ALIGN_RIGHT, Vector2(-10, 10) - ) + init_label(i, Vector2(7, i), str(8 - i), Label.VALIGN_TOP, Label.ALIGN_RIGHT, Vector2(-10, 10)) ) -func init_label( - i: int, position: Vector2, text: String, valign := 0, align := 0, off := Vector2.ZERO -) -> Label: +func init_label(i: int, position: Vector2, text: String, valign := 0, align := 0, off := Vector2.ZERO) -> Label: var label := Label.new() label.rect_size = piece_size label.align = align label.valign = valign label.rect_position = (position * piece_size) + off label.text = text - label.add_color_override( - "font_color", Globals.board_color1 if i % 2 == 0 else Globals.board_color2 - ) + label.add_color_override("font_color", Globals.board_color1 if i % 2 == 0 else Globals.board_color2) var font: DynamicFont = load("res://ui/verdana-bold.tres").duplicate() font.size = 15 label.add_font_override("font", font) @@ -187,9 +174,7 @@ func check_in_check(prin := false) -> bool: # check if in_check for j in range(0, 8): # for each column 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 + if spot.can_attack_piece(Globals.white_king if Globals.turn else Globals.black_king): # if it can take the king if prin: # control never flows here Globals.in_check = true # set in_check @@ -216,9 +201,7 @@ func init_matrix() -> void: # create the matrix matrix[i].append(null) # add a square -func make_piece( - position: Vector2, piece_type: int, white: bool = true, visible: bool = true -) -> void: # make peace +func make_piece(position: Vector2, piece_type: int, white: bool = true, visible: bool = true) -> void: # make peace var piece := PieceScene.instance() # create a piece piece.name = Utils.to_str(piece_type) piece.script = load("res://pieces/%s.gd" % Utils.to_str(piece_type)) # set the script @@ -262,9 +245,7 @@ func check_for_frame(position: Vector2) -> bool: # check for a frame, validatin func square_clicked(position: Vector2) -> void: # square clicked - if stop_input: - return - if Globals.turn != Globals.team: + if stop_input or Globals.turn != Globals.team or Globals.spectating: return Log.debug(Utils.to_algebraic(position) + " clicked") var spot: Piece = matrix[position.y][position.x] # get the spot @@ -293,9 +274,7 @@ func handle_take(position: Vector2) -> void: if Utils.is_pawn(last_clicked): # if its a pawn if check_promote(last_clicked, position, "take"): return - var mov = Move.new( - SanParse.from_str(last_clicked.shortname), [last_clicked.real_position, position], true - ) + var mov = Move.new(SanParse.from_str(last_clicked.shortname), [last_clicked.real_position, position], true) Globals.network.send_mov(mov) # piece taking piece @@ -320,9 +299,7 @@ func handle_move(position: Vector2) -> void: return elif check_promote(pawn, position): return - var mov = Move.new( - SanParse.from_str(last_clicked.shortname), [last_clicked.real_position, position] - ) + var mov = Move.new(SanParse.from_str(last_clicked.shortname), [last_clicked.real_position, position]) Globals.network.send_mov(mov) @@ -414,9 +391,7 @@ func play_san(san: String, instant := false, set_input := true) -> void: # this handles promotion, taking, enpassant, and moves. var positions = mov.move_kind.data if mov.promotion != -1: # promotion part - Piece.at_pos(positions[0]).promote_to( - mov.promotion, mov.is_capture, positions[1], instant - ) + Piece.at_pos(positions[0]).promote_to(mov.promotion, mov.is_capture, positions[1], instant) elif mov.is_capture: # taking part Globals.reset_halfmove() @@ -471,11 +446,11 @@ func kill_matrix(): init_matrix() -func undo(): +func undo(last_move := Utils.pop_move()): Globals.turn = true Globals.fullmove = 1 Globals.halfmove = 0 Globals.in_check = false Globals.checking_piece = null clear_fx() - play_pgn(Utils.pop_move(), true) + play_pgn(last_move, true) @@ -5,11 +5,18 @@ [node name="Board" type="Control"] anchor_right = 1.0 anchor_bottom = 1.0 +rect_min_size = Vector2( 640, 640 ) mouse_filter = 2 script = ExtResource( 1 ) __meta__ = { "_edit_group_": true } +overlay_color = null +clockrunning_color = null +clockrunninglow = null +clocklow = null +ui = null +sidebar = null [node name="Background" type="GridContainer" parent="."] anchor_right = 1.0 @@ -30,7 +37,6 @@ mouse_filter = 2 visible = false anchor_right = 1.0 anchor_bottom = 1.0 -rect_min_size = Vector2( 800, 800 ) mouse_filter = 2 mouse_default_cursor_shape = 7 color = Color( 0, 0, 0, 0.784314 ) @@ -29,7 +29,7 @@ func _ready() -> void: visible = debug -func monitor(node: Node, what: String, code := "") -> void: # code doesnt really work well with ternarys +func monitor(node: Object, what: String, code := "") -> void: # code doesnt really work well with ternarys refs.append([node, what, code] if code else [node, what]) calculate_size() @@ -59,7 +59,7 @@ func _draw() -> void: func get_string(set: Array) -> String: - var node: Node = set[0] + var node: Object = set[0] if !is_instance_valid(node): refs.erase(set) return "invalid!" @@ -47,11 +47,7 @@ func get_fen() -> String: else: pieces += str(empty) else: - pieces += ( - spot.shortname[0].to_upper() - if spot.white - else spot.shortname[0].to_lower() - ) + pieces += (spot.shortname[0].to_upper() if spot.white else spot.shortname[0].to_lower()) empty = 0 if rank != 7: pieces += "/" @@ -3,14 +3,14 @@ extends Control onready var status: StatusLabel = find_node("Status") onready var sidebar = $Holder/SidebarRight onready var panels = [ - sidebar.blackpanel, sidebar.whitepanel, + sidebar.blackpanel, ] func _ready(): if Globals.network: - Globals.network.connect("info_recieved", self, "_on_info") + Globals.network.connect("info_recieved", self, "_spectate_info" if Globals.spectating else "_on_info") func set_status(text: String, length := 5) -> void: @@ -21,13 +21,18 @@ func get_board() -> Node: return $Holder/middle/Board -func _on_info(info: Dictionary): - var pnl = panels[int(!Globals.team)] - pnl.set_name(info.name if info.name else "Anonymous") - pnl.set_flag(info.country) +func _spectate_info(info: Dictionary) -> void: + var whitepnl = panels[0] #white + set_panel(whitepnl, info.white.name, info.white.country) + var blackpnl = panels[1] #black + set_panel(blackpnl, info.black.name, info.black.country) + + +func _on_info(info: Dictionary) -> void: + set_panel(panels[int(!Globals.team)], info.name, info.country) # enemy panel + set_panel(panels[int(Globals.team)], SaveLoad.get_data("id").name, SaveLoad.get_data("id").country) # own panel + - # set my own panel - pnl = panels[int(Globals.team)] - var name = SaveLoad.get_data("id").name +func set_panel(pnl, name, country) -> void: pnl.set_name(name if name else "Anonymous") - pnl.set_flag(SaveLoad.get_data("id").country) + pnl.set_flag(country) @@ -227,7 +227,6 @@ anchor_right = 0.0 anchor_bottom = 0.0 margin_right = 640.0 margin_bottom = 640.0 -rect_min_size = Vector2( 640, 640 ) ui = NodePath("../../..") sidebar = NodePath("../../SidebarRight") @@ -14,6 +14,8 @@ 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 = null var black_king: King = null +var spectating := false +var chat: Chat = null var turn := true # true for white, false for black # true cuz white goes first @@ -22,6 +24,7 @@ func reset_vars() -> void: __nosethalfmove = false pawns = [] team = true + spectating = false grid = null fullmove = 1 halfmove = 0 @@ -54,10 +57,25 @@ func get_turn() -> String: return "white" if turn else "black" +func get_team() -> String: + return "white" if team 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()") - Debug.monitor(self, "team") + Debug.monitor(self, "team", "get_team()") + Debug.monitor(self, "static memory", "get_static_memory()") + Debug.monitor(self, "dynamic memory", "get_dynamic_memory()") + Debug.monitor(Engine, "fps", "get_frames_per_second()") + + +func get_static_memory() -> String: + return String.humanize_size(OS.get_static_memory_usage()) + + +func get_dynamic_memory() -> String: + return String.humanize_size(OS.get_dynamic_memory_usage()) @@ -104,9 +104,10 @@ tracks/0/keys = { } [node name="Piece" type="Control"] -margin_right = 100.0 -margin_bottom = 100.0 -rect_pivot_offset = Vector2( 50, 50 ) +margin_right = 80.0 +margin_bottom = 80.0 +rect_min_size = Vector2( 80, 80 ) +rect_pivot_offset = Vector2( 40, 40 ) mouse_filter = 2 script = ExtResource( 1 ) @@ -127,7 +128,7 @@ visible = false anchor_right = 1.0 anchor_bottom = 1.0 mouse_filter = 2 -color = Color( 0.2, 0.345098, 0.188235, 0.592157 ) +color = Color( 0.0784314, 0.333333, 0.117647, 0.498039 ) [node name="Sprite" type="TextureRect" parent="."] anchor_right = 1.0 diff --git a/SanParse/Move.gd b/SanParse/Move.gd index f6e9ca1..1cb3299 100644 --- a/SanParse/Move.gd +++ b/SanParse/Move.gd @@ -109,11 +109,7 @@ func long_helper(vec: Vector2, attack: bool, move: bool, touch: Vector2): func long_helper_helper(spot, touch, attack, move): - return ( - Utils.spotispiece(piece, spot) - and spot.white == Globals.turn - and spot.can_touch(touch, attack, move) - ) + return Utils.spotispiece(piece, spot) and spot.white == Globals.turn and spot.can_touch(touch, attack, move) class MoveKind: diff --git a/SanParse/SanParse.gd b/SanParse/SanParse.gd index cd7d889..53663af 100644 --- a/SanParse/SanParse.gd +++ b/SanParse/SanParse.gd @@ -73,18 +73,14 @@ func regexmatch(san: String) -> Move: re = regexs.specific_row_piece_movement.search(san) if re: var cap = re.strings - var mov = Move.new( - from_str(cap[1]), [Vector2(-1, Utils.row_pos(cap[2])), pos(cap[3], cap[4])] - ) + var mov = Move.new(from_str(cap[1]), [Vector2(-1, Utils.row_pos(cap[2])), pos(cap[3], cap[4])]) mov.set_check_type(cap[5]) return mov re = regexs.specific_column_piece_movement.search(san) if re: var cap = re.strings - var mov = Move.new( - from_str(cap[1]), [Vector2(Utils.col_pos(cap[2]), -1), pos(cap[3], cap[4])] - ) + var mov = Move.new(from_str(cap[1]), [Vector2(Utils.col_pos(cap[2]), -1), pos(cap[3], cap[4])]) mov.set_check_type(cap[5]) return mov @@ -121,18 +117,14 @@ func regexmatch(san: String) -> Move: re = regexs.specific_column_piece_capture.search(san) if re: var cap = re.strings - var mov = Move.new( - from_str(cap[1]), [Vector2(Utils.col_pos(cap[2]), -1), pos(cap[3], cap[4])], true - ) + var mov = Move.new(from_str(cap[1]), [Vector2(Utils.col_pos(cap[2]), -1), pos(cap[3], cap[4])], true) mov.set_check_type(cap[5]) return mov re = regexs.specific_row_piece_capture.search(san) if re: var cap = re.strings - var mov = Move.new( - from_str(cap[1]), [Vector2(-1, Utils.row_pos(cap[2])), pos(cap[3], cap[4])], true - ) + var mov = Move.new(from_str(cap[1]), [Vector2(-1, Utils.row_pos(cap[2])), pos(cap[3], cap[4])], true) mov.set_check_type(cap[5]) return mov @@ -157,10 +157,7 @@ func format_seconds(time: float, use_milliseconds: bool = false) -> String: func _notification(what: int) -> void: - if ( - what == MainLoop.NOTIFICATION_WM_QUIT_REQUEST - or what == MainLoop.NOTIFICATION_WM_GO_BACK_REQUEST - ): + if what == MainLoop.NOTIFICATION_WM_QUIT_REQUEST or what == MainLoop.NOTIFICATION_WM_GO_BACK_REQUEST: Log.debug("Bye!") diff --git a/assets/ui/svg/undo.svg b/assets/ui/svg/undo.svg index f8910b1..a44e6f2 100644 --- a/assets/ui/svg/undo.svg +++ b/assets/ui/svg/undo.svg @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ce9bac0d637656350b898c20cd712a560156b71fd7c2dacc3ec92847db8f4940 -size 687 +oid sha256:ef0259894db665a24bb92f744073c033622edb75f23f86e21a6271d3483f0df7 +size 422 diff --git a/assets/ui/undo.png b/assets/ui/undo.png index 0b47444..6faa65c 100644 --- a/assets/ui/undo.png +++ b/assets/ui/undo.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:123f7d7ce05bd439ecfa0ff4d07182a73d6b227c4cbadb30dc06d4d4b53a5cdd -size 2315 +oid sha256:17a2bbef97bade7f5a29d6f62029cb532b851602ecbb96a67acfc05439e226bb +size 1138 diff --git a/networking/Network.gd b/networking/Network.gd index 8496386..741ea5f 100644 --- a/networking/Network.gd +++ b/networking/Network.gd @@ -17,7 +17,8 @@ const HEADERS := { "loadpgn": "L", # server telling me to load a pgn "info": "I", "move": "M", - "undo": "<" + "undo": "<", + "spectate": "0" # its a eye you see } const RELAYHEADERS := {chat = "C"} @@ -88,14 +89,18 @@ func signal(body: Dictionary, header: String, _mainheader := HEADERS.signal) -> return data -func join_game(game: String) -> void: +func join_game(game: String = game_code) -> void: send_gamecode_packet(SaveLoad.get_public_info(), HEADERS.joinrequest, game) -func host_game(game: String) -> void: +func host_game(game: String = game_code) -> void: send_gamecode_packet(SaveLoad.get_public_info(), HEADERS.hostrequest, game) +func spectate(game: String = game_code) -> void: + send_gamecode_packet(SaveLoad.get_public_info(), HEADERS.spectate, game) + + func send_gamecode_packet(data: Dictionary, header: String, gamecode: String = game_code): send_packet(Utils.append_dict({"gamecode": gamecode}, data), header) @@ -135,6 +140,13 @@ func _data_recieved() -> void: HEADERS.info: yield(get_tree().create_timer(.5), "timeout") emit_signal("info_recieved", text) + HEADERS.spectate: + # handle spectate here + Globals.spectating = true + emit_signal("start_game") + yield(get_tree().create_timer(.5), "timeout") + Globals.grid.play_pgn(text.pgn, true) + emit_signal("info_recieved", text) HEADERS.loadpgn: emit_signal("start_game") yield(get_tree().create_timer(.5), "timeout") diff --git a/networking/PacketHandler.gd b/networking/PacketHandler.gd index 2960dbd..5806126 100644 --- a/networking/PacketHandler.gd +++ b/networking/PacketHandler.gd @@ -39,16 +39,6 @@ func _ready() -> void: lobby.set_status("Connecting", true) -func requestjoin() -> void: - lobby.set_buttons(false) - Globals.network.join_game(Globals.network.game_code) - - -func requesthost() -> void: - lobby.set_buttons(false) - Globals.network.host_game(Globals.network.game_code) - - func network_ready() -> void: lobby.set_status("", true) lobby.set_buttons(true) diff --git a/pieces/P.gd b/pieces/P.gd index 0eedcb8..73de650 100644 --- a/pieces/P.gd +++ b/pieces/P.gd @@ -23,7 +23,7 @@ func _ready() -> void: for i in range(4): # add 4 sprites var newsprite: TextureButton = load("res://ui/PromotionPreview.tscn").instance() newsprite.texture_normal = load( - "%s%s%s.png" % [Globals.grid.ASSETS_PATH, team.to_lower(), promotables[i]] + "res://assets/pieces/%s/%s%s.png" % [Globals.piece_set, team.to_lower(), promotables[i]] ) newsprite.name = promotables[i] newsprite.connect("pressed", self, "_pressed", [newsprite.name]) @@ -155,7 +155,3 @@ func _on_turn_over() -> void: return if just_double_stepped: just_double_stepped = false - if Utils.to_algebraic(real_position) == "e4": - prints("duble steppe:", just_double_stepped) - prints("just sette:", just_set) - prints("has moved:", has_moved) diff --git a/pieces/Piece.gd b/pieces/Piece.gd index 58fd96f..dddc5db 100644 --- a/pieces/Piece.gd +++ b/pieces/Piece.gd @@ -36,9 +36,7 @@ func set_zindex(zindex: int, obj: CanvasItem = self): VisualServer.canvas_item_set_z_index(obj.get_canvas_item(), zindex) -func load_texture( - path := "%s%s%s.png" % [Globals.grid.ASSETS_PATH, team, shortname.to_upper()] -) -> void: +func load_texture(path := "%s%s%s.png" % [Globals.grid.ASSETS_PATH, team, shortname.to_upper()]) -> void: sprite.texture = load(path) @@ -55,12 +53,7 @@ func clear_clicked() -> void: func move(newpos: Vector2) -> void: # dont use directly; use moveto tween.interpolate_property( - self, - "rect_position", - rect_position, - newpos * Globals.grid.piece_size, - 0.3, - Tween.TRANS_BACK + self, "rect_position", rect_position, newpos * Globals.grid.piece_size, 0.3, Tween.TRANS_BACK ) var signresult := int(sign(real_position.x - newpos.x)) if signresult == 1: @@ -106,9 +99,7 @@ static func all_dirs() -> PoolVector2Array: ) -func traverse( - arr: PoolVector2Array = [], no_enemys := false, check_spots_check := true -) -> PoolVector2Array: +func traverse(arr: PoolVector2Array = [], no_enemys := false, check_spots_check := true) -> PoolVector2Array: var circle_array: PoolVector2Array = [] for i in arr: var pos := real_position diff --git a/pieces/R.gd b/pieces/R.gd index ed81f62..40150d8 100644 --- a/pieces/R.gd +++ b/pieces/R.gd @@ -3,6 +3,4 @@ class_name Rook, "res://assets/pieces/california/wR.png" 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 - ) + return traverse([Vector2.UP, Vector2.DOWN, Vector2.LEFT, Vector2.RIGHT], no_enemys, check_spots_check) diff --git a/project.godot b/project.godot index bbd5ca7..41b022f 100644 --- a/project.godot +++ b/project.godot @@ -20,6 +20,11 @@ _global_script_classes=[ { "path": "res://pieces/B.gd" }, { "base": "Control", +"class": "Chat", +"language": "GDScript", +"path": "res://ui/chat/Chat.gd" +}, { +"base": "Control", "class": "ColorPickerBetter", "language": "GDScript", "path": "res://ui/colorpicker/ColorPicker.gd" @@ -187,6 +192,7 @@ _global_script_classes=[ { _global_script_class_icons={ "BarTextureButton": "", "Bishop": "res://assets/pieces/california/wB.png", +"Chat": "", "ColorPickerBetter": "", "ColorPickerButtonBetter": "", "ColorSelect": "", @@ -19,9 +19,7 @@ class TestSan: func assert_capture(mv: String, start: Vector2, dest: Vector2, piece: int) -> void: assert_all(parse(mv), PoolVector2Array([start, dest]), piece, true) - func assert_all( - mv: Move, vectors: PoolVector2Array, piece: int, capture: bool, promote = -1 - ) -> void: + func assert_all(mv: Move, vectors: PoolVector2Array, piece: int, capture: bool, promote = -1) -> void: assert(mv.move_kind.type == Move.MoveKind.NORMAL) assert([mv.move_kind.data == vectors, mv.piece == piece, mv.is_capture == capture].min()) if promote != -1: @@ -62,9 +60,7 @@ class TestSan: assert_capture("exd4", Vector2(4, -1), Vector2(3, 4), PAWN) func test_pawn_capture_promotion(): - assert_all( - parse("exd8=Q"), PoolVector2Array([Vector2(4, -1), Vector2(3, 0)]), PAWN, true, QUEEN - ) + assert_all(parse("exd8=Q"), PoolVector2Array([Vector2(4, -1), Vector2(3, 0)]), PAWN, true, QUEEN) func test_pawn_capture_long(): assert_capture("e3xd4", Vector2(4, 5), Vector2(3, 4), PAWN) diff --git a/ui/PromotionPreview.gd b/ui/PromotionPreview.gd index c184746..969e10b 100644 --- a/ui/PromotionPreview.gd +++ b/ui/PromotionPreview.gd @@ -9,6 +9,11 @@ func set_focused(is_focused: bool): func _ready(): - rect_pivot_offset = Globals.grid.piece_size / 2 - rect_min_size = Globals.grid.piece_size + if Globals.grid: + rect_pivot_offset = Globals.grid.piece_size / 2 + rect_min_size = Globals.grid.piece_size set_focused(false) + + +func _pressed(): + print("PRESSED") diff --git a/ui/PromotionPreview.tscn b/ui/PromotionPreview.tscn index 71928f6..9bf892e 100644 --- a/ui/PromotionPreview.tscn +++ b/ui/PromotionPreview.tscn @@ -1,6 +1,7 @@ -[gd_scene load_steps=2 format=2] +[gd_scene load_steps=3 format=2] [ext_resource path="res://ui/PromotionPreview.gd" type="Script" id=1] +[ext_resource path="res://assets/pieces/california/wP.png" type="Texture" id=2] [node name="PromotionPreview" type="TextureButton"] anchor_left = 0.5 @@ -9,9 +10,12 @@ anchor_right = 0.5 anchor_bottom = 0.5 margin_left = -711.0 margin_top = -400.0 -margin_right = 711.0 -margin_bottom = 400.0 +margin_right = -631.0 +margin_bottom = -320.0 +rect_min_size = Vector2( 80, 80 ) +rect_pivot_offset = Vector2( 40, 40 ) mouse_filter = 1 +texture_normal = ExtResource( 2 ) expand = true stretch_mode = 5 script = ExtResource( 1 ) diff --git a/ui/barbutton/confirmbutton.gd b/ui/barbutton/confirmbutton.gd index d04e2ce..2b7bc1f 100644 --- a/ui/barbutton/confirmbutton.gd +++ b/ui/barbutton/confirmbutton.gd @@ -5,8 +5,6 @@ const Confirm = preload("res://ui/confirm/Confirm.tscn") var waiting_on_answer: Confirm = null export(String) var confirm_text = "" -export(NodePath) onready var status = get_node(status) as StatusLabel - func _ready() -> void: PacketHandler.connect("game_over", self, "set_disabled", [true]) diff --git a/ui/barbutton/drawbutton.gd b/ui/barbutton/drawbutton.gd index 41d3c38..d70f877 100644 --- a/ui/barbutton/drawbutton.gd +++ b/ui/barbutton/drawbutton.gd @@ -10,7 +10,7 @@ func _signal_recieved(what: Dictionary) -> void: if what.accepted: drawed() else: - status.set_text("Draw request rejected") + Globals.chat.server("Draw request rejected") func drawed() -> GDScriptFunctionState: @@ -18,11 +18,13 @@ func drawed() -> GDScriptFunctionState: func _pressed() -> void: + if Globals.spectating: + return if waiting_on_answer: _confirmed(true) else: Globals.network.signal({"question": ""}, Network.SIGNALHEADERS.draw) - status.set_text("Draw request sent") + Globals.chat.server("Draw request sent") func _confirmed(what: bool) -> void: # called from confirmbar.confirmed diff --git a/ui/barbutton/resignbutton.gd b/ui/barbutton/resignbutton.gd index a9baed5..7e47973 100644 --- a/ui/barbutton/resignbutton.gd +++ b/ui/barbutton/resignbutton.gd @@ -8,6 +8,8 @@ func _signal_recieved(what: Dictionary) -> void: func _pressed() -> void: + if Globals.spectating: + return if waiting_on_answer: _confirmed(true) else: diff --git a/ui/barbutton/undobutton.gd b/ui/barbutton/undobutton.gd index 72c2190..76d171a 100644 --- a/ui/barbutton/undobutton.gd +++ b/ui/barbutton/undobutton.gd @@ -1,12 +1,17 @@ extends ConfirmButton class_name UndoButton, "res://assets/ui/undo.png" +export(NodePath) onready var status = get_node(status) as StatusLabel + func _ready(): - Globals.network.connect("undo", self, "undo_recieved") + if Globals.network: + Globals.network.connect("undo", self, "undo_recieved") func _pressed(): + if Globals.spectating: + return if waiting_on_answer: _confirmed(true) else: @@ -16,9 +21,7 @@ func _pressed(): elif Globals.turn == Globals.team: status.set_text("It is your turn!") return - Globals.network.send_packet( - {gamecode = Globals.network.game_code, question = ""}, Network.HEADERS.undo - ) + Globals.network.send_packet({gamecode = Globals.network.game_code, question = ""}, Network.HEADERS.undo) status.set_text("Undo request sent") @@ -27,20 +30,19 @@ func undo_recieved(sig: Dictionary) -> void: confirm() else: if sig.accepted: - status.set_text("Undo request accepted") undo() else: - status.set_text("Undo request rejected") + Globals.chat.server("Undo request declined") func _confirmed(what: bool) -> void: ._confirmed(what) - Globals.network.send_packet( - {gamecode = Globals.network.game_code, accepted = what}, Network.HEADERS.undo - ) + Globals.network.send_packet({gamecode = Globals.network.game_code, accepted = what}, Network.HEADERS.undo) if what: undo() func undo(): + var mov = Utils.pop_move() + Globals.chat.server("Move %s undone" % mov.move) Globals.grid.undo() diff --git a/ui/chat/Chat.gd b/ui/chat/Chat.gd index e529720..2631750 100644 --- a/ui/chat/Chat.gd +++ b/ui/chat/Chat.gd @@ -1,12 +1,11 @@ extends Control +class_name Chat onready var labels = find_node("labels") onready var text: TextEdit = find_node("text") onready var scroller = find_node("scroller") onready var scrollbar = scroller.get_v_scrollbar() -const server_says = "[b]server[color=#f0e67e]:[/color][/b] " - var tween = Tween.new() var regexes: Array = [ [compile("_([^_]+)_"), "[i]$1[/i]"], @@ -16,17 +15,31 @@ var regexes: Array = [ [compile("`([^`]+)`"), "[code]$1[/code]"], [compile("~~([^~]+)~~"), "[s]$1[/s]"], [compile("#([^#]+)#"), "[rainbow freq=.3 sat=.7]$1[/rainbow]"], - [compile("%([^%]+)%"), "[shake rate=20 level=25]$1[/shake]"] + [compile("%([^%]+)%"), "[shake rate=20 level=25]$1[/shake]"], + [compile("\\[([^\\]]+)\\]\\(([^\\)]+)\\)"), "[url=$2]$1[/url]"], + [compile("((res://)?(http(s)?://.)?(www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{2,256}\\.[a-z]{2,6}\\b([-a-zA-Z0-9@:%_\\+.~#?&//=]*))"), "[url]$1[/url]"], ] +func server(txt: String) -> void: + add_label("[b]server[color=#f0e67e]:[/color] " + md2bb(txt)) + + +func _init(): + Globals.chat = self + + +func _exit_tree(): + Globals.chat = null + + func _ready(): if Globals.network: Globals.network.connect("chat", self, "add_label_with") add_child(tween) - add_label("%s[b]welcome!" % server_says, "server") + server("Welcome!") yield(get_tree().create_timer(.4), "timeout") - add_label("%s[b]you can use markdown(sort of)!" % server_says) + server("You can use markdown(sort of)!") static func compile(src: String) -> RegEx: @@ -40,10 +53,8 @@ func add_label_with(data): add_label(string) -func add_label( - bbcode: String, name = "richtextlabel", size = Vector2(rect_size.x, 35) -) -> RichTextLabel: - var l = RichTextLabel.new() +func add_label(bbcode: String, name = "text", size = Vector2(rect_size.x, 0)) -> RichTextLabel: + var l := RichTextLabel.new() l.name = name l.rect_min_size = size l.bbcode_enabled = true @@ -51,10 +62,8 @@ func add_label( labels.add_child(l) l.connect("meta_clicked", self, "open_url") l.bbcode_text = bbcode - # l.fit_content_height = true - tween.interpolate_property( - scrollbar, "value", scrollbar.value, scrollbar.max_value, .5, Tween.TRANS_BOUNCE - ) + l.fit_content_height = true + tween.interpolate_property(scrollbar, "value", scrollbar.value, scrollbar.max_value, .5, Tween.TRANS_BOUNCE) tween.start() return l @@ -67,19 +76,29 @@ func send(_arg = 0): var t = text.get_text().strip_edges() if !t: return - t = translate_md(t) + t = md2bb(t) text.text = "" var name_data = SaveLoad.get_data("id").name var name = name_data if name_data else "Anonymous" - Globals.network.relay_signal( - {"text": t, "who": name if name else "Anonymous"}, Network.RELAYHEADERS.chat - ) + name += "(%s)" % ("Spectator" if Globals.spectating else Globals.get_team()) + if Globals.network: + Globals.network.relay_signal({"text": t, "who": name}, Network.RELAYHEADERS.chat) + else: + add_label_with({text = t, who = name}) # for testing # markdown to bbcode -func translate_md(input: String) -> String: +func md2bb(input: String) -> String: for replacement in regexes: - input = replacement[0].sub(input, replacement[1]) + var result = replacement[0].search(input) + if result: + var index = input.find(result.strings[0]) - 1 + var char_before = input[index] + if not char_before in "\\": # taboo characters go here + if replacement[1] == "[url]$1[/url]" and result.strings[3] == "res://": # url one must avoid recognizing res:// + continue + input = replacement[0].sub(input, replacement[1], true) + input = input.replace("\\", "") # remove escapers return input diff --git a/ui/chat/Chat.tscn b/ui/chat/Chat.tscn index 6676503..3f83ef0 100644 --- a/ui/chat/Chat.tscn +++ b/ui/chat/Chat.tscn @@ -44,19 +44,19 @@ expand_margin_left = 10.0 expand_margin_right = 10.0 [sub_resource type="DynamicFont" id=18] -size = 20 +size = 15 font_data = ExtResource( 3 ) [sub_resource type="DynamicFont" id=19] -size = 20 +size = 15 font_data = ExtResource( 13 ) [sub_resource type="DynamicFont" id=14] -size = 20 +size = 15 font_data = ExtResource( 7 ) [sub_resource type="DynamicFont" id=20] -size = 25 +size = 15 font_data = ExtResource( 9 ) [sub_resource type="StyleBoxFlat" id=10] @@ -109,7 +109,7 @@ corner_detail = 15 expand_margin_top = 65.0 [sub_resource type="DynamicFont" id=15] -size = 20 +size = 15 font_data = ExtResource( 3 ) [sub_resource type="Theme" id=16] @@ -237,6 +237,7 @@ scroll_horizontal_enabled = false margin_right = 1406.0 size_flags_horizontal = 3 size_flags_vertical = 2 +custom_constants/separation = 0 [node name="h" type="HBoxContainer" parent="v"] margin_top = 740.0 diff --git a/ui/confirm/Confirm.tscn b/ui/confirm/Confirm.tscn index b15ba1b..473b905 100644 --- a/ui/confirm/Confirm.tscn +++ b/ui/confirm/Confirm.tscn @@ -8,9 +8,10 @@ [ext_resource path="res://ui/verdana-bold-small.tres" type="DynamicFont" id=6] [node name="Confirm" type="WindowDialog"] -margin_right = 576.0 -margin_bottom = 168.0 -rect_min_size = Vector2( 700, 0 ) +visible = true +margin_right = 400.0 +margin_bottom = 150.0 +rect_min_size = Vector2( 400, 150 ) theme = ExtResource( 1 ) custom_fonts/title_font = ExtResource( 6 ) popup_exclusive = true @@ -23,20 +24,20 @@ custom_constants/separation = 0 alignment = 1 [node name="no" parent="H" instance=ExtResource( 2 )] -margin_left = 350.0 -margin_top = 34.0 -margin_right = 450.0 -margin_bottom = 134.0 +margin_left = 100.0 +margin_top = 25.0 +margin_right = 200.0 +margin_bottom = 125.0 rect_min_size = Vector2( 100, 100 ) size_flags_horizontal = 4 size_flags_vertical = 4 texture_normal = ExtResource( 3 ) [node name="yes" parent="H" instance=ExtResource( 2 )] -margin_left = 250.0 -margin_top = 34.0 -margin_right = 350.0 -margin_bottom = 134.0 +margin_left = 200.0 +margin_top = 25.0 +margin_right = 300.0 +margin_bottom = 125.0 rect_min_size = Vector2( 100, 100 ) size_flags_horizontal = 4 size_flags_vertical = 4 diff --git a/ui/gridmenu/GridMenuButton.gd b/ui/gridmenu/GridMenuButton.gd index b2d93e1..d3dbd68 100644 --- a/ui/gridmenu/GridMenuButton.gd +++ b/ui/gridmenu/GridMenuButton.gd @@ -6,6 +6,8 @@ onready var gridmenu: GridMenu = $Popup/GridMenu signal selected(index) +export(Vector2) var offset = Vector2(50, -50) + var selected := 0 setget set_selected var items := [] @@ -27,8 +29,7 @@ func set_selected(index: int): func _pressed() -> void: - popup.rect_size = Vector2.ZERO - var rect := popup.get_global_rect() - rect.position = rect_global_position - Vector2(50, 50) - popup.popup(rect) + popup.popup() + yield(get_tree(), "idle_frame") + popup.rect_global_position = rect_global_position + offset gridmenu.open() diff --git a/ui/gridmenu/GridMenuButton.tscn b/ui/gridmenu/GridMenuButton.tscn index 7695610..b4af0a1 100644 --- a/ui/gridmenu/GridMenuButton.tscn +++ b/ui/gridmenu/GridMenuButton.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=34 format=2] +[gd_scene load_steps=35 format=2] [ext_resource path="res://ui/gridmenu/GridMenu.gd" type="Script" id=1] [ext_resource path="res://ui/theme/main.tres" type="Theme" id=2] @@ -17,6 +17,8 @@ [ext_resource path="res://ui/theme/buttonhover.tres" type="StyleBox" id=15] [ext_resource path="res://ui/theme/panel.tres" type="StyleBox" id=16] +[sub_resource type="StyleBoxEmpty" id=24] + [sub_resource type="StyleBoxTexture" id=6] texture = ExtResource( 12 ) region_rect = Rect2( 0, 0, 84, 84 ) @@ -226,12 +228,11 @@ margin_bottom = 40.0 rect_min_size = Vector2( 30, 20 ) size_flags_horizontal = 4 size_flags_vertical = 4 +custom_styles/panel = SubResource( 24 ) [node name="GridMenu" type="GridContainer" parent="Popup"] -margin_left = 10.0 -margin_top = 10.0 -margin_right = 40.0 -margin_bottom = 30.0 +margin_right = 50.0 +margin_bottom = 40.0 rect_min_size = Vector2( 30, 20 ) theme = SubResource( 23 ) custom_constants/vseparation = 0 diff --git a/ui/menus/Lobby.gd b/ui/menus/Lobby.gd index a696ed5..87b422b 100644 --- a/ui/menus/Lobby.gd +++ b/ui/menus/Lobby.gd @@ -37,13 +37,19 @@ func set_buttons(enabled := true) -> void: func _on_join_pressed() -> void: - validate_text() - PacketHandler.requestjoin() + if validate_text(): + set_buttons(false) + Globals.network.join_game() + else: + set_status("Invalid address", false) func _on_HostButton_pressed() -> void: - validate_text() - PacketHandler.requesthost() + if validate_text(): + set_buttons(false) + Globals.network.host_game() + else: + set_status("Invalid address", false) func validate_text(text := address.get_text()) -> String: @@ -60,6 +66,14 @@ func _on_Address_text_entered(new_text: String) -> void: validate_text(new_text) +func _on_spectate_pressed(): + if validate_text(): + set_buttons(false) + Globals.network.spectate() + else: + set_status("Invalid address", false) + + func _on_tabs_tab_changed(tab: int): if self != get_parent().get_children()[tab]: PacketHandler.return() diff --git a/ui/menus/Lobby.tscn b/ui/menus/Lobby.tscn index 5e81983..477dd78 100644 --- a/ui/menus/Lobby.tscn +++ b/ui/menus/Lobby.tscn @@ -12,17 +12,17 @@ theme = ExtResource( 1 ) script = ExtResource( 2 ) [node name="Center" type="CenterContainer" parent="."] -margin_left = 536.0 +margin_left = 411.0 margin_top = 286.0 -margin_right = 886.0 +margin_right = 1011.0 margin_bottom = 513.0 [node name="HBox" type="HBoxContainer" parent="Center"] -margin_right = 350.0 +margin_right = 600.0 margin_bottom = 227.0 [node name="VBox" type="VBoxContainer" parent="Center/HBox"] -margin_right = 350.0 +margin_right = 600.0 margin_bottom = 227.0 [node name="stophost" type="Button" parent="Center/HBox/VBox"] @@ -34,9 +34,9 @@ size_flags_horizontal = 4 text = "stop hosting" [node name="Address" type="LineEdit" parent="Center/HBox/VBox"] -margin_right = 350.0 +margin_right = 600.0 margin_bottom = 106.0 -rect_min_size = Vector2( 350, 0 ) +rect_min_size = Vector2( 600, 0 ) hint_tooltip = "place game code here" focus_mode = 1 text = "game_code" @@ -48,11 +48,22 @@ caret_blink_speed = 0.5 [node name="buttons" type="HBoxContainer" parent="Center/HBox/VBox"] margin_top = 121.0 -margin_right = 350.0 +margin_right = 600.0 margin_bottom = 227.0 +[node name="SpectateButton" type="Button" parent="Center/HBox/VBox/buttons"] +margin_right = 249.0 +margin_bottom = 106.0 +focus_mode = 0 +size_flags_horizontal = 3 +size_flags_vertical = 3 +disabled = true +enabled_focus_mode = 0 +text = "spectate" + [node name="JoinButton" type="Button" parent="Center/HBox/VBox/buttons"] -margin_right = 167.0 +margin_left = 264.0 +margin_right = 424.0 margin_bottom = 106.0 rect_min_size = Vector2( 150, 0 ) hint_tooltip = "join the game" @@ -63,8 +74,8 @@ enabled_focus_mode = 0 text = "join" [node name="HostButton" type="Button" parent="Center/HBox/VBox/buttons"] -margin_left = 182.0 -margin_right = 350.0 +margin_left = 439.0 +margin_right = 600.0 margin_bottom = 106.0 hint_tooltip = "host the game" focus_mode = 0 @@ -112,5 +123,6 @@ color = Color( 0.588235, 0.560784, 0.309804, 1 ) [connection signal="pressed" from="Center/HBox/VBox/stophost" to="." method="_on_stophost_pressed"] [connection signal="text_entered" from="Center/HBox/VBox/Address" to="." method="_on_Address_text_entered"] +[connection signal="pressed" from="Center/HBox/VBox/buttons/SpectateButton" to="." method="_on_spectate_pressed"] [connection signal="pressed" from="Center/HBox/VBox/buttons/JoinButton" to="." method="_on_join_pressed"] [connection signal="pressed" from="Center/HBox/VBox/buttons/HostButton" to="." method="_on_HostButton_pressed"] diff --git a/ui/menus/account/Account.tscn b/ui/menus/account/Account.tscn index c2400ff..e5e8167 100644 --- a/ui/menus/account/Account.tscn +++ b/ui/menus/account/Account.tscn @@ -66,6 +66,7 @@ rect_min_size = Vector2( 230, 0 ) size_flags_horizontal = 4 text = "flag" icon = ExtResource( 3 ) +offset = Vector2( 50, -400 ) [node name="signupbutton" type="Button" parent="choose/signup"] margin_left = 389.0 diff --git a/ui/menus/settings/Settings.gd b/ui/menus/settings/Settings.gd index 22e88bd..fc91565 100644 --- a/ui/menus/settings/Settings.gd +++ b/ui/menus/settings/Settings.gd @@ -1,7 +1,7 @@ extends Control onready var piece_sets := Utils.walk_dir() -onready var piece_set_button := find_node("PieceSet") +onready var piece_set_button: GridMenuButton = find_node("PieceSet") onready var fullscreenbutton := find_node("FullscreenButton") onready var vsyncbutton := find_node("VsyncButton") onready var borderlessbutton := find_node("Borderless") @@ -41,7 +41,7 @@ func _ready() -> void: if OS.has_feature("HTML5"): borderlessbutton.queue_free() for i in piece_sets: # add the items - piece_set_button.add_icon_item(load("res://assets/pieces/" + i + "/wP.png"), i) + piece_set_button.add_item(load("res://assets/pieces/" + i + "/wP.png"), i, Vector2(50, 50)) piece_set_button.selected = Array(piece_sets).find(settings.piece_set) update_vars() update_button_visuals() @@ -59,7 +59,7 @@ func update_vars() -> void: SaveLoad.save("settings") -func _on_PieceSet_item_selected(index: int) -> void: +func _on_PieceSet_selected(index: int) -> void: Globals.piece_set = piece_sets[index] self.settings.piece_set = piece_sets[index] diff --git a/ui/menus/settings/Settings.tscn b/ui/menus/settings/Settings.tscn index f3f01e3..e2bce7f 100644 --- a/ui/menus/settings/Settings.tscn +++ b/ui/menus/settings/Settings.tscn @@ -2,9 +2,9 @@ [ext_resource path="res://ui/theme/main.tres" type="Theme" id=1] [ext_resource path="res://ui/menus/settings/Settings.gd" type="Script" id=2] -[ext_resource path="res://assets/pieces/california/wP.png" type="Texture" id=3] [ext_resource path="res://ui/menus/settings/Preview.gd" type="Script" id=4] [ext_resource path="res://ui/colorpicker/ColorPickerButton.tscn" type="PackedScene" id=5] +[ext_resource path="res://ui/gridmenu/GridMenuButton.tscn" type="PackedScene" id=6] [node name="Settings" type="CenterContainer"] anchor_right = 1.0 @@ -55,19 +55,13 @@ margin_bottom = 278.0 size_flags_horizontal = 4 text = "boardcolor2" -[node name="PieceSet" type="OptionButton" parent="H/TabContainer/colors"] -margin_left = 173.0 +[node name="PieceSet" parent="H/TabContainer/colors" instance=ExtResource( 6 )] +margin_left = 175.0 margin_top = 293.0 -margin_right = 436.0 +margin_right = 434.0 margin_bottom = 399.0 -focus_mode = 0 size_flags_horizontal = 4 -size_flags_vertical = 0 -custom_constants/hseparation = 3 -enabled_focus_mode = 0 text = "piece set" -icon = ExtResource( 3 ) -expand_icon = true [node name="window" type="VBoxContainer" parent="H/TabContainer"] visible = false @@ -161,7 +155,7 @@ __meta__ = { [connection signal="newcolor" from="H/TabContainer/colors/boardcolor1" to="." method="_on_boardcolor1_newcolor"] [connection signal="newcolor" from="H/TabContainer/colors/boardcolor2" to="." method="_on_boardcolor2_newcolor"] -[connection signal="item_selected" from="H/TabContainer/colors/PieceSet" to="." method="_on_PieceSet_item_selected"] +[connection signal="selected" from="H/TabContainer/colors/PieceSet" to="." method="_on_PieceSet_selected"] [connection signal="toggled" from="H/TabContainer/window/VsyncButton" to="." method="_on_VsyncButton_toggled"] [connection signal="toggled" from="H/TabContainer/window/FullscreenButton" to="." method="_on_FullscreenButton_toggled"] [connection signal="toggled" from="H/TabContainer/window/Borderless" to="." method="_on_Borderless_toggled"] diff --git a/ui/menus/sidebarright/SidebarRight.tscn b/ui/menus/sidebarright/SidebarRight.tscn index 7393a0a..2886067 100644 --- a/ui/menus/sidebarright/SidebarRight.tscn +++ b/ui/menus/sidebarright/SidebarRight.tscn @@ -24,9 +24,6 @@ [ext_resource path="res://ui/menus/sidebarright/UserPanel.tscn" type="PackedScene" id=22] [sub_resource type="StyleBoxFlat" id=8] -content_margin_right = 0.0 -content_margin_top = 10.0 -content_margin_bottom = 10.0 bg_color = Color( 0.188235, 0.180392, 0.172549, 1 ) [sub_resource type="StyleBoxEmpty" id=2] @@ -121,14 +118,14 @@ alignment = 1 [node name="BlackPanel" parent="V" instance=ExtResource( 22 )] anchor_right = 0.0 anchor_bottom = 0.0 -margin_top = 184.0 +margin_top = 194.0 margin_right = 482.0 -margin_bottom = 244.0 +margin_bottom = 254.0 [node name="buttonbarholder" type="Control" parent="V"] -margin_top = 244.0 +margin_top = 254.0 margin_right = 482.0 -margin_bottom = 294.0 +margin_bottom = 304.0 rect_min_size = Vector2( 50, 50 ) __meta__ = { "_edit_group_": true, @@ -159,7 +156,6 @@ hint_tooltip = "request a draw" texture_normal = ExtResource( 16 ) script = ExtResource( 1 ) confirm_text = "Your opponent requests a draw" -status = NodePath("../../../../Status") [node name="ResignButton" parent="V/buttonbarholder/Panel/buttonbar" instance=ExtResource( 6 )] margin_left = 241.0 @@ -168,40 +164,39 @@ hint_tooltip = "resign" texture_normal = ExtResource( 20 ) script = ExtResource( 2 ) confirm_text = "Resign?" -status = NodePath("../../../../Status") [node name="UndoButton" parent="V/buttonbarholder/Panel/buttonbar" instance=ExtResource( 6 )] margin_left = 291.0 margin_right = 341.0 +hint_tooltip = "request a undo" texture_normal = ExtResource( 15 ) script = ExtResource( 18 ) -confirm_text = "Your opponent requests a takeback" +confirm_text = "Your opponent requests a undo" status = NodePath("../../../../Status") [node name="SanDisplay" type="PanelContainer" parent="V"] -margin_top = 294.0 +margin_top = 304.0 margin_right = 482.0 -margin_bottom = 514.0 +margin_bottom = 504.0 custom_styles/panel = SubResource( 8 ) [node name="SanDisplay" parent="V/SanDisplay" instance=ExtResource( 21 )] -margin_top = 10.0 margin_right = 482.0 -margin_bottom = 210.0 +margin_bottom = 200.0 rect_min_size = Vector2( 482, 200 ) theme = SubResource( 6 ) [node name="WhitePanel" parent="V" instance=ExtResource( 22 )] anchor_right = 0.0 anchor_bottom = 0.0 -margin_top = 514.0 +margin_top = 504.0 margin_right = 482.0 -margin_bottom = 574.0 +margin_bottom = 564.0 [node name="Status" type="Label" parent="V"] -margin_top = 574.0 +margin_top = 564.0 margin_right = 482.0 -margin_bottom = 616.0 +margin_bottom = 606.0 custom_fonts/font = SubResource( 1 ) align = 1 autowrap = true diff --git a/ui/menus/sidebarright/TimerLabels.gd b/ui/menus/sidebarright/TimerLabels.gd index 81317a7..96feee8 100644 --- a/ui/menus/sidebarright/TimerLabels.gd +++ b/ui/menus/sidebarright/TimerLabels.gd @@ -42,14 +42,6 @@ func _on_game_over() -> void: func set_color() -> void: if time > 10: - colorrect.color = ( - Globals.grid.clockrunning_color - if Globals.turn == white - else Color.transparent - ) + colorrect.color = (Globals.grid.clockrunning_color if Globals.turn == white else Color.transparent) else: - colorrect.color = ( - Globals.grid.clockrunninglow - if Globals.turn == white - else Globals.grid.clocklow - ) + colorrect.color = (Globals.grid.clockrunninglow if Globals.turn == white else Globals.grid.clocklow) diff --git a/ui/menus/sidebarright/sandisplay/SanDisplay.gd b/ui/menus/sidebarright/sandisplay/SanDisplay.gd index dc8410f..23a3aaa 100644 --- a/ui/menus/sidebarright/sandisplay/SanDisplay.gd +++ b/ui/menus/sidebarright/sandisplay/SanDisplay.gd @@ -39,3 +39,8 @@ func on_new_move(move: String) -> void: func reset_moves(): for i in sans.get_children(): i.queue_free() + + +func _gui_input(event): + if event is InputEventMouseButton: + OS.clipboard = Utils.get_pgn() |