online multiplayer chess game (note server currently down)
better chat + move network code to packethandler
bendn 2022-06-21
parent cc0b6c9 · commit 3182062
-rw-r--r--Board.gd31
-rw-r--r--Board.tscn2
-rw-r--r--Debug.gd2
-rw-r--r--Game.gd16
-rw-r--r--Game.tscn13
-rw-r--r--Globals.gd13
-rw-r--r--Log.gd27
-rw-r--r--MessageList.gd28
-rw-r--r--MessageList.tscn31
-rw-r--r--PGN/PGN.gd48
-rw-r--r--PGN/test_pgns.tscn11
-rw-r--r--SanParse/Move.gd9
-rw-r--r--Square.gd7
-rw-r--r--TextInput.tscn106
-rw-r--r--Utils.gd5
-rw-r--r--assets/emojis/3dots.png3
-rw-r--r--assets/emojis/3dots.png.import35
-rw-r--r--assets/emojis/bigsmile.png3
-rw-r--r--assets/emojis/bigsmile.png.import35
-rw-r--r--assets/emojis/cold.png3
-rw-r--r--assets/emojis/cold.png.import35
-rw-r--r--assets/emojis/cry.png3
-rw-r--r--assets/emojis/cry.png.import35
-rw-r--r--assets/emojis/happy.png3
-rw-r--r--assets/emojis/happy.png.import35
-rw-r--r--assets/emojis/hmm.png3
-rw-r--r--assets/emojis/hmm.png.import35
-rw-r--r--assets/emojis/huh.png3
-rw-r--r--assets/emojis/huh.png.import35
-rw-r--r--assets/emojis/smile.png3
-rw-r--r--assets/emojis/smile.png.import35
-rw-r--r--assets/emojis/unhappy.png3
-rw-r--r--assets/emojis/unhappy.png.import35
-rw-r--r--assets/emojis/upsidedown_smile.png3
-rw-r--r--assets/emojis/upsidedown_smile.png.import35
-rw-r--r--assets/emojis/weary.png3
-rw-r--r--assets/emojis/weary.png.import35
-rw-r--r--assets/emojis/what.png3
-rw-r--r--assets/emojis/what.png.import35
-rw-r--r--assets/emojis/wink.png3
-rw-r--r--assets/emojis/wink.png.import35
-rw-r--r--assets/emojis/wink_tongue.png3
-rw-r--r--assets/emojis/wink_tongue.png.import35
-rw-r--r--assets/emojis/wow.png3
-rw-r--r--assets/emojis/wow.png.import35
-rw-r--r--assets/emojis/zany.png3
-rw-r--r--assets/emojis/zany.png.import35
-rw-r--r--export_presets.cfg2
-rw-r--r--networking/Network.gd150
-rw-r--r--networking/PacketHandler.gd161
-rw-r--r--pieces/N.gd4
-rw-r--r--pieces/P.gd54
-rw-r--r--pieces/Piece.gd16
-rw-r--r--project.godot18
-rw-r--r--saveload.gd74
-rw-r--r--ui/barbutton/BarTextureButton.gd3
-rw-r--r--ui/barbutton/BarTextureButton.tscn4
-rw-r--r--ui/barbutton/confirmbutton.gd13
-rw-r--r--ui/barbutton/drawbutton.gd20
-rw-r--r--ui/barbutton/resignbutton.gd4
-rw-r--r--ui/barbutton/undobutton.gd42
-rw-r--r--ui/chat/Chat.gd103
-rw-r--r--ui/chat/Chat.tscn283
-rw-r--r--ui/chat/ExpandableTextEdit.gd76
-rw-r--r--ui/chat/TextInput.gd18
-rw-r--r--ui/chat/chat_theme.tres193
-rw-r--r--ui/chat/emojibutton.gd79
-rw-r--r--ui/chat/grayscale.shader10
-rw-r--r--ui/chat/texteditor.gd42
-rw-r--r--ui/gridmenu/GridMenu.gd6
-rw-r--r--ui/gridmenu/GridMenuButton.gd2
-rw-r--r--ui/menus/Lobby.gd8
-rw-r--r--ui/menus/account/Account.gd13
-rw-r--r--ui/menus/sidebarright/SidebarRight.gd2
-rw-r--r--ui/menus/sidebarright/SidebarRight.tscn164
-rw-r--r--ui/menus/sidebarright/UserPanel.gd4
-rw-r--r--ui/menus/sidebarright/UserPanel.tscn30
-rw-r--r--ui/menus/sidebarright/sandisplay/Base.tscn54
-rw-r--r--ui/menus/sidebarright/sandisplay/SanDisplay.gd14
-rw-r--r--ui/menus/sidebarright/sandisplay/SanDisplay.tscn89
-rw-r--r--ui/theme/main.tres2
-rw-r--r--ui/theme/panel.tres4
82 files changed, 1829 insertions, 889 deletions
diff --git a/Board.gd b/Board.gd
index 3b7c779..3cf6ad1 100644
--- a/Board.gd
+++ b/Board.gd
@@ -37,8 +37,8 @@ func _init() -> void:
func _ready() -> void:
rect_pivot_offset = rect_size / 2
- if Globals.network:
- Globals.network.connect("move_data", self, "play_san")
+ if PacketHandler:
+ PacketHandler.connect("move_data", self, "play_san")
init_board() # create the tile squares
init_matrix() # create 2d matrix
init_pieces() # create the pieces
@@ -127,13 +127,13 @@ func flip_board() -> void:
func init_labels() -> void:
- foreground.offset = rect_global_position
+ # 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], 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), VALIGN_TOP, Label.ALIGN_RIGHT, Vector2(-10, 10))
)
@@ -161,7 +161,7 @@ func drawed(reason := "") -> void:
func win(winner: bool, reason := "") -> void:
- ui.set_status("%s won the game by %s" % ["white" if winner else "black", reason], 0) # black won the game by checkmate
+ ui.set_status("%s won the game by %s" % ["white" if winner else "black", reason], 0) #: 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.fullmove])
SoundFx.play("Victory")
@@ -180,6 +180,7 @@ func check_in_check(prin := false) -> bool: # check if in_check
Globals.in_check = true # set in_check
Globals.checking_piece = spot # set checking_piece
SoundFx.play("Check")
+ Log.debug("check")
return true # stop at the first check found
return false
@@ -188,9 +189,12 @@ func can_move() -> bool:
for i in range(0, 8): # for each row
for j in range(0, 8): # for each column
var spot: Piece = matrix[i][j] # get the square
- if spot and spot.white != Globals.team: # enemie: checking for our enemys
+ if spot and spot.white == Globals.turn:
if spot.can_move():
+ Log.debug("%s %s can mov!" % [Globals.get_turn(), spot.shortname])
return true
+
+ Log.debug("can no mov!")
return false
@@ -275,7 +279,7 @@ func handle_take(position: Vector2) -> void:
if check_promote(last_clicked, position, "take"):
return
var mov = Move.new(SanParse.from_str(last_clicked.shortname), [last_clicked.real_position, position], true)
- Globals.network.send_mov(mov) # piece taking piece
+ PacketHandler.send_mov(mov) # piece taking piece
func handle_move(position: Vector2) -> void:
@@ -285,7 +289,7 @@ func handle_move(position: Vector2) -> void:
if castle_data[0] == position:
# send some packet
var mov = Move.new(SanParser.KING, castle_data[3])
- Globals.network.send_mov(mov)
+ PacketHandler.send_mov(mov)
return
if Utils.is_pawn(last_clicked):
var pawn: Pawn = last_clicked
@@ -295,12 +299,12 @@ func handle_move(position: Vector2) -> void:
if en_passant_data[0] == position:
# send some packet
var mov = Move.new(SanParser.PAWN, [pawn.real_position, position], true)
- Globals.network.send_mov(mov)
+ PacketHandler.send_mov(mov)
return
elif check_promote(pawn, position):
return
var mov = Move.new(SanParse.from_str(last_clicked.shortname), [last_clicked.real_position, position])
- Globals.network.send_mov(mov)
+ PacketHandler.send_mov(mov)
func check_promote(pawn, position, calltype: String = "move") -> bool:
@@ -318,6 +322,7 @@ func clear_fx() -> void: # clear the circles
var piece: Piece = matrix[i][j] # get the piece
if piece: # if there is a piece
piece.set_frame(false) # clear the frame
+ $Darken.hide()
func _on_outoftime(who: bool) -> void:
@@ -446,11 +451,11 @@ func kill_matrix():
init_matrix()
-func undo(last_move := Utils.pop_move()):
+func undo(last_pgn := Utils.pop_move()):
Globals.turn = true
Globals.fullmove = 1
Globals.halfmove = 0
Globals.in_check = false
Globals.checking_piece = null
clear_fx()
- play_pgn(last_move, true)
+ play_pgn(last_pgn, true)
diff --git a/Board.tscn b/Board.tscn
index 8234a93..9349baf 100644
--- a/Board.tscn
+++ b/Board.tscn
@@ -25,7 +25,7 @@ anchor_right = 1.0
anchor_bottom = 1.0
mouse_filter = 2
-[node name="Foreground" type="CanvasLayer" parent="."]
+[node name="Foreground" type="Control" parent="."]
[node name="Darken" type="ColorRect" parent="."]
visible = false
diff --git a/Debug.gd b/Debug.gd
index 367e663..17a0f94 100644
--- a/Debug.gd
+++ b/Debug.gd
@@ -3,7 +3,7 @@ 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-bold.tres")
-var debug := false
+var debug := false # in debug mode or not
var timer := Timer.new()
var expr := Expression.new()
diff --git a/Game.gd b/Game.gd
index def79d0..358c6d3 100644
--- a/Game.gd
+++ b/Game.gd
@@ -1,16 +1,16 @@
extends Control
onready var status: StatusLabel = find_node("Status")
-onready var sidebar = $Holder/SidebarRight
-onready var panels = [
- sidebar.whitepanel,
+onready var sidebar := $Holder/SidebarRight
+onready var panels := [
sidebar.blackpanel,
+ sidebar.whitepanel,
]
-func _ready():
- if Globals.network:
- Globals.network.connect("info_recieved", self, "_spectate_info" if Globals.spectating else "_on_info")
+func _ready() -> void:
+ if PacketHandler:
+ PacketHandler.connect("info_recieved", self, "_spectate_info" if Globals.spectating else "_on_info")
func set_status(text: String, length := 5) -> void:
@@ -22,9 +22,9 @@ func get_board() -> Node:
func _spectate_info(info: Dictionary) -> void:
- var whitepnl = panels[0] #white
+ var whitepnl = panels[Globals.WHITE]
set_panel(whitepnl, info.white.name, info.white.country)
- var blackpnl = panels[1] #black
+ var blackpnl = panels[Globals.BLACK] #black
set_panel(blackpnl, info.black.name, info.black.country)
diff --git a/Game.tscn b/Game.tscn
index 4eaf2b5..38630c6 100644
--- a/Game.tscn
+++ b/Game.tscn
@@ -194,15 +194,15 @@ WindowDialog/icons/close = ExtResource( 2 )
WindowDialog/icons/close_highlight = ExtResource( 2 )
WindowDialog/styles/panel = SubResource( 13 )
-[node name="Game" type="Control"]
+[node name="Game" type="MarginContainer"]
anchor_right = 1.0
anchor_bottom = 1.0
mouse_filter = 2
script = ExtResource( 1 )
[node name="Holder" type="HBoxContainer" parent="."]
-anchor_right = 1.0
-anchor_bottom = 1.0
+margin_right = 1422.0
+margin_bottom = 800.0
mouse_filter = 2
theme = ExtResource( 10 )
custom_constants/separation = 0
@@ -236,7 +236,12 @@ anchor_bottom = 0.0
margin_top = 640.0
margin_right = 640.0
margin_bottom = 800.0
-size_flags_horizontal = 3
size_flags_vertical = 3
[node name="SidebarRight" parent="Holder" instance=ExtResource( 4 )]
+anchor_right = 0.0
+anchor_bottom = 0.0
+margin_left = 940.0
+margin_right = 1422.0
+margin_bottom = 800.0
+rect_min_size = Vector2( 400, 0 )
diff --git a/Globals.gd b/Globals.gd
index 0b2e72b..6522e2a 100644
--- a/Globals.gd
+++ b/Globals.gd
@@ -1,10 +1,12 @@
extends Node
+const WHITE = 1
+const BLACK = 0
+
var __nosethalfmove := false
var pawns := [] # PoolPawnArray
var team := true
var grid: Grid = null
-var network: Network = null
var piece_set := "california"
var fullmove := 1
var halfmove := 0
@@ -53,15 +55,20 @@ func add_turn() -> void:
Events.emit_signal("turn_over")
+func str_bool(b: bool) -> String:
+ return "white" if b else "black"
+
+
func get_turn() -> String:
- return "white" if turn else "black"
+ return str_bool(turn)
func get_team() -> String:
- return "white" if team else "black"
+ return str_bool(team)
func _ready() -> void:
+ Log.info("startup")
VisualServer.set_default_clear_color(Color.black)
Debug.monitor(self, "fullmove")
Debug.monitor(self, "halfmove")
diff --git a/Log.gd b/Log.gd
index 5899abb..912ff23 100644
--- a/Log.gd
+++ b/Log.gd
@@ -1,23 +1,36 @@
extends Node
+# static class
+
static func info(information) -> void: # logs the input string
- print("[i] %s" % to_str(information))
+ print("(%s) [i] %s" % [now(), to_str(information)])
static func debug(information) -> void: # logs the input string on debug builds
if Debug.debug:
- print("[d] %s" % to_str(information))
+ print("(%s) [d] %s" % [now(), to_str(information)])
static func err(information) -> void: # logs the input string to stderr
- printerr("[E] %s" % to_str(information))
+ printerr("(%s) [E] %s" % [now(), to_str(information)])
+
+
+static func to_str(args) -> String:
+ return arr2str(args) if typeof(args) == TYPE_ARRAY else str(args)
+
+
+static func net(args) -> void:
+ file("user://network_log.log", args)
+
+
+static func file(path: String, args) -> void:
+ SaveLoad.append_string(path, "(%s)%s" % [now(), to_str(args)])
-static func to_str(arg) -> String:
- if typeof(arg) == TYPE_ARRAY:
- return arr2str(arg)
- return str(arg)
+static func now():
+ var time = OS.get_time()
+ return "%02d:%02d:%02d" % [time.hour, time.minute, time.second]
static func arr2str(arr: Array) -> String:
diff --git a/MessageList.gd b/MessageList.gd
new file mode 100644
index 0000000..aa407f6
--- /dev/null
+++ b/MessageList.gd
@@ -0,0 +1,28 @@
+extends PanelContainer
+class_name MessageList
+
+onready var labels = find_node("labels")
+onready var scroller = find_node("scroller")
+onready var scrollbar = scroller.get_v_scrollbar()
+
+var tween := Tween.new()
+
+
+func _ready():
+ add_child(tween)
+
+
+func add_label(bbcode: String):
+ var l := RichTextLabel.new()
+ l.bbcode_enabled = true
+ l.scroll_active = false
+ 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)
+ tween.start()
+
+
+func open_url(meta):
+ OS.shell_open(str(meta))
diff --git a/MessageList.tscn b/MessageList.tscn
new file mode 100644
index 0000000..14973ee
--- /dev/null
+++ b/MessageList.tscn
@@ -0,0 +1,31 @@
+[gd_scene load_steps=3 format=2]
+
+[ext_resource path="res://MessageList.gd" type="Script" id=1]
+
+[sub_resource type="StyleBoxFlat" id=1]
+bg_color = Color( 0.188235, 0.180392, 0.172549, 1 )
+
+[node name="MessageList" type="PanelContainer"]
+anchor_right = 1.0
+anchor_bottom = 1.0
+size_flags_vertical = 3
+custom_styles/panel = SubResource( 1 )
+script = ExtResource( 1 )
+
+[node name="MC" type="MarginContainer" parent="."]
+margin_right = 1422.0
+margin_bottom = 800.0
+custom_constants/margin_right = 10
+custom_constants/margin_left = 10
+
+[node name="scroller" type="ScrollContainer" parent="MC"]
+margin_left = 10.0
+margin_right = 1412.0
+margin_bottom = 800.0
+scroll_horizontal_enabled = false
+
+[node name="labels" type="VBoxContainer" parent="MC/scroller"]
+margin_right = 1402.0
+size_flags_horizontal = 3
+size_flags_vertical = 2
+custom_constants/separation = 0
diff --git a/PGN/PGN.gd b/PGN/PGN.gd
index 30aa103..d6ba721 100644
--- a/PGN/PGN.gd
+++ b/PGN/PGN.gd
@@ -2,41 +2,41 @@ extends Node
class_name PGN
-func parse(string) -> Dictionary:
+func parse(pgn: String, tags := true) -> Dictionary:
# put tags into a dictionary,
# and the moves into a array
- var tagex = SanParse.compile('^\\[([A-Za-z0-9_]+)\\s+"([^\\r]*)"\\]\\s*$', false)
- var tagnameex = SanParse.compile("^[A-Za-z0-9_]+\\Z", false)
var movetextex = SanParse.compile(
"([NBKRQ]?[a-h]?[1-8]?[\\-x]?[a-h][1-8](?:=?[nbrqkNBRQK])?|[PNBRQK]?@[a-h][1-8]|--|Z0|0000|@@@@|O-O(?:-O)?|0-0(?:-0)?)|(\\{.*)|(;.*)|(\\$[0-9]+)|(\\()|(\\))|(\\*|1-0|0-1|1\\/2-1\\/2)|([\\?!]{1,2})",
false
)
-
- # get headers
+ var lines = Array(pgn.split("\n"))
var headers := {}
- var lines = Array(string.split("\n"))
- while !lines.empty():
- var line = lines[0].strip_edges()
- if !line or line[0] in ["%", ";"]:
- lines.pop_front()
- continue
+ if tags:
+ var tagex = SanParse.compile('^\\[([A-Za-z0-9_]+)\\s+"([^\\r]*)"\\]\\s*$', false)
+ var tagnameex = SanParse.compile("^[A-Za-z0-9_]+\\Z", false)
+ # get headers
+ while !lines.empty():
+ var line = lines[0].strip_edges()
+ if !line or line[0] in ["%", ";"]:
+ lines.pop_front()
+ continue
- if line[0] != "[":
- break
+ if line[0] != "[":
+ break
- lines.pop_front()
- var tag_match = tagex.search(line)
- if tag_match:
- var cap = tag_match.strings
- if tagnameex.search(cap[1]):
- headers[cap[1]] = cap[2]
+ lines.pop_front()
+ var tag_match = tagex.search(line)
+ if tag_match:
+ var cap = tag_match.strings
+ if tagnameex.search(cap[1]):
+ headers[cap[1]] = cap[2]
+ else:
+ # invalid headers
+ push_error("invalid headers")
+ return {}
else:
- # invalid headers
- push_error("invalid headers")
- return {}
- else:
- break
+ break
var movetext := PoolStringArray()
while !lines.empty():
var line = lines.pop_front().strip_edges()
diff --git a/PGN/test_pgns.tscn b/PGN/test_pgns.tscn
index 874f9cd..eccb21d 100644
--- a/PGN/test_pgns.tscn
+++ b/PGN/test_pgns.tscn
@@ -8,7 +8,7 @@ anchor_right = 1.0
anchor_bottom = 1.0
theme = ExtResource( 1 )
script = ExtResource( 2 )
-pgns = PoolStringArray( "1.Nf3 Nf6 2.c4 g6 3.Nc3 Bg7 4.d4 O-O 5.Bf4 d5 6.Qb3 dxc4 7.Qxc4 c6 8.e4 Nbd7 9.Rd1 Nb6 10.Qc5 Bg4 11.Bg5 Na4 12.Qa3 Nxc3 13.bxc3 Nxe4 14.Bxe7 Qb6 15.Bc4 Nxc3 16.Bc5 Rfe8+ 17.Kf1 Be6 18.Bxb6 Bxc4+ 19.Kg1 Ne2+ 20.Kf1 Nxd4+ 21.Kg1 Ne2+ 22.Kf1 Nc3+ 23.Kg1 axb6 24.Qb4 Ra4 25.Qxb6 Nxd1 26.h3 Rxa2 27.Kh2 Nxf2 28.Re1 Rxe1 29.Qd8+ Bf8 30.Nxe1 Bd5 31.Nf3 Ne4 32.Qb8 b5 33.h4 h5 34.Ne5 Kg7 35.Kg1 Bc5+ 36.Kf1 Ng3+ 37.Ke1 Bb4+ 38.Kd1 Bb3+ 39.Kc1 Ne2+ 40.Kb1 Nc3+ 41.Kc1 Rc2# 0-1", "1. e2e4 Nf6" )
+pgns = PoolStringArray( "1.Nf3 Nf6 2.c4 g6 3.Nc3 Bg7 4.d4 O-O 5.Bf4 d5 6.Qb3 dxc4 7.Qxc4 c6 8.e4 Nbd7 9.Rd1 Nb6 10.Qc5 Bg4 11.Bg5 Na4 12.Qa3 Nxc3 13.bxc3 Nxe4 14.Bxe7 Qb6 15.Bc4 Nxc3 16.Bc5 Rfe8+ 17.Kf1 Be6 18.Bxb6 Bxc4+ 19.Kg1 Ne2+ 20.Kf1 Nxd4+ 21.Kg1 Ne2+ 22.Kf1 Nc3+ 23.Kg1 axb6 24.Qb4 Ra4 25.Qxb6 Nxd1 26.h3 Rxa2 27.Kh2 Nxf2 28.Re1 Rxe1 29.Qd8+ Bf8 30.Nxe1 Bd5 31.Nf3 Ne4 32.Qb8 b5 33.h4 h5 34.Ne5 Kg7 35.Kg1 Bc5+ 36.Kf1 Ng3+ 37.Ke1 Bb4+ 38.Kd1 Bb3+ 39.Kc1 Ne2+ 40.Kb1 Nc3+ 41.Kc1 Rc2# 0-1", "1. e4 e5 2. Nf3 Nc6 3. Bb5 Bc5 4. O-O Nf6 5. Nc3 Nb4 6. Nxe5 c6 7. Bc4 d5 8. exd5 cxd5 9. Bb5+ Bd7 10. Bxd7+ Nxd7 11. Nxd7 Qxd7 12. Re1+ Be7 13. a3 Nc6 14. d4 O-O-O 15. h3 Bh4 16. Qh5 Bf6 17. Nb5 Nxd4 18. Nxa7+ Kb8 19. Bg5 Nxc2 20. Bxf6 gxf6 21. a4 Kxa7 22. Qe2 Nxe1 23. Qxe1 Rhe8 24. Qa5+ Kb8 25. Qb4 d4 26. a5 Re6", "1. e4 f5 2. d4 g5 3. Qh5#" )
[node name="gameofthecentury" type="Button" parent="."]
margin_left = 454.0
@@ -25,5 +25,14 @@ margin_bottom = 227.0
size_flags_horizontal = 4
text = "test sign"
+[node name="test mate" type="Button" parent="."]
+margin_left = 575.0
+margin_top = 242.0
+margin_right = 846.0
+margin_bottom = 348.0
+size_flags_horizontal = 4
+text = "test mate"
+
[connection signal="pressed" from="gameofthecentury" to="." method="_load" binds= [ 0 ]]
[connection signal="pressed" from="test sign" to="." method="_load" binds= [ 1 ]]
+[connection signal="pressed" from="test mate" to="." method="_load" binds= [ 2 ]]
diff --git a/SanParse/Move.gd b/SanParse/Move.gd
index 1cb3299..66fbbd7 100644
--- a/SanParse/Move.gd
+++ b/SanParse/Move.gd
@@ -55,15 +55,6 @@ static func to_str(type: int) -> String:
return " NBRQK"[type].strip_edges() # if its a pawn, return nothing
-## tests
-# print(Utils.to_algebraic(make_long(SanParse.parse("e4").move_kind.data, false, SanParser.PAWN)[0]) == "e2")
-# print(Utils.to_algebraic(make_long(SanParse.parse("Nbc3").move_kind.data, false, SanParser.KNIGHT)[0]) == "b1")
-# print(Utils.to_algebraic(make_long(SanParse.parse("N1c3").move_kind.data, false, SanParser.KNIGHT)[0]) == "b1")
-
-
-# print(Utils.to_algebraic(make_long(SanParse.parse("exe4").move_kind.data, false, SanParser.PAWN)[0]) == "e2")
-# print(Utils.to_algebraic(make_long(SanParse.parse("Nbxc3").move_kind.data, false, SanParser.KNIGHT)[0]) == "b1")
-# print(Utils.to_algebraic(make_long(SanParse.parse("N1xc3").move_kind.data, false, SanParser.KNIGHT)[0]) == "b1")
### fix short san
func make_long() -> Move:
if move_kind.type == MoveKind.CASTLE:
diff --git a/Square.gd b/Square.gd
index 89b7071..9dd9a4e 100644
--- a/Square.gd
+++ b/Square.gd
@@ -13,6 +13,10 @@ func _ready() -> void:
circle.visible = false
rect_min_size = Globals.grid.piece_size
rect_size = rect_min_size
+ if Globals.spectating:
+ mouse_default_cursor_shape = CURSOR_FORBIDDEN
+ else:
+ mouse_default_cursor_shape = CURSOR_POINTING_HAND
func set_circle(boolean: bool) -> void:
@@ -21,5 +25,6 @@ func set_circle(boolean: bool) -> void:
func _gui_input(event: InputEvent):
- if event is InputEventMouseButton and Input.is_action_pressed("click"):
+ if !Globals.spectating and event is InputEventMouseButton and Input.is_action_pressed("click"):
emit_signal("clicked")
+ get_tree().set_input_as_handled()
diff --git a/TextInput.tscn b/TextInput.tscn
new file mode 100644
index 0000000..588b063
--- /dev/null
+++ b/TextInput.tscn
@@ -0,0 +1,106 @@
+[gd_scene load_steps=11 format=2]
+
+[ext_resource path="res://ui/chat/chat_theme.tres" type="Theme" id=1]
+[ext_resource path="res://ui/chat/grayscale.shader" type="Shader" id=2]
+[ext_resource path="res://ui/chat/emojibutton.gd" type="Script" id=3]
+[ext_resource path="res://ui/chat/texteditor.gd" type="Script" id=4]
+[ext_resource path="res://ui/chat/TextInput.gd" type="Script" id=5]
+[ext_resource path="res://assets/emojis/happy.png" type="Texture" id=6]
+[ext_resource path="res://ui/gridmenu/GridMenu.gd" type="Script" id=7]
+
+[sub_resource type="StyleBoxFlat" id=1]
+bg_color = Color( 0.25098, 0.266667, 0.294118, 1 )
+
+[sub_resource type="ShaderMaterial" id=2]
+shader = ExtResource( 2 )
+shader_param/saturation = 0.0
+shader_param/scale = 1.0
+
+[sub_resource type="StyleBoxEmpty" id=3]
+
+[node name="TextInput" type="PanelContainer"]
+anchor_top = 1.0
+anchor_right = 1.0
+anchor_bottom = 1.0
+margin_top = -50.0
+theme = ExtResource( 1 )
+custom_styles/panel = SubResource( 1 )
+script = ExtResource( 5 )
+__meta__ = {
+"_edit_lock_": true
+}
+
+[node name="h" type="HBoxContainer" parent="."]
+margin_right = 1422.0
+margin_bottom = 50.0
+custom_constants/separation = 0
+
+[node name="MC" type="MarginContainer" parent="h"]
+margin_right = 1372.0
+margin_bottom = 50.0
+size_flags_horizontal = 3
+custom_constants/margin_right = 5
+custom_constants/margin_left = 5
+
+[node name="placeholder" type="Label" parent="h/MC"]
+margin_left = 5.0
+margin_top = 15.0
+margin_right = 131.0
+margin_bottom = 35.0
+size_flags_horizontal = 0
+custom_colors/font_color = Color( 1, 1, 1, 0.509804 )
+text = "write text here"
+valign = 2
+
+[node name="text" type="TextEdit" parent="h/MC"]
+margin_left = 5.0
+margin_top = 15.0
+margin_right = 1367.0
+margin_bottom = 35.0
+rect_min_size = Vector2( 200, 20 )
+size_flags_vertical = 4
+context_menu_enabled = false
+smooth_scrolling = true
+wrap_enabled = true
+caret_blink = true
+script = ExtResource( 4 )
+max_lines = 4
+
+[node name="MC2" type="MarginContainer" parent="h"]
+margin_left = 1372.0
+margin_right = 1422.0
+margin_bottom = 50.0
+size_flags_horizontal = 8
+size_flags_vertical = 0
+
+[node name="EmojiButton" type="TextureButton" parent="h/MC2"]
+material = SubResource( 2 )
+margin_right = 50.0
+margin_bottom = 50.0
+rect_min_size = Vector2( 50, 50 )
+focus_mode = 1
+mouse_default_cursor_shape = 2
+enabled_focus_mode = 1
+texture_normal = ExtResource( 6 )
+expand = true
+script = ExtResource( 3 )
+offset = Vector2( -180, -180 )
+
+[node name="Popup" type="PopupPanel" parent="h/MC2/EmojiButton"]
+margin_right = 40.0
+margin_bottom = 40.0
+custom_styles/panel = SubResource( 3 )
+
+[node name="EmojiMenu" type="GridContainer" parent="h/MC2/EmojiButton/Popup"]
+margin_right = 40.0
+margin_bottom = 40.0
+custom_constants/vseparation = 10
+custom_constants/hseparation = 10
+script = ExtResource( 7 )
+
+[connection signal="send" from="h/MC/text" to="." method="_on_text_send"]
+[connection signal="text_changed" from="h/MC/text" to="." method="_on_text_changed"]
+[connection signal="emoji_selected" from="h/MC2/EmojiButton" to="h/MC/text" method="_emoji_selected"]
+[connection signal="mouse_entered" from="h/MC2/EmojiButton" to="h/MC2/EmojiButton" method="_focused" binds= [ true ]]
+[connection signal="mouse_exited" from="h/MC2/EmojiButton" to="h/MC2/EmojiButton" method="_focused" binds= [ false ]]
+[connection signal="pressed" from="h/MC2/EmojiButton/Popup/EmojiMenu" to="h/MC2/EmojiButton" method="_on_EmojiMenu_pressed"]
diff --git a/Utils.gd b/Utils.gd
index a05ae2d..fd10f2a 100644
--- a/Utils.gd
+++ b/Utils.gd
@@ -17,6 +17,7 @@ func _on_turn_over() -> void:
fen = Fen.get_fen()
Log.info("fen: " + fen)
emit_signal("newfen", fen)
+ SaveLoad.save_dict("user://game.json", {"fen": fen, "pgn": get_pgn()}, true)
func pop_move() -> String:
@@ -124,8 +125,8 @@ static func get_node_name(node: Node) -> Array:
func request() -> int: # returns err
var http := HTTPRequest.new()
add_child(http)
- var httpurl := Network.url.replace("wss://", "http://")
- var error := http.request(httpurl)
+ var httpurl: String = PacketHandler.url.replace("wss://", "http://")
+ var error := http.request(httpurl, [], true, HTTPClient.METHOD_POST)
http.free()
internet = error == OK
return error
diff --git a/assets/emojis/3dots.png b/assets/emojis/3dots.png
new file mode 100644
index 0000000..733bebb
--- /dev/null
+++ b/assets/emojis/3dots.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c7661ec9462c56fc1bcfb5a7b2dc5ff6283f3457892792230cc3d019e0eab694
+size 187
diff --git a/assets/emojis/3dots.png.import b/assets/emojis/3dots.png.import
new file mode 100644
index 0000000..be3f458
--- /dev/null
+++ b/assets/emojis/3dots.png.import
@@ -0,0 +1,35 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/3dots.png-265edc5f23fc0c6d796ec934ecab4e46.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://assets/emojis/3dots.png"
+dest_files=[ "res://.import/3dots.png-265edc5f23fc0c6d796ec934ecab4e46.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=false
+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/emojis/bigsmile.png b/assets/emojis/bigsmile.png
new file mode 100644
index 0000000..a8ceed8
--- /dev/null
+++ b/assets/emojis/bigsmile.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f9817c119db6cb4785e6e1ca071fe5e82035fce02c3362e037d478480dcca0ad
+size 196
diff --git a/assets/emojis/bigsmile.png.import b/assets/emojis/bigsmile.png.import
new file mode 100644
index 0000000..b60b70e
--- /dev/null
+++ b/assets/emojis/bigsmile.png.import
@@ -0,0 +1,35 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/bigsmile.png-37d595856c6fae91b765da3fbb2b16cf.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://assets/emojis/bigsmile.png"
+dest_files=[ "res://.import/bigsmile.png-37d595856c6fae91b765da3fbb2b16cf.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=false
+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/emojis/cold.png b/assets/emojis/cold.png
new file mode 100644
index 0000000..138b664
--- /dev/null
+++ b/assets/emojis/cold.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:49947911c27b8570498f406314447c49ee2bdc58bac9e743894781d5a923f0b2
+size 210
diff --git a/assets/emojis/cold.png.import b/assets/emojis/cold.png.import
new file mode 100644
index 0000000..f031a62
--- /dev/null
+++ b/assets/emojis/cold.png.import
@@ -0,0 +1,35 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/cold.png-0cce578f1713b0c54933093400e00150.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://assets/emojis/cold.png"
+dest_files=[ "res://.import/cold.png-0cce578f1713b0c54933093400e00150.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=false
+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/emojis/cry.png b/assets/emojis/cry.png
new file mode 100644
index 0000000..6481a14
--- /dev/null
+++ b/assets/emojis/cry.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:5834e1249c9424535f4bdcb3bc02abfb8ae31580135f648f4472d7b17eece0eb
+size 194
diff --git a/assets/emojis/cry.png.import b/assets/emojis/cry.png.import
new file mode 100644
index 0000000..9a944f5
--- /dev/null
+++ b/assets/emojis/cry.png.import
@@ -0,0 +1,35 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/cry.png-5eea26eebdb21806dd811b40630ca00a.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://assets/emojis/cry.png"
+dest_files=[ "res://.import/cry.png-5eea26eebdb21806dd811b40630ca00a.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=false
+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/emojis/happy.png b/assets/emojis/happy.png
new file mode 100644
index 0000000..84d02dd
--- /dev/null
+++ b/assets/emojis/happy.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:7ee2e81ef530dcdd525d62133d825e1e7da7e8cfee42d2e06dc75f079f1bd3f7
+size 191
diff --git a/assets/emojis/happy.png.import b/assets/emojis/happy.png.import
new file mode 100644
index 0000000..6344300
--- /dev/null
+++ b/assets/emojis/happy.png.import
@@ -0,0 +1,35 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/happy.png-dbd339b0e9993622ba2629b1b1d62332.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://assets/emojis/happy.png"
+dest_files=[ "res://.import/happy.png-dbd339b0e9993622ba2629b1b1d62332.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=false
+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/emojis/hmm.png b/assets/emojis/hmm.png
new file mode 100644
index 0000000..959d290
--- /dev/null
+++ b/assets/emojis/hmm.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:459b1ab2008880d2e37aae0fa9fe86366334b0b458f2189fbe1a30156fe45c62
+size 187
diff --git a/assets/emojis/hmm.png.import b/assets/emojis/hmm.png.import
new file mode 100644
index 0000000..a2edef7
--- /dev/null
+++ b/assets/emojis/hmm.png.import
@@ -0,0 +1,35 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/hmm.png-60dd2211e19c2fc4717bcd6c242d9de5.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://assets/emojis/hmm.png"
+dest_files=[ "res://.import/hmm.png-60dd2211e19c2fc4717bcd6c242d9de5.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=false
+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/emojis/huh.png b/assets/emojis/huh.png
new file mode 100644
index 0000000..ebc9477
--- /dev/null
+++ b/assets/emojis/huh.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:92958f71129436470d563dc6a26f7ebf41534b88918ae2d3d5a6e976e97cec23
+size 185
diff --git a/assets/emojis/huh.png.import b/assets/emojis/huh.png.import
new file mode 100644
index 0000000..a2e68da
--- /dev/null
+++ b/assets/emojis/huh.png.import
@@ -0,0 +1,35 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/huh.png-67b14d49681c9c51c118c83fbd509ad0.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://assets/emojis/huh.png"
+dest_files=[ "res://.import/huh.png-67b14d49681c9c51c118c83fbd509ad0.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=false
+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/emojis/smile.png b/assets/emojis/smile.png
new file mode 100644
index 0000000..c1bbb0c
--- /dev/null
+++ b/assets/emojis/smile.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:2d61ce5475c851b2b7b0d84a3537e417cb1acaf075b3f93965cce5e477af51cb
+size 187
diff --git a/assets/emojis/smile.png.import b/assets/emojis/smile.png.import
new file mode 100644
index 0000000..9bc9691
--- /dev/null
+++ b/assets/emojis/smile.png.import
@@ -0,0 +1,35 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/smile.png-27d755ca199321b47ecec446fbc5d653.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://assets/emojis/smile.png"
+dest_files=[ "res://.import/smile.png-27d755ca199321b47ecec446fbc5d653.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=false
+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/emojis/unhappy.png b/assets/emojis/unhappy.png
new file mode 100644
index 0000000..3491a67
--- /dev/null
+++ b/assets/emojis/unhappy.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:aeaf6bce90e7ab8742b9fbb470f9114d2f3f329ed8d7c3935e87fff5fbc0df42
+size 189
diff --git a/assets/emojis/unhappy.png.import b/assets/emojis/unhappy.png.import
new file mode 100644
index 0000000..d6b71bb
--- /dev/null
+++ b/assets/emojis/unhappy.png.import
@@ -0,0 +1,35 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/unhappy.png-a12fc470e4e81d2afdbd2729a860262b.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://assets/emojis/unhappy.png"
+dest_files=[ "res://.import/unhappy.png-a12fc470e4e81d2afdbd2729a860262b.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=false
+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/emojis/upsidedown_smile.png b/assets/emojis/upsidedown_smile.png
new file mode 100644
index 0000000..d9653be
--- /dev/null
+++ b/assets/emojis/upsidedown_smile.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:47071359f047e3a390ec073b15948218fdf24e62461402d76be162619590d4fa
+size 188
diff --git a/assets/emojis/upsidedown_smile.png.import b/assets/emojis/upsidedown_smile.png.import
new file mode 100644
index 0000000..166fed8
--- /dev/null
+++ b/assets/emojis/upsidedown_smile.png.import
@@ -0,0 +1,35 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/upsidedown_smile.png-c7866fffad0bf377cf32ef6308457098.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://assets/emojis/upsidedown_smile.png"
+dest_files=[ "res://.import/upsidedown_smile.png-c7866fffad0bf377cf32ef6308457098.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=false
+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/emojis/weary.png b/assets/emojis/weary.png
new file mode 100644
index 0000000..7d04786
--- /dev/null
+++ b/assets/emojis/weary.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ee819f32b56d9ec678a534d18aba356492ab485a2271864997275ba3e8dbf6dc
+size 195
diff --git a/assets/emojis/weary.png.import b/assets/emojis/weary.png.import
new file mode 100644
index 0000000..c1c1fcd
--- /dev/null
+++ b/assets/emojis/weary.png.import
@@ -0,0 +1,35 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/weary.png-b27709e5f2dde47a64e943a8c9409597.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://assets/emojis/weary.png"
+dest_files=[ "res://.import/weary.png-b27709e5f2dde47a64e943a8c9409597.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=false
+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/emojis/what.png b/assets/emojis/what.png
new file mode 100644
index 0000000..10a95a2
--- /dev/null
+++ b/assets/emojis/what.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:37751748c271c93743cbdde075531dc24b9a7bf81236e67cc48952154ddf8d8f
+size 190
diff --git a/assets/emojis/what.png.import b/assets/emojis/what.png.import
new file mode 100644
index 0000000..ad78de9
--- /dev/null
+++ b/assets/emojis/what.png.import
@@ -0,0 +1,35 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/what.png-f4be2dcec75571c42863b35c08940afb.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://assets/emojis/what.png"
+dest_files=[ "res://.import/what.png-f4be2dcec75571c42863b35c08940afb.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=false
+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/emojis/wink.png b/assets/emojis/wink.png
new file mode 100644
index 0000000..018aa2d
--- /dev/null
+++ b/assets/emojis/wink.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:7ef0a033ade24b51e0d6608e148d0b711fd6086c49d69ee824a98e7cdf9a3ae5
+size 189
diff --git a/assets/emojis/wink.png.import b/assets/emojis/wink.png.import
new file mode 100644
index 0000000..d167387
--- /dev/null
+++ b/assets/emojis/wink.png.import
@@ -0,0 +1,35 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/wink.png-e680b178ae3f0c2149ab991ba21f425b.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://assets/emojis/wink.png"
+dest_files=[ "res://.import/wink.png-e680b178ae3f0c2149ab991ba21f425b.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=false
+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/emojis/wink_tongue.png b/assets/emojis/wink_tongue.png
new file mode 100644
index 0000000..365cc6c
--- /dev/null
+++ b/assets/emojis/wink_tongue.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d076f4296dc50cb65df27c11c353644e33bac15ea5eb3f97eb1709d283243087
+size 197
diff --git a/assets/emojis/wink_tongue.png.import b/assets/emojis/wink_tongue.png.import
new file mode 100644
index 0000000..c4dd846
--- /dev/null
+++ b/assets/emojis/wink_tongue.png.import
@@ -0,0 +1,35 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/wink_tongue.png-aac93965a129476ddae8270e19ba524a.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://assets/emojis/wink_tongue.png"
+dest_files=[ "res://.import/wink_tongue.png-aac93965a129476ddae8270e19ba524a.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=false
+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/emojis/wow.png b/assets/emojis/wow.png
new file mode 100644
index 0000000..c618efc
--- /dev/null
+++ b/assets/emojis/wow.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:32d671ba9dec01f7d49dd8c3540b7c09e0b94b1aadb5168058b2b17e9d577a3d
+size 189
diff --git a/assets/emojis/wow.png.import b/assets/emojis/wow.png.import
new file mode 100644
index 0000000..94b076e
--- /dev/null
+++ b/assets/emojis/wow.png.import
@@ -0,0 +1,35 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/wow.png-764db233f7502e13012a9580d7059723.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://assets/emojis/wow.png"
+dest_files=[ "res://.import/wow.png-764db233f7502e13012a9580d7059723.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=false
+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/emojis/zany.png b/assets/emojis/zany.png
new file mode 100644
index 0000000..b281505
--- /dev/null
+++ b/assets/emojis/zany.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:68225d350d6d05b5ce8b39cd83759477dbdee38f775e932189ef4b8423b995f2
+size 205
diff --git a/assets/emojis/zany.png.import b/assets/emojis/zany.png.import
new file mode 100644
index 0000000..562b47f
--- /dev/null
+++ b/assets/emojis/zany.png.import
@@ -0,0 +1,35 @@
+[remap]
+
+importer="texture"
+type="StreamTexture"
+path="res://.import/zany.png-4608f795480fa8c4814644f3e9749b86.stex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://assets/emojis/zany.png"
+dest_files=[ "res://.import/zany.png-4608f795480fa8c4814644f3e9749b86.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=false
+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/export_presets.cfg b/export_presets.cfg
index e3fd4f7..cd7d978 100644
--- a/export_presets.cfg
+++ b/export_presets.cfg
@@ -39,7 +39,7 @@ runnable=true
custom_features=""
export_filter="all_resources"
include_filter="COPYING.md, LICENSE"
-exclude_filter="assets/pieces/alpha/*, assets/pieces/cburnett/*, assets/pieces/fresca/*, assets/pieces/governor/*, assets/pieces/horsey/*, assets/pieces/libra/*, assets/pieces/maestro/*, assets/pieces/pixel/*"
+exclude_filter="assets/pieces/alpha/*, assets/pieces/governor/*, assets/pieces/horsey/*, assets/pieces/libra/*, assets/pieces/maestro/*, assets/pieces/pixel/*"
export_path=""
script_export_mode=1
script_encryption_key=""
diff --git a/networking/Network.gd b/networking/Network.gd
index 741ea5f..fdba7a9 100644
--- a/networking/Network.gd
+++ b/networking/Network.gd
@@ -2,63 +2,26 @@ extends Node
class_name Network
var ws := WebSocketClient.new()
-var game_code := ""
var connected := false
-const HEADERS := {
- "joinrequest": "J",
- "hostrequest": "H",
- "stopgame": "K",
- "signup": "C",
- "signin": ">",
- "relay": "R", # relay goes to both
- "signal": "S", # signal is one way
- "loadpgn": "L", # server telling me to load a pgn
- "info": "I",
- "move": "M",
- "undo": "<",
- "spectate": "0" # its a eye you see
-}
-
-const RELAYHEADERS := {chat = "C"}
-const SIGNALHEADERS := {takeback = "T", draw = "D", resign = "R", info = "I"} # subheaders for HEADERS.signal
-
-var notation := ""
-
-signal start_game
-signal move_data(data)
-signal host_result(result)
-signal join_result(result)
signal game_over(problem, isok)
signal connection_established
-signal signal_recieved(what)
-signal chat(text)
-signal undo(undo)
-signal info_recieved(info)
-
-## for accounts(mostly)
-signal signinresult(what)
-signal signupresult(what)
const url := "wss://gd-chess-server.herokuapp.com/"
-func _ready() -> void:
- yield(get_tree(), "idle_frame") # wait a frame
+func _ready():
+ SaveLoad.save_string("user://network_log.log", "") # overwrite last log
+
+
+func open() -> void:
+ ws.connect_to_url(url)
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")
- ws.connect_to_url(url)
-
-
-func signin(data):
- send_packet(data, HEADERS.signin)
-
-
-func signup(data):
- send_packet(data, HEADERS.signup)
+ Log.net("OPEN NETWORK: " + url)
func close() -> void:
@@ -66,13 +29,14 @@ func close() -> void:
func _connection_established(_protocol) -> void:
+ Log.net("CONNECTED TO %s" % url)
+ emit_signal("connection_established") # bubble the signal up
connected = true
- emit_signal("connection_established")
- Log.debug("Connected to server %s..." % url)
func _connection_closed(_was_clean_closed) -> void:
connected = false
+ Log.net("DISCONNECTED FROM %s" % url)
Log.err("Connection closed")
emit_signal("game_over", "Connection closed", false)
@@ -80,93 +44,12 @@ func _connection_closed(_was_clean_closed) -> void:
func _connection_error() -> void:
connected = false
Log.err("Connection error")
+ Log.net("DISCONNECTED FROM %s" % url)
emit_signal("game_over", "Connection error", false)
-func signal(body: Dictionary, header: String, _mainheader := HEADERS.signal) -> Dictionary:
- var data: Dictionary = Utils.append_dict({"type": header}, body)
- send_gamecode_packet(data, _mainheader)
- return data
-
-
-func join_game(game: String = game_code) -> void:
- send_gamecode_packet(SaveLoad.get_public_info(), HEADERS.joinrequest, game)
-
-
-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)
-
-
-func relay_signal(body: Dictionary, header: String, _mainheader := HEADERS.relay) -> Dictionary: # its really the same thing as signal()
- return signal(body, header, _mainheader)
-
-
-func send_mov(mov: Move):
- send_packet({move = mov.compile(), gamecode = game_code}, HEADERS.move)
-
-
-func stopgame(reason: String) -> void:
- send_packet({"reason": reason, "gamecode": game_code}, HEADERS.stopgame)
-
-
-func _data_recieved() -> void:
- var recieve: Dictionary = ws.get_peer(1).get_var()
- var header: String = recieve.header
- var text = recieve.data
- match header:
- HEADERS.undo:
- emit_signal("undo", text)
- HEADERS.move:
- if !OS.is_window_focused():
- OS.request_attention()
- emit_signal("move_data", text.move)
- HEADERS.hostrequest:
- emit_signal("host_result", text)
- HEADERS.relay:
- var relay: Dictionary = text
- match relay.type:
- RELAYHEADERS.chat:
- emit_signal("chat", relay)
- HEADERS.joinrequest:
- emit_signal("join_result", text)
- 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")
- Log.info("load pgn " + text)
- Globals.grid.play_pgn(text, true) # call deferred wont work since grid obj may be null
- HEADERS.stopgame:
- if !PacketHandler.leaving: # dont emit the signal if its a stophost thing (HACK)
- emit_signal("game_over", text, true)
- PacketHandler.leaving = false
- HEADERS.signal:
- var signal: Dictionary = text
- match signal.type:
- _:
- emit_signal("signal_recieved", signal)
- HEADERS.signup:
- emit_signal("signupresult", text)
- HEADERS.signin:
- emit_signal("signinresult", text)
- _:
- Log.err("unknown header %s" % header)
+func _data_recieved():
+ pass
func _process(_delta: float) -> void:
@@ -176,7 +59,10 @@ func _process(_delta: float) -> void:
func send_packet(variant, header: String) -> void:
+ var pckt = {header = header, data = variant}
if ws.get_peer(1).is_connected_to_host():
- ws.get_peer(1).put_var({"header": header, "data": variant})
+ ws.get_peer(1).put_var(pckt)
+ Log.net("SENT: %s" % pckt)
else:
- Log.err("not connected to server: packet %s not sent" % variant)
+ Log.err("not connected to server: packet %s not sent" % pckt)
+ Log.net("FAILED SEND: %s" % pckt)
diff --git a/networking/PacketHandler.gd b/networking/PacketHandler.gd
index 5806126..01f410b 100644
--- a/networking/PacketHandler.gd
+++ b/networking/PacketHandler.gd
@@ -1,10 +1,36 @@
-extends Node
-class_name NetManager
+extends Network
var lobby: Lobby = null
signal hosting(newhosting)
-signal game_over
-signal game_started
+signal signal_recieved(what)
+signal chat(text)
+signal undo(undo)
+signal info_recieved(info)
+signal start_game
+signal move_data(data)
+## for accounts(mostly)
+signal signinresult(what)
+signal signupresult(what)
+
+const HEADERS := {
+ "joinrequest": "J",
+ "hostrequest": "H",
+ "stopgame": "K",
+ "signup": "C",
+ "signin": ">",
+ "relay": "R", # relay goes to both
+ "signal": "S", # signal is one way
+ "loadpgn": "L", # server telling me to load a pgn
+ "info": "I",
+ "move": "M",
+ "undo": "<",
+ "spectate": "0" # its a eye you see
+}
+
+var game_code := ""
+
+const RELAYHEADERS := {chat = "C"}
+const SIGNALHEADERS := {takeback = "T", draw = "D", resign = "R", info = "I"} # subheaders for HEADERS.signal
var hosting := false setget set_hosting
var leaving := false
@@ -18,7 +44,7 @@ func set_hosting(newhosting: bool) -> void:
func return() -> void: # return to the void
if hosting:
leaving = true
- Globals.network.stopgame("") # stop hosting
+ stopgame("") # stop hosting
lobby.set_status("", true)
set_hosting(false)
lobby.set_buttons(true)
@@ -26,29 +52,81 @@ func return() -> void: # return to the void
func _ready() -> void:
if Utils.internet and get_tree().get_root().has_node("StartMenu"):
- var net := Network.new()
- Events.connect("go_back", self, "_handle_game_over")
- net.connect("join_result", self, "_on_join_result")
- net.connect("host_result", self, "_on_host_result")
- net.connect("game_over", self, "_handle_game_over")
- net.connect("start_game", self, "_start_game")
- net.connect("connection_established", self, "network_ready")
- add_child(net)
- Globals.network = net
yield(get_tree().create_timer(.1), "timeout")
+ open() # open connection
lobby.set_status("Connecting", true)
-func network_ready() -> void:
+func _data_recieved() -> void:
+ var data = ws.get_peer(1).get_var()
+ Log.net(["RECIEVED:", data])
+ var header: String = data.header
+ var text = data.data
+ match header:
+ HEADERS.undo:
+ emit_signal("undo", text)
+ HEADERS.move:
+ if !OS.is_window_focused() and !Debug.debug: # dont be annoying in debug mode
+ OS.request_attention()
+ emit_signal("move_data", text.move)
+ HEADERS.hostrequest:
+ host_result(text)
+ HEADERS.relay:
+ var relay: Dictionary = text
+ match relay.type:
+ RELAYHEADERS.chat:
+ emit_signal("chat", relay)
+ HEADERS.joinrequest:
+ join_result(text)
+ HEADERS.info:
+ yield(get_tree().create_timer(.5), "timeout")
+ emit_signal("info_recieved", text)
+ HEADERS.spectate:
+ # handle spectate here
+ if typeof(text) == TYPE_STRING: # ew error
+ lobby.set_status(text, false)
+ lobby.set_buttons(true)
+ return
+ Globals.spectating = true
+ _start_game()
+ yield(get_tree().create_timer(.5), "timeout")
+ Globals.grid.play_pgn(text.pgn, true)
+ emit_signal("info_recieved", text)
+ HEADERS.loadpgn:
+ _start_game()
+ yield(get_tree().create_timer(.5), "timeout")
+ Log.info("load pgn " + text)
+ Globals.grid.play_pgn(text, true) # call deferred wont work since grid obj may be null
+ HEADERS.stopgame:
+ if !leaving: # dont emit the signal if its a stophost thing (HACK)
+ emit_signal("game_over", text, true)
+ leaving = false
+ HEADERS.signal:
+ var signal: Dictionary = text
+ match signal.type:
+ _:
+ emit_signal("signal_recieved", signal)
+ HEADERS.signup:
+ emit_signal("signupresult", text)
+ HEADERS.signin:
+ emit_signal("signinresult", text)
+ _:
+ Log.err("unknown header %s" % header)
+
+
+func _connection_established(protocol) -> void:
+ ._connection_established(protocol)
lobby.set_status("", true)
lobby.set_buttons(true)
-func _on_join_result(accepted) -> void:
- handle_result(accepted, "Joined!")
+func join_result(accepted) -> void:
+ if handle_result(accepted, "Joined!"):
+ yield(get_tree(), "idle_frame")
+ Globals.grid.flip_board() # joine should be black; flip the board
-func _on_host_result(accepted) -> void:
+func host_result(accepted) -> void:
set_hosting(handle_result(accepted, "Hosted!"))
@@ -63,7 +141,7 @@ func handle_result(accepted, resultstring: String) -> bool:
func _handle_game_over(error := "game over", isok := true) -> void:
- Globals.network.stopgame(error)
+ stopgame(error)
Globals.reset_vars()
if has_node("/root/Game"):
get_node("/root/Game").queue_free()
@@ -78,5 +156,48 @@ func _start_game() -> void:
var board: Control = load("res://Game.tscn").instance()
get_tree().get_root().add_child(board)
lobby.toggle(false)
- emit_signal("game_started")
+ emit_signal("start_game")
lobby.set_buttons(false)
+
+
+## packet sending wrapper functions
+func signin(data):
+ send_packet(data, HEADERS.signin)
+
+
+func signup(data):
+ send_packet(data, HEADERS.signup)
+
+
+func signal(body: Dictionary, header: String, _mainheader := HEADERS.signal) -> Dictionary:
+ var data: Dictionary = Utils.append_dict({"type": header}, body)
+ send_gamecode_packet(data, _mainheader)
+ return data
+
+
+func join_game(game: String = game_code) -> void:
+ send_gamecode_packet(SaveLoad.get_public_info(), HEADERS.joinrequest, game)
+
+
+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)
+
+
+func relay_signal(body: Dictionary, header: String) -> Dictionary: # its really the same thing as signal()
+ return signal(body, header, HEADERS.relay)
+
+
+func send_mov(mov: Move):
+ send_packet({move = mov.compile(), gamecode = game_code}, HEADERS.move)
+
+
+func stopgame(reason: String) -> void:
+ send_packet({"reason": reason, "gamecode": game_code}, HEADERS.stopgame)
diff --git a/pieces/N.gd b/pieces/N.gd
index dfb05c8..16dc101 100644
--- a/pieces/N.gd
+++ b/pieces/N.gd
@@ -16,9 +16,7 @@ func get_moves(no_enemys := false, check_spots_check := true) -> PoolVector2Arra
var final: PoolVector2Array = []
for i in moves:
if is_on_board(i):
- if no_enemys and at_pos(i):
- continue
- if check_spots_check and checkcheck(i):
+ if no_enemys and at_pos(i) or (check_spots_check and checkcheck(i)):
continue
final.append(i)
return final
diff --git a/pieces/P.gd b/pieces/P.gd
index 73de650..55c62d9 100644
--- a/pieces/P.gd
+++ b/pieces/P.gd
@@ -50,20 +50,20 @@ func moveto(position: Vector2, instant := false) -> void:
func get_moves(_var := false, check_spots_check := true) -> PoolVector2Array:
- var points := [Vector2.UP, Vector2.UP * 2]
+ var points: PoolVector2Array = [Vector2.UP, Vector2.UP * 2]
var moves: PoolVector2Array = []
for i in range(len(points)):
- var point: Vector2 = points[i]
+ var point := points[i]
point *= whiteint
point = pos_around(point)
if at_pos(point) == null:
- if i == 1:
- if has_moved or at_pos(pos_around(points[0] * whiteint)) != null:
- continue
- if check_spots_check and checkcheck(point):
+ if (
+ (i == 1 and (has_moved or at_pos(pos_around(points[0] * whiteint)) != null))
+ or (check_spots_check and checkcheck(point))
+ or !is_on_board(point)
+ ):
continue
- if is_on_board(point):
- moves.append(point)
+ moves.append(point)
moves.append_array(en_passant())
return moves
@@ -90,30 +90,26 @@ func get_attacks(check_spots_check := true) -> PoolVector2Array:
var point: Vector2 = points[i]
point *= whiteint
point = pos_around(point)
- if !is_on_board(point):
+ if at_pos(point) == null or at_pos(point).white == white or (check_spots_check and checkcheck(point)):
continue
- if check_spots_check and checkcheck(point):
- continue
- if at_pos(point) != null and at_pos(point).white != white:
- moves.append(point)
- en_passant() # for the fen
+ moves.append(point)
return moves
func en_passant(turncheck := true, check_spots_check := true) -> Array: # in passing
+ if turncheck and white != Globals.turn:
+ return []
var passants := [pos_around(Vector2.LEFT), pos_around(Vector2.RIGHT)]
var moves := []
for i in passants:
var spot := at_pos(i)
- if !spot:
- continue
- if spot.white == white or !Utils.is_pawn(spot):
- continue
- if turncheck and white != Globals.turn:
- continue
- if !spot.just_double_stepped:
- continue
- if check_spots_check and checkcheck(i):
+ if (
+ !spot # spot doesnt exist
+ or spot.white == white # spot is my team
+ or !Utils.is_pawn(spot) #spot isnt a pawn
+ or !spot.just_double_stepped # spot didnt just double step
+ or (check_spots_check and checkcheck(i))
+ ): # moving there would put me in check
continue
var position: Vector2 = i + (Vector2.UP * whiteint)
if !at_pos(position):
@@ -124,12 +120,12 @@ func en_passant(turncheck := true, check_spots_check := true) -> Array: # in pa
func promote(position: Vector2, type: String) -> void:
if type == "take":
- at_pos(position).hide()
+ at_pos(position).hide() # only hide the visuals
move(position) # only move the visuals
- promoteposition = position
- darken.show()
- yield(tween, "tween_completed")
- open_previews()
+ promoteposition = position # save the position
+ darken.show() # open fx
+ yield(tween, "tween_completed") # wait till were done moving to the new position
+ open_previews() # open the previews
func promote_to(promote_to: int, is_capture: bool, position: Vector2, instant := false):
@@ -146,7 +142,7 @@ func _pressed(promote_to: String) -> void:
var is_cap = at_pos(promoteposition) != null
var mov = Move.new(SanParser.PAWN, [real_position, promoteposition], is_cap)
mov.promotion = SanParse.from_str(promote_to)
- Globals.network.send_mov(mov)
+ PacketHandler.send_mov(mov)
func _on_turn_over() -> void:
diff --git a/pieces/Piece.gd b/pieces/Piece.gd
index dddc5db..5fa6f2c 100644
--- a/pieces/Piece.gd
+++ b/pieces/Piece.gd
@@ -27,12 +27,14 @@ func _ready() -> void:
rect_pivot_offset = Globals.grid.piece_size / 2
frame.modulate = Globals.grid.overlay_color
colorrect.color = Globals.grid.overlay_color
+ load_texture()
+
+ # for undos
sprite.flip_v = Globals.grid.flipped
sprite.flip_h = Globals.grid.flipped
- load_texture()
-func set_zindex(zindex: int, obj: CanvasItem = self):
+func set_zindex(zindex: int, obj: CanvasItem = self): # used by the animation player
VisualServer.canvas_item_set_z_index(obj.get_canvas_item(), zindex)
@@ -128,13 +130,11 @@ static func at_pos(vector: Vector2) -> Piece:
func can_move() -> bool: # checks if you can legally move
- if get_moves().size() != 0 or get_attacks().size() != 0:
- return true
- return false
+ return not get_moves().empty() or not get_attacks().empty()
-func get_moves(_no_enemys := false, _check_spots_check := true) -> PoolVector2Array: # @Override
- return PoolVector2Array()
+func get_moves(_no_enemys := false, _check_spots_check := true) -> PoolVector2Array: # plz override
+ return all_dirs()
func get_attacks(check_spots_check := true) -> PoolVector2Array: # @Override
@@ -186,6 +186,8 @@ static func set_circle(positions: Array, type := "move") -> void:
func checkcheck(pos) -> bool: # moves to position, then checks if your king is in check
# TODO: figure out why this function isnt working with can_move()
+ if Globals.turn != white:
+ Log.err("@checkcheck: %s != %s" % [Globals.turn, white])
var mat: Array = Globals.grid.matrix.duplicate(true) # make a copy of the matrix
Globals.grid.matrix[real_position.y][real_position.x] = null # remove the piece from the matrix
Globals.grid.matrix[pos.y][pos.x] = self # move the piece to the new position
diff --git a/project.godot b/project.godot
index 41b022f..7f23283 100644
--- a/project.godot
+++ b/project.godot
@@ -54,6 +54,11 @@ _global_script_classes=[ {
"language": "GDScript",
"path": "res://ui/barbutton/drawbutton.gd"
}, {
+"base": "TextEdit",
+"class": "ExpandableTextEdit",
+"language": "GDScript",
+"path": "res://ui/chat/ExpandableTextEdit.gd"
+}, {
"base": "Node",
"class": "FEN",
"language": "GDScript",
@@ -104,17 +109,17 @@ _global_script_classes=[ {
"language": "GDScript",
"path": "res://ui/menus/Lobby.gd"
}, {
+"base": "PanelContainer",
+"class": "MessageList",
+"language": "GDScript",
+"path": "res://MessageList.gd"
+}, {
"base": "Resource",
"class": "Move",
"language": "GDScript",
"path": "res://SanParse/Move.gd"
}, {
"base": "Node",
-"class": "NetManager",
-"language": "GDScript",
-"path": "res://networking/PacketHandler.gd"
-}, {
-"base": "Node",
"class": "Network",
"language": "GDScript",
"path": "res://networking/Network.gd"
@@ -199,6 +204,7 @@ _global_script_class_icons={
"Confirm": "",
"ConfirmButton": "",
"DrawButton": "res://assets/ui/draw.png",
+"ExpandableTextEdit": "",
"FEN": "",
"FENLabel": "",
"FlipButton": "res://assets/ui/flip_board.png",
@@ -209,8 +215,8 @@ _global_script_class_icons={
"King": "res://assets/pieces/california/wK.png",
"Knight": "res://assets/pieces/california/wN.png",
"Lobby": "",
+"MessageList": "",
"Move": "",
-"NetManager": "",
"Network": "",
"OldColorView": "",
"PGN": "",
diff --git a/saveload.gd b/saveload.gd
index 73e1052..f3772d3 100644
--- a/saveload.gd
+++ b/saveload.gd
@@ -4,6 +4,8 @@ class_name SaveLoader
const settings_file := "user://chess.settings"
const id := "user://.chess.id"
+var file: File = File.new()
+
const default_settings_data = {
vsync = OS.vsync_enabled,
fullscreen = OS.window_fullscreen,
@@ -33,43 +35,73 @@ func get_data(type: String) -> Dictionary:
func _ready() -> void:
- # Debug.monitor(self, "id data", "files.id.data")
SaveLoad.load_data("settings")
SaveLoad.load_data("id")
-func to_base64(variant) -> String:
+static func to_base64(variant) -> String:
return Marshalls.variant_to_base64(variant)
-func from_base64(base64: String):
+static func from_base64(base64: String):
return Marshalls.base64_to_variant(base64)
func save(type: String) -> void:
- var file := File.new()
- file.open(files[type]["file"], File.WRITE)
- file.store_string(to_base64(files[type]["data"]))
+ save_dict(files[type]["file"], files[type]["data"])
-func load_data(type: String) -> Dictionary:
- if check_file(type):
- var file := File.new()
- file.open(files[type]["file"], File.READ)
- var text = file.get_as_text()
- if len(text) > 0:
- var read_dictionary = from_base64(text)
- if typeof(read_dictionary) != TYPE_DICTIONARY:
- save(type) # OVERWRITE
- elif files[type]["data"].keys() == read_dictionary.keys():
- files[type]["data"] = read_dictionary
- save(type) # overwrite.
+func save_dict(path: String, data: Dictionary, plain := false) -> void:
+ file.open(path, File.WRITE)
+ file.store_string(var2str(data) if plain else to_base64(data))
+ file.close()
+
+
+func save_string(path: String, string: String) -> void:
+ file.open(path, File.WRITE)
+ file.store_string(string)
+ file.close()
+
+
+func append_string(path: String, string: String) -> void:
+ file.open(path, File.READ_WRITE)
+ file.seek_end()
+ file.store_string("\n%s" % string)
+ file.close()
+
+
+func load_string(path: String) -> String:
+ if file.file_exists(path):
+ file.open(path, File.READ)
+ var string = file.get_as_text()
file.close()
- else:
- save(type)
+ return string
+ return ""
+
+
+func load_data(type: String) -> Dictionary:
+ var read_dictionary = load_file(files[type]["file"])
+ if files[type]["data"].keys() == read_dictionary.keys():
+ files[type]["data"] = read_dictionary
+ save(type) # write over old data
return files[type]["data"]
+func load_file(path: String) -> Dictionary:
+ if file.file_exists(path):
+ file.open(path, File.READ)
+ var text := file.get_as_text()
+ var dict := {}
+ if text:
+ var read_dict = str2var(text)
+ if typeof(read_dict) == TYPE_DICTIONARY: # it may be plaintext
+ dict = read_dict
+ else:
+ dict = from_base64(text)
+ file.close()
+ return dict
+ return {}
+
+
func check_file(type: String) -> bool:
- var file := File.new()
return file.file_exists(files[type]["file"])
diff --git a/ui/barbutton/BarTextureButton.gd b/ui/barbutton/BarTextureButton.gd
index 4bb51e2..3a7e488 100644
--- a/ui/barbutton/BarTextureButton.gd
+++ b/ui/barbutton/BarTextureButton.gd
@@ -17,7 +17,8 @@ func _ready() -> void:
func set_disabled(new: bool) -> void:
disabled = new
- self_modulate = Color(.1, .1, .1, 0.5) if disabled else Color.white
+ self_modulate = Color.gray if disabled else Color.white
+ mouse_default_cursor_shape = CURSOR_FORBIDDEN if disabled else CURSOR_POINTING_HAND
func _input(_event: InputEvent):
diff --git a/ui/barbutton/BarTextureButton.tscn b/ui/barbutton/BarTextureButton.tscn
index f36a2ac..0290105 100644
--- a/ui/barbutton/BarTextureButton.tscn
+++ b/ui/barbutton/BarTextureButton.tscn
@@ -6,11 +6,11 @@
margin_right = 50.0
margin_bottom = 50.0
rect_min_size = Vector2( 50, 50 )
-focus_mode = 1
-enabled_focus_mode = 1
+mouse_default_cursor_shape = 2
expand = true
script = ExtResource( 2 )
normal_color = Color( 0.188235, 0.180392, 0.172549, 1 )
+disabled_color = Color( 0.188235, 0.180392, 0.172549, 1 )
[node name="Background" type="ColorRect" parent="."]
show_behind_parent = true
diff --git a/ui/barbutton/confirmbutton.gd b/ui/barbutton/confirmbutton.gd
index 2b7bc1f..dbf4987 100644
--- a/ui/barbutton/confirmbutton.gd
+++ b/ui/barbutton/confirmbutton.gd
@@ -8,15 +8,16 @@ export(String) var confirm_text = ""
func _ready() -> void:
PacketHandler.connect("game_over", self, "set_disabled", [true])
- if Globals.network:
- Globals.network.connect("signal_recieved", self, "_signal_recieved")
+ if PacketHandler:
+ PacketHandler.connect("signal_recieved", self, "_signal_recieved")
func confirm() -> void:
- var confirm = Confirm.instance()
- add_child(confirm)
- confirm.confirm(self, confirm_text, 20)
- waiting_on_answer = confirm
+ if !waiting_on_answer:
+ var confirm = Confirm.instance()
+ add_child(confirm)
+ confirm.confirm(self, confirm_text, 20)
+ waiting_on_answer = confirm
func _signal_recieved(_signal: Dictionary) -> void:
diff --git a/ui/barbutton/drawbutton.gd b/ui/barbutton/drawbutton.gd
index d70f877..14f4f57 100644
--- a/ui/barbutton/drawbutton.gd
+++ b/ui/barbutton/drawbutton.gd
@@ -1,16 +1,22 @@
extends ConfirmButton
class_name DrawButton, "res://assets/ui/draw.png"
+const draw_declined_message = "draw request rejected"
+const draw_request_message = "%s requests a draw"
+
func _signal_recieved(what: Dictionary) -> void:
- if what.type == Network.SIGNALHEADERS.draw:
+ if what.type == PacketHandler.SIGNALHEADERS.draw:
+ set_disabled(false)
if "question" in what:
confirm()
+ Globals.chat.server(draw_request_message % Globals.str_bool(!Globals.team))
else:
if what.accepted:
drawed()
else:
- Globals.chat.server("Draw request rejected")
+ # declined signal recieved
+ Globals.chat.server(draw_declined_message)
func drawed() -> GDScriptFunctionState:
@@ -23,12 +29,16 @@ func _pressed() -> void:
if waiting_on_answer:
_confirmed(true)
else:
- Globals.network.signal({"question": ""}, Network.SIGNALHEADERS.draw)
- Globals.chat.server("Draw request sent")
+ set_disabled(true)
+ PacketHandler.signal({"question": ""}, PacketHandler.SIGNALHEADERS.draw)
+ Globals.chat.server(draw_request_message % Globals.get_team())
func _confirmed(what: bool) -> void: # called from confirmbar.confirmed
._confirmed(what)
- Globals.network.signal({"accepted": what}, Network.SIGNALHEADERS.draw)
+ PacketHandler.signal({"accepted": what}, PacketHandler.SIGNALHEADERS.draw)
if what:
drawed()
+ else:
+ # no pressed
+ Globals.chat.server(draw_declined_message)
diff --git a/ui/barbutton/resignbutton.gd b/ui/barbutton/resignbutton.gd
index 7e47973..e84569d 100644
--- a/ui/barbutton/resignbutton.gd
+++ b/ui/barbutton/resignbutton.gd
@@ -3,7 +3,7 @@ class_name ResignButton, "res://assets/ui/flag.png"
func _signal_recieved(what: Dictionary) -> void:
- if what.type == Network.SIGNALHEADERS.resign:
+ if what.type == PacketHandler.SIGNALHEADERS.resign:
Globals.grid.win(Globals.team, "resignation")
@@ -17,6 +17,6 @@ func _pressed() -> void:
func after_confirmed():
- Globals.network.signal({}, Network.SIGNALHEADERS.resign)
+ PacketHandler.signal({}, PacketHandler.SIGNALHEADERS.resign)
Globals.grid.win(!Globals.team, "resignation")
disabled = true
diff --git a/ui/barbutton/undobutton.gd b/ui/barbutton/undobutton.gd
index 6c56327..6788c5e 100644
--- a/ui/barbutton/undobutton.gd
+++ b/ui/barbutton/undobutton.gd
@@ -2,14 +2,16 @@ extends ConfirmButton
class_name UndoButton, "res://assets/ui/undo.png"
export(NodePath) onready var status = get_node(status) as StatusLabel
+const undo_request_message = "%s requested a undo"
+const undo_declined_message = "undo declined"
-func _ready():
- if Globals.network:
- Globals.network.connect("undo", self, "undo_recieved")
+func _ready() -> void:
+ if PacketHandler:
+ PacketHandler.connect("undo", self, "undo_signal_recieved")
-func _pressed():
+func _pressed() -> void:
if Globals.spectating:
return
if waiting_on_answer:
@@ -21,29 +23,45 @@ 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)
- status.set_text("Undo request sent")
+ PacketHandler.send_packet({gamecode = PacketHandler.game_code, question = ""}, PacketHandler.HEADERS.undo)
+ Globals.chat.server(undo_request_message % Globals.get_team())
+ set_disabled(true)
-func undo_recieved(sig: Dictionary) -> void:
+func undo_signal_recieved(sig: Dictionary) -> void:
if "question" in sig:
+ Globals.chat.server(undo_request_message % Globals.str_bool(!Globals.team))
confirm()
else:
+ set_disabled(false)
if sig.accepted:
undo()
else:
- Globals.chat.server("Undo request declined")
+ # declined signal reception
+ Globals.chat.server(undo_declined_message)
func _confirmed(what: bool) -> void:
._confirmed(what)
- Globals.network.send_packet({gamecode = Globals.network.game_code, accepted = what}, Network.HEADERS.undo)
+ PacketHandler.send_packet({gamecode = PacketHandler.game_code, accepted = what}, PacketHandler.HEADERS.undo)
if what:
undo()
+ else:
+ # pressed no reception
+ Globals.chat.server(undo_declined_message)
func undo():
- var mov = Utils.pop_move()
- Globals.chat.server("Move %s undone" % mov)
- Globals.grid.undo(mov)
+ var numberex = SanParse.compile("([0-9]+)\\.", false)
+ var which_move = 0
+ var mov = Utils.moves_list[-1]
+ var result = numberex.search(mov)
+ if result:
+ which_move = result.strings[1]
+ else:
+ result = numberex.search(Utils.moves_list[-2])
+ which_move = result.strings[1] if result else 0
+ var pgn = Utils.pop_move()
+ Globals.chat.server("Move (%s) %s undone" % [which_move, mov.split(" ")[-1]])
+ Globals.grid.undo(pgn)
status.set_text("")
diff --git a/ui/chat/Chat.gd b/ui/chat/Chat.gd
index 2631750..143cedf 100644
--- a/ui/chat/Chat.gd
+++ b/ui/chat/Chat.gd
@@ -1,13 +1,9 @@
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()
+onready var list: MessageList = $v/MessageList
-var tween = Tween.new()
-var regexes: Array = [
+var regexes := [
[compile("_([^_]+)_"), "[i]$1[/i]"],
[compile("\\*\\*([^\\*\\*]+)\\*\\*"), "[b]$1[/b]"],
[compile("\\*([^\\*]+)\\*"), "[i]$1[/i]"],
@@ -17,12 +13,42 @@ var regexes: Array = [
[compile("#([^#]+)#"), "[rainbow freq=.3 sat=.7]$1[/rainbow]"],
[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]"],
+ [compile("([-a-zA-Z0-9@:%._\\+~#=]{2,256}\\.[a-z]{2,6}\\b([-a-zA-Z0-9@:%_\\+.~#?&//=]*))"), "[url]$1[/url]"],
]
-
-
+var emoji_replace_regex := compile(":[^:]{1,15}:")
+
+const piece_emoji_path = "res://assets/pieces/cburnett/"
+const emoji_path = "res://assets/emojis/"
+const emojis := {
+ [":cold:"]: emoji_path + "cold.png",
+ [":bigsmile:"]: emoji_path + "bigsmile.png",
+ [":cry:", ":sad:"]: emoji_path + "cry.png",
+ [":happy:"]: emoji_path + "happy.png",
+ [":hmm:"]: emoji_path + "hmm.png",
+ [":huh:"]: emoji_path + "huh.png",
+ [":smile:"]: emoji_path + "smile.png",
+ [":unhappy:"]: emoji_path + "unhappy.png",
+ [":upsidedown_smile:"]: emoji_path + "upsidedown_smile.png",
+ [":weary:"]: emoji_path + "weary.png",
+ [":what:"]: emoji_path + "what.png",
+ [":wink_tongue:"]: emoji_path + "wink_tongue.png",
+ [":wink:"]: emoji_path + "wink.png",
+ [":wow:"]: emoji_path + "wow.png",
+ [":zany:"]: emoji_path + "zany.png",
+ [":...:"]: emoji_path + "3dots.png",
+ [":R:", ":rook:"]: piece_emoji_path + "wR.png",
+ [":N:", ":knight:"]: piece_emoji_path + "wN.png",
+ [":B:", ":bishop:"]: piece_emoji_path + "wB.png",
+ [":Q:", ":queen:"]: piece_emoji_path + "wQ.png",
+ [":K:", ":king:"]: piece_emoji_path + "wK.png",
+ [":P:", ":pawn:"]: piece_emoji_path + "wP.png",
+}
+var expanded_emojis = {}
+
+
+# create smokey centered text
func server(txt: String) -> void:
- add_label("[b]server[color=#f0e67e]:[/color] " + md2bb(txt))
+ list.add_label("[center][b][color=#a9a9a9]%s[/color][/b][/center]" % md2bb(txt))
func _init():
@@ -34,12 +60,16 @@ func _exit_tree():
func _ready():
- if Globals.network:
- Globals.network.connect("chat", self, "add_label_with")
- add_child(tween)
+ for trigger_list in emojis:
+ for trigger in trigger_list:
+ expanded_emojis[trigger] = emojis[trigger_list]
+
+ if PacketHandler:
+ PacketHandler.connect("chat", self, "add_label_with")
server("Welcome!")
yield(get_tree().create_timer(.4), "timeout")
server("You can use markdown(sort of)!")
+ $v/TextInput.setup_emojis(emojis)
static func compile(src: String) -> RegEx:
@@ -48,41 +78,21 @@ static func compile(src: String) -> RegEx:
return regex
-func add_label_with(data):
- var string = "[b]%s[color=#f0e67e]:[/color][/b] %s" % [data.who, data.text]
- add_label(string)
-
+func add_label_with(data: Dictionary) -> void:
+ var string := "[b]{who}[color=#f0e67e]:[/color][/b] {text}".format(data)
+ list.add_label(string)
-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
- l.scroll_active = false
- 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)
- tween.start()
- return l
-
-func open_url(meta):
- OS.shell_open(meta)
-
-
-func send(_arg = 0):
- var t = text.get_text().strip_edges()
+func send(t: String) -> void:
+ t = t.strip_edges()
if !t:
return
- t = md2bb(t)
- text.text = ""
+ t = md2bb(emoji2bb(t))
var name_data = SaveLoad.get_data("id").name
var name = name_data if name_data else "Anonymous"
name += "(%s)" % ("Spectator" if Globals.spectating else Globals.get_team())
- if Globals.network:
- Globals.network.relay_signal({"text": t, "who": name}, Network.RELAYHEADERS.chat)
+ if PacketHandler:
+ PacketHandler.relay_signal({"text": t, "who": name}, PacketHandler.RELAYHEADERS.chat)
else:
add_label_with({text = t, who = name}) # for testing
@@ -95,13 +105,16 @@ func md2bb(input: String) -> String:
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://
+ if replacement[1] == "[url]$1[/url]" and "png" in result.strings[0]: # url one must avoid recognizing res://
continue
input = replacement[0].sub(input, replacement[1], true)
input = input.replace("\\", "") # remove escapers
return input
-func err(err: String):
- add_label("[b][color=#ff6347]error:[i] %s" % err)
- text.editable = false
+func emoji2bb(input: String) -> String:
+ for i in emoji_replace_regex.search_all(input):
+ var emoji = i.strings[0]
+ if emoji in expanded_emojis:
+ input = input.replace(emoji, "[img=30]%s[/img]" % expanded_emojis[emoji])
+ return input
diff --git a/ui/chat/Chat.tscn b/ui/chat/Chat.tscn
index 3f83ef0..50675f6 100644
--- a/ui/chat/Chat.tscn
+++ b/ui/chat/Chat.tscn
@@ -1,274 +1,35 @@
-[gd_scene load_steps=35 format=2]
+[gd_scene load_steps=5 format=2]
-[ext_resource path="res://assets/ui/whitespace.png" type="Texture" id=1]
+[ext_resource path="res://ui/chat/chat_theme.tres" type="Theme" id=1]
[ext_resource path="res://ui/chat/Chat.gd" type="Script" id=2]
-[ext_resource path="res://assets/ui/verdana-bold.ttf" type="DynamicFontData" id=3]
-[ext_resource path="res://assets/ui/button.png" type="Texture" id=4]
-[ext_resource path="res://assets/ui/send.png" type="Texture" id=5]
-[ext_resource path="res://ui/barbutton/BarTextureButton.tscn" type="PackedScene" id=6]
-[ext_resource path="res://assets/ui/CascadiaCode.ttf" type="DynamicFontData" id=7]
-[ext_resource path="res://ui/theme/flatblack.tres" type="StyleBox" id=8]
-[ext_resource path="res://assets/ui/verdana.ttf" type="DynamicFontData" id=9]
-[ext_resource path="res://assets/ui/checkedbox.png" type="Texture" id=10]
-[ext_resource path="res://ui/theme/transblack.tres" type="StyleBox" id=11]
-[ext_resource path="res://ui/theme/buttonhover.tres" type="StyleBox" id=12]
-[ext_resource path="res://assets/ui/verdana-bold-italic.ttf" type="DynamicFontData" id=13]
-[ext_resource path="res://ui/theme/button.tres" type="StyleBox" id=14]
+[ext_resource path="res://MessageList.tscn" type="PackedScene" id=3]
+[ext_resource path="res://TextInput.tscn" type="PackedScene" id=5]
-[sub_resource type="StyleBoxTexture" id=6]
-texture = ExtResource( 4 )
-region_rect = Rect2( 0, 0, 84, 84 )
-margin_left = 28.0
-margin_right = 28.0
-margin_top = 28.0
-margin_bottom = 28.0
-modulate_color = Color( 0.772549, 0.772549, 0.772549, 0.54902 )
-
-[sub_resource type="StyleBoxEmpty" id=7]
-
-[sub_resource type="StyleBoxEmpty" id=8]
-
-[sub_resource type="StyleBoxEmpty" id=9]
-
-[sub_resource type="StyleBoxEmpty" id=4]
-
-[sub_resource type="StyleBoxFlat" id=3]
-bg_color = Color( 0.0784314, 0.0784314, 0.0784314, 1 )
-border_width_left = 2
-border_width_top = 2
-border_width_right = 2
-border_width_bottom = 2
-border_color = Color( 1, 1, 1, 1 )
-corner_detail = 20
-expand_margin_left = 10.0
-expand_margin_right = 10.0
-
-[sub_resource type="DynamicFont" id=18]
-size = 15
-font_data = ExtResource( 3 )
-
-[sub_resource type="DynamicFont" id=19]
-size = 15
-font_data = ExtResource( 13 )
-
-[sub_resource type="DynamicFont" id=14]
-size = 15
-font_data = ExtResource( 7 )
-
-[sub_resource type="DynamicFont" id=20]
-size = 15
-font_data = ExtResource( 9 )
-
-[sub_resource type="StyleBoxFlat" id=10]
-content_margin_left = 30.0
-content_margin_right = 30.0
-content_margin_top = 30.0
-content_margin_bottom = 30.0
-bg_color = Color( 0, 0, 0, 0.313726 )
-border_blend = true
-corner_radius_top_left = 50
-corner_radius_top_right = 50
-corner_radius_bottom_right = 30
-corner_radius_bottom_left = 30
-corner_detail = 15
-
-[sub_resource type="StyleBoxFlat" id=12]
-content_margin_left = 10.0
-content_margin_right = 10.0
-bg_color = Color( 0, 0, 0, 0.313726 )
-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_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]
-
-[sub_resource type="StyleBoxFlat" id=13]
-content_margin_left = 10.0
-content_margin_right = 10.0
-content_margin_bottom = 10.0
-bg_color = Color( 0, 0, 0, 0.588235 )
-border_width_top = 65
-border_color = Color( 0.180392, 0.180392, 0.180392, 1 )
-corner_radius_top_left = 30
-corner_radius_top_right = 30
-corner_radius_bottom_right = 30
-corner_radius_bottom_left = 30
-corner_detail = 15
-expand_margin_top = 65.0
-
-[sub_resource type="DynamicFont" id=15]
-size = 15
-font_data = ExtResource( 3 )
-
-[sub_resource type="Theme" id=16]
-default_font = SubResource( 15 )
-Button/colors/font_color = Color( 1, 1, 1, 1 )
-Button/colors/font_color_disabled = Color( 1, 1, 1, 0.305882 )
-Button/colors/font_color_focus = Color( 1, 1, 1, 1 )
-Button/colors/font_color_hover = Color( 0, 0, 0, 1 )
-Button/colors/font_color_pressed = Color( 1, 1, 1, 1 )
-Button/styles/disabled = SubResource( 6 )
-Button/styles/focus = ExtResource( 14 )
-Button/styles/hover = ExtResource( 12 )
-Button/styles/normal = ExtResource( 14 )
-Button/styles/pressed = ExtResource( 14 )
-CheckBox/icons/checked = ExtResource( 10 )
-CheckBox/icons/checked_disabled = null
-CheckBox/icons/radio_checked = null
-CheckBox/icons/radio_checked_disabled = null
-CheckBox/icons/radio_unchecked = null
-CheckBox/icons/radio_unchecked_disabled = null
-CheckBox/icons/unchecked = ExtResource( 4 )
-CheckBox/icons/unchecked_disabled = null
-ColorPicker/icons/color_sample = ExtResource( 1 )
-ColorPicker/icons/overbright_indicator = ExtResource( 1 )
-ColorPicker/icons/preset_bg = ExtResource( 1 )
-ColorPicker/icons/screen_picker = ExtResource( 1 )
-ColorPickerButton/colors/font_color = Color( 1, 1, 1, 1 )
-ColorPickerButton/colors/font_color_disabled = Color( 1, 1, 1, 0.301961 )
-ColorPickerButton/colors/font_color_focus = Color( 1, 1, 1, 1 )
-ColorPickerButton/colors/font_color_hover = Color( 1, 1, 1, 1 )
-ColorPickerButton/colors/font_color_pressed = Color( 0.913725, 0.913725, 0.913725, 1 )
-ColorPickerButton/icons/bg = ExtResource( 1 )
-HBoxContainer/constants/separation = 15
-HSlider/styles/grabber_area = SubResource( 7 )
-HSlider/styles/grabber_area_highlight = SubResource( 8 )
-HSlider/styles/slider = SubResource( 9 )
-ItemList/colors/font_color = Color( 1, 1, 1, 1 )
-ItemList/colors/font_color_selected = Color( 0.905882, 0.905882, 0.905882, 1 )
-ItemList/styles/bg = SubResource( 4 )
-ItemList/styles/bg_focus = ExtResource( 8 )
-LineEdit/colors/cursor_color = Color( 1, 1, 1, 1 )
-LineEdit/colors/font_color = Color( 1, 1, 1, 1 )
-LineEdit/colors/font_color_uneditable = Color( 1, 1, 1, 0.67451 )
-LineEdit/styles/focus = ExtResource( 14 )
-LineEdit/styles/normal = ExtResource( 14 )
-LineEdit/styles/read_only = ExtResource( 14 )
-OptionButton/colors/font_color = Color( 1, 1, 1, 1 )
-OptionButton/colors/font_color_focus = Color( 1, 1, 1, 1 )
-OptionButton/colors/font_color_hover = Color( 0, 0, 0, 1 )
-OptionButton/colors/font_color_pressed = Color( 1, 1, 1, 1 )
-OptionButton/icons/arrow = ExtResource( 1 )
-PopupMenu/colors/font_color = Color( 1, 1, 1, 1 )
-PopupMenu/colors/font_color_accel = Color( 1, 1, 1, 0.8 )
-PopupMenu/colors/font_color_hover = Color( 1, 1, 1, 1 )
-PopupMenu/colors/font_color_separator = Color( 0.262745, 0.262745, 0.262745, 1 )
-PopupMenu/icons/radio_checked = ExtResource( 1 )
-PopupMenu/icons/radio_unchecked = ExtResource( 1 )
-PopupMenu/styles/hover = SubResource( 3 )
-PopupMenu/styles/panel = ExtResource( 8 )
-PopupPanel/styles/panel = ExtResource( 11 )
-RichTextLabel/colors/default_color = Color( 1, 1, 1, 1 )
-RichTextLabel/fonts/bold_font = SubResource( 18 )
-RichTextLabel/fonts/bold_italics_font = SubResource( 19 )
-RichTextLabel/fonts/italics_font = SubResource( 19 )
-RichTextLabel/fonts/mono_font = SubResource( 14 )
-RichTextLabel/fonts/normal_font = SubResource( 20 )
-SpinBox/icons/updown = ExtResource( 1 )
-TabContainer/colors/font_color_bg = Color( 0.709804, 0.709804, 0.709804, 0.72549 )
-TabContainer/colors/font_color_fg = Color( 1, 1, 1, 1 )
-TabContainer/styles/panel = SubResource( 10 )
-TabContainer/styles/tab_bg = SubResource( 12 )
-TabContainer/styles/tab_fg = SubResource( 11 )
-VBoxContainer/constants/separation = 15
-VScrollBar/styles/scroll = SubResource( 5 )
-WindowDialog/colors/title_color = Color( 1, 1, 1, 1 )
-WindowDialog/constants/close_h_ofs = 0
-WindowDialog/constants/close_v_ofs = 0
-WindowDialog/constants/title_height = 60
-WindowDialog/icons/close = ExtResource( 1 )
-WindowDialog/icons/close_highlight = ExtResource( 1 )
-WindowDialog/styles/panel = SubResource( 13 )
-
-[sub_resource type="StyleBoxFlat" id=17]
-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 )
-
-[sub_resource type="StyleBoxFlat" id=1]
-content_margin_left = 10.0
-content_margin_right = 10.0
-bg_color = Color( 0.192157, 0.192157, 0.192157, 1 )
-
-[sub_resource type="StyleBoxFlat" id=2]
-content_margin_left = 10.0
-content_margin_right = 10.0
-bg_color = Color( 0.0980392, 0.0980392, 0.0980392, 1 )
-
-[node name="Chat" type="Control"]
+[node name="Chat" type="MarginContainer"]
anchor_right = 1.0
anchor_bottom = 1.0
+margin_right = -918.0
rect_min_size = Vector2( 300, 0 )
-theme = SubResource( 16 )
+theme = ExtResource( 1 )
script = ExtResource( 2 )
[node name="v" type="VBoxContainer" parent="."]
-anchor_right = 1.0
-anchor_bottom = 1.0
-custom_constants/separation = 0
-
-[node name="Panel" type="Panel" parent="v"]
-margin_right = 1422.0
-margin_bottom = 740.0
-size_flags_vertical = 3
-custom_styles/panel = SubResource( 17 )
-
-[node name="scroller" type="ScrollContainer" parent="v/Panel"]
-anchor_right = 1.0
-anchor_bottom = 1.0
-margin_left = 16.0
-scroll_horizontal_enabled = false
-
-[node name="labels" type="VBoxContainer" parent="v/Panel/scroller"]
-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
-margin_right = 1422.0
+margin_right = 504.0
margin_bottom = 800.0
custom_constants/separation = 0
-[node name="text" type="TextEdit" parent="v/h"]
-margin_right = 1362.0
-margin_bottom = 60.0
-rect_min_size = Vector2( 0, 60 )
-size_flags_horizontal = 3
-custom_styles/focus = SubResource( 1 )
-custom_styles/normal = SubResource( 2 )
-text = "hello ! write text here !"
-show_line_numbers = true
-context_menu_enabled = false
-smooth_scrolling = true
-wrap_enabled = true
-minimap_draw = true
-minimap_width = 50
-caret_blink = true
-
-[node name="send" parent="v/h" instance=ExtResource( 6 )]
-margin_left = 1362.0
-margin_right = 1422.0
-margin_bottom = 60.0
-rect_min_size = Vector2( 60, 60 )
-focus_mode = 2
-enabled_focus_mode = 2
-texture_normal = ExtResource( 5 )
-normal_color = Color( 0, 0, 0, 0.784314 )
+[node name="MessageList" parent="v" instance=ExtResource( 3 )]
+anchor_right = 0.0
+anchor_bottom = 0.0
+margin_right = 504.0
+margin_bottom = 750.0
+
+[node name="TextInput" parent="v" instance=ExtResource( 5 )]
+anchor_top = 0.0
+anchor_right = 0.0
+anchor_bottom = 0.0
+margin_top = 750.0
+margin_right = 504.0
+margin_bottom = 800.0
-[connection signal="pressed" from="v/h/send" to="." method="send"]
+[connection signal="send" from="v/TextInput" to="." method="send"]
diff --git a/ui/chat/ExpandableTextEdit.gd b/ui/chat/ExpandableTextEdit.gd
new file mode 100644
index 0000000..2e338f5
--- /dev/null
+++ b/ui/chat/ExpandableTextEdit.gd
@@ -0,0 +1,76 @@
+# https://gist.github.com/MattUV/469ad2be96961c0afe8dfc1bf0932f76
+class_name ExpandableTextEdit
+extends TextEdit
+
+export(bool) var expand := true
+export(int) var max_lines := 5
+
+var scroll_bar
+
+onready var font = get_font("font")
+var line_spacing
+var line_height
+var line_count = -1
+
+
+func _ready():
+ scroll_bar = _get_vscroll_bar()
+ line_spacing = _get_line_spacing()
+ line_height = font.get_height() + line_spacing
+ line_count = _get_real_line_count()
+ _update_height(line_count)
+
+ connect("text_changed", self, "_text_changed")
+
+
+func _get_line_spacing():
+ var spacing = 4
+ if get_constant("linespacing") != null:
+ spacing = get_constant("line_spacing")
+
+ return spacing
+
+
+func _get_real_line_count():
+ var count = get_line_count()
+ var lines_to_add = 0
+ var scroll_size = scroll_bar.rect_size.x if scroll_bar.visible else 0
+
+ # Loop over every actual line in the TextEdit
+ for i in count:
+ var line = get_line(i) # Get the string of the line
+ var width = font.get_string_size(line).x
+ if width > rect_size.x - scroll_size:
+ lines_to_add += int(width / (rect_size.x - scroll_size))
+
+ return count + lines_to_add
+
+
+func _get_vscroll_bar():
+ for c in get_children():
+ if c is VScrollBar:
+ return c
+
+
+func _update_height(count):
+ if !expand:
+ return
+
+ var lines_to_show = count
+ if lines_to_show > max_lines:
+ lines_to_show = max_lines
+
+ rect_min_size.y = lines_to_show * (line_height + line_spacing * 1.45)
+ rect_size.y = rect_min_size.y
+ update()
+
+
+func _text_changed():
+ _on_text_changed(false)
+
+
+func _on_text_changed(force = false):
+ var new_line_count = _get_real_line_count()
+ if force or line_count != new_line_count:
+ line_count = new_line_count
+ _update_height(new_line_count)
diff --git a/ui/chat/TextInput.gd b/ui/chat/TextInput.gd
new file mode 100644
index 0000000..c3a8134
--- /dev/null
+++ b/ui/chat/TextInput.gd
@@ -0,0 +1,18 @@
+extends Control
+
+signal send(message)
+
+onready var textedit := $h/MC/text
+onready var placeholder := $h/MC/placeholder
+
+
+func _on_text_changed() -> void:
+ placeholder.visible = len(textedit.text) == 0
+
+
+func _on_text_send(msg: String) -> void:
+ emit_signal("send", msg)
+
+
+func setup_emojis(_emojis: Dictionary) -> void:
+ $h/MC2/EmojiButton._setup(_emojis)
diff --git a/ui/chat/chat_theme.tres b/ui/chat/chat_theme.tres
new file mode 100644
index 0000000..d44effb
--- /dev/null
+++ b/ui/chat/chat_theme.tres
@@ -0,0 +1,193 @@
+[gd_resource type="Theme" load_steps=29 format=2]
+
+[ext_resource path="res://assets/ui/verdana-bold-italic.ttf" type="DynamicFontData" id=1]
+[ext_resource path="res://assets/ui/CascadiaCode.ttf" type="DynamicFontData" id=2]
+[ext_resource path="res://assets/ui/button.png" type="Texture" id=3]
+[ext_resource path="res://assets/ui/whitespace.png" type="Texture" id=4]
+[ext_resource path="res://assets/ui/checkedbox.png" type="Texture" id=5]
+[ext_resource path="res://assets/ui/verdana.ttf" type="DynamicFontData" id=6]
+[ext_resource path="res://assets/ui/verdana-bold.ttf" type="DynamicFontData" id=7]
+[ext_resource path="res://ui/theme/button.tres" type="StyleBox" id=8]
+[ext_resource path="res://ui/theme/buttonhover.tres" type="StyleBox" id=9]
+[ext_resource path="res://ui/theme/transblack.tres" type="StyleBox" id=10]
+[ext_resource path="res://ui/theme/flatblack.tres" type="StyleBox" id=11]
+
+[sub_resource type="StyleBoxTexture" id=6]
+texture = ExtResource( 3 )
+region_rect = Rect2( 0, 0, 84, 84 )
+margin_left = 28.0
+margin_right = 28.0
+margin_top = 28.0
+margin_bottom = 28.0
+modulate_color = Color( 0.772549, 0.772549, 0.772549, 0.54902 )
+
+[sub_resource type="StyleBoxEmpty" id=7]
+
+[sub_resource type="StyleBoxEmpty" id=8]
+
+[sub_resource type="StyleBoxEmpty" id=9]
+
+[sub_resource type="StyleBoxEmpty" id=4]
+
+[sub_resource type="StyleBoxFlat" id=3]
+bg_color = Color( 0.0784314, 0.0784314, 0.0784314, 1 )
+border_width_left = 2
+border_width_top = 2
+border_width_right = 2
+border_width_bottom = 2
+border_color = Color( 1, 1, 1, 1 )
+corner_detail = 20
+expand_margin_left = 10.0
+expand_margin_right = 10.0
+
+[sub_resource type="DynamicFont" id=18]
+size = 15
+font_data = ExtResource( 7 )
+
+[sub_resource type="DynamicFont" id=19]
+size = 15
+font_data = ExtResource( 1 )
+
+[sub_resource type="DynamicFont" id=14]
+size = 15
+font_data = ExtResource( 2 )
+
+[sub_resource type="DynamicFont" id=20]
+size = 15
+font_data = ExtResource( 6 )
+
+[sub_resource type="StyleBoxFlat" id=10]
+content_margin_left = 30.0
+content_margin_right = 30.0
+content_margin_top = 30.0
+content_margin_bottom = 30.0
+bg_color = Color( 0, 0, 0, 0.313726 )
+border_blend = true
+corner_radius_top_left = 50
+corner_radius_top_right = 50
+corner_radius_bottom_right = 30
+corner_radius_bottom_left = 30
+corner_detail = 15
+
+[sub_resource type="StyleBoxFlat" id=12]
+content_margin_left = 10.0
+content_margin_right = 10.0
+bg_color = Color( 0, 0, 0, 0.313726 )
+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_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=21]
+
+[sub_resource type="StyleBoxEmpty" id=5]
+
+[sub_resource type="StyleBoxFlat" id=13]
+content_margin_left = 10.0
+content_margin_right = 10.0
+content_margin_bottom = 10.0
+bg_color = Color( 0, 0, 0, 0.588235 )
+border_width_top = 65
+border_color = Color( 0.180392, 0.180392, 0.180392, 1 )
+corner_radius_top_left = 30
+corner_radius_top_right = 30
+corner_radius_bottom_right = 30
+corner_radius_bottom_left = 30
+corner_detail = 15
+expand_margin_top = 65.0
+
+[sub_resource type="DynamicFont" id=15]
+size = 15
+font_data = ExtResource( 7 )
+
+[resource]
+default_font = SubResource( 15 )
+Button/colors/font_color = Color( 1, 1, 1, 1 )
+Button/colors/font_color_disabled = Color( 1, 1, 1, 0.305882 )
+Button/colors/font_color_focus = Color( 1, 1, 1, 1 )
+Button/colors/font_color_hover = Color( 0, 0, 0, 1 )
+Button/colors/font_color_pressed = Color( 1, 1, 1, 1 )
+Button/styles/disabled = SubResource( 6 )
+Button/styles/focus = ExtResource( 8 )
+Button/styles/hover = ExtResource( 9 )
+Button/styles/normal = ExtResource( 8 )
+Button/styles/pressed = ExtResource( 8 )
+CheckBox/icons/checked = ExtResource( 5 )
+CheckBox/icons/checked_disabled = null
+CheckBox/icons/radio_checked = null
+CheckBox/icons/radio_checked_disabled = null
+CheckBox/icons/radio_unchecked = null
+CheckBox/icons/radio_unchecked_disabled = null
+CheckBox/icons/unchecked = ExtResource( 3 )
+CheckBox/icons/unchecked_disabled = null
+ColorPicker/icons/color_sample = ExtResource( 4 )
+ColorPicker/icons/overbright_indicator = ExtResource( 4 )
+ColorPicker/icons/preset_bg = ExtResource( 4 )
+ColorPicker/icons/screen_picker = ExtResource( 4 )
+ColorPickerButton/colors/font_color = Color( 1, 1, 1, 1 )
+ColorPickerButton/colors/font_color_disabled = Color( 1, 1, 1, 0.301961 )
+ColorPickerButton/colors/font_color_focus = Color( 1, 1, 1, 1 )
+ColorPickerButton/colors/font_color_hover = Color( 1, 1, 1, 1 )
+ColorPickerButton/colors/font_color_pressed = Color( 0.913725, 0.913725, 0.913725, 1 )
+ColorPickerButton/icons/bg = ExtResource( 4 )
+HBoxContainer/constants/separation = 15
+HSlider/styles/grabber_area = SubResource( 7 )
+HSlider/styles/grabber_area_highlight = SubResource( 8 )
+HSlider/styles/slider = SubResource( 9 )
+ItemList/colors/font_color = Color( 1, 1, 1, 1 )
+ItemList/colors/font_color_selected = Color( 0.905882, 0.905882, 0.905882, 1 )
+ItemList/styles/bg = SubResource( 4 )
+ItemList/styles/bg_focus = ExtResource( 11 )
+LineEdit/colors/cursor_color = Color( 1, 1, 1, 1 )
+LineEdit/colors/font_color = Color( 1, 1, 1, 1 )
+LineEdit/colors/font_color_uneditable = Color( 1, 1, 1, 0.67451 )
+LineEdit/styles/focus = ExtResource( 8 )
+LineEdit/styles/normal = ExtResource( 8 )
+LineEdit/styles/read_only = ExtResource( 8 )
+OptionButton/colors/font_color = Color( 1, 1, 1, 1 )
+OptionButton/colors/font_color_focus = Color( 1, 1, 1, 1 )
+OptionButton/colors/font_color_hover = Color( 0, 0, 0, 1 )
+OptionButton/colors/font_color_pressed = Color( 1, 1, 1, 1 )
+OptionButton/icons/arrow = ExtResource( 4 )
+PopupMenu/colors/font_color = Color( 1, 1, 1, 1 )
+PopupMenu/colors/font_color_accel = Color( 1, 1, 1, 0.8 )
+PopupMenu/colors/font_color_hover = Color( 1, 1, 1, 1 )
+PopupMenu/colors/font_color_separator = Color( 0.262745, 0.262745, 0.262745, 1 )
+PopupMenu/icons/radio_checked = ExtResource( 4 )
+PopupMenu/icons/radio_unchecked = ExtResource( 4 )
+PopupMenu/styles/hover = SubResource( 3 )
+PopupMenu/styles/panel = ExtResource( 11 )
+PopupPanel/styles/panel = ExtResource( 10 )
+RichTextLabel/colors/default_color = Color( 1, 1, 1, 1 )
+RichTextLabel/fonts/bold_font = SubResource( 18 )
+RichTextLabel/fonts/bold_italics_font = SubResource( 19 )
+RichTextLabel/fonts/italics_font = SubResource( 19 )
+RichTextLabel/fonts/mono_font = SubResource( 14 )
+RichTextLabel/fonts/normal_font = SubResource( 20 )
+SpinBox/icons/updown = ExtResource( 4 )
+TabContainer/colors/font_color_bg = Color( 0.709804, 0.709804, 0.709804, 0.72549 )
+TabContainer/colors/font_color_fg = Color( 1, 1, 1, 1 )
+TabContainer/styles/panel = SubResource( 10 )
+TabContainer/styles/tab_bg = SubResource( 12 )
+TabContainer/styles/tab_fg = SubResource( 11 )
+TextEdit/styles/normal = SubResource( 21 )
+VBoxContainer/constants/separation = 15
+VScrollBar/styles/scroll = SubResource( 5 )
+WindowDialog/colors/title_color = Color( 1, 1, 1, 1 )
+WindowDialog/constants/close_h_ofs = 0
+WindowDialog/constants/close_v_ofs = 0
+WindowDialog/constants/title_height = 60
+WindowDialog/icons/close = ExtResource( 4 )
+WindowDialog/icons/close_highlight = ExtResource( 4 )
+WindowDialog/styles/panel = SubResource( 13 )
diff --git a/ui/chat/emojibutton.gd b/ui/chat/emojibutton.gd
new file mode 100644
index 0000000..b63e418
--- /dev/null
+++ b/ui/chat/emojibutton.gd
@@ -0,0 +1,79 @@
+extends TextureButton
+
+export(float) var scale_normal := 0.8
+export(float) var scale_hover := 1.0
+var cur_scale := 0.8
+
+export(float) var saturation_normal := 0.0
+export(float) var saturation_hover := 1.0
+var cur_saturation := 0.0
+
+export(float) var weight := 0.35
+
+export(Vector2) var offset = Vector2.ZERO
+
+var emojis := {}
+
+var focused := false
+
+signal emoji_selected(emoji)
+
+onready var emojimenu: GridMenu = $Popup/EmojiMenu
+onready var popup: PopupPanel = $Popup
+
+
+func change_icon():
+ if emojis:
+ texture_normal = load(emojis.values()[randi() % len(emojis)])
+
+
+func _ready():
+ material.set_shader_param("scale", scale_normal)
+ set_process(false)
+
+
+func _setup(_emojis: Dictionary):
+ emojis = _emojis
+ change_icon()
+ for key in emojis.keys():
+ emojimenu.add_item(load(emojis[key]), arr2tooltip(key), Vector2(30, 30))
+
+
+func arr2tooltip(arr: Array) -> String:
+ var string = ""
+ for i in arr:
+ string += i + " "
+ return string
+
+
+func _focused(q: bool):
+ focused = q
+ if q:
+ change_icon()
+ set_process(true)
+
+
+func _process(_delta: float) -> void:
+ if focused:
+ cur_scale = lerp(cur_scale, scale_hover, weight)
+ cur_saturation = lerp(cur_saturation, saturation_hover, weight)
+ else:
+ cur_scale = lerp(cur_scale, scale_normal, weight)
+ cur_saturation = lerp(cur_saturation, saturation_normal, weight)
+ if is_equal_approx(cur_scale, scale_normal):
+ set_process(false)
+
+ material.set_shader_param("scale", cur_scale)
+ material.set_shader_param("saturation", cur_saturation)
+
+
+func _pressed() -> void:
+ popup.popup()
+ emojimenu.open()
+ yield(get_tree(), "idle_frame")
+ popup.rect_global_position = rect_global_position + offset
+
+
+func _on_EmojiMenu_pressed(index: int):
+ emit_signal("emoji_selected", emojis.keys()[index][0])
+ popup.hide()
diff --git a/ui/chat/grayscale.shader b/ui/chat/grayscale.shader
new file mode 100644
index 0000000..3188c10
--- /dev/null
+++ b/ui/chat/grayscale.shader
@@ -0,0 +1,10 @@
+shader_type canvas_item;
+uniform float saturation: hint_range(0.0, 1.0) = 0.0;
+uniform float scale: hint_range(0.0, 1.0) = 1.0;
+const float pivot = 0.5;
+
+void fragment() {
+ vec4 tex_color = texture(TEXTURE, (UV - pivot) * (2.0 - scale) + pivot);
+ COLOR.rgb = mix(vec3(dot(tex_color.rgb, vec3(0.299, 0.587, 0.114))), tex_color.rgb, saturation); // magic numbers
+ COLOR.a = tex_color.a;
+} \ No newline at end of file
diff --git a/ui/chat/texteditor.gd b/ui/chat/texteditor.gd
new file mode 100644
index 0000000..4aa92da
--- /dev/null
+++ b/ui/chat/texteditor.gd
@@ -0,0 +1,42 @@
+extends ExpandableTextEdit
+
+signal send(msg)
+
+const auto_complete = [
+ "bigsmile",
+ "cold",
+ "cry",
+ "flushed",
+ "happy",
+ "hmm",
+ "huh",
+ "kiss",
+ "oh",
+ "smile",
+ "unhappy",
+ "upsidedown_smile",
+ "weary",
+ "what",
+ "wink_tongue",
+ "wink",
+ "wow",
+ "zany",
+ "..."
+]
+
+
+func _input(event: InputEvent) -> void:
+ if event is InputEventKey:
+ if event.pressed:
+ var key_name = OS.get_scancode_string(event.get_scancode_with_modifiers())
+ if key_name == "Enter" or key_name == "Kp Enter":
+ get_tree().set_input_as_handled()
+ if text.length() != 0:
+ emit_signal("send", text)
+ text = ""
+ emit_signal("text_changed")
+
+
+func _emoji_selected(emoji: String):
+ text += emoji
+ emit_signal("text_changed")
diff --git a/ui/gridmenu/GridMenu.gd b/ui/gridmenu/GridMenu.gd
index 6d14477..8a4f7d8 100644
--- a/ui/gridmenu/GridMenu.gd
+++ b/ui/gridmenu/GridMenu.gd
@@ -11,12 +11,11 @@ func open():
func add_item(icon: Texture, tooltip: String, size: Vector2) -> void:
- var pnl := PanelContainer.new()
var tex := texture_button.instance()
tex.connect("pressed", self, "_pressed", [get_child_count()])
tex.expand = true
tex.texture_normal = icon
- tex.name = str(get_child_count() + 1)
+ tex.name = tooltip
tex.rect_min_size = size
tex.hint_tooltip = tooltip
tex.stretch_mode = tex.STRETCH_KEEP_ASPECT_CENTERED
@@ -26,8 +25,7 @@ func add_item(icon: Texture, tooltip: String, size: Vector2) -> void:
back.margin_right = 5
back.margin_top = -5
back.margin_bottom = 5
- pnl.add_child(tex)
- add_child(pnl)
+ add_child(tex)
func _pressed(index: int):
diff --git a/ui/gridmenu/GridMenuButton.gd b/ui/gridmenu/GridMenuButton.gd
index d3dbd68..91ca486 100644
--- a/ui/gridmenu/GridMenuButton.gd
+++ b/ui/gridmenu/GridMenuButton.gd
@@ -29,7 +29,7 @@ func set_selected(index: int):
func _pressed() -> void:
+ gridmenu.open()
popup.popup()
yield(get_tree(), "idle_frame")
popup.rect_global_position = rect_global_position + offset
- gridmenu.open()
diff --git a/ui/menus/Lobby.gd b/ui/menus/Lobby.gd
index 87b422b..a1f2549 100644
--- a/ui/menus/Lobby.gd
+++ b/ui/menus/Lobby.gd
@@ -39,7 +39,7 @@ func set_buttons(enabled := true) -> void:
func _on_join_pressed() -> void:
if validate_text():
set_buttons(false)
- Globals.network.join_game()
+ PacketHandler.join_game()
else:
set_status("Invalid address", false)
@@ -47,7 +47,7 @@ func _on_join_pressed() -> void:
func _on_HostButton_pressed() -> void:
if validate_text():
set_buttons(false)
- Globals.network.host_game()
+ PacketHandler.host_game()
else:
set_status("Invalid address", false)
@@ -58,7 +58,7 @@ func validate_text(text := address.get_text()) -> String:
text = text.replace(" ", "_")
address.text = text
address.caret_position = pos
- Globals.network.game_code = text
+ PacketHandler.game_code = text
return text
@@ -69,7 +69,7 @@ func _on_Address_text_entered(new_text: String) -> void:
func _on_spectate_pressed():
if validate_text():
set_buttons(false)
- Globals.network.spectate()
+ PacketHandler.spectate()
else:
set_status("Invalid address", false)
diff --git a/ui/menus/account/Account.gd b/ui/menus/account/Account.gd
index 93261ab..fb150e8 100644
--- a/ui/menus/account/Account.gd
+++ b/ui/menus/account/Account.gd
@@ -25,10 +25,9 @@ func set_signed_in(new):
func _ready():
loading.show()
tabcontainer.hide()
- if Globals.network:
- Globals.network.connect("signinresult", self, "_on_signin_result")
- Globals.network.connect("signupresult", self, "_on_signup_result")
- Globals.network.connect("connection_established", self, "attempt_autologin")
+ PacketHandler.connect("signinresult", self, "_on_signin_result")
+ PacketHandler.connect("signupresult", self, "_on_signup_result")
+ PacketHandler.connect("connection_established", self, "attempt_autologin")
flags.append_array(Utils.walk_dir("res://assets/flags", false, ["rainbow"]))
for i in flags: # add the items
flagchoice.add_item(load("res://assets/flags/%s.png" % i), i.replace("_", " "))
@@ -37,7 +36,7 @@ func _ready():
func attempt_autologin():
if data.name and data.password:
- Globals.network.signin(data)
+ PacketHandler.signin(data)
else:
reset("", false)
@@ -45,7 +44,7 @@ func attempt_autologin():
func _on_signin_pressed():
$choose/signin/signinbutton.disabled = true
update_data(tabs.signin.username, tabs.signin.pw)
- Globals.network.signin(data)
+ PacketHandler.signin(data)
func _on_signin_result(result):
@@ -65,7 +64,7 @@ func _on_signup_pressed():
$choose/signup/signupbutton.disabled = true
data.country = flags[flagchoice.selected]
update_data(tabs.signup.username, tabs.signup.pw)
- Globals.network.signup(data)
+ PacketHandler.signup(data)
func _on_signup_result(result: String):
diff --git a/ui/menus/sidebarright/SidebarRight.gd b/ui/menus/sidebarright/SidebarRight.gd
index 8762ff7..39f6188 100644
--- a/ui/menus/sidebarright/SidebarRight.gd
+++ b/ui/menus/sidebarright/SidebarRight.gd
@@ -1,4 +1,4 @@
-extends ColorRect
+extends Control
onready var whitepanel = find_node("WhitePanel")
onready var blackpanel = find_node("BlackPanel")
diff --git a/ui/menus/sidebarright/SidebarRight.tscn b/ui/menus/sidebarright/SidebarRight.tscn
index 2886067..b66c5b2 100644
--- a/ui/menus/sidebarright/SidebarRight.tscn
+++ b/ui/menus/sidebarright/SidebarRight.tscn
@@ -1,16 +1,9 @@
-[gd_scene load_steps=31 format=2]
+[gd_scene load_steps=18 format=2]
[ext_resource path="res://ui/barbutton/drawbutton.gd" type="Script" id=1]
[ext_resource path="res://ui/barbutton/resignbutton.gd" type="Script" id=2]
[ext_resource path="res://ui/Status.gd" type="Script" id=3]
-[ext_resource path="res://assets/ui/whitespace.png" type="Texture" id=4]
-[ext_resource path="res://assets/ui/verdana-bold.ttf" type="DynamicFontData" id=5]
[ext_resource path="res://ui/barbutton/BarTextureButton.tscn" type="PackedScene" id=6]
-[ext_resource path="res://ui/theme/flatblack.tres" type="StyleBox" id=7]
-[ext_resource path="res://ui/theme/button.tres" type="StyleBox" id=8]
-[ext_resource path="res://assets/ui/button.png" type="Texture" id=9]
-[ext_resource path="res://assets/ui/checkedbox.png" type="Texture" id=10]
-[ext_resource path="res://ui/theme/buttonhover.tres" type="StyleBox" id=11]
[ext_resource path="res://assets/ui/Roboto-Medium.ttf" type="DynamicFontData" id=12]
[ext_resource path="res://ui/menus/sidebarright/SidebarRight.gd" type="Script" id=13]
[ext_resource path="res://ui/theme/main.tres" type="Theme" id=14]
@@ -23,86 +16,20 @@
[ext_resource path="res://ui/menus/sidebarright/sandisplay/SanDisplay.tscn" type="PackedScene" id=21]
[ext_resource path="res://ui/menus/sidebarright/UserPanel.tscn" type="PackedScene" id=22]
-[sub_resource type="StyleBoxFlat" id=8]
-bg_color = Color( 0.188235, 0.180392, 0.172549, 1 )
-
-[sub_resource type="StyleBoxEmpty" id=2]
-
-[sub_resource type="StyleBoxEmpty" id=4]
-
-[sub_resource type="StyleBoxFlat" id=3]
-bg_color = Color( 0.0784314, 0.0784314, 0.0784314, 1 )
-border_width_left = 2
-border_width_top = 2
-border_width_right = 2
-border_width_bottom = 2
-border_color = Color( 1, 1, 1, 1 )
-corner_detail = 20
-
-[sub_resource type="StyleBoxEmpty" id=5]
-
-[sub_resource type="DynamicFont" id=7]
-size = 35
-font_data = ExtResource( 5 )
-
-[sub_resource type="Theme" id=6]
-default_font = SubResource( 7 )
-Button/colors/font_color = Color( 1, 1, 1, 1 )
-Button/colors/font_color_focus = Color( 1, 1, 1, 1 )
-Button/colors/font_color_hover = Color( 0, 0, 0, 1 )
-Button/colors/font_color_pressed = Color( 1, 1, 1, 1 )
-Button/styles/disabled = SubResource( 2 )
-Button/styles/focus = ExtResource( 8 )
-Button/styles/hover = ExtResource( 11 )
-Button/styles/normal = ExtResource( 8 )
-Button/styles/pressed = ExtResource( 8 )
-CheckBox/icons/checked = ExtResource( 10 )
-CheckBox/icons/checked_disabled = null
-CheckBox/icons/radio_checked = null
-CheckBox/icons/radio_checked_disabled = null
-CheckBox/icons/radio_unchecked = null
-CheckBox/icons/radio_unchecked_disabled = null
-CheckBox/icons/unchecked = ExtResource( 9 )
-CheckBox/icons/unchecked_disabled = null
-HBoxContainer/constants/separation = 15
-ItemList/colors/font_color = Color( 1, 1, 1, 1 )
-ItemList/colors/font_color_selected = Color( 0.905882, 0.905882, 0.905882, 1 )
-ItemList/styles/bg = SubResource( 4 )
-ItemList/styles/bg_focus = ExtResource( 7 )
-LineEdit/colors/cursor_color = Color( 1, 1, 1, 1 )
-LineEdit/colors/font_color = Color( 1, 1, 1, 1 )
-LineEdit/colors/font_color_uneditable = Color( 1, 1, 1, 0.67451 )
-LineEdit/styles/focus = ExtResource( 8 )
-LineEdit/styles/normal = ExtResource( 8 )
-LineEdit/styles/read_only = ExtResource( 8 )
-OptionButton/colors/font_color = Color( 1, 1, 1, 1 )
-OptionButton/colors/font_color_focus = Color( 1, 1, 1, 1 )
-OptionButton/colors/font_color_hover = Color( 0, 0, 0, 1 )
-OptionButton/colors/font_color_pressed = Color( 1, 1, 1, 1 )
-OptionButton/icons/arrow = ExtResource( 4 )
-PopupMenu/colors/font_color = Color( 1, 1, 1, 1 )
-PopupMenu/colors/font_color_accel = Color( 1, 1, 1, 0.8 )
-PopupMenu/colors/font_color_hover = Color( 1, 1, 1, 1 )
-PopupMenu/colors/font_color_separator = Color( 0.262745, 0.262745, 0.262745, 1 )
-PopupMenu/icons/radio_checked = ExtResource( 4 )
-PopupMenu/icons/radio_unchecked = ExtResource( 4 )
-PopupMenu/styles/hover = SubResource( 3 )
-PopupMenu/styles/panel = ExtResource( 7 )
-VBoxContainer/constants/separation = 15
-VScrollBar/styles/scroll = SubResource( 5 )
+[sub_resource type="StyleBoxFlat" id=9]
+bg_color = Color( 0.14902, 0.141176, 0.129412, 0.588235 )
[sub_resource type="DynamicFont" id=1]
size = 35
font_data = ExtResource( 12 )
-[node name="SidebarRight" type="ColorRect"]
-margin_left = 940.0
-margin_right = 1422.0
-margin_bottom = 800.0
+[node name="SidebarRight" type="PanelContainer"]
+anchor_right = 1.0
+anchor_bottom = 1.0
rect_min_size = Vector2( 300, 0 )
size_flags_horizontal = 3
theme = ExtResource( 14 )
-color = Color( 0.14902, 0.141176, 0.129412, 0.588235 )
+custom_styles/panel = SubResource( 9 )
script = ExtResource( 13 )
__meta__ = {
"_edit_lock_": true
@@ -110,21 +37,21 @@ __meta__ = {
panel_holder = NodePath("V")
[node name="V" type="VBoxContainer" parent="."]
-anchor_right = 1.0
-anchor_bottom = 1.0
+margin_right = 1422.0
+margin_bottom = 800.0
custom_constants/separation = 0
alignment = 1
[node name="BlackPanel" parent="V" instance=ExtResource( 22 )]
anchor_right = 0.0
anchor_bottom = 0.0
-margin_top = 194.0
-margin_right = 482.0
+margin_top = 214.0
+margin_right = 1422.0
margin_bottom = 254.0
-[node name="buttonbarholder" type="Control" parent="V"]
+[node name="buttonbarholder" type="PanelContainer" parent="V"]
margin_top = 254.0
-margin_right = 482.0
+margin_right = 1422.0
margin_bottom = 304.0
rect_min_size = Vector2( 50, 50 )
__meta__ = {
@@ -132,71 +59,70 @@ __meta__ = {
"_edit_lock_": true
}
-[node name="Panel" type="Panel" parent="V/buttonbarholder"]
-anchor_right = 1.0
-anchor_bottom = 1.0
-
-[node name="buttonbar" type="HBoxContainer" parent="V/buttonbarholder/Panel"]
-anchor_right = 1.0
-anchor_bottom = 1.0
+[node name="buttonbar" type="HBoxContainer" parent="V/buttonbarholder"]
+margin_right = 1422.0
+margin_bottom = 50.0
custom_constants/separation = 0
alignment = 1
-[node name="FlipBoard" parent="V/buttonbarholder/Panel/buttonbar" instance=ExtResource( 6 )]
-margin_left = 141.0
-margin_right = 191.0
+[node name="FlipBoard" parent="V/buttonbarholder/buttonbar" instance=ExtResource( 6 )]
+margin_right = 355.0
hint_tooltip = "rotate the board"
+size_flags_horizontal = 3
texture_normal = ExtResource( 17 )
+stretch_mode = 5
script = ExtResource( 19 )
-[node name="DrawButton" parent="V/buttonbarholder/Panel/buttonbar" instance=ExtResource( 6 )]
-margin_left = 191.0
-margin_right = 241.0
+[node name="DrawButton" parent="V/buttonbarholder/buttonbar" instance=ExtResource( 6 )]
+margin_left = 355.0
+margin_right = 711.0
hint_tooltip = "request a draw"
+size_flags_horizontal = 3
texture_normal = ExtResource( 16 )
+stretch_mode = 5
script = ExtResource( 1 )
confirm_text = "Your opponent requests a draw"
-[node name="ResignButton" parent="V/buttonbarholder/Panel/buttonbar" instance=ExtResource( 6 )]
-margin_left = 241.0
-margin_right = 291.0
+[node name="ResignButton" parent="V/buttonbarholder/buttonbar" instance=ExtResource( 6 )]
+margin_left = 711.0
+margin_right = 1066.0
hint_tooltip = "resign"
+size_flags_horizontal = 3
texture_normal = ExtResource( 20 )
+stretch_mode = 5
script = ExtResource( 2 )
confirm_text = "Resign?"
-[node name="UndoButton" parent="V/buttonbarholder/Panel/buttonbar" instance=ExtResource( 6 )]
-margin_left = 291.0
-margin_right = 341.0
+[node name="UndoButton" parent="V/buttonbarholder/buttonbar" instance=ExtResource( 6 )]
+margin_left = 1066.0
+margin_right = 1422.0
hint_tooltip = "request a undo"
+size_flags_horizontal = 3
texture_normal = ExtResource( 15 )
+stretch_mode = 5
script = ExtResource( 18 )
confirm_text = "Your opponent requests a undo"
-status = NodePath("../../../../Status")
+status = NodePath("../../../Status")
-[node name="SanDisplay" type="PanelContainer" parent="V"]
+[node name="SanDisplay" parent="V" instance=ExtResource( 21 )]
+anchor_right = 0.0
+anchor_bottom = 0.0
margin_top = 304.0
-margin_right = 482.0
+margin_right = 1422.0
margin_bottom = 504.0
-custom_styles/panel = SubResource( 8 )
-
-[node name="SanDisplay" parent="V/SanDisplay" instance=ExtResource( 21 )]
-margin_right = 482.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 = 504.0
-margin_right = 482.0
-margin_bottom = 564.0
+margin_right = 1422.0
+margin_bottom = 544.0
[node name="Status" type="Label" parent="V"]
-margin_top = 564.0
-margin_right = 482.0
-margin_bottom = 606.0
+margin_top = 544.0
+margin_right = 1422.0
+margin_bottom = 586.0
custom_fonts/font = SubResource( 1 )
align = 1
autowrap = true
diff --git a/ui/menus/sidebarright/UserPanel.gd b/ui/menus/sidebarright/UserPanel.gd
index 280d689..e9b3935 100644
--- a/ui/menus/sidebarright/UserPanel.gd
+++ b/ui/menus/sidebarright/UserPanel.gd
@@ -1,7 +1,7 @@
extends PanelContainer
-onready var flag_display = $H/Flag
-onready var name_display = $H/Name
+onready var flag_display = $MC/H/Flag
+onready var name_display = $MC/H/Name
var flag := "rainbow" setget set_flag
var _name := "name" setget set_name
diff --git a/ui/menus/sidebarright/UserPanel.tscn b/ui/menus/sidebarright/UserPanel.tscn
index 4322adb..fffa3f6 100644
--- a/ui/menus/sidebarright/UserPanel.tscn
+++ b/ui/menus/sidebarright/UserPanel.tscn
@@ -12,27 +12,31 @@ rect_min_size = Vector2( 0, 40 )
theme = ExtResource( 3 )
script = ExtResource( 4 )
-[node name="H" type="HBoxContainer" parent="."]
+[node name="MC" type="MarginContainer" parent="."]
+margin_right = 1422.0
+margin_bottom = 800.0
+custom_constants/margin_left = 10
+
+[node name="H" type="HBoxContainer" parent="MC"]
margin_left = 10.0
-margin_top = 10.0
-margin_right = 1412.0
-margin_bottom = 790.0
+margin_right = 1422.0
+margin_bottom = 800.0
custom_constants/separation = 10
-[node name="Name" type="Label" parent="H"]
-margin_top = 370.0
+[node name="Name" type="Label" parent="MC/H"]
+margin_top = 380.0
margin_right = 61.0
-margin_bottom = 410.0
+margin_bottom = 420.0
rect_min_size = Vector2( 0, 40 )
custom_fonts/font = ExtResource( 1 )
text = "name"
valign = 1
-[node name="Flag" type="TextureRect" parent="H"]
+[node name="Flag" type="TextureRect" parent="MC/H"]
margin_left = 71.0
-margin_top = 380.0
+margin_top = 390.0
margin_right = 97.0
-margin_bottom = 400.0
+margin_bottom = 410.0
rect_min_size = Vector2( 26, 20 )
size_flags_horizontal = 4
size_flags_vertical = 4
@@ -40,8 +44,8 @@ texture = ExtResource( 2 )
expand = true
stretch_mode = 6
-[node name="Spacer2" type="Control" parent="H"]
+[node name="Spacer2" type="Control" parent="MC/H"]
margin_left = 107.0
-margin_right = 1402.0
-margin_bottom = 780.0
+margin_right = 1412.0
+margin_bottom = 800.0
size_flags_horizontal = 3
diff --git a/ui/menus/sidebarright/sandisplay/Base.tscn b/ui/menus/sidebarright/sandisplay/Base.tscn
index 188f9d9..b1908eb 100644
--- a/ui/menus/sidebarright/sandisplay/Base.tscn
+++ b/ui/menus/sidebarright/sandisplay/Base.tscn
@@ -1,67 +1,77 @@
-[gd_scene load_steps=2 format=2]
+[gd_scene load_steps=3 format=2]
[ext_resource path="res://ui/menus/sidebarright/sandisplay/Base.gd" type="Script" id=1]
+[ext_resource path="res://ui/verdana-bold-small.tres" type="DynamicFont" id=2]
[node name="Base" type="HBoxContainer"]
anchor_right = 1.0
-margin_right = -940.0
-margin_bottom = 50.0
-rect_min_size = Vector2( 482, 0 )
+anchor_bottom = 1.0
+mouse_filter = 2
custom_constants/separation = 0
script = ExtResource( 1 )
[node name="Number" type="ColorRect" parent="."]
margin_right = 100.0
-margin_bottom = 50.0
-rect_min_size = Vector2( 100, 50 )
+margin_bottom = 800.0
+rect_min_size = Vector2( 100, 25 )
+mouse_filter = 2
color = Color( 0.368627, 0.356863, 0.341176, 1 )
[node name="Number" type="Label" parent="Number"]
anchor_right = 1.0
anchor_bottom = 1.0
-rect_min_size = Vector2( 100, 50 )
+rect_min_size = Vector2( 100, 25 )
+custom_fonts/font = ExtResource( 2 )
align = 1
valign = 1
[node name="Spacer" type="ColorRect" parent="."]
margin_left = 100.0
margin_right = 110.0
-margin_bottom = 50.0
-rect_min_size = Vector2( 10, 0 )
+margin_bottom = 800.0
+rect_min_size = Vector2( 10, 25 )
+mouse_filter = 2
color = Color( 0.188235, 0.180392, 0.172549, 1 )
[node name="San1" type="ColorRect" parent="."]
margin_left = 110.0
-margin_right = 291.0
-margin_bottom = 50.0
-rect_min_size = Vector2( 100, 50 )
+margin_right = 761.0
+margin_bottom = 800.0
+rect_min_size = Vector2( 100, 25 )
+mouse_filter = 2
size_flags_horizontal = 3
color = Color( 0.188235, 0.180392, 0.172549, 1 )
[node name="San1" type="Label" parent="San1"]
anchor_right = 1.0
anchor_bottom = 1.0
-rect_min_size = Vector2( 100, 50 )
+rect_min_size = Vector2( 100, 25 )
+size_flags_horizontal = 3
+custom_fonts/font = ExtResource( 2 )
valign = 1
[node name="San2" type="ColorRect" parent="."]
-margin_left = 291.0
-margin_right = 472.0
-margin_bottom = 50.0
-rect_min_size = Vector2( 100, 50 )
+margin_left = 761.0
+margin_right = 1412.0
+margin_bottom = 800.0
+rect_min_size = Vector2( 100, 25 )
+mouse_filter = 2
size_flags_horizontal = 3
color = Color( 0.188235, 0.180392, 0.172549, 1 )
[node name="San2" type="Label" parent="San2"]
anchor_right = 1.0
anchor_bottom = 1.0
-rect_min_size = Vector2( 100, 50 )
+rect_min_size = Vector2( 100, 25 )
+size_flags_horizontal = 3
+custom_fonts/font = ExtResource( 2 )
align = 2
valign = 1
[node name="Spacer2" type="ColorRect" parent="."]
-margin_left = 472.0
-margin_right = 482.0
-margin_bottom = 50.0
-rect_min_size = Vector2( 10, 0 )
+margin_left = 1412.0
+margin_right = 1422.0
+margin_bottom = 800.0
+rect_min_size = Vector2( 10, 25 )
+mouse_filter = 2
color = Color( 0.188235, 0.180392, 0.172549, 1 )
diff --git a/ui/menus/sidebarright/sandisplay/SanDisplay.gd b/ui/menus/sidebarright/sandisplay/SanDisplay.gd
index 23a3aaa..504fb55 100644
--- a/ui/menus/sidebarright/sandisplay/SanDisplay.gd
+++ b/ui/menus/sidebarright/sandisplay/SanDisplay.gd
@@ -1,16 +1,16 @@
-extends ScrollContainer
+extends PanelContainer
var tween := Tween.new()
export(PackedScene) var Base
-onready var scroll_container := self
-onready var scroll_bar := get_v_scrollbar()
-onready var sans := $V
+onready var scroll_container := $Scroller
+onready var scroll_bar: VScrollBar = scroll_container.get_v_scrollbar()
+onready var sans := $Scroller/sanholder
func _ready() -> void:
- scroll_bar.step = .15
+ scroll_bar.step = .15 #smoth
add_child(tween)
Utils.connect("newmove", self, "on_new_move")
Utils.connect("pop_move", self, "reset_moves")
@@ -36,11 +36,11 @@ func on_new_move(move: String) -> void:
tween.start()
-func reset_moves():
+func reset_moves() -> void:
for i in sans.get_children():
i.queue_free()
-func _gui_input(event):
+func _gui_input(event: InputEvent) -> void:
if event is InputEventMouseButton:
OS.clipboard = Utils.get_pgn()
diff --git a/ui/menus/sidebarright/sandisplay/SanDisplay.tscn b/ui/menus/sidebarright/sandisplay/SanDisplay.tscn
index e133178..80b9b1c 100644
--- a/ui/menus/sidebarright/sandisplay/SanDisplay.tscn
+++ b/ui/menus/sidebarright/sandisplay/SanDisplay.tscn
@@ -1,87 +1,22 @@
-[gd_scene load_steps=16 format=2]
+[gd_scene load_steps=3 format=2]
-[ext_resource path="res://assets/ui/verdana-bold.ttf" type="DynamicFontData" id=1]
-[ext_resource path="res://assets/ui/whitespace.png" type="Texture" id=2]
-[ext_resource path="res://assets/ui/checkedbox.png" type="Texture" id=3]
-[ext_resource path="res://assets/ui/button.png" type="Texture" id=4]
-[ext_resource path="res://ui/theme/flatblack.tres" type="StyleBox" id=5]
-[ext_resource path="res://ui/theme/button.tres" type="StyleBox" id=6]
-[ext_resource path="res://ui/theme/buttonhover.tres" type="StyleBox" id=7]
[ext_resource path="res://ui/menus/sidebarright/sandisplay/SanDisplay.gd" type="Script" id=8]
[ext_resource path="res://ui/menus/sidebarright/sandisplay/Base.tscn" type="PackedScene" id=10]
-[sub_resource type="StyleBoxEmpty" id=2]
-
-[sub_resource type="StyleBoxEmpty" id=4]
-
-[sub_resource type="StyleBoxFlat" id=3]
-bg_color = Color( 0.0784314, 0.0784314, 0.0784314, 1 )
-border_width_left = 2
-border_width_top = 2
-border_width_right = 2
-border_width_bottom = 2
-border_color = Color( 1, 1, 1, 1 )
-corner_detail = 20
-
-[sub_resource type="StyleBoxEmpty" id=5]
-
-[sub_resource type="DynamicFont" id=7]
-size = 35
-font_data = ExtResource( 1 )
-
-[sub_resource type="Theme" id=6]
-default_font = SubResource( 7 )
-Button/colors/font_color = Color( 1, 1, 1, 1 )
-Button/colors/font_color_focus = Color( 1, 1, 1, 1 )
-Button/colors/font_color_hover = Color( 0, 0, 0, 1 )
-Button/colors/font_color_pressed = Color( 1, 1, 1, 1 )
-Button/styles/disabled = SubResource( 2 )
-Button/styles/focus = ExtResource( 6 )
-Button/styles/hover = ExtResource( 7 )
-Button/styles/normal = ExtResource( 6 )
-Button/styles/pressed = ExtResource( 6 )
-CheckBox/icons/checked = ExtResource( 3 )
-CheckBox/icons/checked_disabled = null
-CheckBox/icons/radio_checked = null
-CheckBox/icons/radio_checked_disabled = null
-CheckBox/icons/radio_unchecked = null
-CheckBox/icons/radio_unchecked_disabled = null
-CheckBox/icons/unchecked = ExtResource( 4 )
-CheckBox/icons/unchecked_disabled = null
-HBoxContainer/constants/separation = 15
-ItemList/colors/font_color = Color( 1, 1, 1, 1 )
-ItemList/colors/font_color_selected = Color( 0.905882, 0.905882, 0.905882, 1 )
-ItemList/styles/bg = SubResource( 4 )
-ItemList/styles/bg_focus = ExtResource( 5 )
-LineEdit/colors/cursor_color = Color( 1, 1, 1, 1 )
-LineEdit/colors/font_color = Color( 1, 1, 1, 1 )
-LineEdit/colors/font_color_uneditable = Color( 1, 1, 1, 0.67451 )
-LineEdit/styles/focus = ExtResource( 6 )
-LineEdit/styles/normal = ExtResource( 6 )
-LineEdit/styles/read_only = ExtResource( 6 )
-OptionButton/colors/font_color = Color( 1, 1, 1, 1 )
-OptionButton/colors/font_color_focus = Color( 1, 1, 1, 1 )
-OptionButton/colors/font_color_hover = Color( 0, 0, 0, 1 )
-OptionButton/colors/font_color_pressed = Color( 1, 1, 1, 1 )
-OptionButton/icons/arrow = ExtResource( 2 )
-PopupMenu/colors/font_color = Color( 1, 1, 1, 1 )
-PopupMenu/colors/font_color_accel = Color( 1, 1, 1, 0.8 )
-PopupMenu/colors/font_color_hover = Color( 1, 1, 1, 1 )
-PopupMenu/colors/font_color_separator = Color( 0.262745, 0.262745, 0.262745, 1 )
-PopupMenu/icons/radio_checked = ExtResource( 2 )
-PopupMenu/icons/radio_unchecked = ExtResource( 2 )
-PopupMenu/styles/hover = SubResource( 3 )
-PopupMenu/styles/panel = ExtResource( 5 )
-VBoxContainer/constants/separation = 15
-VScrollBar/styles/scroll = SubResource( 5 )
+[node name="SanDisplay" type="PanelContainer"]
+anchor_right = 1.0
+anchor_bottom = 1.0
+mouse_filter = 2
+script = ExtResource( 8 )
+Base = ExtResource( 10 )
-[node name="SanDisplay" type="ScrollContainer"]
+[node name="Scroller" type="ScrollContainer" parent="."]
margin_right = 1422.0
margin_bottom = 800.0
-theme = SubResource( 6 )
+hint_tooltip = "click to copy pgn"
scroll_horizontal_enabled = false
-script = ExtResource( 8 )
-Base = ExtResource( 10 )
-[node name="V" type="VBoxContainer" parent="."]
+[node name="sanholder" type="VBoxContainer" parent="Scroller"]
+margin_right = 1422.0
+size_flags_horizontal = 3
custom_constants/separation = 0
diff --git a/ui/theme/main.tres b/ui/theme/main.tres
index 1b8a212..a28f518 100644
--- a/ui/theme/main.tres
+++ b/ui/theme/main.tres
@@ -92,7 +92,7 @@ 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 )
+bg_color = Color( 0, 0, 0, 0.694118 )
corner_radius_top_left = 20
corner_radius_top_right = 20
corner_radius_bottom_right = 20
diff --git a/ui/theme/panel.tres b/ui/theme/panel.tres
index 2d6a689..1651cef 100644
--- a/ui/theme/panel.tres
+++ b/ui/theme/panel.tres
@@ -1,8 +1,4 @@
[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.188235, 0.180392, 0.172549, 1 )