From ecf18aa33870223ad7b05daa6e2d94650bbc1acc Mon Sep 17 00:00:00 2001 From: Aristeas <94058548+Jnick-24@users.noreply.github.com> Date: Thu, 6 Jun 2024 20:58:23 -0500 Subject: [PATCH] spawn asteroid --- .../AsteroidEntities/AsteroidEntity.cs | 41 +++++++------ .../AsteroidEntities/AsteroidSpawner.cs | 58 +++++++++++++++++++ .../DynamicAsteroids/AsteroidSettings.cs | 52 +++++++++++++++++ .../Scripts/DynamicAsteroids/MainSession.cs | 8 ++- 4 files changed, 139 insertions(+), 20 deletions(-) create mode 100644 Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidEntities/AsteroidSpawner.cs create mode 100644 Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidSettings.cs diff --git a/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidEntities/AsteroidEntity.cs b/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidEntities/AsteroidEntity.cs index 5175c4dc..843b8b42 100644 --- a/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidEntities/AsteroidEntity.cs +++ b/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidEntities/AsteroidEntity.cs @@ -20,15 +20,18 @@ namespace DynamicAsteroids.AsteroidEntities { public class AsteroidEntity : MyEntity, IMyDestroyableObject { - private const double VelocityVariablility = 4; + private const double VelocityVariability = 10; + private const double AngularVelocityVariability = 0.1; private static readonly string[] AvailableModels = { @"Models\Components\Sphere.mwm" }; - public static void CreateAsteroid(Vector3D position, float size, Vector3D initialVelocity) + public static AsteroidEntity CreateAsteroid(Vector3D position, float size, Vector3D initialVelocity) { - new AsteroidEntity().Init(position, size, initialVelocity); + var ent = new AsteroidEntity(); + ent.Init(position, size, initialVelocity); + return ent; } public float Size = 3; @@ -57,7 +60,7 @@ public void SplitAsteroid() //MyFloatingObjects.Spawn(item, PositionComp.GetPosition() + RandVector*Size*4, Vector3D.Forward, Vector3D.Up); //MyObjectBuilder_PhysicalObject newObject = MyObjectBuilderSerializerKeen.CreateNewObject(item.Id.TypeId, item.Id.SubtypeName) as MyObjectBuilder_PhysicalObject; - MyFloatingObjects.Spawn(new MyPhysicalInventoryItem(1000, newObject), PositionComp.GetPosition() + RandVector*Size, Vector3D.Forward, Vector3D.Up, Physics); + MyFloatingObjects.Spawn(new MyPhysicalInventoryItem(1000, newObject), PositionComp.GetPosition() + RandVector()*Size, Vector3D.Forward, Vector3D.Up, Physics); } Close(); return; @@ -65,11 +68,13 @@ public void SplitAsteroid() for (int i = 0; i < splits; i++) { - CreateAsteroid(this.PositionComp.GetPosition() + RandVector*Size, newSize, this.Physics.LinearVelocity); + Vector3D newPos = this.PositionComp.GetPosition() + RandVector() * Size; + CreateAsteroid(newPos, newSize, this.Physics.GetVelocityAtPoint(newPos)); } Close(); } + public void OnDestroy() { SplitAsteroid(); @@ -86,12 +91,7 @@ public bool DoDamage(float damage, MyStringHash damageSource, bool sync, MyHitIn public float Integrity => _integrity; - public bool UseDamageSystem { get; } = true; - - - - - + public bool UseDamageSystem => true; private void Init(Vector3D position, float size, Vector3D initialVelocity) @@ -118,11 +118,13 @@ private void Init(Vector3D position, float size, Vector3D initialVelocity) MyEntities.Add(this); CreatePhysics(); - Physics.LinearVelocity = initialVelocity + RandVector * VelocityVariablility; + Physics.LinearVelocity = initialVelocity + RandVector() * VelocityVariability; + Physics.AngularVelocity = RandVector() * AngularVelocityVariability; } private void CreatePhysics() { + float mass = 10000 * Size * Size * Size; PhysicsSettings settings = MyAPIGateway.Physics.CreateSettingsForPhysics( this, WorldMatrix, @@ -130,20 +132,25 @@ private void CreatePhysics() linearDamping: 0, angularDamping: 0, collisionLayer: CollisionLayers.DefaultCollisionLayer, - rigidBodyFlags: RigidBodyFlag.RBF_UNLOCKED_SPEEDS, + //rigidBodyFlags: RigidBodyFlag.RBF_UNLOCKED_SPEEDS, isPhantom: false, - mass: new ModAPIMass(PositionComp.LocalAABB.Volume(), 10000, Vector3.Zero, new Matrix(48531.0f, -1320.0f, 0.0f, -1320.0f, 256608.0f, 0.0f, 0.0f, 0.0f, 211333.0f)) + mass: new ModAPIMass(PositionComp.LocalAABB.Volume(), mass, Vector3.Zero, mass * PositionComp.LocalAABB.Height * PositionComp.LocalAABB.Height / 6 * Matrix.Identity) ); //settings.DetectorColliderCallback += HitCallback; //settings.Entity.Flags |= EntityFlags.IsGamePrunningStructureObject; MyAPIGateway.Physics.CreateBoxPhysics(settings, PositionComp.LocalAABB.HalfExtents, 0); - + Physics.Enabled = true; Physics.Activate(); } - private Vector3D RandVector => new Vector3D(MainSession.I.Rand.NextDouble(), MainSession.I.Rand.NextDouble(), - MainSession.I.Rand.NextDouble()); + private Vector3D RandVector() + { + var theta = MainSession.I.Rand.NextDouble() * 2.0 * Math.PI; + var phi = Math.Acos(2.0 * MainSession.I.Rand.NextDouble() - 1.0); + var sinPhi = Math.Sin(phi); + return Math.Pow(MainSession.I.Rand.NextDouble(), 1/3d) * new Vector3D(sinPhi * Math.Cos(theta), sinPhi * Math.Sin(theta), Math.Cos(phi)); + } } } diff --git a/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidEntities/AsteroidSpawner.cs b/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidEntities/AsteroidSpawner.cs new file mode 100644 index 00000000..54bfc633 --- /dev/null +++ b/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidEntities/AsteroidSpawner.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using Sandbox.ModAPI; +using VRageMath; + +namespace DynamicAsteroids.AsteroidEntities +{ + internal class AsteroidSpawner + { + private List _asteroids; + + public void Init() + { + _asteroids = new List(AsteroidSettings.MaxAsteroidCount); + } + + public void Close() + { + _asteroids.Clear(); + } + + public void UpdateTick() + { + Vector3D playerPosition = MyAPIGateway.Session?.Player?.GetPosition() ?? Vector3D.MaxValue; + + if (playerPosition == Vector3D.MaxValue || !AsteroidSettings.SpawnAsteroidsAtPoint(playerPosition)) + return; + + foreach (var asteroid in _asteroids.ToArray()) + { + if (Vector3D.DistanceSquared(asteroid.PositionComp.GetPosition(), playerPosition) > + AsteroidSettings.AsteroidSpawnRadius * AsteroidSettings.AsteroidSpawnRadius * 1.1) + { + _asteroids.Remove(asteroid); + continue; + } + } + + int asteroidsSpawned = 0; + while (_asteroids.Count < AsteroidSettings.MaxAsteroidCount && asteroidsSpawned < 10) + { + _asteroids.Add(AsteroidEntity.CreateAsteroid(playerPosition + RandVector()*AsteroidSettings.AsteroidSpawnRadius, RandAsteroidSize, Vector3D.Zero)); + + asteroidsSpawned++; + } + } + + private Vector3D RandVector() + { + var theta = MainSession.I.Rand.NextDouble() * 2.0 * Math.PI; + var phi = Math.Acos(2.0 * MainSession.I.Rand.NextDouble() - 1.0); + var sinPhi = Math.Sin(phi); + return Math.Pow(MainSession.I.Rand.NextDouble(), 1/3d) * new Vector3D(sinPhi * Math.Cos(theta), sinPhi * Math.Sin(theta), Math.Cos(phi)); + } + + private float RandAsteroidSize => (float) (MainSession.I.Rand.NextDouble()*MainSession.I.Rand.NextDouble()*MainSession.I.Rand.NextDouble()*500) + 1.5f; + } +} diff --git a/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidSettings.cs b/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidSettings.cs new file mode 100644 index 00000000..141aeb93 --- /dev/null +++ b/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidSettings.cs @@ -0,0 +1,52 @@ +using VRageMath; + +namespace DynamicAsteroids +{ + internal static class AsteroidSettings + { + public static int MaxAsteroidCount = 500; + public static int AsteroidSpawnRadius = 10000; + + public static SpawnableArea[] ValidSpawnLocations = + { + new SpawnableArea + { + CenterPosition = new Vector3D(148001024.50, 1024.50, 1024.50), + Normal = new Vector3D(1, 10, 0.5).Normalized(), + Radius = 60268000 * 2.5, + InnerRadius = 60268000 * 1.2, + HeightFromCenter = 25000, + } + }; + + public static bool SpawnAsteroidsAtPoint(Vector3D point) + { + foreach (var area in ValidSpawnLocations) + if (area.ContainsPoint(point)) + return true; + return false; + } + } + + internal class SpawnableArea + { + public Vector3D CenterPosition; + public Vector3D Normal; + public double Radius; + public double InnerRadius; + public double HeightFromCenter; + + public bool ContainsPoint(Vector3D point) + { + point -= CenterPosition; + double pointDistanceSq = point.LengthSquared(); + + if (pointDistanceSq > Radius * Radius || pointDistanceSq < InnerRadius * InnerRadius) + return false; + + // TODO: Normal and HeightFromCenter + + return true; + } + } +} diff --git a/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/MainSession.cs b/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/MainSession.cs index 097bf51f..4ae553e6 100644 --- a/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/MainSession.cs +++ b/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/MainSession.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using DynamicAsteroids.AsteroidEntities; +using Sandbox.Game.EntityComponents; using Sandbox.ModAPI; using SC.SUGMA; using VRage.Game.Components; @@ -16,7 +17,7 @@ public class MainSession : MySessionComponentBase public Random Rand = new Random(); - private List _asteroids; + private AsteroidSpawner _spawner = new AsteroidSpawner(); #region Base Methods @@ -27,7 +28,7 @@ public override void LoadData() try { - + _spawner.Init(); } catch (Exception ex) { @@ -39,7 +40,7 @@ protected override void UnloadData() { try { - + _spawner.Close(); } catch (Exception ex) { @@ -54,6 +55,7 @@ public override void UpdateAfterSimulation() { try { + _spawner.UpdateTick(); if (MyAPIGateway.Input.IsNewKeyPressed(MyKeys.MiddleButton)) AsteroidEntity.CreateAsteroid(MyAPIGateway.Session.Player?.GetPosition() ?? Vector3D.Zero, Rand.Next(50), MyAPIGateway.Session.Player?.Character?.Physics?.LinearVelocity ?? Vector3D.Zero); }