Core Game Loop Additions
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
using ProjectM.Simulation;
|
||||
using Unity.Burst;
|
||||
using Unity.Collections;
|
||||
using Unity.Entities;
|
||||
using Unity.NetCode;
|
||||
|
||||
namespace ProjectM.Server
|
||||
{
|
||||
/// <summary>
|
||||
/// Server-authoritative per-connection ghost relevancy for the base/expedition region split. Each tick:
|
||||
/// build a connection -> region map from the region-tagged player ghosts, then mark every region-tagged
|
||||
/// ghost IRRELEVANT to each connection whose player is in a DIFFERENT region. Uses
|
||||
/// <see cref="GhostRelevancyMode.SetIsIrrelevant"/> so untagged/global ghosts (e.g. the cycle director)
|
||||
/// stay relevant to everyone for free — only cross-region ghosts are hidden. Runs in the
|
||||
/// <see cref="GhostSimulationSystemGroup"/> (before GhostSendSystem reads the set). The set holds
|
||||
/// (connection, ghost) pairs for the CURRENT simulated tick only, so it is cleared and repopulated every
|
||||
/// update. A connection with no spawned player yet is absent from the map and simply sees everything.
|
||||
/// </summary>
|
||||
[BurstCompile]
|
||||
[WorldSystemFilter(WorldSystemFilterFlags.ServerSimulation)]
|
||||
[UpdateInGroup(typeof(GhostSimulationSystemGroup))]
|
||||
public partial struct RegionRelevancySystem : ISystem
|
||||
{
|
||||
[BurstCompile]
|
||||
public void OnCreate(ref SystemState state)
|
||||
{
|
||||
state.RequireForUpdate<GhostRelevancy>();
|
||||
}
|
||||
|
||||
[BurstCompile]
|
||||
public void OnUpdate(ref SystemState state)
|
||||
{
|
||||
// Map each in-game connection (by NetworkId) to its player's region.
|
||||
var connRegion = new NativeHashMap<int, byte>(8, Allocator.Temp);
|
||||
foreach (var (owner, region) in
|
||||
SystemAPI.Query<RefRO<GhostOwner>, RefRO<RegionTag>>().WithAll<PlayerTag>())
|
||||
{
|
||||
connRegion[owner.ValueRO.NetworkId] = region.ValueRO.Region;
|
||||
}
|
||||
|
||||
ref var relevancy = ref SystemAPI.GetSingletonRW<GhostRelevancy>().ValueRW;
|
||||
relevancy.GhostRelevancyMode = GhostRelevancyMode.SetIsIrrelevant;
|
||||
var set = relevancy.GhostRelevancySet;
|
||||
set.Clear();
|
||||
|
||||
if (!connRegion.IsEmpty)
|
||||
{
|
||||
var conns = connRegion.GetKeyValueArrays(Allocator.Temp);
|
||||
foreach (var (ghost, region) in
|
||||
SystemAPI.Query<RefRO<GhostInstance>, RefRO<RegionTag>>())
|
||||
{
|
||||
int ghostId = ghost.ValueRO.ghostId;
|
||||
if (ghostId == 0)
|
||||
continue; // ghost id not assigned yet this tick
|
||||
|
||||
byte ghostRegion = region.ValueRO.Region;
|
||||
for (int i = 0; i < conns.Keys.Length; i++)
|
||||
{
|
||||
if (conns.Values[i] != ghostRegion)
|
||||
set.Add(new RelevantGhostForConnection { Connection = conns.Keys[i], Ghost = ghostId }, 1);
|
||||
}
|
||||
}
|
||||
conns.Dispose();
|
||||
}
|
||||
|
||||
connRegion.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user