using System; using Unity.Netcode; namespace ProjectI.Enemies { public struct EnemyArrivalSnapshot : INetworkSerializable, IEquatable { public bool Enabled; public ulong SpawnIdentity; public double BornAt, ReadyAt; public bool Valid => Enabled && SpawnIdentity != 0 && EnemyDirectorDefinition.Finite(BornAt) && BornAt >= 0 && EnemyDirectorDefinition.Finite(ReadyAt) && ReadyAt > BornAt; public void NetworkSerialize(BufferSerializer serializer) where T : IReaderWriter { serializer.SerializeValue(ref Enabled); serializer.SerializeValue(ref SpawnIdentity); serializer.SerializeValue(ref BornAt); serializer.SerializeValue(ref ReadyAt); } public bool Equals(EnemyArrivalSnapshot other) => Enabled == other.Enabled && SpawnIdentity == other.SpawnIdentity && BornAt == other.BornAt && ReadyAt == other.ReadyAt; } public sealed class EnemyArrivalState { private bool configured; private double bornAt, readyAt; public bool ConfigureBeforeSpawn(double start, double duration) { if (configured || !EnemyDirectorDefinition.Finite(start) || start < 0 || !EnemyDirectorDefinition.Positive(duration) || duration > 10 || !EnemyDirectorDefinition.Finite(start + duration) || start + duration <= start) return false; configured = true; bornAt = start; readyAt = start + duration; return true; } public EnemyArrivalSnapshot Bind(ulong identity) => configured && identity != 0 ? new EnemyArrivalSnapshot { Enabled = true, SpawnIdentity = identity, BornAt = bornAt, ReadyAt = readyAt } : default; internal void ClearForNextBirth() { configured = false; bornAt = readyAt = 0; } public static bool Ready(EnemyArrivalSnapshot snapshot, ulong identity, double now) => !snapshot.Enabled || snapshot.Valid && snapshot.SpawnIdentity == identity && EnemyDirectorDefinition.Finite(now) && now >= snapshot.ReadyAt; } }