diff --git a/project.godot b/project.godot index ffb8cb7..a2a4bd5 100644 --- a/project.godot +++ b/project.godot @@ -26,6 +26,7 @@ Session="*res://scripts/multiplayer/session.gd" window/size/viewport_width=1280 window/size/viewport_height=720 window/stretch/mode="viewport" +window/stretch/aspect="ignore" [input] diff --git a/scenes/main_menu.tscn b/scenes/main_menu.tscn index 35a644a..a229a05 100644 --- a/scenes/main_menu.tscn +++ b/scenes/main_menu.tscn @@ -1,22 +1,20 @@ -[gd_scene load_steps=4 format=3 uid="uid://cbtp4rvg66ba1"] +[gd_scene load_steps=3 format=3 uid="uid://cbtp4rvg66ba1"] [ext_resource type="Script" uid="uid://bsyuos803g7qf" path="res://scripts/gui/main_menu_gui.gd" id="1_l6cm7"] -[ext_resource type="Script" uid="uid://cl3hhmw5666sj" path="res://scripts/gui/lobby/players_display.gd" id="2_ekxnf"] [ext_resource type="Script" uid="uid://2uyxkfmbbims" path="res://scripts/gui/lobby/lobby_buttons.gd" id="3_bqqt6"] -[node name="MainMenu" type="Control"] -layout_mode = 3 +[node name="MainMenu" type="CenterContainer"] anchors_preset = 15 anchor_right = 1.0 anchor_bottom = 1.0 grow_horizontal = 2 grow_vertical = 2 script = ExtResource("1_l6cm7") +metadata/_edit_lock_ = true [node name="MainMenu" type="PanelContainer" parent="."] -layout_mode = 0 -offset_right = 293.0 -offset_bottom = 101.0 +custom_minimum_size = Vector2(256, 0) +layout_mode = 2 [node name="VBoxContainer" type="VBoxContainer" parent="MainMenu"] layout_mode = 2 @@ -35,30 +33,82 @@ placeholder_text = "ip" [node name="Lobby" type="PanelContainer" parent="."] visible = false -layout_mode = 0 -offset_right = 305.0 -offset_bottom = 242.0 +custom_minimum_size = Vector2(256, 256) +layout_mode = 2 [node name="VBoxContainer" type="VBoxContainer" parent="Lobby"] layout_mode = 2 [node name="Players" type="HBoxContainer" parent="Lobby/VBoxContainer"] layout_mode = 2 -script = ExtResource("2_ekxnf") +size_flags_vertical = 3 +alignment = 1 + +[node name="AttackTeam" type="VBoxContainer" parent="Lobby/VBoxContainer/Players"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="TeamName" type="Label" parent="Lobby/VBoxContainer/Players/AttackTeam"] +layout_mode = 2 +text = "Attack" +horizontal_alignment = 1 + +[node name="DefenceTeam" type="VBoxContainer" parent="Lobby/VBoxContainer/Players"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="TeamName" type="Label" parent="Lobby/VBoxContainer/Players/DefenceTeam"] +layout_mode = 2 +text = "Defence" +horizontal_alignment = 1 + +[node name="SpectatorsTeam" type="VBoxContainer" parent="Lobby/VBoxContainer/Players"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="TeamName" type="Label" parent="Lobby/VBoxContainer/Players/SpectatorsTeam"] +layout_mode = 2 +text = "Spectators" +horizontal_alignment = 1 [node name="Buttons" type="HBoxContainer" parent="Lobby/VBoxContainer"] layout_mode = 2 +alignment = 1 script = ExtResource("3_bqqt6") [node name="LeaveButton" type="Button" parent="Lobby/VBoxContainer/Buttons"] +unique_name_in_owner = true layout_mode = 2 text = "Leave" [node name="StartButton" type="Button" parent="Lobby/VBoxContainer/Buttons"] +unique_name_in_owner = true layout_mode = 2 text = "Start" +[node name="JoinAttackButton" type="Button" parent="Lobby/VBoxContainer/Buttons"] +unique_name_in_owner = true +layout_mode = 2 +text = "Join Attack" + +[node name="JoinDefenceButton" type="Button" parent="Lobby/VBoxContainer/Buttons"] +unique_name_in_owner = true +layout_mode = 2 +text = "Join Defence" + +[node name="JoinSpectatorsButton" type="Button" parent="Lobby/VBoxContainer/Buttons"] +unique_name_in_owner = true +visible = false +layout_mode = 2 +text = "Join Spectators" + [connection signal="pressed" from="MainMenu/VBoxContainer/HostButton" to="." method="_on_host_button_pressed"] [connection signal="pressed" from="MainMenu/VBoxContainer/ConnectButton" to="." method="_on_connect_button_pressed"] -[connection signal="pressed" from="Lobby/VBoxContainer/Buttons/LeaveButton" to="Lobby/VBoxContainer/Buttons" method="_on_leave_button_pressed"] -[connection signal="pressed" from="Lobby/VBoxContainer/Buttons/StartButton" to="Lobby/VBoxContainer/Buttons" method="_on_start_button_pressed"] +[connection signal="pressed" from="Lobby/VBoxContainer/Buttons/LeaveButton" to="." method="_on_leave_button_pressed"] +[connection signal="pressed" from="Lobby/VBoxContainer/Buttons/StartButton" to="." method="_on_start_button_pressed"] +[connection signal="pressed" from="Lobby/VBoxContainer/Buttons/JoinAttackButton" to="." method="_on_join_attack_button_pressed"] +[connection signal="pressed" from="Lobby/VBoxContainer/Buttons/JoinDefenceButton" to="." method="_on_join_defence_button_pressed"] +[connection signal="pressed" from="Lobby/VBoxContainer/Buttons/JoinSpectatorsButton" to="." method="_on_join_spectators_button_pressed"] diff --git a/scripts/gui/lobby/players_display.gd b/scripts/gui/lobby/players_display.gd deleted file mode 100644 index 39709d7..0000000 --- a/scripts/gui/lobby/players_display.gd +++ /dev/null @@ -1,28 +0,0 @@ -extends Node - - -func _ready() -> void: - multiplayer.peer_connected.connect(on_peer_connected) - multiplayer.peer_disconnected.connect(on_peer_disconnected) - Lobby.lobby_created.emit(add_self) - Lobby.lobby_joined.emit(add_self) - Lobby.lobby_closed.emit(clear) - -func on_peer_connected(id: int) -> void: - var label = Label.new() - label.text = str(id) - label.name = str(id) - add_child(label,true) - -func on_peer_disconnected(id: int) -> void: - get_node(str(id)).queue_free() - -func add_self() -> void: - var label = Label.new() - label.text = str(multiplayer.get_unique_id()) - label.name = str(multiplayer.get_unique_id()) - add_child(label,true) - -func clear() -> void: - for child in get_children(): - child.queue_free() diff --git a/scripts/gui/lobby/players_display.gd.uid b/scripts/gui/lobby/players_display.gd.uid deleted file mode 100644 index a08b12b..0000000 --- a/scripts/gui/lobby/players_display.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://cl3hhmw5666sj diff --git a/scripts/gui/main_menu_gui.gd b/scripts/gui/main_menu_gui.gd index b438b81..7bca66e 100644 --- a/scripts/gui/main_menu_gui.gd +++ b/scripts/gui/main_menu_gui.gd @@ -1,13 +1,38 @@ extends Node +func _ready() -> void: + Lobby.lobby_joined.connect(hide_host_buttons) + Lobby.lobby_created.connect(show_host_buttons) + Lobby.lobby_closed.connect(cleanup_lobby) + Lobby.update_teams_state.connect(on_player_switched_team) + +func _on_leave_button_pressed() -> void: + Lobby.leave() + cleanup_lobby() + +func cleanup_lobby() -> void: + $Lobby.hide() + $MainMenu.show() + %JoinAttackButton.show() + %JoinDefenceButton.show() + %JoinSpectatorsButton.hide() + + +func _on_start_button_pressed() -> void: + Lobby.start_game.rpc() + +func hide_host_buttons() -> void: + %StartButton.hide() + +func show_host_buttons() -> void: + %StartButton.show() func _on_host_button_pressed() -> void: Lobby.host() $MainMenu.hide() $Lobby.show() - func _on_connect_button_pressed() -> void: var ip = $MainMenu/VBoxContainer/LineEdit.text if ip == "": @@ -17,3 +42,53 @@ func _on_connect_button_pressed() -> void: return $MainMenu.hide() $Lobby.show() + +func on_player_switched_team(): + %JoinAttackButton.hide() + %JoinDefenceButton.hide() + %JoinSpectatorsButton.visible = Lobby.specators_team.has(multiplayer.get_unique_id()) == false + if Lobby.attack_team.size() < 5 and not Lobby.attack_team.has(multiplayer.get_unique_id()): + %JoinAttackButton.show() + if Lobby.defence_team.size() < 5 and not Lobby.defence_team.has(multiplayer.get_unique_id()): + %JoinDefenceButton.show() + + for child in %AttackTeam.get_children(): + if child.name == "TeamName": + continue + child.queue_free() + + for child in %DefenceTeam.get_children(): + if child.name == "TeamName": + continue + child.queue_free() + + for child in %SpectatorsTeam.get_children(): + if child.name == "TeamName": + continue + child.queue_free() + + for attacker in Lobby.attack_team: + var label = Label.new() + label.text = str(attacker) + %AttackTeam.add_child(label) + + for defender in Lobby.defence_team: + var label = Label.new() + label.text = str(defender) + %DefenceTeam.add_child(label) + + for spectator in Lobby.specators_team: + var label = Label.new() + label.text = str(spectator) + %SpectatorsTeam.add_child(label) + +func _on_join_attack_button_pressed() -> void: + Lobby.switch_team(Session.TEAMS.ATTACK) + + +func _on_join_defence_button_pressed() -> void: + Lobby.switch_team(Session.TEAMS.DEFENCE) + + +func _on_join_spectators_button_pressed() -> void: + Lobby.switch_team(Session.TEAMS.SPECTATE) diff --git a/scripts/multiplayer/lobby.gd b/scripts/multiplayer/lobby.gd index de42188..5b926e6 100644 --- a/scripts/multiplayer/lobby.gd +++ b/scripts/multiplayer/lobby.gd @@ -7,12 +7,35 @@ const PORT: int = 7777 signal lobby_created signal lobby_joined signal lobby_closed +signal update_teams_state + +var attack_team: Array[int] = [] +var defence_team: Array[int] = [] +var specators_team: Array[int] = [] + +func _ready() -> void: + multiplayer.peer_disconnected.connect(player_left) + multiplayer.server_disconnected.connect(server_disconnected) + multiplayer.peer_connected.connect(add_and_sync_peer) + +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) + update_teams_state.emit() + +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()) func join(ip: String) -> Error: var peer: ENetMultiplayerPeer = ENetMultiplayerPeer.new() @@ -25,8 +48,55 @@ func join(ip: String) -> Error: func leave() -> void: multiplayer.multiplayer_peer = OfflineMultiplayerPeer.new() + attack_team.clear() + defence_team.clear() + specators_team.clear() lobby_closed.emit() +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_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() + +func switch_team(team: int) -> void: + team_switch_notification.rpc(multiplayer.get_unique_id(),team) + +@rpc("any_peer","call_local","reliable") +func team_switch_notification(id: int, team: int) -> void: + if (team == Session.TEAMS.DEFENCE and len(defence_team) > 4) or (team == Session.TEAMS.ATTACK and len(attack_team) > 4): + return + 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() + @rpc("authority","call_local","reliable") func start_game() -> void: get_tree().change_scene_to_file("res://levels/prototype_scene.tscn")