online multiplayer chess game (note server currently down)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
extends Node
class_name NetManager

### for the ui
signal set_buttons(enabled)
signal set_status(status, err, isok)
signal set_visible(visibility)
signal set_back_button(disabled)

signal game_over
signal game_started

var hosting = false
var leaving = false

var status = ["", true, false]

func set_buttons(enabled):
	status[2] = enabled
	emit_signal("set_buttons", enabled)

func return():
	if hosting:
		leaving = true
		Globals.network.send_packet(Globals.network.game_code, Network.HEADERS.stopgame)  # stop hosting
		hosting = false
	set_buttons(true)
	set_status("", true)


func _ready():
	get_tree().set_auto_accept_quit(false)
	if Utils.internet_available():
		var net = Network.new()
		set_status("Connecting", true)
		Events.connect("go_back", self, "_handle_game_over")
		net.connect("move_data", self, "_on_data")
		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


func requestjoin():
	set_buttons( false)
	emit_signal("set_back_button", true)
	Globals.network.send_packet(Globals.network.game_code, Globals.network.HEADERS.joinrequest)


func requesthost():
	set_buttons(false)
	emit_signal("set_back_button", true)
	Globals.network.send_packet(Globals.network.game_code, Globals.network.HEADERS.hostrequest)


func network_ready():
	set_status("", true)
	set_buttons(true)


func set_status(text, isok):
	status[0] = text
	status[1] = isok
	emit_signal("set_status", text, isok)


func _on_join_result(accepted: String) -> void:
	if handle_result(accepted, "Joined!", false):
		Globals.network.send_packet(Globals.network.game_code, Globals.network.HEADERS.startgame)


func _on_host_result(accepted: String) -> void:
	hosting = handle_result(accepted, "Hosted!")


func handle_result(accepted: String, resultstring: String, team: bool = true) -> bool:
	emit_signal("set_back_button", false)
	Globals.team = team
	if accepted == "Y":
		set_status(resultstring, true)
		return true
	set_status(accepted, false)
	set_buttons( true)
	return false


func _handle_game_over(error = "game over", isok = true) -> void:
	Globals.reset_vars()
	if get_tree().get_root().has_node("Board"):
		get_tree().get_root().get_node("Board").queue_free()
	set_status(error, isok)
	emit_signal("set_visible", true)
	emit_signal("game_over")


func _start_game() -> void:
	hosting = false
	var board = load("res://Board.tscn").instance()
	get_tree().get_root().add_child(board)
	emit_signal("set_visible", false)
	emit_signal("game_started")
	set_buttons(false)


static func add_turn() -> void:
	Events.emit_signal("just_before_turn_over")
	Globals.add_turn()
	Globals.turn = not Globals.turn
	Events.emit_signal("turn_over")


func _on_data(data: Dictionary) -> void:
	Log.debug([data, " recieved"])
	Globals.fullmove = data["fullmove"]
	Globals.turn = data["turn"]
	Globals.halfmove = data["halfmove"]
	Events.emit_signal("data_recieved")
	match data["movetype"]:
		Network.MOVEHEADERS.passant:
			# en passant
			var end_pos = dict2vec(data["positions"][1])
			var start_piece = Piece.at_pos(dict2vec(data["positions"][0]))
			Piece.at_pos(dict2vec(data["positions"][2])).took()  # kill the unfortunate
			start_piece.passant(end_pos)
		Network.MOVEHEADERS.move:
			var start_piece = Piece.at_pos(dict2vec(data["positions"][0]))
			var end_pos = dict2vec(data["positions"][1])
			var end_piece = Piece.at_pos(end_pos)
			if end_piece != null:
				start_piece.take(end_piece)
			else:
				start_piece.moveto(end_pos)
		Network.MOVEHEADERS.castle:
			var king = Piece.at_pos(dict2vec(data["positions"]["king"]))
			var rook = Piece.at_pos(dict2vec(data["positions"]["rook"]))
			rook.moveto(dict2vec(data["positions"]["rookdestination"]), true, false, true)
			Utils.add_move(king.castle(dict2vec(data["positions"]["kingdestination"])))
		Network.MOVEHEADERS.promote:
			var dict_data = data["positions"]  # positions is a dict for readability sometimes
			var pawn = Piece.at_pos(dict2vec(dict_data["start_position"]))
			var dest = dict2vec(dict_data["destination"])
			if Piece.at_pos(dest) != null:
				Piece.at_pos(dest).took()  # move the pawn to the new place, killing if necessary
				pawn.clear_clicked()
			Globals.grid.make_piece(dest, Pawn.piece(dict_data["become"]), dict_data["white"])  # create the promotion
			pawn.took()  # kill the pawn
			Utils.add_move(dict_data["notation"])  # add a move
			Globals.grid.print_matrix_pretty(Globals.grid.matrix)


static func dict2vec(dict: Dictionary) -> Vector2:
	return Vector2(dict["x"], dict["y"])