Inventory management focused game written in Godot / C#
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

81 lines
2.1 KiB

public partial class MultiplayerManager : Node
{
[Export] public Player LocalPlayer { get; set; }
[Export] public Node3D Players { get; set; }
[Export] public PackedScene PlayerScene { get; set; }
public event Action<Player> PlayerJoined;
public event Action<Player> PlayerLeft;
public override void _Ready()
{
Multiplayer.ConnectedToServer += OnMultiplayerReady;
Multiplayer.ServerDisconnected += OnMultiplayerDisconnected;
Multiplayer.PeerConnected += OnPeerConnected;
Multiplayer.PeerDisconnected += OnPeerDisconnected;
}
public void Connect(string address, ushort port)
{
var peer = new ENetMultiplayerPeer();
peer.CreateClient(address, port);
Multiplayer.MultiplayerPeer = peer;
}
public bool CreateServer(ushort port)
{
var peer = new ENetMultiplayerPeer();
if (peer.CreateServer(port) == Error.Ok) {
Multiplayer.MultiplayerPeer = peer;
OnMultiplayerReady();
return true;
} else
return false;
}
public void Disconnect()
=> OnMultiplayerDisconnected();
void OnMultiplayerReady()
{
var localId = Multiplayer.GetUniqueId();
LocalPlayer.Name = localId.ToString();
LocalPlayer.SetMultiplayerAuthority(localId);
if (!Multiplayer.IsServer())
// Spawn players for all the other peers. This excludes the server,
// since `OnPeerConnected` will already be called for it on connecting.
foreach (var peerId in Multiplayer.GetPeers())
if (peerId != 1) OnPeerConnected(peerId);
}
void OnMultiplayerDisconnected()
{
LocalPlayer.Name = "Local";
foreach (var player in Players.GetChildren().Cast<Player>())
if (!player.IsLocal) OnPeerDisconnected(player.PeerId);
Multiplayer.MultiplayerPeer.Close();
Multiplayer.MultiplayerPeer = null;
}
void OnPeerConnected(long peerId)
{
var player = PlayerScene.Instantiate<Player>();
player.SetMultiplayerAuthority((int)peerId);
player.Name = peerId.ToString();
player.IsLocal = false;
player.PeerId = (int)peerId;
Players.AddChild(player);
PlayerJoined?.Invoke(player);
}
void OnPeerDisconnected(long peerId)
{
var player = Players.GetNode<Player>(peerId.ToString());
PlayerLeft?.Invoke(player);
player.QueueFree();
}
}