Beispiel #1
0
        /// <summary>
        /// If the missile is near the target and not getting closer, detonate.
        /// </summary>
        private void ProximityDetonate()
        {
            if (!MyAPIGateway.Multiplayer.IsServer || myDescr.DetonateRange == 0f)
            {
                return;
            }

            Target cached = CurrentTarget;

            if (!cached.FiringDirection.HasValue)
            {
                return;
            }

            Vector3D myPosition     = MyEntity.GetPosition();
            Vector3D targetPosition = cached.GetPosition();

            double distSq; Vector3D.DistanceSquared(ref myPosition, ref targetPosition, out distSq);

            if (distSq < myDescr.DetonateRange * myDescr.DetonateRange && Vector3.Normalize(MyEntity.GetLinearVelocity()).Dot(cached.FiringDirection.Value) < Static.Cos_Angle_Detonate)
            {
                Log.DebugLog("proximity detonation, target: " + cached.Entity + ", target position: " + cached.GetPosition() + ", real position: " + cached.Entity.GetPosition() + ", type: " + cached.GetType().Name, Logger.severity.INFO);
                Explode();
                m_stage = Stage.Terminated;
            }
        }
Beispiel #2
0
        private void Update()
        {
            Target cached = CurrentTarget;

            if (!cached.FiringDirection.HasValue)
            {
                return;
            }

            Log.TraceLog("target: " + cached.Entity.getBestName() + ", ContactPoint: " + cached.ContactPoint);

            Log.TraceLog("FiringDirection invalid: " + cached.FiringDirection, Logger.severity.FATAL, condition: !cached.FiringDirection.IsValid());
            Log.TraceLog("ContactPoint invalid: " + cached.ContactPoint, Logger.severity.FATAL, condition: !cached.ContactPoint.IsValid());

            Vector3 targetDirection;

            switch (m_stage)
            {
            case Stage.Boost:
                Log.DebugLog("m_gravData == null", Logger.severity.FATAL, condition: m_gravData == null);
                targetDirection = -m_gravData.Normal;
                break;

            case Stage.MidCourse:
                Vector3 toTarget = cached.GetPosition() - MyEntity.GetPosition();
                targetDirection = Vector3.Normalize(Vector3.Reject(toTarget, m_gravData.Normal));
                break;

            case Stage.SemiActive:
            case Stage.Golis:
            case Stage.Guided:
                targetDirection = cached.FiringDirection.Value;
                break;

            default:
                return;
            }

            Vector3 forward = MyEntity.WorldMatrix.Forward;
            float angle     = (float)Math.Acos(Vector3.Dot(forward, targetDirection));

            Log.DebugLog("forward: " + forward + ", targetDirection: " + targetDirection + ", angle: " + angle);

            if (m_stage <= Stage.Guided && angle > 0.001f) // if the angle is too small, the matrix will be invalid
            {                                              // rotate missile
                float rotate = Math.Min(angle, myDescr.RotationPerUpdate);
                Vector3 axis = forward.Cross(targetDirection);
                axis.Normalize();
                Quaternion rotation = Quaternion.CreateFromAxisAngle(axis, rotate);

                if (!Stopped)
                {
                    MatrixD WorldMatrix = MyEntity.WorldMatrix;
                    MatrixD newMatrix   = WorldMatrix.GetOrientation();
                    newMatrix             = MatrixD.Transform(newMatrix, rotation);
                    newMatrix.Translation = WorldMatrix.Translation;

                    MyEntity.WorldMatrix = newMatrix;
                }
            }

            {             // accelerate if facing target
                if (angle < Static.Angle_AccelerateWhen && addSpeedPerUpdate > 0f && MyEntity.GetLinearVelocity().LengthSquared() < myAmmo.AmmoDefinition.DesiredSpeed * myAmmo.AmmoDefinition.DesiredSpeed)
                {
                    //Log.DebugLog("accelerate. angle: " + angle, "Update()");
                    if (!Stopped)
                    {
                        MyEntity.Physics.LinearVelocity += MyEntity.WorldMatrix.Forward * addSpeedPerUpdate;
                    }
                }
            }

            if (myDescr.TargetRange != 0f && CurrentTarget is LastSeenTarget)
            {
                Vector3D myPosition    = MyEntity.GetPosition();
                Vector3D realTargetPos = CurrentTarget.Entity.GetPosition();
                double distSq; Vector3D.DistanceSquared(ref myPosition, ref realTargetPos, out distSq);
                if (distSq < myDescr.TargetRange * myDescr.TargetRange)
                {
                    Log.DebugLog("Promoting targeting");
                    SetTarget(new TurretTarget(CurrentTarget.Entity, CurrentTarget.TType));
                }
            }

            if (myDescr.AcquisitionAngle == MathHelper.Pi)             // otherwise we check while outside of AcquisitionAngle see CanRotateTo
            {
                ProximityDetonate();
            }
        }