コード例 #1
0
        private void FollowToRoutePosition(MySmallShipBot bot)
        {
            // Fly to visible position, if too close look for new visible position
            if (Vector3.DistanceSquared(m_followPosition.Value, bot.GetPosition()) < 5 * 5)
            {
                m_followPosition = null;
            }
            else
            {
                bot.Move(m_followPosition.Value, m_followPosition.Value, bot.WorldMatrix.Up, false, 1, 2);

                if (m_stuckTimer > STUCK_TIME)
                {
                    if (Vector3.DistanceSquared(bot.GetPosition(), m_stuckPosition) > STUCK_DISTANCE)
                    {
                        m_followPosition = null;
                    }
                    else
                    {
                        m_followPosition = m_stuckPosition + MyMwcUtils.GetRandomVector3Normalized() * 1000;
                    }
                }
                else if (Vector3.DistanceSquared(bot.GetPosition(), m_stuckPosition) > STUCK_DISTANCE)
                {
                    ResetStuck(bot);
                }
                else
                {
                    m_stuckTimer += MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;
                }
            }
        }
コード例 #2
0
        static void UpdateExplosionLines()
        {
            foreach (LinkedListNode <ExplosionLine> explosionLine in m_preallocatedExplosionLines)
            {
                explosionLine.Value.ActualTime += MyConstants.PHYSICS_STEP_SIZE_IN_MILLISECONDS;
                if (explosionLine.Value.ActualTime > explosionLine.Value.TotalTime)
                {
                    m_preallocatedExplosionLines.MarkForDeallocate(explosionLine);
                    continue;
                }

                explosionLine.Value.ActualDir = Vector3.Lerp(explosionLine.Value.StartDir, explosionLine.Value.EndDir, explosionLine.Value.ActualTime / (float)explosionLine.Value.TotalTime);
            }

            m_preallocatedExplosionLines.DeallocateAllMarked();
            if (m_State == NuclearState.FADE_IN && MyMwcUtils.GetRandomFloat(0, 1) > 0.75f)
            {
                ExplosionLine line = m_preallocatedExplosionLines.Allocate(true);
                if (line != null)
                {
                    line.TotalTime  = 5000;
                    line.ActualTime = 0;
                    line.StartDir   = MyMwcUtils.GetRandomVector3Normalized();

                    Vector3 rotDir    = MyMwcUtils.GetRandomVector3Normalized();
                    Matrix  rotMatrix = Matrix.CreateFromAxisAngle(rotDir, 0.3f);
                    line.EndDir = Vector3.Transform(line.StartDir, rotMatrix);
                }
            }
        }
コード例 #3
0
ファイル: MyIceStorm.cs プロジェクト: whztt07/Miner-Wars-2081
        public static void Start()
        {
            Clear();

            IsActive     = true;
            startTime    = MyMinerGame.TotalGamePlayTimeInMilliseconds;
            ambientSound = MyAudio.AddCue3D(MySoundCuesEnum.SfxSolarWind,
                                            MyCamera.Position + MyCamera.ForwardVector * MaxSoundDistance, Vector3.Forward,
                                            Vector3.Up, Vector3.Zero, 0);


            sphereCenter = MyCamera.Position + MyCamera.ForwardVector * 400;


            for (int i = 0; i < SmokeCount; i++)
            {
                Vector3 pos = sphereCenter +
                              MyMwcUtils.GetRandomVector3Normalized() * MyMwcUtils.GetRandomFloat(0, SmokeSphereRadius);
                var smokePart = new SmokeParticle
                {
                    Angle           = MyMwcUtils.GetRandomRadian(),
                    Color           = Vector4.Zero,
                    AngularVelocity = MyMwcUtils.GetRandomFloat(-0.15f, 0.15f),
                    Pos             = pos,
                    Velocity        =
                        MyMwcUtils.GetRandomVector3Normalized() * MyMwcUtils.GetRandomFloat(0, 30f)
                };
                smokeParticles.Add(smokePart);
            }
        }
コード例 #4
0
            //  I used this method only when we didn't have real persistant sectors... for fly-through animations
            List <MyVoxelMapImpostor> CreateFakeImpostors()
            {
                List <MyVoxelMapImpostor> ret = new List <MyVoxelMapImpostor>(ImpostorProperties.ImpostorsCount);

                for (int i = 0; i < ImpostorProperties.ImpostorsCount; i++)
                {
                    Vector3 sectorCenter = Vector3.Zero;

                    float   randomDistance             = MyMwcUtils.GetRandomFloat(ImpostorProperties.MinDistance, ImpostorProperties.MaxDistance);
                    Vector3 randomPositionWithinSector = MyMwcUtils.GetRandomVector3Normalized() * randomDistance;

                    float radius = MyMwcUtils.GetRandomFloat(ImpostorProperties.MinRadius, ImpostorProperties.MaxRadius);

                    Vector3 position = sectorCenter + randomPositionWithinSector;

                    float angle = MyMwcUtils.GetRandomRadian();

                    ret.Add(new MyVoxelMapImpostor(position, radius, angle));
                }

                //  Sort by distance (back-to-front) so alpha won't make problems on overlapping quads
                ret.Sort();

                return(ret);
            }
コード例 #5
0
 void UpdateGoals(MySmallShipBot bot)
 {
     moveTarget = bot.GetPosition() + MyMwcUtils.GetRandomVector3Normalized() * 1000;
     lookTarget = bot.GetPosition() + MyMwcUtils.GetRandomVector3Normalized() * 1000;
     up         = MyMwcUtils.GetRandomVector3Normalized() * 1000;
     shoot      = MyMwcUtils.GetRandomBool(2);
 }
コード例 #6
0
        //  This method will start sun wind. Or if there is one coming, this will reset it so it will start again.
        public static void Start()
        {
            IsActive = true;

            //m_burningCue = MyAudio.AddCue3D(MySoundCuesEnum.SfxSolarWind, m_initialSunWindPosition, m_directionFromSunNormalized, Vector3.Up, Vector3.Zero);

            const int meteorsCount = 5;
            //const int frontDistance = 1000;
            //const int sideDistance = 3000;

            const int minSpeed = 1000;
            const int maxSpeed = 4000;

            //Vector3 sphereCenter = MyCamera.Position + MyCamera.ForwardVector * frontDistance - MyCamera.LeftVector * sideDistance;
            Vector3 sphereCenter = MyCamera.Position + MyGuiScreenGamePlay.Static.GetDirectionToSunNormalized() * 10000;
            //Vector3 windForwardDirection = MyCamera.LeftVector ;

            int i = 0;

            while (i < meteorsCount)
            {
                //float distance = MyMwcUtils.GetRandomFloat(0, sphereRadius);
                //Vector3 position = sphereCenter + MyMwcUtils.GetRandomVector3Normalized() * new Vector3(distance, distance, distance);

                //Vector3 meteorDirection = (windForwardDirection + (MyMwcUtils.GetRandomVector3Normalized() * 0.05f)) * MyMwcUtils.GetRandomInt(minSpeed, maxSpeed);
                //Vector3 meteorDirection = -MyGuiScreenGamePlay.Static.GetDirectionToSunNormalized();// MyMwcUtils.GetRandomVector3HemisphereNormalized(-MyGuiScreenGamePlay.Static.GetDirectionToSunNormalized());
                Vector3 meteorDirection = MyMwcUtils.GetRandomVector3HemisphereNormalized(-MyGuiScreenGamePlay.Static.GetDirectionToSunNormalized());
                Vector3 position        = sphereCenter + meteorDirection * MyMwcUtils.GetRandomInt(100, 5000);

                //float normalizedDistance = distance / sphereRadius;

                float size = MyMwcUtils.GetRandomInt(minSize, maxSize);


                MyLine line = new MyLine(position, position + meteorDirection * 100);
                MyIntersectionResultLineBoundingSphere?result = MyEntities.GetIntersectionWithLineAndBoundingSphere(ref line, null, null, 1, null, true);
                if (result != null)
                {   //Do not create meteors colliding with base
                    if (!(result.Value.PhysObject is MyMeteor))
                    {
                        continue;
                    }
                }

                Matrix worldMatrix = Matrix.CreateFromAxisAngle(MyMwcUtils.GetRandomVector3Normalized(), MyMwcUtils.GetRandomFloat(0, MathHelper.Pi));
                worldMatrix.Translation = position;

                MyMeteor meteor = MyMeteor.GenerateMeteor(size, worldMatrix, position, m_fireMeteorMaterials[MyMwcUtils.GetRandomInt(0, m_fireMeteorMaterials.Count)]);


                float speed = MyMwcUtils.GetRandomInt(minSpeed, maxSpeed);


                meteor.Start(meteorDirection * speed, MyMwcUtils.GetRandomFloat(0, 1) > 0.92f ? 101 : 100);

                i++;
            }
        }
コード例 #7
0
ファイル: MyIceStorm.cs プロジェクト: whztt07/Miner-Wars-2081
        public static void Draw()
        {
            if (!IsActive)
            {
                return;
            }

            // main smoke
            foreach (SmokeParticle part in smokeParticles)
            {
                MyTransparentGeometry.AddPointBillboard(MyTransparentMaterialEnum.Smoke, part.Color, part.Pos, 900,
                                                        part.Angle, 0, true);
            }

            float darkeningPhase;
            float dt;

            GetDarkeningPhase(out darkeningPhase, out dt);

            // small pieces of debris
            if (darkeningPhase > 0.2)
            {
                var color = new Vector4(1, 1, 1, darkeningPhase);

                for (int i = 0; i < 100; i++)
                {
                    Vector3 pos = MyCamera.Position +
                                  GetRandomVector3CircleNormalizedFixed(MyCamera.ForwardVector) *
                                  MyMwcUtils.GetRandomFloat(0, 500) + MyCamera.ForwardVector * 20;
                    MyTransparentGeometry.AddPointBillboard(MyTransparentMaterialEnum.particle_stone, color, pos,
                                                            MyMwcUtils.GetRandomFloat(0.008f, 0.05f),
                                                            MyMwcUtils.GetRandomRadian());
                }

                for (int i = 0; i < 100; i++)
                {
                    Vector3 pos = MyCamera.Position +
                                  GetRandomVector3CircleNormalizedFixed(MyCamera.ForwardVector) *
                                  MyMwcUtils.GetRandomFloat(0, 500) + MyCamera.ForwardVector * 20;
                    MyTransparentGeometry.AddPointBillboard(MyTransparentMaterialEnum.Sparks_b, color, pos,
                                                            MyMwcUtils.GetRandomFloat(0.008f, 0.05f),
                                                            MyMwcUtils.GetRandomRadian());
                }
            }

            // storm aftersparks
            foreach (ElectricStorm storm in storms)
            {
                MyTransparentGeometry.AddPointBillboard(MyTransparentMaterialEnum.Sparks_a, new Vector4(1f, 1f, 1f, 1f),
                                                        storm.Position +
                                                        MyMwcUtils.GetRandomVector3Normalized() *
                                                        MyMwcUtils.GetRandomFloat(0, 50),
                                                        MyMwcUtils.GetRandomFloat(10, 20), MyMwcUtils.GetRandomRadian());
            }
        }
コード例 #8
0
        internal bool TrySwitchExploreSearch(MySmallShipBot bot)
        {
            Vector3 flyTo = bot.GetPosition() + MyMwcUtils.GetRandomVector3Normalized() * MyMwcUtils.GetRandomFloat(0, 100);

            if (bot.TryTestPosition(flyTo, bot.GetPosition()))
            {
                m_state = CuriousState.EXPLORE_SEARCHING;
                return(true);
            }
            return(false);
        }
コード例 #9
0
        private static Vector3 GetDirection(Vector3 position, Vector3 sphereCenter)
        {
            Vector3 dist = position - sphereCenter;

            if (MyUtils.IsValid(dist) && MyMwcUtils.HasValidLength(dist))
            {
                return(Vector3.Normalize(dist));
            }
            else
            {
                return(MyMwcUtils.GetRandomVector3Normalized());
            }
        }
コード例 #10
0
        public static MyMeteor CreateComet(Vector3 position, Vector3 direction)
        {
            float size = MyMwcUtils.GetRandomInt(m_sizeMin, m_sizeMax);

            Matrix worldMatrix = Matrix.CreateFromAxisAngle(MyMwcUtils.GetRandomVector3Normalized(), MyMwcUtils.GetRandomFloat(0, MathHelper.Pi));

            worldMatrix.Translation = position;

            MyMeteor meteor = MyMeteor.GenerateMeteor(size, worldMatrix, position, m_iceMeteorMaterials[MyMwcUtils.GetRandomInt(0, m_iceMeteorMaterials.Count)]);

            meteor.Start(direction, 953);

            return(meteor);
        }
コード例 #11
0
        internal static void Start()
        {
            IsActive    = true;
            m_startTime = MyMinerGame.TotalGamePlayTimeInMilliseconds;

            const int meteorsCount = 3;

            const int minSpeed = 1200;
            const int maxSpeed = 1400;

            Vector3 sphereCenter         = MyCamera.Position + MyCamera.ForwardVector * m_frontDistance - MyCamera.LeftVector * m_sideDistance;
            Vector3 windForwardDirection = MyCamera.LeftVector;

            for (int i = 0; i < meteorsCount; i++)
            {
                Vector3 meteorDirection = (windForwardDirection + (MyMwcUtils.GetRandomVector3Normalized() * 0.001f)) * MyMwcUtils.GetRandomInt(minSpeed, maxSpeed);
                float   distance        = MyMwcUtils.GetRandomFloat(1000, 1500);

                CreateComet(sphereCenter + MyMwcUtils.GetRandomVector3Normalized() * new Vector3(distance, distance, distance), meteorDirection);
            }
        }
コード例 #12
0
        public static MyMeteor GenerateMeteor(float sizeInMeters, Matrix worldMatrix, Vector3 position, MyMwcVoxelMaterialsEnum material)
        {
            int size = MySectorGenerator.FindAsteroidSize(sizeInMeters, MyMwcObjectBuilder_StaticAsteroid.AsteroidSizes);

            asteroids.Clear();
            MyMwcObjectBuilder_Meteor.GetAsteroids(size, MyStaticAsteroidTypeSetEnum.A, asteroids);
            int rndIndex = MyMwcUtils.GetRandomInt(0, asteroids.Count);

            var builder = new MyMwcObjectBuilder_Meteor(asteroids[rndIndex], material);

            builder.PositionAndOrientation.Position = position;
            builder.PositionAndOrientation.Forward  = MyMwcUtils.GetRandomVector3Normalized();
            builder.PositionAndOrientation.Up       = MyMwcUtils.GetRandomVector3Normalized();

            builder.UseModelTechnique = false;

            MyMeteor meteor = (MyMeteor)MyEntities.CreateFromObjectBuilderAndAdd(null, builder, worldMatrix);

            meteor.m_size = sizeInMeters;

            return(meteor);
        }
コード例 #13
0
        private bool GetSafePositionForSpawn(MyMwcObjectBuilder_SmallShip_TypesEnum shipType, out Vector3?safePosition)
        {
            var shipRadius = MyModels.GetModelOnlyData(MyShipTypeConstants.GetShipTypeProperties(shipType).Visual.ModelLod0Enum).BoundingSphere.Radius;

            for (int c = MAX_SPAWN_ATTEMPTS; c-- != 0;)
            {
                Vector3 randomPointInSphere = MyMwcUtils.GetRandomVector3Normalized() * MyMwcUtils.GetRandomFloat(0, 1) * BoundingSphereRadius; // Random point in sphere
                Vector3 newTestPos          = GetPosition() + randomPointInSphere;

                BoundingSphere bsphere = new BoundingSphere(newTestPos, shipRadius);
                MyEntity       col     = MyEntities.GetIntersectionWithSphere(ref bsphere);

                if (col == null)
                {
                    safePosition = newTestPos;
                    return(true);
                }
            }

            safePosition = null;
            return(false);
        }
コード例 #14
0
        /// <summary>
        /// Once per few frames, generates a flicker.
        /// Actually only manipulates the m_scale vector in order to simulate flicker appearance.
        /// </summary>
        private void GenerateFlicker()
        {
            // TODO simon how do I make this independent of FPS?
            bool startFlickerNow = MyMwcUtils.GetRandomBool(MyHologramConstants.FLICKER_FREQUENCY);

            if (startFlickerNow && m_flickerElapsedMilliseconds > MyHologramConstants.FLICKER_DURATION)
            {
                m_flickerElapsedMilliseconds = 0;
                m_flickerScale = MyMwcUtils.GetRandomVector3Normalized();
            }

            if (m_flickerElapsedMilliseconds < MyHologramConstants.FLICKER_DURATION)
            {
                float   flickerProgress = m_flickerElapsedMilliseconds / MyHologramConstants.FLICKER_DURATION;
                Vector3 maxFlickerScale = MyHologramConstants.FLICKER_MAX_SIZE * Vector3.One;
                m_scale = Vector3.Lerp(maxFlickerScale, m_flickerScale, flickerProgress);
            }
            else
            {
                m_scale = Vector3.One;
            }

            m_flickerElapsedMilliseconds += MyConstants.PHYSICS_STEP_SIZE_IN_MILLISECONDS;
        }
コード例 #15
0
        private void FollowPath(MySmallShipBot bot)
        {
            if (m_currentPathPosition >= m_followPath.Count)
            {
                m_followPath = null;  // reached the goal or got stuck
            }
            else if (Vector3.DistanceSquared(m_followPath[m_currentPathPosition], bot.GetPosition()) < PATH_NEAR_DISTANCE_SQR)
            {
                m_currentPathPosition++;  // next waypoint reached
            }
            else
            {
                bot.Move(m_followPath[m_currentPathPosition], m_followPath[m_currentPathPosition], bot.WorldMatrix.Up, false, 1, 2);

                if (m_stuckTimer > STUCK_TIME)
                {
                    if (Vector3.DistanceSquared(bot.GetPosition(), m_stuckPosition) > STUCK_DISTANCE)
                    {
                        m_currentPathPosition++;  // try skipping ahead to the next waypoint instead of getting stuck right away
                        ResetStuck(bot);
                    }
                    else
                    {
                        m_followPath[m_currentPathPosition] += MyMwcUtils.GetRandomVector3Normalized() * 1000;  // jitter the sub-goal
                    }
                }
                else if (Vector3.DistanceSquared(bot.GetPosition(), m_stuckPosition) > STUCK_DISTANCE)
                {
                    ResetStuck(bot);
                }
                else
                {
                    m_stuckTimer += MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS;
                }
            }
        }
コード例 #16
0
        public void CalculateStartPosition(float elapsedTime, Matrix worldMatrix, float userScale, out Vector3 startOffset, out Vector3 startPosition)
        {
            Vector3 currentOffsetUntransformed;

            Offset.GetInterpolatedValue <Vector3>(elapsedTime, out currentOffsetUntransformed);

            float currentSize;

            Size.GetInterpolatedValue <float>(elapsedTime, out currentSize);
            currentSize *= MyMwcUtils.GetRandomFloat(RadiusMin, RadiusMax) * userScale;

            Vector3 localPos = Vector3.Zero;
            Vector3 worldOffset;

            Vector3.Transform(ref currentOffsetUntransformed, ref worldMatrix, out worldOffset);

            switch (Type)
            {
            case MyParticleEmitterType.Point:
                localPos = Vector3.Zero;
                break;

            case MyParticleEmitterType.Line:
                localPos = Vector3.Forward * MyMwcUtils.GetRandomFloat(0.0f, currentSize);
                break;

            case MyParticleEmitterType.Sphere:
                localPos = MyMwcUtils.GetRandomVector3Normalized() * currentSize;
                break;

            case MyParticleEmitterType.Box:
                float currentSizeHalf = currentSize * 0.5f;
                localPos =
                    new Vector3(
                        MinerWars.CommonLIB.AppCode.Utils.MyMwcUtils.GetRandomFloat(-currentSizeHalf, currentSizeHalf),
                        MinerWars.CommonLIB.AppCode.Utils.MyMwcUtils.GetRandomFloat(-currentSizeHalf, currentSizeHalf),
                        MinerWars.CommonLIB.AppCode.Utils.MyMwcUtils.GetRandomFloat(-currentSizeHalf, currentSizeHalf)
                        );
                break;

            case MyParticleEmitterType.Hemisphere:
                localPos = MyMwcUtils.GetRandomVector3HemisphereNormalized(Vector3.Forward) * currentSize;
                break;

            case MyParticleEmitterType.Circle:
                localPos = MyMwcUtils.GetRandomVector3CircleNormalized() * currentSize;
                break;

            default:
                System.Diagnostics.Debug.Assert(false);
                break;
            }

            Vector3 worldPos;

            if (DirToCamera)
            {
                Matrix WorldView = worldMatrix * MyCamera.ViewMatrix;
                WorldView.Translation += currentOffsetUntransformed;
                Matrix newWorld = WorldView * Matrix.Invert(MyCamera.ViewMatrix);

                Vector3 dir = MyCamera.Position - newWorld.Translation;
                dir.Normalize();

                Matrix matrix = MyMath.MatrixFromDir(dir);
                matrix.Translation = newWorld.Translation;

                Vector3.Transform(ref localPos, ref matrix, out worldPos);

                startOffset   = newWorld.Translation;
                startPosition = worldPos;
            }
            else
            {
                Vector3.TransformNormal(ref localPos, ref worldMatrix, out worldPos);

                startOffset   = worldOffset;
                startPosition = worldOffset + worldPos;
            }
        }
コード例 #17
0
        public override void UpdateBeforeSimulation()
        {
            try
            {
                MyRender.GetRenderProfiler().StartProfilingBlock("MyCannonShot.UpdateBeforeSimulation");

                if (this.WorldMatrix.Translation != m_previousPosition)
                {
                    MyLine line = new MyLine(this.WorldMatrix.Translation, m_previousPosition);
                    MyDangerZones.Instance.Notify(line, OwnerEntity);
                }

                //  Kill this missile
                if (m_isExploded && !m_wasPenetration)
                {
                    //  Create explosion
                    MyExplosion newExplosion = MyExplosions.AddExplosion();
                    if (newExplosion != null)
                    {
                        float           radius          = MyMwcUtils.GetRandomFloat(m_ammoProperties.ExplosionRadius - 2, m_ammoProperties.ExplosionRadius + 2);
                        BoundingSphere  explosionSphere = new BoundingSphere((m_collisionPoint.HasValue ? m_collisionPoint.Value : GetPosition()), radius);
                        MyExplosionInfo info            = new MyExplosionInfo(m_ammoProperties.HealthDamage, m_ammoProperties.ShipDamage, m_ammoProperties.EMPDamage, explosionSphere, m_explosionType, true)
                        {
                            GroupMask            = Physics.GroupMask,
                            CascadeLevel         = CascadedExplosionLevel,
                            HitEntity            = m_collidedEntity,
                            OwnerEntity          = this.OwnerEntity,
                            Direction            = WorldMatrix.Forward,
                            ParticleScale        = 1.5f,
                            VoxelExplosionCenter = explosionSphere.Center + radius * WorldMatrix.Forward * 0.6f,
                        };
                        info.CreateParticleEffect = !m_hasExplosion;
                        newExplosion.Start(ref info);
                    }

                    if (m_collidedEntity != null && !m_collidedEntity.IsExploded())
                    {
                        m_collidedEntity.Physics.AddForce(
                            MyPhysicsForceType.APPLY_WORLD_IMPULSE_AND_WORLD_ANGULAR_IMPULSE,
                            WorldMatrix.Forward * MyMissileConstants.HIT_STRENGTH_IMPULSE,
                            GetPosition() + MyMwcUtils.GetRandomVector3Normalized() * 2,
                            MyMissileConstants.HIT_STRENGTH_IMPULSE * MyMwcUtils.GetRandomVector3Normalized());
                    }

                    MarkForClose();

                    return;
                }

                base.UpdateBeforeSimulation();

                //  Chech timeout and max distance
                if ((m_elapsedMiliseconds > MyCannonConstants.SHOT_TIMEOUT) || (Vector3.Distance(this.WorldMatrix.Translation, m_origin) >= m_ammoProperties.MaxTrajectory))
                {
                    MarkForClose();
                    return;
                }



                Matrix orientation = GetWorldRotation();

                //  Update thruster cue/sound
                MyAudio.UpdateCuePosition(m_thrusterCue, this.WorldMatrix.Translation, orientation.Forward, orientation.Up, this.Physics.LinearVelocity);

                Vector3 pos = this.WorldMatrix.Translation;

                if (m_penetratedVoxelMap == null)
                {
                    if (m_smokeEffect != null)
                    {
                        m_smokeEffect.WorldMatrix = WorldMatrix;
                    }
                }

                /*
                 * if (m_wasPenetration)
                 * {
                 * //  Create explosion
                 * MyExplosion newExplosion = MyExplosions.AddExplosion();
                 * if (newExplosion != null)
                 * {
                 * float radius = MyMwcUtils.GetRandomFloat(1, 2);
                 * float particleScale = 2.2f; // must be large enough to cover the hole
                 * newExplosion.StartWithPositionOffset(m_ammoProperties.HealthDamage, m_ammoProperties.ShipDamage, m_ammoProperties.EMPDamage, m_explosionType, m_penetrationOrigin - WorldMatrix.Forward * 2, radius, MyExplosionsConstants.EXPLOSION_LIFESPAN, CascadedExplosionLevel, particleScale: particleScale, hitEntity: m_collidedEntity, ownerEntity: m_ownerEntity);
                 * }
                 * m_wasPenetration = false;
                 * m_hasExplosion = true;
                 * }        */

                if (m_usedAmmo.AmmoType == MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Cannon_Proximity_Explosive)
                {
                    //  Look for small ships in shots's proximity
                    BoundingSphere boundingSphere = new BoundingSphere(GetPosition(), MyCannonShotConstants.PROXIMITY_DETECTION_RADIUS);
                    BoundingBox    boundingBox    = new BoundingBox();
                    BoundingBox.CreateFromSphere(ref boundingSphere, out boundingBox);

                    var elements = MyEntities.GetElementsInBox(ref boundingBox);
                    for (int i = 0; i < elements.Count; i++)
                    {
                        var rigidBody = (MyPhysicsBody)elements[i].GetRigidBody().m_UserData;
                        var entity    = rigidBody.Entity;


                        if (!(entity is MinerWars.AppCode.Game.Entities.MySmallShip))
                        {
                            continue;
                        }
                        if (entity == OwnerEntity)
                        {
                            continue;
                        }
                        if (entity == this)
                        {
                            continue;
                        }

                        Explode(entity);
                        break;
                    }
                    elements.Clear();
                }

                /*
                 * if (m_usedAmmo.AmmoType == MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Cannon_Tunnel_Buster)
                 * {
                 *  m_cuttingSphere.Center = GetPosition();
                 *
                 *  //  We found voxel so lets make tunel into it
                 *  MyPhysObjectBase collisionResult = MyEntities.GetIntersectionWithSphere(ref m_cuttingSphere, this, (MySmallShip)Parent);
                 *  if (collisionResult is MyVoxelMap)
                 *  {
                 *      MyVoxelMap voxelMap = collisionResult as MyVoxelMap;
                 *      if (m_penetratedVoxelMap == null)
                 *      {
                 *          m_penetratedVoxelMap = voxelMap;
                 *          m_penetrationOrigin = GetPosition();
                 *      }
                 *
                 *      Game.Voxels.MyVoxelGenerator.CutOutSphereFast(voxelMap, m_cuttingSphere);
                 *  }
                 * } */
                /*
                 * if (m_usedAmmo.AmmoType == MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Cannon_Tunnel_Buster)
                 * {
                 * if (m_penetratedVoxelMap != null)
                 * {
                 * //MyCannonShotConstants.BUSTER_PENETRATION_LENGTH
                 * float busterPenetrationLength = m_ammoProperties.ExplosionRadius * 0.75f;
                 * if (Vector3.Distance(m_penetrationOrigin, GetPosition()) >= busterPenetrationLength)
                 * {
                 *    m_collisionPoint = GetPosition(); //We want to explode inside voxel, not on collision point
                 *    Explode(m_penetratedVoxelMap);
                 * }
                 * }
                 * }    */
            }
            finally
            {
                MyRender.GetRenderProfiler().EndProfilingBlock();
            }
        }
コード例 #18
0
ファイル: MyIceStorm.cs プロジェクト: whztt07/Miner-Wars-2081
 //  Random vector distributed over the circle about normal.
 //  Returns random vector that always lies on circle
 public static Vector3 GetRandomVector3CircleNormalizedFixed(Vector3 normal)
 {
     return(MyMwcUtils.GetRandomVector3Normalized() * normal);
 }
コード例 #19
0
ファイル: MyIceStorm.cs プロジェクト: whztt07/Miner-Wars-2081
        public static void Update()
        {
            //  Update only if sun wind is active
            if (IsActive == false)
            {
                return;
            }

            float darkeningPhase;
            float dt;
            int   relTime = GetDarkeningPhase(out darkeningPhase, out dt);

            if (relTime > MaxTimeMs)
            {
                Clear();
                return;
            }


            MyAudio.UpdateCuePosition(ambientSound,
                                      MyCamera.Position + MyCamera.ForwardVector * -MaxSoundDistance * (1 - darkeningPhase),
                                      MyCamera.ForwardVector, MyCamera.UpVector, Vector3.Zero);
            MyAudio.UpdateCueVolume(ambientSound, darkeningPhase * MaxAmbientVolume);

            // update smoke
            foreach (SmokeParticle part in smokeParticles)
            {
                Vector3 toCamera = (MyCamera.Position - part.Pos);
                toCamera.Normalize();
                float alpha = darkeningPhase * MaxSmokeAlpha;
                part.Color = new Vector4(alpha, alpha, alpha, alpha);
                //part.Color.W = darkeningPhase;
                part.Pos   += part.Velocity * dt + toCamera * CenterBias * dt;
                part.Angle += part.AngularVelocity * dt;
            }


            // remove old ice and sparks

            m_iceList.Clear();
            foreach (IceParticle particle in iceParticles)
            {
                if (particle.StartTime + 4000 < relTime)
                {
                    m_iceList.Add(particle);
                }
            }

            foreach (IceParticle ice in m_iceList)
            {
                ice.AsteroidEntity.MarkForClose();
                Debug.Assert(ice.TrailEffect != null, "ice.TrailEffect != null");
                ice.TrailEffect.Stop();
                ice.TrailEffect = null;
                StopCue(ice.Sound);
                iceParticles.Remove(ice);
            }

            int c = 0;

            while (c < storms.Count)
            {
                ElectricStorm storm = storms[c];
                if (storm.StartTime + 1500 < relTime)
                {
                    storms.RemoveAt(c);
                    continue;
                }
                c++;
            }



            // if its dark add new sparks and ice balls
            if (darkeningPhase >= 1)
            {
                if (storms.Count < MaxSparkCount && MyMwcUtils.GetRandomInt(SparkEveryMs) < dt * 1000.0f)
                {
                    var storm = new ElectricStorm
                    {
                        Position =
                            MyCamera.Position + MyCamera.ForwardVector * 250 +
                            MyMwcUtils.GetRandomVector3HemisphereNormalized(MyCamera.ForwardVector) *
                            MyMwcUtils.GetRandomFloat(0, 300),
                        StartTime = relTime,
                        Effect    =
                            MyParticlesManager.CreateParticleEffect(
                                (int)MyParticleEffectsIDEnum.Damage_Sparks),
                    };
                    storm.Effect.WorldMatrix = Matrix.CreateTranslation(storm.Position);
                    storm.Effect.AutoDelete  = true;
                    storm.Effect.UserScale   = 2;
                    storm.Sound = MyAudio.AddCue2D(MySoundCuesEnum.SfxSpark);
                    storms.Add(storm);
                }


                if (iceParticles.Count < MaxIceCount && MyMwcUtils.GetRandomInt(IceEveryMs) < dt * 1000.0f)
                {
                    Vector3 dir = MyMwcUtils.GetRandomVector3HemisphereNormalized(MyCamera.ForwardVector);
                    Vector3 pos = MyCamera.Position + MyCamera.ForwardVector * 250 +
                                  MyMwcUtils.GetRandomVector3Normalized() * MyMwcUtils.GetRandomFloat(0, 200) +
                                  dir * MyMwcUtils.GetRandomFloat(0, 500);
                    MyMwcObjectBuilder_StaticAsteroid rockModel =
                        MySectorGenerator.GenerateStaticAsteroid(MyMwcUtils.GetRandomFloat(0.1f, 2f),
                                                                 MyStaticAsteroidTypeSetEnum.A,
                                                                 MyMwcVoxelMaterialsEnum.Ice_01, pos, random,
                                                                 asteroidTypes);
                    Matrix matrix = Matrix.CreateFromAxisAngle(MyMwcUtils.GetRandomVector3Normalized(),
                                                               MyMwcUtils.GetRandomFloat(0, MathHelper.Pi));
                    matrix.Translation = pos;
                    MyEntity asteroid = MyEntities.CreateFromObjectBuilderAndAdd(null, rockModel, matrix);
                    asteroid.Physics.Enabled = false;
                    asteroid.CastShadows     = false;

                    MyParticleEffect effect =
                        MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.Smoke_CannonShot);
                    Vector3 velocity = -dir *MyMwcUtils.GetRandomInt(150, 400);

                    iceParticles.Add(new IceParticle
                    {
                        StartTime       = relTime,
                        Position        = pos,
                        Direction       = -dir,
                        AsteroidEntity  = asteroid,
                        TrailEffect     = effect,
                        RotAxis         = MyMwcUtils.GetRandomVector3Normalized(),
                        RotAngle        = MyMwcUtils.GetRandomRadian(),
                        AngularVelocity = MyMwcUtils.GetRandomFloat(0.2f, 10f),
                        Velocity        = velocity,
                        Sound           =
                            MyAudio.AddCue3D(MySoundCuesEnum.WepSniperHighFire2d, pos, dir,
                                             dir * -dir, velocity)
                    });
                }
            }

            // update ice parts
            foreach (IceParticle particle in iceParticles)
            {
                particle.RotAngle += particle.AngularVelocity * dt;
                particle.Position += particle.Velocity * dt;
                Matrix matrix = Matrix.CreateFromAxisAngle(particle.RotAxis, particle.RotAngle);
                matrix.Translation = particle.Position;
                particle.AsteroidEntity.SetWorldMatrix(matrix);
                Matrix trans = Matrix.CreateTranslation(-particle.Direction * 10);
                particle.TrailEffect.WorldMatrix = matrix * trans;
                MyAudio.UpdateCuePosition(particle.Sound, particle.Position, particle.Direction,
                                          particle.Direction * -particle.Direction, particle.Velocity);
            }



            lastUpdateMs = MyMinerGame.TotalGamePlayTimeInMilliseconds;
        }
コード例 #20
0
        //  Update position, check collisions, etc. and draw if particle still lives.
        //  Return false if particle dies/timeouts in this tick.
        public bool Draw(MyBillboard billboard)
        {
            MyTransparentGeometry.StartParticleProfilingBlock("Distance calculation");
            //  This time is scaled according to planned lifespan of the particle

            // Distance for sorting
            Vector3 campos = MyCamera.Position;

            Vector3.DistanceSquared(ref campos, ref m_actualPosition, out billboard.DistanceSquared);

            MyTransparentGeometry.EndParticleProfilingBlock();

            // If distance to camera is really small don't draw it.
            if (billboard.DistanceSquared <= 1)
            {
                return(false);
            }

            MyTransparentGeometry.StartParticleProfilingBlock("Quad calculation");

            MyTransparentGeometry.StartParticleProfilingBlock("actualRadius");
            float actualRadius = 1;

            Radius.GetInterpolatedValue <float>(m_normalizedTime, out actualRadius);
            MyTransparentGeometry.EndParticleProfilingBlock();

            billboard.ContainedBillboards.Clear();

            billboard.Near   = m_generation.GetEffect().Near;
            billboard.Lowres = m_generation.GetEffect().LowRes || MyRenderConstants.RenderQualityProfile.LowResParticles;

            float alpha = 1;

            if (Type == MyParticleTypeEnum.Point)
            {
                MyTransparentGeometry.StartParticleProfilingBlock("GetBillboardQuadRotated");
                MyUtils.GetBillboardQuadRotated(billboard, ref m_actualPosition, actualRadius, m_actualAngle);
                MyTransparentGeometry.EndParticleProfilingBlock();
            }
            else if (Type == MyParticleTypeEnum.Line)
            {
                if (MyMwcUtils.IsZero(Velocity.LengthSquared()))
                {
                    Velocity = MyMwcUtils.GetRandomVector3Normalized();
                }

                MyQuad quad = new MyQuad();

                MyPolyLine polyLine = new MyPolyLine();
                polyLine.LineDirectionNormalized = MyMwcUtils.Normalize(Velocity);

                if (m_actualAngle > 0)
                {
                    polyLine.LineDirectionNormalized = Vector3.TransformNormal(polyLine.LineDirectionNormalized, Matrix.CreateRotationY(MathHelper.ToRadians(m_actualAngle)));
                }

                polyLine.Point0   = m_actualPosition;
                polyLine.Point1.X = m_actualPosition.X + polyLine.LineDirectionNormalized.X * actualRadius;
                polyLine.Point1.Y = m_actualPosition.Y + polyLine.LineDirectionNormalized.Y * actualRadius;
                polyLine.Point1.Z = m_actualPosition.Z + polyLine.LineDirectionNormalized.Z * actualRadius;

                if (m_actualAngle > 0)
                { //centerize
                    polyLine.Point0.X = polyLine.Point0.X - polyLine.LineDirectionNormalized.X * actualRadius * 0.5f;
                    polyLine.Point0.Y = polyLine.Point0.Y - polyLine.LineDirectionNormalized.Y * actualRadius * 0.5f;
                    polyLine.Point0.Z = polyLine.Point0.Z - polyLine.LineDirectionNormalized.Z * actualRadius * 0.5f;
                    polyLine.Point1.X = polyLine.Point1.X - polyLine.LineDirectionNormalized.X * actualRadius * 0.5f;
                    polyLine.Point1.Y = polyLine.Point1.Y - polyLine.LineDirectionNormalized.Y * actualRadius * 0.5f;
                    polyLine.Point1.Z = polyLine.Point1.Z - polyLine.LineDirectionNormalized.Z * actualRadius * 0.5f;
                }

                polyLine.Thickness = Thickness;
                MyUtils.GetPolyLineQuad(out quad, ref polyLine);

                if (this.m_generation.AlphaAnisotropic)
                {
                    float angle     = 1 - Math.Abs(Vector3.Dot(MyMwcUtils.Normalize(MyCamera.ForwardVector), polyLine.LineDirectionNormalized));
                    float alphaCone = (float)Math.Pow(angle, 0.5f);
                    alpha = alphaCone;
                }

                billboard.Position0 = quad.Point0;
                billboard.Position1 = quad.Point1;
                billboard.Position2 = quad.Point2;
                billboard.Position3 = quad.Point3;
            }
            else if (Type == MyParticleTypeEnum.Trail)
            {
                if (Quad.Point0 == Quad.Point2) //not moving particle
                {
                    return(false);
                }
                if (Quad.Point1 == Quad.Point3) //not moving particle was previous one
                {
                    return(false);
                }
                if (Quad.Point0 == Quad.Point3) //not moving particle was previous one
                {
                    return(false);
                }

                billboard.Position0 = Quad.Point0;
                billboard.Position1 = Quad.Point1;
                billboard.Position2 = Quad.Point2;
                billboard.Position3 = Quad.Point3;

                //if (this.m_generation.AlphaAnisotropic)

                /*   { //Trails are anisotropic by default (nobody wants them to see ugly)
                 *     Vector3 lineDir = Vector3.Normalize(Quad.Point1 - Quad.Point0);
                 *     float angle = 1 - Math.Abs(Vector3.Dot(MyMwcUtils.Normalize(MyCamera.ForwardVector), lineDir));
                 *     float alphaCone = (float)Math.Pow(angle, 0.3f);
                 *     alpha = alphaCone;
                 * }*/
            }
            else
            {
                throw new NotSupportedException(Type + " is not supported particle type");
            }

            MyTransparentGeometry.EndParticleProfilingBlock();

            MyTransparentGeometry.StartParticleProfilingBlock("Material calculation");

            Vector4 color;

            Color.GetInterpolatedValue <Vector4>(m_normalizedTime, out color);

            int   material1         = (int)MyTransparentMaterialEnum.Test;
            int   material2         = (int)MyTransparentMaterialEnum.Test;
            float textureBlendRatio = 0;

            if ((Flags & ParticleFlags.BlendTextures) != 0)
            {
                float prevTime, nextTime, difference;
                Material.GetPreviousValue(m_normalizedTime, out material1, out prevTime);
                Material.GetNextValue(m_normalizedTime, out material2, out nextTime, out difference);

                if (prevTime != nextTime)
                {
                    textureBlendRatio = (m_normalizedTime - prevTime) * difference;
                }
            }
            else
            {
                Material.GetInterpolatedValue <int>(m_normalizedTime, out material1);
            }

            MyTransparentGeometry.EndParticleProfilingBlock();

            //This gets 0.44ms for 2000 particles
            MyTransparentGeometry.StartParticleProfilingBlock("billboard.Start");


            billboard.MaterialEnum      = (MyTransparentMaterialEnum)material1;
            billboard.BlendMaterial     = (MyTransparentMaterialEnum)material2;
            billboard.BlendTextureRatio = textureBlendRatio;
            billboard.EnableColorize    = false;

            billboard.Color = color * alpha * m_generation.GetEffect().UserColorMultiplier;

            MyTransparentGeometry.EndParticleProfilingBlock();

            return(true);
        }
コード例 #21
0
ファイル: MyMissile.cs プロジェクト: whztt07/Miner-Wars-2081
        /// <summary>
        /// Updates resource.
        /// </summary>
        public override void UpdateBeforeSimulation()
        {
            try
            {
                MyRender.GetRenderProfiler().StartProfilingBlock("MyMissile.UpdateBeforeSimulation");

                //Large ship weapons wont make bots curious
                if ((!(OwnerEntity is MyLargeShipMissileLauncherBarrel)) && MyMwcUtils.HasValidLength(this.WorldMatrix.Translation - m_previousPosition))
                {
                    MyLine line = new MyLine(this.WorldMatrix.Translation, m_previousPosition);
                    MyDangerZones.Instance.Notify(line, OwnerEntity);
                }

                if (m_isExploded)
                {
                    //  Create explosion
                    MyExplosion newExplosion = MyExplosions.AddExplosion();
                    if (newExplosion != null)
                    {
                        float radius = m_ammoProperties.ExplosionRadius;

                        // Explicitly on Marek's request (ticket 4740)
                        bool amplifyRadius = m_collidedEntity != null?MyFactions.GetFactionsRelation(m_collidedEntity.Faction, Faction) != MyFactionRelationEnum.Friend : false;

                        if (amplifyRadius)
                        {
                            radius *= 2;
                        }

                        BoundingSphere explosionSphere = new BoundingSphere(m_collisionPoint.HasValue ? m_collisionPoint.Value : GetPosition(), radius);

                        //  Call main explosion starter
                        MyExplosionInfo info = new MyExplosionInfo()
                        {
                            PlayerDamage            = m_ammoProperties.HealthDamage,
                            Damage                  = m_ammoProperties.ShipDamage,
                            EmpDamage               = m_ammoProperties.EMPDamage,
                            ExplosionType           = m_explosionType,
                            ExplosionSphere         = explosionSphere,
                            LifespanMiliseconds     = MyExplosionsConstants.EXPLOSION_LIFESPAN,
                            ExplosionForceDirection = MyExplosionForceDirection.EXPLOSION,
                            GroupMask               = Physics.GroupMask,
                            CascadeLevel            = CascadedExplosionLevel,
                            HitEntity               = m_collidedEntity,
                            ParticleScale           = 1.5f,
                            OwnerEntity             = this.OwnerEntity,
                            Direction               = WorldMatrix.Forward,
                            VoxelExplosionCenter    = explosionSphere.Center + m_ammoProperties.ExplosionRadius * WorldMatrix.Forward * 0.5f,
                            ExplosionFlags          = MyExplosionFlags.AFFECT_VOXELS | MyExplosionFlags.APPLY_FORCE_AND_DAMAGE | MyExplosionFlags.CREATE_DEBRIS | MyExplosionFlags.CREATE_DECALS | MyExplosionFlags.CREATE_PARTICLE_EFFECT,
                            VoxelCutoutScale        = amplifyRadius ? 0.5f : 1.0f,
                            PlaySound               = true,
                        };

                        newExplosion.Start(ref info);
                    }

                    if (m_collidedEntity != null && !m_collidedEntity.IsExploded())
                    {
                        m_collidedEntity.Physics.AddForce(
                            MyPhysicsForceType.APPLY_WORLD_IMPULSE_AND_WORLD_ANGULAR_IMPULSE,
                            WorldMatrix.Forward * MyMissileConstants.HIT_STRENGTH_IMPULSE,
                            GetPosition() + MyMwcUtils.GetRandomVector3Normalized() * 2,
                            MyMissileConstants.HIT_STRENGTH_IMPULSE * MyMwcUtils.GetRandomVector3Normalized());
                        m_collidedEntity.OnClose -= m_collidedEntity_OnClose;
                    }

                    MarkForClose();

                    return;
                }

                bool firstTargetting = m_elapsedMiliseconds == 0;

                base.UpdateBeforeSimulation();

                m_missileTargetUpdate += MyConstants.PHYSICS_STEP_SIZE_IN_MILLISECONDS;

                if (m_missileTargetUpdate >= MyGuidedMissileConstants.MISSILE_TARGET_UPDATE_INTERVAL_IN_MS || firstTargetting)
                {
                    m_missileTargetUpdate = 0;

                    switch (m_missileType)
                    {
                    case MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Guided_Missile_Radar_Detection:
                    {
                        MySmallShip targetShip = m_targetEntity as MySmallShip;
                        if (targetShip != null && targetShip.IsRadarJammed())
                        {
                            m_targetEntity = null;
                        }
                    }
                    break;

                    case MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Guided_Missile_Engine_Detection:
                    {
                        m_targetEntities.Clear();

                        Matrix proj = Matrix.CreateOrthographic(MyGuidedMissileConstants.ENGINE_GUIDED_MISSILE_RADIUS, MyGuidedMissileConstants.ENGINE_GUIDED_MISSILE_RADIUS, 0, 1000);
                        Matrix view = Matrix.CreateLookAt(GetPosition(), GetPosition() + WorldMatrix.Forward, WorldMatrix.Up);
                        m_visualFrustum.Matrix = view * proj;

                        MyEntities.GetAllIntersectionWithBoundingFrustum(ref m_visualFrustum, m_targetEntities);

                        if (m_targetEntities.Contains(m_targetEntity))
                        {
                            break;
                        }

                        MyEntity target = null;
                        float    closestToMissileDirection = float.MaxValue;

                        foreach (MyEntity entity in m_targetEntities)
                        {
                            if (CanTarget(entity))
                            {
                                MySmallShip targetShip = entity as MySmallShip;
                                if (targetShip != null)
                                {
                                    if ((targetShip.IsEngineTurnedOff()))
                                    {
                                        continue;
                                    }
                                }

                                Vector3 targetPos     = entity.GetPosition();
                                Vector3 missilePos    = this.GetPosition();
                                Vector3 missilePosEnd = this.GetPosition() + this.WorldMatrix.Forward * 10000;
                                Vector3 closestPos    = MyUtils.GetClosestPointOnLine(ref missilePos, ref missilePosEnd, ref targetPos);

                                float distance = Vector3.Distance(closestPos, targetPos);
                                if (distance < closestToMissileDirection)
                                {
                                    closestToMissileDirection = distance;
                                    target = entity;
                                }
                            }
                        }

                        UpdateTarget(target);
                    }
                    break;

                    case MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Guided_Missile_Visual_Detection:
                    {
                        Matrix projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(MyGuidedMissileConstants.VISUAL_GUIDED_MISSILE_FOV), 1, 10, MyGuidedMissileConstants.VISUAL_GUIDED_MISSILE_RANGE);
                        m_visualFrustum.Matrix = Matrix.Invert(WorldMatrix) * projectionMatrix;

                        m_targetEntities.Clear();
                        MyEntities.GetAllIntersectionWithBoundingFrustum(ref m_visualFrustum, m_targetEntities);
                        int testsLimit = 8;

                        if (m_targetEntities.Contains(m_targetEntity))
                        {
                            break;
                        }

                        MyEntity target = null;         //looks better if missile gets "lost"

                        float closestToMissileDirection = float.MaxValue;

                        foreach (MyEntity entity in m_targetEntities)
                        {
                            if (!CanTarget(entity))
                            {
                                continue;
                            }

                            if (testsLimit-- == 0)
                            {
                                break;
                            }

                            if (MyEnemyTargeting.CanSee(this, entity) == null)
                            {
                                Vector3 targetPos     = entity.GetPosition();
                                Vector3 missilePos    = this.GetPosition();
                                Vector3 missilePosEnd = this.GetPosition() + this.WorldMatrix.Forward * 10000;
                                Vector3 closestPos    = MyUtils.GetClosestPointOnLine(ref missilePos, ref missilePosEnd, ref targetPos);

                                float distance = Vector3.Distance(closestPos, targetPos);
                                if (distance < closestToMissileDirection)
                                {
                                    closestToMissileDirection = distance;
                                    target = entity;
                                }
                            }
                        }

                        UpdateTarget(target);
                    }
                    break;
                    }
                }

                if ((m_initTime - m_elapsedMiliseconds) > 0)
                {   //simulating missile launch and engine ignition
                    MyEntity owner = OwnerEntity;
                    if (owner != null)
                    {
                        Vector3 transformedInitDir = Vector3.TransformNormal(m_initDir, owner.WorldMatrix); //
                        Vector3 initialVelocity    = Vector3.Zero;
                        if (owner.Physics != null)
                        {
                            initialVelocity = owner.Physics.LinearVelocity;
                        }
                        Physics.LinearVelocity = transformedInitDir * m_ammoProperties.InitialSpeed + initialVelocity;
                    }
                }
                else
                {
                    //  This will help blend "initial velocity" and "thrust velocity" so at the beginning missile is powered by initiatal velocity only, but later
                    float velocityBlend = MathHelper.Clamp((float)(m_elapsedMiliseconds - m_initTime) / m_blendVelocities, 0, 1);

                    if (velocityBlend == 1.0f)
                    {
                        m_actualSpeed = m_ammoProperties.DesiredSpeed;
                    }
                    else
                    {
                        float    initialSpeed = 0.0f;
                        MyEntity owner        = OwnerEntity;
                        if (owner != null)
                        {
                            if (owner.Physics != null)
                            {
                                initialSpeed = owner.Physics.LinearVelocity.Length();
                            }
                        }

                        m_actualSpeed = velocityBlend * m_ammoProperties.DesiredSpeed + ((1.0f - velocityBlend) * (m_ammoProperties.InitialSpeed + initialSpeed));

                        if (m_missileType != MyMwcObjectBuilder_SmallShip_Ammo_TypesEnum.Missile_Basic && m_smokeEffect == null)
                        {
                            // if (MyCamera.GetDistanceWithFOV(GetPosition()) < 150)
                            {
                                /*
                                 * MyParticleEffect startEffect = MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.Smoke_MissileStart);
                                 * startEffect.WorldMatrix = WorldMatrix;
                                 */
                                m_smokeEffect             = MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.Smoke_Missile);
                                m_smokeEffect.WorldMatrix = WorldMatrix;
                                m_smokeEffect.AutoDelete  = false;
                            }
                        }
                    }

                    m_desiredVelocity = GetDesiredVelocity(m_targetEntity);

                    Physics.LinearVelocity = m_desiredVelocity * m_actualSpeed * 1.0f;
                }

                Physics.AngularVelocity = Vector3.Zero;

                if ((m_elapsedMiliseconds > m_missileTimeout) || (Vector3.Distance(GetPosition(), m_origin) >= m_maxTrajectory))
                {
                    Explode();
                    return;
                }


                if (m_smokeEffect != null)
                {
                    Matrix smokeMatrix = Matrix.CreateWorld(WorldMatrix.Translation - 0.5f * WorldMatrix.Forward, WorldMatrix.Forward, WorldMatrix.Up);
                    m_smokeEffect.WorldMatrix = smokeMatrix;
                }

                if (m_targetEntity != null)
                {
                    if (m_targetEntity.Physics != null)
                    {
                        m_targetVelocity = m_targetEntity.Physics.LinearVelocity;
                    }
                    else
                    {
                        m_targetVelocity = Vector3.Zero;
                    }
                }
            }
            finally
            {
                MyRender.GetRenderProfiler().EndProfilingBlock();
            }
        }
コード例 #22
0
        public static void Update()
        {
            /*
             * foreach (var pair in m_usedCoords)
             * {
             *  pair.Value.MarkForClose();
             * }
             *
             * m_usedCoords.Clear(); */
            if (!MySector.DebrisProperties.Enabled || !MinerWars.AppCode.Game.Render.MyRenderConstants.RenderQualityProfile.EnableFlyingDebris)
            {
                return;
            }

            MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("MyDebrisField.Update");

            if ((lastDustFieldCountInDirectionHalf != DustFieldCountInDirectionHalf)
                ||
                (lastDistanceBetween != DistanceBetween))
            {
                lastDistanceBetween = DistanceBetween;
                lastDustFieldCountInDirectionHalf = DustFieldCountInDirectionHalf;

                //  Fill 3D array with random values from interval <0..1>
                m_random = new float[DustFieldCountInDirection][][];
                for (int x = 0; x < m_random.Length; x++)
                {
                    m_random[x] = new float[DustFieldCountInDirection][];

                    for (int y = 0; y < m_random.Length; y++)
                    {
                        m_random[x][y] = new float[DustFieldCountInDirection];

                        for (int z = 0; z < m_random.Length; z++)
                        {
                            m_random[x][y][z] = MyMwcUtils.GetRandomFloat(0, 1);
                        }
                    }
                }
            }

            //  Update helper frustum and then its bounding box
            m_helperBoundingSphere = new BoundingSphere(MySession.PlayerShip.GetPosition(), MaxDistance);
            BoundingBox helperBoundingBox = BoundingBox.CreateFromSphere(m_helperBoundingSphere);

            MyMwcVector3Int minCoord = GetMetersToDustFieldCoord(ref helperBoundingBox.Min);
            MyMwcVector3Int maxCoord = GetMetersToDustFieldCoord(ref helperBoundingBox.Max);

            m_entitiesToRemove.Clear();
            m_entitiesToRemove.AddRange(m_usedCoords.Keys);

            BoundingSphere collisionBoundingSphere    = new BoundingSphere(MySession.PlayerShip.GetPosition(), MaxDistance / 3);
            BoundingBox    helperCollisionBoundingBox = BoundingBox.CreateFromSphere(m_helperBoundingSphere);


            MyEntities.GetCollisionsInBoundingBox(ref helperCollisionBoundingBox, m_list);

            bool newDebrisAllowed = true;

            foreach (MyRBElement element in m_list)
            {
                MyEntity entity = ((MinerWars.AppCode.Game.Physics.MyPhysicsBody)element.GetRigidBody().m_UserData).Entity;
                if ((entity is MyVoxelMap)
                    ||
                    (entity is MinerWars.AppCode.Game.Prefabs.MyPrefabBase))
                {
                    newDebrisAllowed = false;
                }
            }

            MyMwcVector3Int tempCoord;

            for (tempCoord.X = minCoord.X; tempCoord.X <= maxCoord.X; tempCoord.X++)
            {
                for (tempCoord.Y = minCoord.Y; tempCoord.Y <= maxCoord.Y; tempCoord.Y++)
                {
                    for (tempCoord.Z = minCoord.Z; tempCoord.Z <= maxCoord.Z; tempCoord.Z++)
                    {
                        //  Position of this particle
                        Vector3 position;
                        position.X = tempCoord.X * DistanceBetween;
                        position.Y = tempCoord.Y * DistanceBetween;
                        position.Z = tempCoord.Z * DistanceBetween;


                        //  Get pseudo-random number. It's randomness is based on 3D position, so values don't change between draw calls.
                        float pseudoRandomVariationMod = m_random[Math.Abs(tempCoord.X) % m_random.Length][Math.Abs(tempCoord.Y) % m_random.Length][Math.Abs(tempCoord.Z) % m_random.Length];

                        //  Alter position by randomness
                        position.X += MathHelper.Lerp(-DistanceBetweenHalf, +DistanceBetweenHalf, pseudoRandomVariationMod);
                        position.Y += MathHelper.Lerp(-DistanceBetweenHalf, +DistanceBetweenHalf, pseudoRandomVariationMod);
                        position.Z += MathHelper.Lerp(-DistanceBetweenHalf, +DistanceBetweenHalf, pseudoRandomVariationMod);

                        //  Distance to particle
                        float   distance;
                        Vector3 center = MySession.PlayerShip.GetPosition();

                        Vector3.Distance(ref center, ref position, out distance);

                        if (distance > MaxDistance)
                        {
                            continue;
                        }

                        //  Pseudo-random color and alpha
                        float pseudoRandomColor = MathHelper.Lerp(0.1f, 0.2f, pseudoRandomVariationMod); //MathHelper.Lerp(0.2f, 0.3f, pseudoRandomVariationMod);
                        //float pseudoRandomAlpha = 0.5f; //0.4f;  // 0.2f;// MathHelper.Lerp(0.2f, 0.3f, pseudoRandomVariationMod);


                        //Remove only entities outside distance, not frustum (looks better)
                        m_entitiesToRemove.Remove(tempCoord);

                        if (MyCamera.GetBoundingFrustum().Contains(position) == ContainmentType.Disjoint)
                        {
                            continue;
                        }

                        float alpha = 0;

                        if (distance < FullScaleDistance)
                        {
                            alpha = 1;
                        }
                        else if ((distance >= FullScaleDistance) && (distance < MaxDistance))
                        {
                            alpha = 1 - MathHelper.Clamp((distance - FullScaleDistance) / (MaxDistance - FullScaleDistance), 0, 1);
                        }
                        else
                        {
                            alpha = 0;
                        }

                        MyEntity entity;
                        m_usedCoords.TryGetValue(tempCoord, out entity);

                        float scale = MathHelper.Lerp(0.2f, 1.0f, alpha);

                        if (entity == null)
                        {
                            if (!newDebrisAllowed)
                            {
                                continue;
                            }

                            if (alpha > 0.2f)
                            {
                                continue;  //it would be popping
                            }
                            MinerWars.CommonLIB.AppCode.ObjectBuilders.MyMwcObjectBuilder_Base debrisBuilder = null;

                            if (MyMwcUtils.GetRandomInt(2) % 2 == 0)
                            {
                                entity = MyExplosionDebrisVoxel.Allocate();
                                if (entity == null)
                                {
                                    continue;
                                }

                                int voxelMatEnumIndex = (int)MyMwcUtils.GetRandomShort((short)0, (short)(MySector.DebrisProperties.DebrisVoxelMaterials.Length));
                                MyMwcVoxelMaterialsEnum voxelMatEnum = (MyMwcVoxelMaterialsEnum)MySector.DebrisProperties.DebrisVoxelMaterials.GetValue(voxelMatEnumIndex);

                                ((MyExplosionDebrisVoxel)entity).Start(position, 1, voxelMatEnum, MyGroupMask.Empty, false);
                                MyEntities.Add(entity);
                            }
                            else
                            {
                                int debrisEnumIndex = (int)MyMwcUtils.GetRandomShort((short)0, (short)(MySector.DebrisProperties.DebrisEnumValues.Length));
                                MyMwcObjectBuilder_SmallDebris_TypesEnum debrisEnum = (MyMwcObjectBuilder_SmallDebris_TypesEnum)MySector.DebrisProperties.DebrisEnumValues.GetValue(debrisEnumIndex);

                                debrisBuilder = new MyMwcObjectBuilder_SmallDebris(debrisEnum, true, 0);
                                //MyMwcObjectBuilder_SmallDebris debrisBuilder = new MyMwcObjectBuilder_SmallDebris(MyMwcObjectBuilder_SmallDebris_TypesEnum.Debris32_pilot, true, 0);
                                entity = MyEntities.CreateFromObjectBuilderAndAdd(null, debrisBuilder, Matrix.CreateWorld(position, MyMwcUtils.GetRandomVector3Normalized(), MyMwcUtils.GetRandomVector3Normalized()));
                            }

                            entity.Save        = false;
                            entity.CastShadows = false;

                            m_usedCoords.Add(tempCoord, entity);
                        }


                        if (entity.Physics != null && entity.Physics.Enabled == true)
                        {
                            entity.Physics.Enabled = false;
                        }


                        /*
                         * if (!(entity is MyExplosionDebrisVoxel) && (distance < FullScaleDistance / 2.0f))
                         * {
                         *  if (entity.Physics == null)
                         *  {
                         *      entity.InitBoxPhysics(MyMaterialType.METAL, entity.ModelCollision, 500, 0, MyConstants.COLLISION_LAYER_MODEL_DEBRIS, RigidBodyFlag.RBF_DEFAULT);
                         *  }
                         *  if (entity.Physics.Enabled == false)
                         *  {
                         *      entity.Physics.Clear();
                         *      entity.Physics.Enabled = true;
                         *  }
                         * }*/
                        /*
                         * else
                         * {
                         * if (entity.Physics != null && entity.Physics.Enabled)
                         * {
                         *  entity.Physics.Enabled = false;
                         * }
                         * }     */


                        if (entity is MyExplosionDebrisVoxel)
                        {
                            scale *= 0.08f;
                        }

                        entity.Scale = scale;

                        /*
                         * if (entity.Physics == null && distance < FullScaleDistance / 3)
                         * {
                         *  entity.InitBoxPhysics(MyMaterialType.METAL, entity.ModelLod0, 100, MyPhysicsConfig.DefaultAngularDamping, MyConstants.COLLISION_LAYER_ALL, RigidBodyFlag.RBF_DEFAULT);
                         *  entity.Physics.Enabled = true;
                         * } */
                    }
                }
            }


            foreach (MyMwcVector3Int positionToRemove in m_entitiesToRemove)
            {
                MyEntity entity = m_usedCoords[positionToRemove];

                /*
                 * if (entity.Physics != null && entity.Physics.LinearVelocity.LengthSquared() > 0.1f)
                 * {
                 *  //  Particles.MyParticleEffect effect = Particles.MyParticlesManager.CreateParticleEffect((int)MyParticleEffectsIDEnum.Explosion_Missile);
                 *  //  effect.WorldMatrix = entity.WorldMatrix;
                 * } */

                entity.MarkForClose();

                m_usedCoords.Remove(positionToRemove);
            }

            MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();
        }