diff --git a/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidEntities/AsteroidEntity.cs b/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidEntities/AsteroidEntity.cs index d9e20b8b..c6966fd0 100644 --- a/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidEntities/AsteroidEntity.cs +++ b/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidEntities/AsteroidEntity.cs @@ -123,6 +123,9 @@ public void SplitAsteroid() MyAPIGateway.Multiplayer.SendMessageToOthers(32000, removalMessageBytes); } + // Remove from asteroid list + MainSession.I._spawner._asteroids.Remove(this); + Close(); return; } @@ -136,6 +139,9 @@ public void SplitAsteroid() var subChunk = CreateAsteroid(newPos, newSize, newVelocity, Type); subChunk.Physics.AngularVelocity = newAngularVelocity; + // Add sub-chunks to the asteroid list + MainSession.I._spawner._asteroids.Add(subChunk); + // Send a network message to clients if (MyAPIGateway.Utilities.IsDedicated || !MyAPIGateway.Session.IsServer) { @@ -153,10 +159,12 @@ public void SplitAsteroid() MyAPIGateway.Multiplayer.SendMessageToOthers(32000, removalMessageBytes); } + // Remove from asteroid list + MainSession.I._spawner._asteroids.Remove(this); + Close(); } - private int GetRandomDropAmount(AsteroidType type) { switch (type) @@ -203,6 +211,16 @@ public void OnDestroy() public bool DoDamage(float damage, MyStringHash damageSource, bool sync, MyHitInfo? hitInfo = null, long attackerId = 0, long realHitEntityId = 0, bool shouldDetonateAmmo = true, MyStringHash? extraInfo = null) { + // Define the explosion damage type + var explosionDamageType = MyStringHash.GetOrCompute("Explosion"); + + // Check if the damage source is explosion + //if (damageSource == explosionDamageType) + //{ + // Log.Info($"Ignoring explosion damage for asteroid. Damage source: {damageSource.String}"); + // return false; // Ignore the damage + //} + _integrity -= damage; Log.Info($"DoDamage called with damage: {damage}, damageSource: {damageSource.String}, attackerId: {attackerId}, realHitEntityId: {realHitEntityId}, new integrity: {_integrity}"); @@ -269,7 +287,7 @@ private void Init(Vector3D position, float size, Vector3D initialVelocity, Aster } Size = size; - _integrity = AsteroidSettings.BaseIntegrity * Size; + _integrity = AsteroidSettings.BaseIntegrity + Size; Log.Info($"Attempting to load model: {ModelString}"); @@ -329,8 +347,7 @@ private void CreatePhysics() Physics.Enabled = true; Physics.Activate(); } - - + private Vector3D RandVector() { var theta = MainSession.I.Rand.NextDouble() * 2.0 * Math.PI; diff --git a/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidEntities/AsteroidSpawner.cs b/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidEntities/AsteroidSpawner.cs index 6890aab8..15c87497 100644 --- a/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidEntities/AsteroidSpawner.cs +++ b/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidEntities/AsteroidSpawner.cs @@ -8,7 +8,7 @@ namespace DynamicAsteroids.AsteroidEntities { - internal class AsteroidSpawner + public class AsteroidSpawner { public List _asteroids; private const double MinDistanceFromVanillaAsteroids = 1000; // 1 km @@ -59,15 +59,12 @@ public void UpdateTick() { Vector3D playerPosition = player.GetPosition(); - if (!AsteroidSettings.PlayerCanSeeRings(playerPosition)) - { - continue; - } - foreach (var asteroid in _asteroids.ToArray()) { - if (Vector3D.DistanceSquared(asteroid.PositionComp.GetPosition(), playerPosition) > - AsteroidSettings.AsteroidSpawnRadius * AsteroidSettings.AsteroidSpawnRadius * 1.1) + double distanceSquared = Vector3D.DistanceSquared(asteroid.PositionComp.GetPosition(), playerPosition); + + // Remove asteroids that are outside the spherical spawn radius + if (distanceSquared > AsteroidSettings.AsteroidSpawnRadius * AsteroidSettings.AsteroidSpawnRadius) { Log.Info($"Removing asteroid at {asteroid.PositionComp.GetPosition()} due to distance from player"); _asteroids.Remove(asteroid); @@ -82,13 +79,26 @@ public void UpdateTick() } int asteroidsSpawned = 0; + int spawnAttempts = 0; + int maxAttempts = 50; // Limit the number of attempts to find valid positions + while (_asteroids.Count < AsteroidSettings.MaxAsteroidCount && asteroidsSpawned < 10) { + if (spawnAttempts >= maxAttempts) + { + Log.Info("Reached maximum spawn attempts, breaking out of loop to prevent freeze"); + break; + } + Vector3D newPosition; do { newPosition = playerPosition + RandVector() * AsteroidSettings.AsteroidSpawnRadius; - } while (Vector3D.DistanceSquared(newPosition, playerPosition) < MinDistanceFromPlayer * MinDistanceFromPlayer); + spawnAttempts++; + } while (Vector3D.DistanceSquared(newPosition, playerPosition) < MinDistanceFromPlayer * MinDistanceFromPlayer && spawnAttempts < maxAttempts); + + if (spawnAttempts >= maxAttempts) + break; Vector3D newVelocity; if (!AsteroidSettings.CanSpawnAsteroidAtPoint(newPosition, out newVelocity)) diff --git a/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidSettings.cs b/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidSettings.cs index 7edb9989..e86113ec 100644 --- a/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidSettings.cs +++ b/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidSettings.cs @@ -11,6 +11,7 @@ public static class AsteroidSettings public static int AsteroidVelocityBase = 0; public static double VelocityVariability = 0; public static double AngularVelocityVariability = 0; + //TODO: DespawnRangeFromPlayer public static double IceWeight = 0.80; public static double StoneWeight = 0.11; diff --git a/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/MainSession.cs b/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/MainSession.cs index 04b4a0dc..7b119896 100644 --- a/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/MainSession.cs +++ b/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/MainSession.cs @@ -19,7 +19,7 @@ public class MainSession : MySessionComponentBase public Random Rand = new Random(); - private AsteroidSpawner _spawner = new AsteroidSpawner(); + public AsteroidSpawner _spawner = new AsteroidSpawner(); #region Base Methods