extends Control signal joined var current_map_idx := 0 var current_map_scene: Node var settings := {} var teams := {} @onready var list: Control = %PlayersListContainer.list func _ready() -> void: if not multiplayer.is_server(): %StartButton.disabled = true if multiplayer.is_server(): joined.connect(func(): set_map.rpc(current_map_idx) ) for idx in %Maps.get_child_count(): %Maps.get_child(idx).pressed.connect(func(): if current_map_idx != idx: set_map.rpc(idx) ) if not multiplayer.is_server(): for node: Control in %Maps.get_children(): node.mouse_filter = Control.MOUSE_FILTER_IGNORE Network.players_changed.connect(update_players) update_players() multiplayer.peer_disconnected.connect(remove_player) multiplayer.peer_connected.connect(_on_peer_connected) multiplayer.peer_disconnected.connect(_on_peer_disconnected) # reset map texture for clean load %Thumbnail.texture = null set_map(current_map_idx) # send keep-alive to game-lobby-server if multiplayer.is_server(): $KeepAliveTimer.start() $KeepAliveTimer.timeout.connect(func(): await GameLobby.request_post("/keep-alive") ) func update_players(): update_list(list, Network.get_ordered_player_ids()) func remove_player(id): list.remove_child(list.get_node(str(id))) func update_list(current_list: Control, player_ids: Array): for id in player_ids: var player: Player = Network.get_player(id) var control: Control = current_list.get_node_or_null(str(id)) if not control: control = MarginContainer.new() control.name = str(id) var label = Label.new() label.add_theme_color_override("font_color", player.get_color()) if id == multiplayer.get_unique_id(): label.add_theme_color_override("font_outline_color", Color(0.75, 0.75, 0.75, 0.75)) label.add_theme_constant_override("outline_size", 10) control.add_child(label) current_list.add_child(control) #joined.emit() control.get_child(0).text = str(player.username) control.get_child(0).tooltip_text = str(id) current_list.move_child(control, player_ids.find(id) + 1) # TODO: test with 3 players func _on_peer_connected(id): Network._on_peer_connected(id) func _on_peer_disconnected(id): Network._on_peer_disconnected(id) func _on_start_button_pressed() -> void: start.rpc() func _on_cancel_button_pressed() -> void: multiplayer.multiplayer_peer.close() # TODO: if was host => Start. if was joined and connected from list => List get_tree().change_scene_to_file("res://UI/Start.tscn") @rpc("authority", "call_local") func start(): var packed_scene = %Maps.get_child(current_map_idx).get_meta("map_scene") var scene = packed_scene.instantiate() for setting in settings: scene[setting] = settings[setting] if settings.get("use_premade_teams"): var premade_teams = {} for team_name in teams: premade_teams[team_name] = teams[team_name]["players"] scene.premade_teams = premade_teams Client.change_scene_to_instance(scene) @rpc("authority", "call_local") func set_map(index: int): current_map_idx = index for node: Control in %Teams.get_children().slice(1): node.queue_free() %PlayersListContainer.visible = true for node: Button in %Maps.get_children(): node.add_theme_color_override("font_color", Color(1.0, 1.0, 1.0, 0.5)) var map_button = %Maps.get_child(index) var thumbnail = map_button.get_meta("thumbnail") # settings for child in %Settings.get_children(): child.queue_free() if map_button.has_meta("settings"): current_map_scene = map_button.get_meta("map_scene").instantiate() var map_settings = map_button.get_meta("settings", []) for setting in map_settings: settings[setting] = current_map_scene[setting] var control = preload("res://UI/PlayerLobby/lobby_setting.tscn").instantiate() control.label = setting control.value = settings[setting] control.disabled = !multiplayer.is_server() if multiplayer.is_server(): control.value_changed.connect(func(value): set_setting.rpc(setting, value) ) %Settings.add_child(control) map_button.add_theme_color_override("font_color", Color(1.0, 1.0, 1.0, 1.0)) %Thumbnail.texture = thumbnail @rpc("authority", "call_local") func set_setting(key: String, value: Variant): settings[key] = value if not multiplayer.is_server(): %Settings.get_node(key).value = value # generate PlayersLists per team with clickable labels to switch team if settings.get("use_premade_teams"): %PlayersListContainer.visible = false var team_names = current_map_scene.teams.names() var players_per_team = Network.get_ordered_player_ids().size() / team_names.size() for idx in team_names.size(): var team_name = team_names[idx] var new_list_container = preload("res://UI/players_list_container.tscn").instantiate() new_list_container.label = team_name.to_upper() new_list_container.clicked.connect(func(): switch_team.rpc(team_name) ) %Teams.add_child(new_list_container) var offset = players_per_team * idx teams[team_name] = {} teams[team_name]["players"] = Network.get_ordered_player_ids().slice(offset, offset + players_per_team) teams[team_name]["list"] = new_list_container.list update_list(teams[team_name]["list"], teams[team_name]["players"]) @rpc("any_peer", "call_local") func switch_team(team_name: String): #func switch_team(previous_team_name: String, new_team_name: String): var player_id = multiplayer.get_remote_sender_id() for key in teams: var team = teams[key] team["players"].erase(player_id) var node = team["list"].get_node_or_null(str(player_id)) if node: team["list"].remove_child(node) teams[team_name]["players"].append(player_id) update_list(teams[team_name]["list"], teams[team_name]["players"])