1
Fork 0
mirror of https://github.com/Steffo99/nanogolf.git synced 2024-11-21 15:44:21 +00:00

Keep refactoring player trackers

This commit is contained in:
Steffo 2024-03-07 05:06:37 +01:00
parent ada7d71855
commit a10ad9aa64
Signed by: steffo
GPG key ID: 5ADA3868646C3FC0
11 changed files with 146 additions and 67 deletions

View file

@ -43,7 +43,10 @@ func _on_peer_connected(peer_id: int):
if multiplayer.is_server():
assert(peer_id != 1, "This is a server, but the remote peer_id is 1.")
Log.peer(self, "Initializing tracker for: " + str(peer_id))
mp_tracker.spawn(peer_id)
mp_tracker.create(peer_id)
# Log.peer(self, "Setting multiplayer authority: " + str(peer_id))
# var sp_tracker = mp_tracker.find(peer_id)
# sp_tracker.set_multiplayer_authority(peer_id)
func _on_peer_disconnected(peer_id: int):
Log.peer(self, "Peer disconnected: " + str(peer_id))
@ -51,13 +54,28 @@ func _on_peer_disconnected(peer_id: int):
assert(peer_id != 1, "This is a server, but the remote peer_id is 1.")
Log.peer(self, "Deinitializing tracker for: " + str(peer_id))
mp_tracker.mark_disconnected.rpc(peer_id)
# Log.peer(self, "Unsetting multiplayer authority: " + str(peer_id))
# var sp_tracker = mp_tracker.find(peer_id)
# sp_tracker.set_multiplayer_authority(1)
func _on_single_player_tracker_spawned(spawned_tracker: SinglePlayerTracker) -> void:
func _on_single_player_tracker_created(spawned_tracker: SinglePlayerTracker) -> void:
# If we spawned ourselves, set our own identity
if spawned_tracker.get_multiplayer_authority() == multiplayer.multiplayer_peer.get_unique_id():
Log.peer(self, "Checking if we should notify our identity to everybody else...")
spawned_tracker.update_identity.rpc(local_player_name, local_player_color)
# If another player spawned, and they connected before us, send them our identity
else:
elif not multiplayer.is_server():
Log.peer(self, "Checking if we should notify our identity to: " + str(spawned_tracker.get_multiplayer_authority()))
var self_tracker = mp_tracker.find(multiplayer.multiplayer_peer.get_unique_id())
if self_tracker != null:
self_tracker.notify_identity(spawned_tracker.get_multiplayer_authority())
# If we're the server, broadcast information about disconnected players
else:
Log.peer(self, "Checking if we should notify identity for disconnected peers...")
for tracker in mp_tracker.find_children("", "SinglePlayerTracker", true, false):
Log.peer(self, str(tracker))
if tracker.get_multiplayer_authority() == 1:
Log.peer(self, "I'm the authority, do notify.")
tracker.notify_identity(spawned_tracker.get_multiplayer_authority())
else:
Log.peer(self, "I'm not the authority, do not notify.")

View file

@ -8,5 +8,5 @@ script = ExtResource("1_cdtng")
[node name="MultiplePlayersTracker" parent="." instance=ExtResource("2_f2gy2")]
[connection signal="spawned" from="MultiplePlayersTracker" to="." method="_on_single_player_tracker_spawned"]
[connection signal="created" from="MultiplePlayersTracker" to="." method="_on_single_player_tracker_created"]
[connection signal="trackers_changed" from="MultiplePlayersTracker" to="." method="_on_trackers_changed"]

View file

@ -2,8 +2,17 @@ extends Control
class_name LobbyMenu
signal leave_confirmed
signal start_confirmed
@onready var players_list: PlayersList = $"Layout/PlayersList"
func _on_trackers_changed(trackers: Dictionary):
players_list._on_trackers_changed(trackers)
func _on_leave_button_pressed() -> void:
leave_confirmed.emit()
func _on_start_button_pressed() -> void:
start_confirmed.emit()

View file

@ -38,6 +38,18 @@ layout_mode = 2
custom_minimum_size = Vector2(0, 16)
layout_mode = 2
[node name="Button" type="Button" parent="Layout"]
[node name="HBoxContainer" type="HBoxContainer" parent="Layout"]
layout_mode = 2
text = "Avvia partita"
[node name="LeaveButton" type="Button" parent="Layout/HBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3
text = "Esci"
[node name="StartButton" type="Button" parent="Layout/HBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3
text = "Avvia"
[connection signal="pressed" from="Layout/HBoxContainer/LeaveButton" to="." method="_on_leave_button_pressed"]
[connection signal="pressed" from="Layout/HBoxContainer/StartButton" to="." method="_on_start_button_pressed"]

View file

@ -42,9 +42,7 @@ func init_server_game(server_port: int):
smp.set_multiplayer_peer(peer)
func deinit_server_game():
var smp: SceneMultiplayer = scene_tree.get_multiplayer(^"/root/Main/Server")
smp.multiplayer_peer.close()
smp.multiplayer_peer = null
server_game_instance.multiplayer.multiplayer_peer = null
scene_tree.set_multiplayer(multiplayer, ^"/root/Main/Server")
server_game_instance.queue_free()
@ -67,14 +65,14 @@ func init_client_game(player_name: String, player_color: Color, server_address:
smp.set_multiplayer_peer(peer)
func deinit_client_game():
var smp: SceneMultiplayer = scene_tree.get_multiplayer(^"/root/Main/Server")
smp.multiplayer_peer.close()
smp.multiplayer_peer = null
client_game_instance.multiplayer.multiplayer_peer = null
scene_tree.set_multiplayer(multiplayer, ^"/root/Main/Client")
client_game_instance.queue_free()
func init_lobby_menu():
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)
interface_instance.add_child(lobby_menu_instance)
func deinit_lobby_menu():
@ -95,3 +93,13 @@ func _on_connecting_confirmed(player_name: String, player_color: Color, server_a
init_client_game(player_name, player_color, server_address, server_port)
init_lobby_menu()
client_game_instance.trackers_changed.connect(lobby_menu_instance._on_trackers_changed)
func _on_leave_confirmed():
deinit_lobby_menu()
deinit_client_game()
if server_game_instance != null:
deinit_server_game()
init_main_menu()
func _on_start_confirmed():
pass

View file

@ -1,38 +1,68 @@
extends MultiplayerSpawner
extends Node
class_name MultiplePlayersTracker
# Requires the peer_id as data for the spawn function.
## Manager of all the instances of [SinglePlayerTracker] for a given multiplayer room.
##
## Authority of this object is always given to the server (1).
##
## The server uses its authority to assign authority to the child [SinglePlayerTracker]s.
signal trackers_changed(trackers: Dictionary)
## Emitted when a new [SinglePlayerTracker] is created.
signal created(tracker: SinglePlayerTracker)
func emit_trackers_changed():
trackers_changed.emit(trackers_by_peer_id)
## Emitted when any [SinglePlayerTracker] has changed.
signal changed(all_trackers: Array[SinglePlayerTracker])
## Emitted when any [SinglePlayerTracker] is about to be destroyed.
signal before_destroyed(tracker: SinglePlayerTracker)
var trackers_by_peer_id: Dictionary = {}
## The scene to be instantiated.
const tracker_scene = preload("res://scenes/single_player_tracker.tscn")
## Return the [Array] of [SinglePlayerTrackers] managed by this object.
func find_all() -> Array[SinglePlayerTracker]:
return find_children("", "SinglePlayerTracker", false, false) as Array[SinglePlayerTracker]
func find(peer_id: int) -> SinglePlayerTracker:
return trackers_by_peer_id.get(peer_id)
## Find the first [SinglePlayerTracker] over which the given peer id has authority.
func find_id(peer_id: int) -> SinglePlayerTracker:
for tracker in find_all():
if tracker.get_multiplayer_authority() == peer_id:
return tracker
return null
## Find the first [SinglePlayerTracker] over which the running instance has authority.
func find_self() -> SinglePlayerTracker:
var self_id = multiplayer.multiplayer_peer.get_unique_id()
return find_id(self_id)
## Find the first [SinglePlayerTracker] representing a player with the given name.
func find_name(player_name: String) -> SinglePlayerTracker:
for tracker in find_all():
if tracker.player_name == player_name:
return tracker
return null
## Create a new [SinglePlayerTracker] for the given peer id, or return the one that already exists.
@rpc("authority", "call_local", "reliable")
func mark_disconnected(peer_id: int):
var single_tracker_instance = find(peer_id)
single_tracker_instance.set_multiplayer_authority(1)
single_tracker_instance.peer_connected = false
emit_trackers_changed()
func create(peer_id: int) -> SinglePlayerTracker:
var tracker = find_id(peer_id)
if tracker != null:
return tracker
Log.peer(self, "Creating tracker for peer: %d" % peer_id)
tracker = tracker_scene.instantiate()
tracker.set_multiplayer_authority(peer_id)
created.emit(tracker)
var trackers = find_all()
changed.emit(trackers)
return tracker
func _ready():
spawn_function = _spawn_tracker
func _spawn_tracker(peer_id: int) -> Node:
var single_tracker_scene: PackedScene = load(get_spawnable_scene(0))
var single_tracker_instance: SinglePlayerTracker = single_tracker_scene.instantiate()
single_tracker_instance.set_multiplayer_authority(peer_id)
single_tracker_instance.identity_updated.connect(_on_tracker_identity_updated)
trackers_by_peer_id[peer_id] = single_tracker_instance
emit_trackers_changed()
return single_tracker_instance
func _on_tracker_identity_updated(_player_name: String, _player_color: Color):
emit_trackers_changed()
## Destroy the [SinglePlayerTracker] for the given peer id, or do nothing if it already exists.
func destroy(peer_id: int) -> void:
var tracker = find_id(peer_id)
if tracker == null:
return
Log.peer(self, "Destroying tracker for peer: %d" % peer_id)
before_destroyed.emit(tracker)
tracker.queue_free()
var trackers = find_all()
changed.emit(trackers)

View file

@ -2,8 +2,5 @@
[ext_resource type="Script" path="res://scenes/multiple_players_tracker.gd" id="1_fxysy"]
[node name="MultiplePlayersTracker" type="MultiplayerSpawner"]
_spawnable_scenes = PackedStringArray("res://scenes/single_player_tracker.tscn")
spawn_path = NodePath(".")
spawn_limit = 32
[node name="MultiplePlayersTracker" type="Node"]
script = ExtResource("1_fxysy")

View file

@ -5,4 +5,4 @@ class_name PlayerLabel
func update_from_tracker(tracker: SinglePlayerTracker):
text = tracker.player_name
add_theme_color_override("font_color", tracker.player_color)
modulate.a = 1.0 if tracker.peer_connected else 0.3
modulate.a = 1.0 if tracker.get_multiplayer_authority() != 1 else 0.3

View file

@ -10,5 +10,5 @@ signal name_confirmed(selected_name: String)
func _on_button_pressed():
name_confirmed.emit(line_edit.text)
func _on_line_edit_text_submitted(new_text: String):
func _on_line_edit_text_submitted(_new_text: String):
name_confirmed.emit(line_edit.text)

View file

@ -1,12 +1,9 @@
extends Node
extends MultiplayerSynchronizer
class_name SinglePlayerTracker
signal identity_updated(player_name: String, player_color: Color)
## Whether the peer is connected or not.
var peer_connected: bool = true
## Node representative of a player connected to the room.
##
## The peer of the player this node represents has authority over it.
## The player's name.
var player_name: String = "Player"
@ -14,16 +11,5 @@ var player_name: String = "Player"
## The player's color.
var player_color: Color = Color.WHITE
## This player's score, with an item per hole played.
var strokes_per_hole: Array[int] = []
@rpc("authority", "call_local", "reliable")
func update_identity(new_player_name: String, new_player_color: Color):
player_name = new_player_name
player_color = new_player_color
identity_updated.emit(player_name, player_color)
func notify_identity(peer_id: int):
Log.peer(self, "Notifying of our identity: " + str(peer_id))
update_identity.rpc_id(peer_id, player_name, player_color)
## Whether this player is currently connected or not.
var player_connected: bool = false

View file

@ -1,6 +1,25 @@
[gd_scene load_steps=2 format=3 uid="uid://drccgvtcng3ju"]
[gd_scene load_steps=3 format=3 uid="uid://drccgvtcng3ju"]
[ext_resource type="Script" path="res://scenes/single_player_tracker.gd" id="1_jwlkv"]
[node name="SinglePlayerTracker" type="Node"]
[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_755wr"]
properties/0/path = NodePath(".:player_connected")
properties/0/spawn = true
properties/0/replication_mode = 2
properties/1/path = NodePath(".:player_name")
properties/1/spawn = true
properties/1/replication_mode = 2
properties/2/path = NodePath(".:player_color")
properties/2/spawn = true
properties/2/replication_mode = 2
properties/3/path = NodePath(".:strokes_per_hole")
properties/3/spawn = true
properties/3/replication_mode = 2
[node name="SinglePlayerTracker" type="MultiplayerSynchronizer"]
root_path = NodePath(".")
replication_interval = 1.0
delta_interval = 0.125
replication_config = SubResource("SceneReplicationConfig_755wr")
visibility_update_mode = 2
script = ExtResource("1_jwlkv")