using Unity.Entities;
namespace ProjectM.Simulation
{
///
/// SERVER-ONLY expiry tracker paired with a by . It is NOT a
/// [GhostField] and lives in a SEPARATE buffer so the replicated layout stays
/// byte-identical — adding ANY member (even non-ghost) to a [GhostField] buffer element regenerates its
/// serializer/stride/hash = an effective ghost re-bake. To grant a TIMED buff, append both a StatModifier and a
/// TimedModifier sharing one unique SourceId; TimedModifierExpirySystem removes the matching StatModifier
/// when elapses, and that removal replicates for free via the StatModifier [GhostField]
/// buffer (OwnerSendType.All), so StatRecomputeSystem reverts the effective stat on both worlds with no change.
///
public struct TimedModifier : IBufferElementData
{
/// Matches the this row governs.
public uint SourceId;
/// Server tick at which the paired StatModifier expires (0 = no expiry / inert; schedule via TickUtil.NonZero).
public uint UntilTick;
}
/// Pure helpers for removing modifiers by provenance (clear-by-type / timed expiry). Deterministic, no RNG/wall-clock.
public static class TimedModifierUtil
{
/// Remove every row whose SourceId matches (RemoveAtSwapBack). Returns the count removed.
public static int RemoveBySourceId(DynamicBuffer mods, uint sourceId)
{
int removed = 0;
for (int j = mods.Length - 1; j >= 0; j--)
if (mods[j].SourceId == sourceId) { mods.RemoveAtSwapBack(j); removed++; }
return removed;
}
}
}