/// <summary>
        /// Gets the dynamic launch parameters.
        /// </summary>
        /// <returns>The dynamic launch parameters.</returns>
        /// <param name="launcherVelocity">Launcher velocity.</param>
        /// <param name="targetVelocity">Target velocity.</param>
        public static MissileLaunchParams GetDynamicLaunchParams(MissileBase missile, Vector3 targetVelocity, Vector3 targetPosition)
        {
            Vector3 launcherVelocity = missile.vessel.srf_velocity;
            float   launcherSpeed    = (float)missile.vessel.srfSpeed;
            float   minLaunchRange   = missile.minStaticLaunchRange;
            float   maxLaunchRange   = missile.maxStaticLaunchRange;

            float rangeAddMin = 0;
            float rangeAddMax = 0;
            float relSpeed;

            Vector3 relV           = targetVelocity - launcherVelocity;
            Vector3 vectorToTarget = targetPosition - missile.part.transform.position;
            Vector3 relVProjected  = Vector3.Project(relV, vectorToTarget);

            relSpeed = -Mathf.Sign(Vector3.Dot(relVProjected, vectorToTarget)) * relVProjected.magnitude;


            rangeAddMin += relSpeed * 2;
            rangeAddMax += relSpeed * 8;
            rangeAddMin += launcherSpeed * 2;
            rangeAddMax += launcherSpeed * 2;

            double diffAlt = missile.vessel.altitude - FlightGlobals.getAltitudeAtPos(targetPosition);

            rangeAddMax += (float)diffAlt;

            float min = Mathf.Clamp(minLaunchRange + rangeAddMin, 0, 20000);
            float max = Mathf.Clamp(maxLaunchRange + rangeAddMax, min + 100, 20000);

            return(new MissileLaunchParams(min, max));
        }
        public static Vector3 GetAirToAirFireSolution(MissileBase missile, Vessel targetVessel)
        {
            if (!targetVessel)
            {
                return(missile.transform.position + (missile.GetForwardTransform() * 1000));
            }
            Vector3 targetPosition = targetVessel.transform.position;
            float   leadTime       = 0;
            float   targetDistance = Vector3.Distance(targetVessel.transform.position, missile.transform.position);


            Vector3 simMissileVel = 500 * (targetPosition - missile.transform.position).normalized;

            var   launcher = missile as MissileLauncher;
            float optSpeed = 400;         //TODO: Add parameter

            if (launcher != null)
            {
                optSpeed = launcher.optimumAirspeed;
            }
            simMissileVel = optSpeed * (targetPosition - missile.transform.position).normalized;

            leadTime       = targetDistance / (float)(targetVessel.srf_velocity - simMissileVel).magnitude;
            leadTime       = Mathf.Clamp(leadTime, 0f, 8f);
            targetPosition = targetPosition + (targetVessel.srf_velocity * leadTime);

            if (targetVessel && targetDistance < 800)
            {
                targetPosition += (Vector3)targetVessel.acceleration * 0.05f * leadTime * leadTime;
            }

            return(targetPosition);
        }
        public static Vector3 GetAirToAirFireSolution(MissileBase missile, Vector3 targetPosition, Vector3 targetVelocity)
        {
            float leadTime       = 0;
            float targetDistance = Vector3.Distance(targetPosition, missile.transform.position);

            float optSpeed = 400; //TODO: Add parameter
            var   launcher = missile as MissileLauncher;

            if (launcher != null)
            {
                optSpeed = launcher.optimumAirspeed;
            }

            Vector3 simMissileVel = optSpeed * (targetPosition - missile.transform.position).normalized;

            leadTime = targetDistance / (targetVelocity - simMissileVel).magnitude;
            leadTime = Mathf.Clamp(leadTime, 0f, 8f);

            targetPosition = targetPosition + (targetVelocity * leadTime);

            return(targetPosition);
        }
Exemple #4
0
        void Awake()
        {
            if (!vessel)
            {
                vessel = GetComponent <Vessel>();
            }
            if (!vessel)
            {
                Debug.Log("[BDArmory]:TargetInfo was added to a non-vessel");
                Destroy(this);
                return;
            }

            //destroy this if a target info is already attached to the vessel
            foreach (var otherInfo in vessel.gameObject.GetComponents <TargetInfo>())
            {
                if (otherInfo != this)
                {
                    Destroy(this);
                    return;
                }
            }

            team = BDArmorySettings.BDATeams.None;

            bool foundMf = false;

            foreach (var mf in vessel.FindPartModulesImplementing <MissileFire>())
            {
                foundMf       = true;
                team          = BDATargetManager.BoolToTeam(mf.team);
                weaponManager = mf;
                break;
            }
            if (!foundMf)
            {
                foreach (var ml in vessel.FindPartModulesImplementing <MissileBase>())
                {
                    isMissile         = true;
                    MissileBaseModule = ml;
                    team = BDATargetManager.BoolToTeam(ml.Team);
                    break;
                }
            }

            if (team != BDArmorySettings.BDATeams.None)
            {
                if (!BDATargetManager.TargetDatabase[BDATargetManager.OtherTeam(team)].Contains(this))
                {
                    BDATargetManager.TargetDatabase[BDATargetManager.OtherTeam(team)].Add(this);
                }
            }

            friendliesEngaging = new List <MissileFire>();

            vessel.OnJustAboutToBeDestroyed += AboutToBeDestroyed;
            lifeRoutine = StartCoroutine(LifetimeRoutine());
            //add delegate to peace enable event
            BDArmorySettings.OnPeaceEnabled += OnPeaceEnabled;

            if (!isMissile && team != BDArmorySettings.BDATeams.None)
            {
                massRoutine = StartCoroutine(MassRoutine());
            }
        }
        ///// <summary>
        ///// Gets the laser target painter with the least angle off boresight. Set the missileBase as the reference missilePosition.
        ///// </summary>
        ///// <returns>The laser target painter.</returns>
        ///// <param name="referenceTransform">Reference missilePosition.</param>
        ///// <param name="maxBoreSight">Max bore sight.</param>
        //public static ModuleTargetingCamera GetLaserTarget(MissileLauncher ml, bool parentOnly)
        //{
        //          return GetModuleTargeting(parentOnly, ml.transform.forward, ml.transform.position, ml.maxOffBoresight, ml.vessel, ml.SourceVessel);
        //      }

        //      public static ModuleTargetingCamera GetLaserTarget(BDModularGuidance ml, bool parentOnly)
        //      {
        //          float maxOffBoresight = 45;

        //          return GetModuleTargeting(parentOnly, ml.MissileReferenceTransform.forward, ml.MissileReferenceTransform.position, maxOffBoresight,ml.vessel,ml.SourceVessel);
        //      }

        /// <summary>
        /// Gets the laser target painter with the least angle off boresight. Set the missileBase as the reference missilePosition.
        /// </summary>
        /// <returns>The laser target painter.</returns>
        public static ModuleTargetingCamera GetLaserTarget(MissileBase ml, bool parentOnly)
        {
            return(GetModuleTargeting(parentOnly, ml.GetForwardTransform(), ml.MissileReferenceTransform.position, ml.maxOffBoresight, ml.vessel, ml.SourceVessel));
        }