using ProjectM.Simulation;
using Unity.Burst;
using Unity.Collections;
using Unity.Entities;
using Unity.NetCode;
namespace ProjectM.Server
{
///
/// 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
/// so untagged/global ghosts (e.g. the cycle director)
/// stay relevant to everyone for free — only cross-region ghosts are hidden. Runs in the
/// (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.
///
[BurstCompile]
[WorldSystemFilter(WorldSystemFilterFlags.ServerSimulation)]
[UpdateInGroup(typeof(GhostSimulationSystemGroup))]
public partial struct RegionRelevancySystem : ISystem
{
[BurstCompile]
public void OnCreate(ref SystemState state)
{
state.RequireForUpdate();
}
[BurstCompile]
public void OnUpdate(ref SystemState state)
{
// Map each in-game connection (by NetworkId) to its player's region.
var connRegion = new NativeHashMap(8, Allocator.Temp);
foreach (var (owner, region) in
SystemAPI.Query, RefRO>().WithAll())
{
connRegion[owner.ValueRO.NetworkId] = region.ValueRO.Region;
}
ref var relevancy = ref SystemAPI.GetSingletonRW().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>())
{
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();
}
}
}