diff --git a/Orrery Combat Framework - Heart Module/Data/Scripts/HeartModule/Projectiles/ProjectileManager.cs b/Orrery Combat Framework - Heart Module/Data/Scripts/HeartModule/Projectiles/ProjectileManager.cs index 6b21e9e7..80169c7f 100644 --- a/Orrery Combat Framework - Heart Module/Data/Scripts/HeartModule/Projectiles/ProjectileManager.cs +++ b/Orrery Combat Framework - Heart Module/Data/Scripts/HeartModule/Projectiles/ProjectileManager.cs @@ -27,7 +27,7 @@ public partial class ProjectileManager private ConcurrentDictionary ActiveProjectiles = new ConcurrentDictionary(); private ConcurrentCachingHashSet ProjectilesWithHealth = new ConcurrentCachingHashSet(); public uint NextId { get; private set; } = 0; - private List QueuedCloseProjectiles = new List(); + private ConcurrentQueue QueuedCloseProjectiles = new ConcurrentQueue(); /// /// Delta for engine ticks; 60tps /// @@ -91,8 +91,37 @@ public void UpdateAfterSimulation() return false; }); + // Queued removal of projectiles + uint toRemove = 0; + while (QueuedCloseProjectiles.TryDequeue(out toRemove)) + { + if (!ActiveProjectiles.ContainsKey(toRemove)) + continue; + + Projectile projectile = ActiveProjectiles[toRemove]; + if (projectile == null) // Emergency cull null projectiles. + { + ActiveProjectiles.Remove(toRemove); + continue; + } + + //MyAPIGateway.Utilities.ShowMessage("Heart", $"Closing projectile {projectile.Id}. Age: {projectile.Age} "); + if (MyAPIGateway.Session.IsServer) + QueueSync(projectile, 2); + + if (!MyAPIGateway.Utilities.IsDedicated) + projectile.CloseDrawing(); + + ActiveProjectiles.Remove(toRemove); + ProjectilesWithHealth.Remove(projectile); + projectile.OnClose.Invoke(projectile); + } + DamageHandler.Update(); + // Sync stuff + UpdateSync(); + clockTick.Restart(); ticksReady++; @@ -135,37 +164,14 @@ public void UpdateProjectilesParallel() MyAPIGateway.Parallel.ForEach(projectiles, (projectile) => { + if (HeartData.I.IsSuspended) + return; + projectile.Value.AVTickUpdate(deltaTick); projectile.Value.AsyncTickUpdate(delta, spheres); if (projectile.Value == null || projectile.Value.QueuedDispose) - QueuedCloseProjectiles.Add(projectile.Key); + QueuedCloseProjectiles.Enqueue(projectile.Key); }); - - // Queued removal of projectiles - foreach (var projectileId in QueuedCloseProjectiles) - { - Projectile projectile = ActiveProjectiles[projectileId]; - if (projectile == null) // Emergency cull null projectiles. - { - ActiveProjectiles.Remove(projectileId); - continue; - } - - //MyAPIGateway.Utilities.ShowMessage("Heart", $"Closing projectile {projectile.Id}. Age: {projectile.Age} "); - if (MyAPIGateway.Session.IsServer) - QueueSync(projectile, 2); - - if (!MyAPIGateway.Utilities.IsDedicated) - projectile.CloseDrawing(); - - ActiveProjectiles.Remove(projectileId); - ProjectilesWithHealth.Remove(projectile); - projectile.OnClose.Invoke(projectile); - } - QueuedCloseProjectiles.Clear(); - - // Sync stuff - UpdateSync(); } catch (Exception ex) {