Map Updates
This commit is contained in:
@@ -12,10 +12,13 @@ namespace ProjectM.Server
|
||||
/// counts players whose server-only <see cref="RegionTag"/> is the Expedition region, and on the
|
||||
/// empty->occupied edge (a new sortie) bumps <see cref="CycleRuntime.ExpeditionEpoch"/> and scatters
|
||||
/// <see cref="ResourceFieldSpawner.Count"/> resource-node ghosts (seeded by the epoch) around the expedition
|
||||
/// origin, each RegionTag{Expedition}; on the occupied->empty edge (the LAST player left) it destroys every
|
||||
/// node. So the field lives as long as anyone is out there, not on a global timer. Plain server
|
||||
/// SimulationSystemGroup. Server-authoritative; clients despawn nodes via GhostDespawnSystem. Per-epoch
|
||||
/// reproducible (the seed is the monotonic int epoch, compared by equality — never tick math, never 0).
|
||||
/// origin — PLUS, if a <see cref="ClutterFieldSpawner"/> singleton is present,
|
||||
/// <see cref="ClutterFieldSpawner.Count"/> Blight-clutter ghosts (seeded DISTINCTLY so clutter and nodes don't
|
||||
/// co-locate, Variant round-robined), each RegionTag{Expedition}; on the occupied->empty edge (the LAST
|
||||
/// player left) it destroys every node AND every clutter piece. So the field lives as long as anyone is out
|
||||
/// there, not on a global timer. Plain server SimulationSystemGroup. Server-authoritative; clients despawn
|
||||
/// ghosts via GhostDespawnSystem. Per-epoch reproducible (the seed is the monotonic int epoch, compared by
|
||||
/// equality — never tick math, never 0).
|
||||
/// </summary>
|
||||
[BurstCompile]
|
||||
[WorldSystemFilter(WorldSystemFilterFlags.ServerSimulation)]
|
||||
@@ -80,14 +83,42 @@ namespace ProjectM.Server
|
||||
rn.ResourceId = (byte)(ResourceId.Aether + (byte)(i % 3));
|
||||
ecb.SetComponent(node, rn);
|
||||
}
|
||||
|
||||
// Blight clutter (OPTIONAL singleton): scatter alongside the nodes with a DISTINCT seed so the
|
||||
// two fields don't co-locate. Round-robin Variant for client visual variety.
|
||||
if (SystemAPI.TryGetSingleton<ClutterFieldSpawner>(out var clutterSpawner)
|
||||
&& clutterSpawner.Prefab != Entity.Null)
|
||||
{
|
||||
var clutterXform = SystemAPI.GetComponent<LocalTransform>(clutterSpawner.Prefab);
|
||||
var prefabClutter = SystemAPI.GetComponent<BlightClutter>(clutterSpawner.Prefab);
|
||||
var crng = new Random((uint)math.max(1, runtime.ExpeditionEpoch * 2 + 1));
|
||||
int ccount = math.max(1, clutterSpawner.Count);
|
||||
for (int i = 0; i < ccount; i++)
|
||||
{
|
||||
var piece = ecb.Instantiate(clutterSpawner.Prefab);
|
||||
|
||||
float ang = crng.NextFloat(0f, math.PI * 2f);
|
||||
float rad = clutterSpawner.Radius * math.sqrt(crng.NextFloat(0f, 1f));
|
||||
var xform = clutterXform;
|
||||
xform.Position = origin + new float3(math.cos(ang) * rad, 0f, math.sin(ang) * rad);
|
||||
ecb.SetComponent(piece, xform);
|
||||
|
||||
var bc = prefabClutter;
|
||||
bc.Variant = (byte)(i % 3);
|
||||
ecb.SetComponent(piece, bc);
|
||||
}
|
||||
}
|
||||
|
||||
runtime.LastSpawnedEpoch = runtime.ExpeditionEpoch;
|
||||
}
|
||||
|
||||
// DESTROY: the last player left the expedition — clear the whole field.
|
||||
// DESTROY: the last player left the expedition — clear the whole field (nodes + clutter).
|
||||
if (wasOccupied && !occupied)
|
||||
{
|
||||
foreach (var (rn, e) in SystemAPI.Query<RefRO<ResourceNode>>().WithEntityAccess())
|
||||
ecb.DestroyEntity(e);
|
||||
foreach (var (bc, e) in SystemAPI.Query<RefRO<BlightClutter>>().WithEntityAccess())
|
||||
ecb.DestroyEntity(e);
|
||||
}
|
||||
|
||||
runtime.PrevExpeditionOccupied = (byte)(occupied ? 1 : 0);
|
||||
|
||||
Reference in New Issue
Block a user