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.

94 lines
2.4 KiB

public partial class MultiplayerManager : Node
{
[Export] public PackedScene PlayerScene { get; set; }
[Export] public PackedScene WorkshopScene { 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()
{
SetAuthorityAndName(Game.LocalPlayer, Multiplayer.GetUniqueId());
SetAuthorityAndName(Game.LocalWorkshop, Multiplayer.GetUniqueId());
// 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()
{
Multiplayer.MultiplayerPeer.Close();
Multiplayer.MultiplayerPeer = new OfflineMultiplayerPeer();
foreach (var player in Game.Players)
if (player != Game.LocalPlayer)
OnPeerDisconnected(player.PeerId);
SetAuthorityAndName(Game.LocalPlayer, Multiplayer.GetUniqueId());
SetAuthorityAndName(Game.LocalWorkshop, Multiplayer.GetUniqueId());
}
void OnPeerConnected(long _peerId)
{
var player = PlayerScene.Instantiate<Player>();
SetAuthorityAndName(player, (int)_peerId);
Game.Players.AddChild(player);
PlayerJoined?.Invoke(player);
}
void OnPeerDisconnected(long _peerId)
{
var player = Game.Players.ByPeerId((int)_peerId);
Game.Players.RemoveChild(player);
player.QueueFree();
var workshop = Game.Workshops.ByPeerId((int)_peerId);
Game.Workshops.RemoveChild(workshop);
workshop.QueueFree();
PlayerLeft?.Invoke(player);
}
static void SetAuthorityAndName(Node node, int peerId)
{
node.SetMultiplayerAuthority(peerId);
node.Name = peerId.ToString();
}
}