summaryrefslogtreecommitdiff
path: root/Network/Network.gd
blob: ce4952c01d6e257058fa924647153ca4c597f1eb (plain)
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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
extends Node


signal connection_succeeded()
signal connection_failed()
signal player_list_changed()
signal player_changed()
signal game_error()
signal game_started()
signal game_ended()


const PORT = 10567
const MAX_PEERS = 2
var peer: ENetMultiplayerPeer = null


var player = null
var winning_player = player

# Dictionary { id = player }
var players = {}

func create_player():
	return {
		name = "",
		character = "",
		symbol = "",
		components = [],
		current_level = -1,
		position = Vector2(0, 0),
	}


func _ready():
	self.player = self.create_player()
	
	multiplayer.connect("peer_connected", Callable(self, '_player_connected'))
	multiplayer.connect("peer_disconnected", Callable(self, "_player_disconnected"))
	multiplayer.connect("connected_to_server", Callable(self, "_connection_succeeded"))
	multiplayer.connect("connection_failed", Callable(self, "_connection_failed"))
	multiplayer.connect("server_disconnected", Callable(self, "_server_disconnected"))
	Global.connect("game_started", Callable(self, "_on_Global_game_started"))
	Global.connect("game_ended", Callable(self, "_on_Global_game_ended"))
	Global.connect("game_won", Callable(self, "_on_Global_game_won"))


@rpc("any_peer") func register_player(player_name):
	var id = multiplayer.get_remote_sender_id()
	
	var network_player = self.create_player()
	network_player.name = player_name
	self.players[id] = network_player
	
	emit_signal("player_list_changed")


func unregister_player(id):
	self.players.erase(id)
	emit_signal("player_list_changed")


func update_player():
	rpc("remote_update_player", self.player)
	
@rpc("any_peer") func remote_update_player(network_player):
	var id = multiplayer.get_remote_sender_id()
	self.players[id] = network_player
	emit_signal("player_changed", id)


func host_game(player_name):
	self.player.name = player_name
	self.peer = ENetMultiplayerPeer.new()
	self.peer.create_server(self.PORT, self.MAX_PEERS)
	multiplayer.multiplayer_peer = self.peer


func join_game(ip, player_name):
	self.player.name = player_name
	self.peer = ENetMultiplayerPeer.new()
	self.peer.create_client(ip, self.PORT)
	multiplayer.multiplayer_peer = self.peer


func leave_game():
	rpc("_leave_game")
	multiplayer.multiplayer_peer = null
	self.players = []


@rpc("any_peer") func _leave_game():
	var id = multiplayer.get_remote_sender_id()
	self.peer.disconnect_peer(id)


func get_player_count():
	return self.players.size() + 1


func _on_Global_game_started():
	# set symbols
	self.player.symbol = "X"
	var idx = 1
	for id in self.players:
		self.players[id].symbol = ["X", "O", "P"][idx]
		idx += 1
	
	# preconfigure game
	var all_players = self.players.duplicate()
	all_players[1] = self.player
	rpc("_preconfigure_game", {
		level_map = Global.Level_Map,
		players = all_players,
	})
	
	# start game for everyone
	rpc("_start_game")


@rpc("any_peer") func _preconfigure_game(configuration):
	Global.Level_Map = configuration.level_map
	
	self.player = configuration.players[multiplayer.get_unique_id()]
	configuration.players.erase(multiplayer.get_unique_id())
	self.players = configuration.players

@rpc("any_peer", "call_local") func _start_game():
	rpc("remote_update_player", self.player)
	emit_signal("game_started")


func _on_Global_game_ended():
	# tell all peers to end the game
	rpc("_end_game")


func _on_Global_game_won(winning_player_object):
	rpc("_end_game", winning_player_object)


@rpc("any_peer", "call_local") func _end_game(winning_player_object):
	self.winning_player = winning_player_object
	emit_signal("game_ended")


func _player_connected(_id):
	rpc("register_player", self.player.name)


func _player_disconnected(id):
	# if game is in progress:
		# self.end_game() ?
	# else
		#rpc("unregister_player", id)
	#rpc("unregister_player", id)
	self.unregister_player(id)


func _connection_succeeded():
	emit_signal("connection_succeeded")


func _connection_failed():
	multiplayer.multiplayer_peer = null # remove peer
	self.players = []
	emit_signal("connection_failed")


func _server_disconnected():
	emit_signal("game_error", "Server disconnected!")
	multiplayer.multiplayer_peer = null
	self.players = []
	#self.end_game("")