extends Node const MAX_PLAYERS: int = 20 const PORT: int = 7777 signal lobby_created signal lobby_joined signal lobby_closed signal update_teams_state signal client_data_updated(id) var in_lobby: bool = false var attack_team: Array[int] = [] var defence_team: Array[int] = [] var specators_team: Array[int] = [] var client_nicknames: Dictionary[int,StringName] = {} func _ready() -> void: multiplayer.peer_disconnected.connect(player_left) multiplayer.server_disconnected.connect(server_disconnected) multiplayer.peer_connected.connect(add_and_sync_peer) func _enter_tree() -> void: pass func player_left(id: int) -> void: if attack_team.has(id): attack_team.erase(id) elif defence_team.has(id): defence_team.erase(id) elif specators_team.has(id): specators_team.erase(id) client_nicknames.erase(id) update_teams_state.emit() client_data_updated.emit(-id) func server_disconnected() -> void: leave() func host() -> void: var peer: ENetMultiplayerPeer = ENetMultiplayerPeer.new() peer.create_server(PORT,MAX_PLAYERS) multiplayer.multiplayer_peer = peer lobby_created.emit() specators_team.append(multiplayer.get_unique_id()) in_lobby = true client_nicknames = {1 : ClientSettings.NICKNAME} func join(ip: String) -> Error: var peer: ENetMultiplayerPeer = ENetMultiplayerPeer.new() var res = peer.create_client(ip,PORT) if res != 0: return res multiplayer.multiplayer_peer = peer lobby_joined.emit() in_lobby = true return Error.OK func leave() -> void: multiplayer.multiplayer_peer = OfflineMultiplayerPeer.new() attack_team.clear() defence_team.clear() specators_team.clear() lobby_closed.emit() in_lobby = false func add_and_sync_peer(id: int) -> void: if multiplayer.is_server() == false: return specators_team.append(id) update_teams_state.emit() set_teams.rpc_id(id,attack_team,defence_team,specators_team) @rpc("any_peer","call_local","reliable") func recieve_client_data(data: Dictionary): if multiplayer.is_server() == false: return var id = multiplayer.get_remote_sender_id() var nickname: StringName = data["nick"].left(16) client_nicknames[id] = nickname sync_client_data.rpc(client_nicknames) client_data_updated.emit(id) @rpc("authority","call_remote") func sync_client_data(new_client_nicknames: Dictionary[int,StringName]): if multiplayer.is_server() or multiplayer.get_remote_sender_id() != 1: return client_nicknames = new_client_nicknames @rpc("authority","call_remote","reliable") func set_teams(attack: Array[int],defence: Array[int],spectators: Array[int]): attack_team = attack defence_team = defence specators_team = spectators update_teams_state.emit() if is_multiplayer_authority(): set_teams.rpc(attack,defence,spectators) func switch_team(team: int) -> void: team_switch_notification.rpc_id(1,team) func swap_teams() -> void: if not is_multiplayer_authority(): return set_teams(defence_team,attack_team,specators_team) func shuffle_teams() -> void: if not is_multiplayer_authority(): return var peers: Array = Array(multiplayer.get_peers()) peers.append(1) var new_attack_team: Array[int] = [] var new_defence_team: Array[int] = [] var new_spectator_team: Array[int] = [] while len(new_attack_team) < 5 and len(new_defence_team) < 5: if len(peers) == 0: break var picked_peer = peers.pop_at(randi_range(0,len(peers)-1)) var picked_team = randi_range(0,1) match picked_team: Session.TEAMS.DEFENCE: if len(new_defence_team) < 5: new_defence_team.append(picked_peer) else: new_attack_team.append(picked_peer) Session.TEAMS.ATTACK: if len(new_attack_team) < 5: new_attack_team.append(picked_peer) else: new_defence_team.append(picked_peer) new_spectator_team.append_array(peers) set_teams(new_attack_team,new_defence_team,new_spectator_team) @rpc("any_peer","call_local","reliable") func team_switch_notification(team: int) -> void: if not is_multiplayer_authority() or (team == Session.TEAMS.DEFENCE and len(defence_team) > 4) or (team == Session.TEAMS.ATTACK and len(attack_team) > 4) or not LobbySettings.allow_team_switch: return var id: int = multiplayer.get_remote_sender_id() if team == Session.TEAMS.DEFENCE: if attack_team.has(id): attack_team.erase(id) if specators_team.has(id): specators_team.erase(id) defence_team.append(id) if team == Session.TEAMS.ATTACK: if defence_team.has(id): defence_team.erase(id) if specators_team.has(id): specators_team.erase(id) attack_team.append(id) if team == Session.TEAMS.SPECTATE: if attack_team.has(id): attack_team.erase(id) elif defence_team.has(id): defence_team.erase(id) specators_team.append(id) update_teams_state.emit() set_teams.rpc(attack_team,defence_team,specators_team) func start_game() -> void: if not multiplayer.is_server(): return get_tree().current_scene.get_node("%LevelContainer").add_child(Registry.maps[LobbySettings.selected_map].instantiate()) Session.start_session() func get_team() -> Session.TEAMS: var id = multiplayer.get_unique_id() if attack_team.has(id): return Session.TEAMS.ATTACK if defence_team.has(id): return Session.TEAMS.DEFENCE if specators_team.has(id): return Session.TEAMS.SPECTATE return Session.TEAMS.UNASSIGNED