Further Tests & Progress
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
using ProjectM.Simulation;
|
||||
using Unity.Burst;
|
||||
using Unity.Entities;
|
||||
using Unity.NetCode;
|
||||
|
||||
namespace ProjectM.Server
|
||||
{
|
||||
/// <summary>
|
||||
/// Server-authoritative expiry of TIMED <see cref="StatModifier"/>s. Each tick it walks every entity's
|
||||
/// server-only <see cref="TimedModifier"/> buffer; for any row whose <see cref="TimedModifier.UntilTick"/> has
|
||||
/// elapsed (wrap-safe <see cref="Unity.NetCode.NetworkTick.IsNewerThan"/> compare, never raw uint<) it removes
|
||||
/// the matching StatModifier(s) by SourceId and the timed row. The shortened StatModifier [GhostField] buffer
|
||||
/// auto-replicates (OwnerSendType.All), so StatRecomputeSystem reverts the effective stat on both worlds with no
|
||||
/// change. Runs in the plain server <see cref="SimulationSystemGroup"/> (NOT the predicted loop) so it is applied
|
||||
/// exactly once and never double-removed on rollback; a DynamicBuffer mutation is not a structural change, so it
|
||||
/// is safe to mutate the iterated entity's own buffers in place.
|
||||
/// </summary>
|
||||
[BurstCompile]
|
||||
[WorldSystemFilter(WorldSystemFilterFlags.ServerSimulation)]
|
||||
[UpdateInGroup(typeof(SimulationSystemGroup))]
|
||||
public partial struct TimedModifierExpirySystem : ISystem
|
||||
{
|
||||
[BurstCompile]
|
||||
public void OnCreate(ref SystemState state)
|
||||
{
|
||||
state.RequireForUpdate<NetworkTime>();
|
||||
state.RequireForUpdate(state.GetEntityQuery(ComponentType.ReadOnly<TimedModifier>()));
|
||||
}
|
||||
|
||||
[BurstCompile]
|
||||
public void OnUpdate(ref SystemState state)
|
||||
{
|
||||
var serverTick = SystemAPI.GetSingleton<NetworkTime>().ServerTick;
|
||||
if (!serverTick.IsValid)
|
||||
return;
|
||||
|
||||
foreach (var (timed, mods) in
|
||||
SystemAPI.Query<DynamicBuffer<TimedModifier>, DynamicBuffer<StatModifier>>())
|
||||
{
|
||||
for (int i = timed.Length - 1; i >= 0; i--)
|
||||
{
|
||||
uint until = timed[i].UntilTick;
|
||||
if (until == 0)
|
||||
continue; // inert (no expiry scheduled)
|
||||
|
||||
var untilTick = new NetworkTick(until);
|
||||
if (untilTick.IsValid && untilTick.IsNewerThan(serverTick))
|
||||
continue; // not yet due
|
||||
|
||||
TimedModifierUtil.RemoveBySourceId(mods, timed[i].SourceId);
|
||||
timed.RemoveAtSwapBack(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user