diff --git a/scenes/game.gd b/scenes/game.gd index 393ba48..68f198e 100644 --- a/scenes/game.gd +++ b/scenes/game.gd @@ -7,13 +7,18 @@ var local_player_name: String ## The color to be given to the player controlled by the local peer. var local_player_color: Color + ## The [PeerNodeDirectory] instance child of this node. @onready var peer_dir: PeerNodeDirectory = $"PeerNodeDirectory" ## The [PlayerNodeDirectory] instance child of this node. @onready var player_dir: PlayerNodeDirectory = $"PlayerNodeDirectory" +## The [PhaseTracker] instance child of this node. +@onready var phase_tracker: PhaseTracker = $"PhaseTracker" + +## Initialize some signals needed by this node to function properly. func init_signals() -> void: multiplayer.connected_to_server.connect(_on_multiplayer_connected_to_server) multiplayer.server_disconnected.connect(_on_multiplayer_disconnected_from_server) @@ -41,6 +46,7 @@ func _on_multiplayer_peer_connected(peer_id: int) -> void: playernode.rpc_query_name.rpc_id(playernode.get_multiplayer_authority()) playernode.rpc_query_color.rpc_id(playernode.get_multiplayer_authority()) peer_dir.rpc_create_peernode.rpc(peer_id) + rpc_set_phase.rpc_id(peer_id, phase) func _on_multiplayer_peer_disconnected(peer_id: int) -> void: Log.peer(self, "Peer disconnected: %d" % peer_id) @@ -81,3 +87,8 @@ func _on_playerdir_playernode_possessed(old: int, new: int, playernode: PlayerNo if playernode.is_multiplayer_authority() and not multiplayer.is_server(): playernode.rpc_set_name.rpc(local_player_name) playernode.rpc_set_color.rpc(local_player_color) + + +func _on_main_start_confirmed() -> void: + if multiplayer.is_server(): + rpc_set_phase.rpc(Phase.PLAYING) diff --git a/scenes/lobby_menu.gd b/scenes/lobby_menu.gd index 875ecde..204b32a 100644 --- a/scenes/lobby_menu.gd +++ b/scenes/lobby_menu.gd @@ -7,9 +7,11 @@ signal start_confirmed var players_list: Container +var start_button: Button func init_refs(): players_list = $"Layout/PlayersList" + start_button = $"Layout/HBoxContainer/StartButton" func _on_leave_button_pressed() -> void: diff --git a/scenes/lobby_menu.tscn b/scenes/lobby_menu.tscn index 64a8eea..645f932 100644 --- a/scenes/lobby_menu.tscn +++ b/scenes/lobby_menu.tscn @@ -49,6 +49,7 @@ text = "Esci" [node name="StartButton" type="Button" parent="Layout/HBoxContainer"] layout_mode = 2 size_flags_horizontal = 3 +disabled = true text = "Avvia" [connection signal="pressed" from="Layout/HBoxContainer/LeaveButton" to="." method="_on_leave_button_pressed"] diff --git a/scenes/main.gd b/scenes/main.gd index d4fd380..e71d5d6 100644 --- a/scenes/main.gd +++ b/scenes/main.gd @@ -15,16 +15,16 @@ var client_game_instance: Game = null const lobby_menu_scene: PackedScene = preload("res://scenes/lobby_menu.tscn") var lobby_menu_instance: LobbyMenu = null -func init_main_menu(): +func init_main_menu() -> void: main_menu_instance = main_menu_scene.instantiate() main_menu_instance.hosting_confirmed.connect(_on_hosting_confirmed) main_menu_instance.connecting_confirmed.connect(_on_connecting_confirmed) interface_instance.add_child(main_menu_instance) -func deinit_main_menu(): +func deinit_main_menu() -> void: main_menu_instance.queue_free() -func init_server_game(server_port: int): +func init_server_game(server_port: int) -> void: server_game_instance = game_scene.instantiate() server_game_instance.name = "Server" add_child(server_game_instance, true) @@ -41,12 +41,12 @@ func init_server_game(server_port: int): server_game_instance.init_signals() smp.set_multiplayer_peer(peer) -func deinit_server_game(): +func deinit_server_game() -> void: server_game_instance.multiplayer.multiplayer_peer = null scene_tree.set_multiplayer(multiplayer, ^"/root/Main/Server") server_game_instance.queue_free() -func init_client_game(player_name: String, player_color: Color, server_address: String, server_port: int): +func init_client_game(player_name: String, player_color: Color, server_address: String, server_port: int) -> void: client_game_instance = game_scene.instantiate() client_game_instance.name = "Client" add_child(client_game_instance, true) @@ -65,53 +65,66 @@ func init_client_game(player_name: String, player_color: Color, server_address: client_game_instance.local_player_color = player_color smp.set_multiplayer_peer(peer) -func deinit_client_game(): +func deinit_client_game() -> void: client_game_instance.multiplayer.multiplayer_peer = null scene_tree.set_multiplayer(multiplayer, ^"/root/Main/Client") client_game_instance.queue_free() -func init_lobby_menu(): +func init_lobby_menu() -> void: lobby_menu_instance = lobby_menu_scene.instantiate() - lobby_menu_instance.leave_confirmed.connect(_on_leave_confirmed) - lobby_menu_instance.start_confirmed.connect(_on_start_confirmed) lobby_menu_instance.init_refs() + lobby_menu_instance.leave_confirmed.connect(_on_leave_confirmed) + if server_game_instance: + lobby_menu_instance.start_button.disabled = false + lobby_menu_instance.start_confirmed.connect(server_game_instance._on_main_start_confirmed) client_game_instance.multiplayer.server_disconnected.connect(_on_leave_confirmed) client_game_instance.player_dir.child_entered_tree.connect(lobby_menu_instance.players_list._on_playernode_created) client_game_instance.player_dir.child_exiting_tree.connect(lobby_menu_instance.players_list._on_playernode_destroyed) client_game_instance.player_dir.playernode_name_changed.connect(lobby_menu_instance.players_list._on_playernode_name_changed) client_game_instance.player_dir.playernode_color_changed.connect(lobby_menu_instance.players_list._on_playernode_color_changed) client_game_instance.player_dir.playernode_possessed.connect(lobby_menu_instance.players_list._on_playernode_possessed) + client_game_instance.phase_tracker.phase_changed.connect(_on_phase_changed) interface_instance.add_child(lobby_menu_instance) -func deinit_lobby_menu(): - client_game_instance.multiplayer.server_disconnected.disconnect(_on_leave_confirmed) - client_game_instance.player_dir.child_entered_tree.disconnect(lobby_menu_instance.players_list._on_playernode_created) - client_game_instance.player_dir.child_exiting_tree.disconnect(lobby_menu_instance.players_list._on_playernode_destroyed) - client_game_instance.player_dir.playernode_name_changed.disconnect(lobby_menu_instance.players_list._on_playernode_name_changed) - client_game_instance.player_dir.playernode_color_changed.disconnect(lobby_menu_instance.players_list._on_playernode_color_changed) - client_game_instance.player_dir.playernode_possessed.disconnect(lobby_menu_instance.players_list._on_playernode_possessed) +func deinit_lobby_menu() -> void: + # TODO: Disconnect all signals above lobby_menu_instance.queue_free() -func _ready(): +func _ready() -> void: init_main_menu() -func _on_hosting_confirmed(player_name: String, player_color: Color, server_port: int): +func _on_hosting_confirmed(player_name: String, player_color: Color, server_port: int) -> void: deinit_main_menu() init_server_game(server_port) init_client_game(player_name, player_color, "127.0.0.1", server_port) init_lobby_menu() -func _on_connecting_confirmed(player_name: String, player_color: Color, server_address: String, server_port: int): +func _on_connecting_confirmed(player_name: String, player_color: Color, server_address: String, server_port: int) -> void: deinit_main_menu() init_client_game(player_name, player_color, server_address, server_port) init_lobby_menu() -func _on_leave_confirmed(): +func _on_leave_confirmed() -> void: deinit_lobby_menu() deinit_client_game() if server_game_instance != null: deinit_server_game() init_main_menu() -func _on_start_confirmed(): - pass +func _on_phase_changed(old: PhaseTracker.Phase, new: PhaseTracker.Phase) -> void: + # First, deinitialize the current interface + match old: + PhaseTracker.Phase.LOBBY: + deinit_lobby_menu() + PhaseTracker.Phase.PLAYING: + pass # TODO + PhaseTracker.Phase.ENDED: + pass # TODO + # Then, initialize the new one + match new: + PhaseTracker.Phase.LOBBY: + init_lobby_menu() + PhaseTracker.Phase.PLAYING: + pass # TODO + PhaseTracker.Phase.ENDED: + pass # TODO diff --git a/scenes/phase_tracker.gd b/scenes/phase_tracker.gd new file mode 100644 index 0000000..bd01d27 --- /dev/null +++ b/scenes/phase_tracker.gd @@ -0,0 +1,34 @@ +extends Node +class_name PhaseTracker + + +## Phases of play of the game. +enum Phase { + ## The game is currently gathering players in a lobby. + LOBBY, + ## The game is currently running. + PLAYING, + ## The game has ended. + ENDED, +} + +## The phase the game is currently in. +var phase: Phase = Phase.LOBBY + +## Change the current game phase everywhere. +@rpc("authority", "call_local", "reliable") +func rpc_set_phase(value: Phase): + Log.peer(self, "Changing phase to: %s" % value) + if phase != value: + var old: Phase = phase + phase = value + phase_changed.emit(old, value) + +## Ask the server which phase the game is currently in. +@rpc("any_peer", "call_local", "reliable") +func rpc_query_phase(): + if multiplayer.is_server(): + rpc_set_phase.rpc(phase) + +## Emitted when the phase changes on the local scene because of [method rpc_set_phase]. +signal phase_changed(old: Phase, new: Phase) diff --git a/scenes/phase_tracker.tscn b/scenes/phase_tracker.tscn new file mode 100644 index 0000000..a0fcbe5 --- /dev/null +++ b/scenes/phase_tracker.tscn @@ -0,0 +1,3 @@ +[gd_scene format=3 uid="uid://dc8pe5dnk8kbv"] + +[node name="PhaseTracker" type="Node"]