///// <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)); }
/// <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.Velocity(); float launcherSpeed = (float)missile.vessel.srfSpeed; float minLaunchRange = missile.minStaticLaunchRange; float maxLaunchRange = missile.maxStaticLaunchRange; float bodyGravity = (float)PhysicsGlobals.GravitationalAcceleration * (float)missile.vessel.orbit.referenceBody.GeeASL; // Set gravity for calculations; float missileActiveTime = 2f; float rangeAddMin = 0; float rangeAddMax = 0; float relSpeed; // Calculate relative speed 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; if (missile.GetComponent <BDModularGuidance>() == null) { // Basic time estimate for missile to drop and travel a safe distance from vessel assuming constant acceleration and firing vessel not accelerating MissileLauncher ml = missile.GetComponent <MissileLauncher>(); float maxMissileAccel = ml.thrust / missile.part.mass; float blastRadius = Mathf.Min(missile.GetBlastRadius(), 150f); // Allow missiles with absurd blast ranges to still be launched if desired missileActiveTime = Mathf.Min((missile.vessel.LandedOrSplashed ? 0f : missile.dropTime) + Mathf.Sqrt(2 * blastRadius / maxMissileAccel), 2f); // Clamp at 2s for now // Rough range estimate of max missile G in a turn after launch, the following code is quite janky but works decently well in practice float maxEstimatedGForce = Mathf.Max(bodyGravity * ml.maxTorque, 15f); // Rough estimate of max G based on missile torque, use minimum of 15G to prevent some VLS parts from not working if (ml.aero) // If missile has aerodynamics, modify G force by AoA limit { maxEstimatedGForce *= Mathf.Sin(ml.maxAoA * Mathf.Deg2Rad); } // Rough estimate of turning radius and arc length to travel float arcLength = 0; if ((!missile.vessel.LandedOrSplashed) && (missile.GetWeaponClass() != WeaponClasses.SLW)) // If the missile isn't a torpedo { float futureTime = Mathf.Clamp((missile.vessel.LandedOrSplashed ? 0f : missile.dropTime), 0f, 2f); Vector3 futureRelPosition = (targetPosition + targetVelocity * futureTime) - (missile.part.transform.position + launcherVelocity * futureTime); float missileTurnRadius = (ml.optimumAirspeed * ml.optimumAirspeed) / maxEstimatedGForce; float targetAngle = Vector3.Angle(missile.GetForwardTransform(), futureRelPosition); arcLength = Mathf.Deg2Rad * targetAngle * missileTurnRadius; } // Add additional range term for the missile to manuever to target at missileActiveTime rangeAddMin += arcLength; } float missileMaxRangeTime = 8f; // Placeholder value since this doesn't really matter much in BDA combat // Add to ranges rangeAddMin += relSpeed * missileActiveTime; rangeAddMax += relSpeed * missileMaxRangeTime; // Add altitude term to max double diffAlt = missile.vessel.altitude - FlightGlobals.getAltitudeAtPos(targetPosition); rangeAddMax += (float)diffAlt; float min = Mathf.Clamp(minLaunchRange + rangeAddMin, 0, BDArmorySettings.MAX_ENGAGEMENT_RANGE); float max = Mathf.Clamp(maxLaunchRange + rangeAddMax, min + 100, BDArmorySettings.MAX_ENGAGEMENT_RANGE); return(new MissileLaunchParams(min, max)); }