Implement RPC Node
This commit is contained in:
parent
f7ee533d5a
commit
605e43273e
13 changed files with 524 additions and 206 deletions
|
|
@ -16,25 +16,29 @@ public partial class GameManager : Node3D
|
|||
[Export] public int maxFarThreads = 16;
|
||||
|
||||
public static bool Loading { get; private set; } = true;
|
||||
public static GameManager Singleton { get; private set; }
|
||||
public static GameManager Instance { get; private set; }
|
||||
public static IGenerator Generator { get; private set; }
|
||||
public static Universe GameUniverse { get; private set; }
|
||||
public Player MainPlayer { get; private set; }
|
||||
public List<Player> Players { get; private set; } = [];
|
||||
public Dictionary<long, Player> Players { get; private set; } = [];
|
||||
|
||||
private double closeTickTimer = 0;
|
||||
private double farTickTimer = 0;
|
||||
|
||||
public bool simulating = false;
|
||||
public bool simulatingClose = false;
|
||||
public bool simulatingFar = false;
|
||||
public bool playerReady = false;
|
||||
|
||||
private readonly Dictionary<GameObject, Node3D> spawnedObjects = [];
|
||||
private readonly ConcurrentQueue<GameObject> spawnQueue = [];
|
||||
|
||||
public override void _EnterTree()
|
||||
{
|
||||
Instance = this;
|
||||
}
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
Singleton = this;
|
||||
|
||||
Generator = new TestGenerator();
|
||||
|
||||
if (Global.IsGameHost)
|
||||
|
|
@ -53,7 +57,7 @@ public partial class GameManager : Node3D
|
|||
public override void _ExitTree()
|
||||
{
|
||||
Loading = true;
|
||||
Singleton = null;
|
||||
Instance = null;
|
||||
}
|
||||
|
||||
public override void _Process(double delta)
|
||||
|
|
@ -64,20 +68,14 @@ public partial class GameManager : Node3D
|
|||
}
|
||||
|
||||
closeTickTimer += delta;
|
||||
farTickTimer += delta;
|
||||
|
||||
if (closeTickTimer >= closeTickInterval)
|
||||
if (closeTickTimer >= closeTickInterval && !simulatingClose)
|
||||
{
|
||||
SimulateClose(closeTickTimer);
|
||||
closeTickTimer = 0;
|
||||
}
|
||||
|
||||
if (simulating)
|
||||
{
|
||||
farTickTimer = 0;
|
||||
}
|
||||
|
||||
if (farTickTimer >= farTickInterval)
|
||||
farTickTimer += delta;
|
||||
if (farTickTimer >= farTickInterval && !simulatingFar)
|
||||
{
|
||||
double taskFarTickTimer = farTickTimer;
|
||||
Task.Run(() =>
|
||||
|
|
@ -94,22 +92,48 @@ public partial class GameManager : Node3D
|
|||
return MainPlayer.PlayerData.CurrentSector;
|
||||
}
|
||||
|
||||
public Player GetPlayer(long id)
|
||||
{
|
||||
Players.TryGetValue(id, out Player player);
|
||||
return player;
|
||||
}
|
||||
|
||||
private void SimulateClose(double delta)
|
||||
{
|
||||
List<Sector> neighbours = GetCurrentSector().GetNeighbouringSectors();
|
||||
simulatingClose = true;
|
||||
|
||||
neighbours.ForEach(sector =>
|
||||
List<Sector> sectorsClose = GetCurrentSector().GetNeighbouringSectors();
|
||||
|
||||
List<Task> tasks = [];
|
||||
sectorsClose.ForEach(sector =>
|
||||
{
|
||||
Task.Run(() =>
|
||||
Task simulateTask = Task.Run(() =>
|
||||
{
|
||||
sector.Simulate(delta);
|
||||
});
|
||||
|
||||
tasks.Add(simulateTask);
|
||||
});
|
||||
Task.WaitAll([.. tasks]);
|
||||
|
||||
foreach (KeyValuePair<long, Player> player in Players)
|
||||
{
|
||||
List<Sector> playerSectors = player.Value.PlayerData.CurrentSector.GetNeighbouringSectors();
|
||||
playerSectors.ForEach(sector =>
|
||||
{
|
||||
if (player.Key != 1)
|
||||
{
|
||||
sector.NetworkSync(player.Key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
simulatingClose = false;
|
||||
}
|
||||
|
||||
private void SimulateFar(double delta)
|
||||
{
|
||||
simulating = true;
|
||||
simulatingFar = true;
|
||||
|
||||
List<Task> tasks = [];
|
||||
|
||||
|
|
@ -134,7 +158,7 @@ public partial class GameManager : Node3D
|
|||
|
||||
Task.WaitAll([.. tasks]);
|
||||
|
||||
simulating = false;
|
||||
simulatingFar = false;
|
||||
}
|
||||
|
||||
private void SimulateFarClustered(double delta, int startX, int countX)
|
||||
|
|
@ -195,7 +219,7 @@ public partial class GameManager : Node3D
|
|||
neighbours.ForEach(sector => sector.SpawnObjects());
|
||||
}
|
||||
|
||||
public Player SpawnPlayer(Character character, bool isMainPlayer = false)
|
||||
public Player SpawnPlayer(Character character, long networkId, bool isMainPlayer = false)
|
||||
{
|
||||
Player player = character.InstantiatePlayer();
|
||||
player.GameMenu = GameMenu;
|
||||
|
|
@ -206,7 +230,7 @@ public partial class GameManager : Node3D
|
|||
OnPlayerReady();
|
||||
}
|
||||
|
||||
Players.Add(player);
|
||||
Players.Add(networkId, player);
|
||||
|
||||
character.UpdateSector();
|
||||
|
||||
|
|
@ -262,10 +286,10 @@ public partial class GameManager : Node3D
|
|||
{
|
||||
Sector current = GetCurrentSector();
|
||||
|
||||
foreach (Player player in Players)
|
||||
foreach (KeyValuePair<long, Player> player in Players)
|
||||
{
|
||||
player.PlayerData.UpdateSectorOffset(current);
|
||||
player.PlayerData.UpdateNodePosition();
|
||||
player.Value.PlayerData.UpdateSectorOffset(current);
|
||||
player.Value.PlayerData.UpdateNodePosition();
|
||||
}
|
||||
|
||||
List<Sector> nearby = current.GetNeighbouringSectors();
|
||||
|
|
@ -281,20 +305,18 @@ public partial class GameManager : Node3D
|
|||
else
|
||||
{
|
||||
gameObject.UpdateSectorOffset(current);
|
||||
node.GlobalPosition = gameObject.LocalCoordinates + gameObject.SectorOffset;
|
||||
node._Process(0);
|
||||
}
|
||||
}
|
||||
|
||||
nearby.ForEach(sector => sector.SpawnObjects());
|
||||
}
|
||||
|
||||
// These should be in RPCNode and should be queued
|
||||
public void SendUniverseToClient(long id)
|
||||
{
|
||||
RpcId(id, nameof(RpcDownloadUniverse), Generator.GetUniverseSize(), Generator.GetSectorSize());
|
||||
}
|
||||
|
||||
// These should be in RPCNode and should be queued
|
||||
[Rpc(MultiplayerApi.RpcMode.Authority)]
|
||||
public void RpcDownloadUniverse(Vector3I universeSize, Vector3 sectorSize)
|
||||
{
|
||||
|
|
@ -302,96 +324,4 @@ public partial class GameManager : Node3D
|
|||
|
||||
Loading = false;
|
||||
}
|
||||
|
||||
// These should be in RPCNode and should be queued
|
||||
[Rpc(MultiplayerApi.RpcMode.AnyPeer)]
|
||||
public void RpcSendNearbySectors(Vector3I coordinates, long id = -1)
|
||||
{
|
||||
Sector sector = GameUniverse.GetSector(coordinates);
|
||||
if (sector == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
List<Sector> sectors = sector.GetNeighbouringSectors();
|
||||
sectors.ForEach(sector => SendSectorToClients(sector, id == -1 ? null : id));
|
||||
}
|
||||
|
||||
// These should be in RPCNode and should be queued
|
||||
public void SendSectorToClients(Sector sector, long? id = null)
|
||||
{
|
||||
foreach (GameObject gameObject in sector.GameObjects)
|
||||
{
|
||||
if (gameObject is Character)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Godot.Collections.Dictionary gameObjectData = new() {
|
||||
{ "type", gameObject.GetType().Name },
|
||||
{ "sectorCoordinates", sector.Coordinates },
|
||||
{ "coordinates", gameObject.LocalCoordinates },
|
||||
{ "uuid", gameObject.UUID.ToString() },
|
||||
};
|
||||
|
||||
if (id.HasValue)
|
||||
{
|
||||
RpcId(id.Value, nameof(RpcDownloadGameObject), gameObjectData);
|
||||
}
|
||||
else
|
||||
{
|
||||
Rpc(nameof(RpcDownloadGameObject), gameObjectData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// These should be in RPCNode and should be queued
|
||||
[Rpc(MultiplayerApi.RpcMode.Authority)]
|
||||
public void RpcDownloadGameObject(Godot.Collections.Dictionary gameObjectData)
|
||||
{
|
||||
if (!gameObjectData.TryGetValue("type", out var typeData))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!gameObjectData.TryGetValue("sectorCoordinates", out var sectorCoordinatesData))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!gameObjectData.TryGetValue("coordinates", out var coordinatesData))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!gameObjectData.TryGetValue("uuid", out var uuidData))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string type = (string)typeData;
|
||||
Vector3I sectorCoordinates = (Vector3I)sectorCoordinatesData;
|
||||
Vector3 coordinates = (Vector3)coordinatesData;
|
||||
Guid uuid = Guid.Parse((string)uuidData);
|
||||
|
||||
Sector sector = GameUniverse.GetSector(sectorCoordinates);
|
||||
if (sector == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GameObject gameObject;
|
||||
switch (type)
|
||||
{
|
||||
case "Star":
|
||||
gameObject = new Star(sector, coordinates);
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
gameObject.UUID = uuid;
|
||||
|
||||
Spawn(gameObject);
|
||||
|
||||
sector.AssignObject(gameObject);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue