using UnityEngine; namespace MegaKoop.Game.Networking { internal static class NetworkIdAllocator { public const int PlayerIdStart = 1; public const int EnemyIdStart = 10000; private const int EnemyIdRange = 10000; private static int nextEnemyId = EnemyIdStart; private static readonly System.Collections.Generic.HashSet ActiveEnemyIds = new(); [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] private static void ResetOnLoad() { Reset(); } public static void Reset() { nextEnemyId = EnemyIdStart; ActiveEnemyIds.Clear(); } public static int AllocateEnemyId() { if (nextEnemyId < EnemyIdStart) { nextEnemyId = EnemyIdStart; } const int maxAttempts = EnemyIdRange; int attempts = 0; while ((ActiveEnemyIds.Contains(nextEnemyId) || NetworkIdRegistry.IsIdRegistered(nextEnemyId) || NetworkIdRegistry.IsIdReserved(nextEnemyId)) && attempts < maxAttempts) { AdvanceEnemyCursor(); attempts++; } int allocated = nextEnemyId; AdvanceEnemyCursor(); ActiveEnemyIds.Add(allocated); return allocated; } public static bool IsPlayerId(int id) => id >= PlayerIdStart && id < EnemyIdStart; public static bool IsEnemyId(int id) => id >= EnemyIdStart; public static void SyncEnemyCursor(int id) { if (id >= EnemyIdStart && id >= nextEnemyId) { nextEnemyId = id + 1; } if (id >= EnemyIdStart) { ActiveEnemyIds.Add(id); } } public static void ReleaseEnemyId(int id) { if (id >= EnemyIdStart) { ActiveEnemyIds.Remove(id); } } private static void AdvanceEnemyCursor() { nextEnemyId++; if (nextEnemyId >= EnemyIdStart + EnemyIdRange) { nextEnemyId = EnemyIdStart; } } } }