Пример #1
0
        IEnumerator LaunchWarningRoutine(TargetSignatureData data)
        {
            launchWarnings.Add(data);
            yield return(new WaitForSeconds(2));

            launchWarnings.Remove(data);
        }
Пример #2
0
        /// <summary>
        /// Find a flare within acceptable thermal range that will "decoy" for the passed heatsignature
        /// </summary>
        public static TargetSignatureData GetFlareTarget(Ray ray, float scanRadius, float highpassThreshold, bool allAspect, float heatSignature)
        {
            TargetSignatureData flareTarget = TargetSignatureData.noTarget;

            List <CMFlare> .Enumerator flare = BDArmorySetup.Flares.GetEnumerator();
            while (flare.MoveNext())
            {
                if (!flare.Current)
                {
                    continue;
                }

                float angle = Vector3.Angle(flare.Current.transform.position - ray.origin, ray.direction);
                if (angle < scanRadius)
                {
                    float score = flare.Current.thermal * Mathf.Clamp01(15 / angle);

                    score *= Mathf.Pow(1400, 2) / Mathf.Clamp((flare.Current.transform.position - ray.origin).sqrMagnitude, 90000, 36000000);
                    score *= Mathf.Clamp(Vector3.Angle(flare.Current.transform.position - ray.origin, -VectorUtils.GetUpDirection(ray.origin)) / 90, 0.5f, 1.5f);

                    // check acceptable range:
                    // flare cannot be too cool, but also not too bright
                    if ((score > heatSignature * 0.9) && (score < heatSignature * 1.15))
                    {
                        flareTarget = new TargetSignatureData(flare.Current, score);
                    }
                }
            }

            return(flareTarget);
        }
Пример #3
0
        public override void OnStart(StartState state)
        {
            if (HighLogic.LoadedSceneIsFlight)
            {
                pingsData          = new TargetSignatureData[dataCount];
                pingWorldPositions = new Vector3[dataCount];
                TargetSignatureData.ResetTSDArray(ref pingsData);
                launchWarnings = new List <TargetSignatureData>();

                rwrIconLabelStyle                  = new GUIStyle();
                rwrIconLabelStyle.alignment        = TextAnchor.MiddleCenter;
                rwrIconLabelStyle.normal.textColor = Color.green;
                rwrIconLabelStyle.fontSize         = 12;
                rwrIconLabelStyle.border           = new RectOffset(0, 0, 0, 0);
                rwrIconLabelStyle.clipping         = TextClipping.Overflow;
                rwrIconLabelStyle.wordWrap         = false;
                rwrIconLabelStyle.fontStyle        = FontStyle.Bold;

                audioSource              = gameObject.AddComponent <AudioSource>();
                audioSource.minDistance  = 500;
                audioSource.maxDistance  = 1000;
                audioSource.spatialBlend = 1;
                audioSource.dopplerLevel = 0;
                audioSource.loop         = false;

                UpdateVolume();
                BDArmorySetup.OnVolumeChange += UpdateVolume;

                float size = displayRect.height + 20;
                if (!WindowRectRWRInitialized)
                {
                    BDArmorySetup.WindowRectRwr = new Rect(40, Screen.height - size - 20, size, size + 20);
                    WindowRectRWRInitialized    = true;
                }

                List <MissileFire> .Enumerator mf = vessel.FindPartModulesImplementing <MissileFire>().GetEnumerator();
                while (mf.MoveNext())
                {
                    if (mf.Current == null)
                    {
                        continue;
                    }
                    mf.Current.rwr = this;
                    if (!weaponManager)
                    {
                        weaponManager = mf.Current;
                    }
                }
                mf.Dispose();
                if (rwrEnabled)
                {
                    EnableRWR();
                }
            }
        }
Пример #4
0
 public void SetActiveLock(TargetSignatureData target)
 {
     for (int i = 0; i < lockedTargets.Count; i++)
     {
         if (target.vessel == lockedTargets[i].vessel)
         {
             lockedTargetIndex = i;
             return;
         }
     }
 }
        public override void OnStart(StartState state)
        {
            if (HighLogic.LoadedSceneIsFlight)
            {
                pingsData          = new TargetSignatureData[dataCount];
                pingWorldPositions = new Vector3[dataCount];
                TargetSignatureData.ResetTSDArray(ref pingsData);
                launchWarnings = new List <TargetSignatureData>();

                rwrIconLabelStyle                  = new GUIStyle();
                rwrIconLabelStyle.alignment        = TextAnchor.MiddleCenter;
                rwrIconLabelStyle.normal.textColor = Color.green;
                rwrIconLabelStyle.fontSize         = 12;
                rwrIconLabelStyle.border           = new RectOffset(0, 0, 0, 0);
                rwrIconLabelStyle.clipping         = TextClipping.Overflow;
                rwrIconLabelStyle.wordWrap         = false;
                rwrIconLabelStyle.fontStyle        = FontStyle.Bold;

                audioSource              = gameObject.AddComponent <AudioSource>();
                audioSource.minDistance  = 500;
                audioSource.maxDistance  = 1000;
                audioSource.spatialBlend = 1;
                audioSource.dopplerLevel = 0;
                audioSource.loop         = false;

                UpdateVolume();
                BDArmorySetup.OnVolumeChange += UpdateVolume;

                if (!WindowRectRWRInitialized)
                {
                    BDArmorySetup.WindowRectRwr = new Rect(BDArmorySetup.WindowRectRwr.x, BDArmorySetup.WindowRectRwr.y, RwrDisplayRect.height + BorderSize, RwrDisplayRect.height + BorderSize + HeaderSize);
                    // BDArmorySetup.WindowRectRwr = new Rect(40, Screen.height - RwrDisplayRect.height, RwrDisplayRect.height + BorderSize, RwrDisplayRect.height + BorderSize + HeaderSize);
                    WindowRectRWRInitialized = true;
                }

                using (var mf = VesselModuleRegistry.GetModules <MissileFire>(vessel).GetEnumerator())
                    while (mf.MoveNext())
                    {
                        if (mf.Current == null)
                        {
                            continue;
                        }
                        mf.Current.rwr = this; // Set the rwr on all weapon managers to this.
                        if (!weaponManager)
                        {
                            weaponManager = mf.Current; // Set the first found weapon manager as the one in control.
                        }
                    }
                //if (rwrEnabled) EnableRWR();
                EnableRWR();
            }
        }
Пример #6
0
        public void UpdateLockedTargetInfo(TargetSignatureData newData)
        {
            int index = -1;

            for (int i = 0; i < lockedTargets.Count; i++)
            {
                if (lockedTargets[i].vessel != newData.vessel)
                {
                    continue;
                }
                index = i;
                break;
            }

            if (index >= 0)
            {
                lockedTargets[index] = newData;
            }
        }
Пример #7
0
        public void ReceiveContactData(TargetSignatureData contactData, bool _locked)
        {
            if (vesselRadarData)
            {
                vesselRadarData.AddRadarContact(this, contactData, _locked);
            }

            List <VesselRadarData> .Enumerator vrd = linkedToVessels.GetEnumerator();
            while (vrd.MoveNext())
            {
                if (vrd.Current == null)
                {
                    continue;
                }
                if (vrd.Current.canReceiveRadarData && vrd.Current.vessel != contactData.vessel)
                {
                    vrd.Current.AddRadarContact(this, contactData, _locked);
                }
            }
            vrd.Dispose();
        }
Пример #8
0
        protected void UpdateHeatTarget()
        {
            if (lockFailTimer > 1)
            {
                legacyTargetVessel = null;
                TargetAcquired     = false;
                return;
            }


            if (heatTarget.exists && lockFailTimer < 0)
            {
                lockFailTimer = 0;
            }
            if (lockFailTimer >= 0)
            {
                Ray lookRay = new Ray(transform.position, heatTarget.position + (heatTarget.velocity * Time.fixedDeltaTime) - transform.position);
                heatTarget = BDATargetManager.GetHeatTarget(SourceVessel, vessel, lookRay, lockedSensorFOV / 2, heatThreshold, allAspect, SourceVessel?.gameObject?.GetComponent <MissileFire>());

                if (heatTarget.exists)
                {
                    TargetAcquired     = true;
                    TargetPosition     = heatTarget.position + (2 * heatTarget.velocity * Time.fixedDeltaTime);
                    TargetVelocity     = heatTarget.velocity;
                    TargetAcceleration = heatTarget.acceleration;
                    lockFailTimer      = 0;
                }
                else
                {
                    TargetAcquired = false;
                    if (FlightGlobals.ready)
                    {
                        lockFailTimer += Time.fixedDeltaTime;
                    }
                }
            }
        }
Пример #9
0
        public void AddRadarContact(ModuleRadar radar, TargetSignatureData contactData, bool _locked)
        {
            RadarDisplayData rData = new RadarDisplayData();
            rData.vessel = contactData.vessel;

            if(rData.vessel == vessel)
            {
                return;
            }

            rData.signalPersistTime = radar.signalPersistTime;
            rData.detectedByRadar = radar;
            rData.locked = _locked;
            rData.targetData = contactData;
            rData.pingPosition = UpdatedPingPosition(contactData.position, radar);

            if(_locked)
            {
                radar.UpdateLockedTargetInfo(contactData);
            }

            bool dontOverwrite = false;

            int replaceIndex = -1;
            for(int i = 0; i < displayedTargets.Count; i++)
            {
                if(displayedTargets[i].vessel == rData.vessel)
                {
                    if(displayedTargets[i].locked && !_locked)
                    {
                        dontOverwrite = true;
                        break;
                    }

                    replaceIndex = i;
                    break;
                }
            }

            if(replaceIndex >= 0)
            {
                displayedTargets[replaceIndex] = rData;
                //UpdateLockedTargets();
                return;
            }
            else if(dontOverwrite)
            {
                //UpdateLockedTargets();
                return;
            }
            else
            {
                displayedTargets.Add(rData);
                UpdateLockedTargets();
                return;
            }
        }
Пример #10
0
        public override void OnAwake()
        {
            clickSound = GameDatabase.Instance.GetAudioClip("BDArmory/Sounds/click");
            warningSound = GameDatabase.Instance.GetAudioClip("BDArmory/Sounds/warning");
            armOnSound = GameDatabase.Instance.GetAudioClip("BDArmory/Sounds/armOn");
            armOffSound = GameDatabase.Instance.GetAudioClip("BDArmory/Sounds/armOff");
            heatGrowlSound = GameDatabase.Instance.GetAudioClip("BDArmory/Sounds/heatGrowl");

            //HEAT LOCKING
            heatTarget = TargetSignatureData.noTarget;
        }
Пример #11
0
		void UpdateRadarTarget()
		{
			targetAcquired = false;

			float angleToTarget = Vector3.Angle(radarTarget.predictedPosition-transform.position,transform.forward);
			if(radarTarget.exists)
			{
				if(!activeRadar && ((radarTarget.predictedPosition - transform.position).sqrMagnitude > Mathf.Pow(activeRadarRange, 2) || angleToTarget > maxOffBoresight * 0.75f))
				{
					if(vrd)
					{
						TargetSignatureData t = TargetSignatureData.noTarget;
						List<TargetSignatureData> possibleTargets = vrd.GetLockedTargets();
						for(int i = 0; i < possibleTargets.Count; i++)
						{
							if(possibleTargets[i].vessel == radarTarget.vessel)
							{
								t = possibleTargets[i];
							}
						}

				
						if(t.exists)
						{
							targetAcquired = true;
							radarTarget = t;
							targetPosition = radarTarget.predictedPosition;
							targetVelocity = radarTarget.velocity;
							targetAcceleration = radarTarget.acceleration;
							radarFailTimer = 0;
							return;
						}
						else
						{
							if(radarFailTimer > maxRadarFailTime)
							{
								Debug.Log("Semi-Active Radar guidance failed. Parent radar lost target.");
								radarTarget = TargetSignatureData.noTarget;
								legacyTargetVessel = null;
								return;
							}
							else
							{
								if(radarFailTimer == 0)
								{
									Debug.Log("Semi-Active Radar guidance failed - waiting for data");
								}
								radarFailTimer += Time.fixedDeltaTime;
								radarTarget.timeAcquired = Time.time;
								radarTarget.position = radarTarget.predictedPosition;
								targetPosition = radarTarget.predictedPosition;
								targetVelocity = radarTarget.velocity;
								targetAcceleration = Vector3.zero;
								targetAcquired = true;
							}
						}
					}
					else
					{
						Debug.Log("Semi-Active Radar guidance failed. Out of range and no data feed.");
						radarTarget = TargetSignatureData.noTarget;
						legacyTargetVessel = null;
						return;
					}
				}
				else
				{
					vrd = null;

					if(angleToTarget > maxOffBoresight)
					{
						Debug.Log("Radar guidance failed.  Target is out of active seeker gimbal limits.");
						radarTarget = TargetSignatureData.noTarget;
						legacyTargetVessel = null;
						return;
					}
					else
					{
						if(scannedTargets == null) scannedTargets = new TargetSignatureData[5];
						TargetSignatureData.ResetTSDArray(ref scannedTargets);
						Ray ray = new Ray(transform.position, radarTarget.predictedPosition - transform.position);
						bool pingRWR = Time.time - lastRWRPing > 0.4f;
						if(pingRWR) lastRWRPing = Time.time;
						bool radarSnapshot = (snapshotTicker > 20);
						if(radarSnapshot)
						{
							snapshotTicker = 0;
						}
						else
						{
							snapshotTicker++;
						}
						RadarUtils.UpdateRadarLock(ray, lockedSensorFOV, activeRadarMinThresh, ref scannedTargets, 0.4f, pingRWR, RadarWarningReceiver.RWRThreatTypes.MissileLock, radarSnapshot);
						float sqrThresh = radarLOALSearching ? Mathf.Pow(500, 2) : Mathf.Pow(40, 2);

						if(radarLOAL && radarLOALSearching && !radarSnapshot)
						{
							//only scan on snapshot interval
						}
						else
						{
							for(int i = 0; i < scannedTargets.Length; i++)
							{
								if(scannedTargets[i].exists && (scannedTargets[i].predictedPosition - radarTarget.predictedPosition).sqrMagnitude < sqrThresh)
								{
									radarTarget = scannedTargets[i];
									targetAcquired = true;
									radarLOALSearching = false;
									targetPosition = radarTarget.predictedPosition + (radarTarget.velocity * Time.fixedDeltaTime);
									targetVelocity = radarTarget.velocity;
									targetAcceleration = radarTarget.acceleration;
									radarFailTimer = 0;
									if(!activeRadar && Time.time - timeFired > 1)
									{
										if(locksCount == 0)
										{
											RadarWarningReceiver.PingRWR(ray, lockedSensorFOV, RadarWarningReceiver.RWRThreatTypes.MissileLaunch, 2f);
											Debug.Log("Pitbull! Radar missile has gone active.  Radar sig strength: " + radarTarget.signalStrength.ToString("0.0"));

										}
										else if(locksCount > 2)
										{
											guidanceActive = false;
											checkMiss = true;
											if(BDArmorySettings.DRAW_DEBUG_LABELS)
											{
												Debug.Log("Radar missile reached max re-lock attempts.");
											}
										}
										locksCount++;
									}
									activeRadar = true;
									return;
								}
							}
						}

						if(radarLOAL)
						{
							radarLOALSearching = true;
							targetAcquired = true;
							targetPosition = radarTarget.predictedPosition + (radarTarget.velocity * Time.fixedDeltaTime);
							targetVelocity = radarTarget.velocity;
							targetAcceleration = Vector3.zero;
							activeRadar = false;
						}
						else
						{
							radarTarget = TargetSignatureData.noTarget;
						}

					}
				}
			}
			else if(radarLOAL && radarLOALSearching)
			{
				if(scannedTargets == null) scannedTargets = new TargetSignatureData[5];
				TargetSignatureData.ResetTSDArray(ref scannedTargets);
				Ray ray = new Ray(transform.position, transform.forward);
				bool pingRWR = Time.time - lastRWRPing > 0.4f;
				if(pingRWR) lastRWRPing = Time.time;
				bool radarSnapshot = (snapshotTicker > 6);
				if(radarSnapshot)
				{
					snapshotTicker = 0;
				}
				else
				{
					snapshotTicker++;
				}
				RadarUtils.UpdateRadarLock(ray, lockedSensorFOV*3, activeRadarMinThresh*2, ref scannedTargets, 0.4f, pingRWR, RadarWarningReceiver.RWRThreatTypes.MissileLock, radarSnapshot);
				float sqrThresh = Mathf.Pow(300, 2);

				float smallestAngle = 360;
				TargetSignatureData lockedTarget = TargetSignatureData.noTarget;

				for(int i = 0; i < scannedTargets.Length; i++)
				{
					if(scannedTargets[i].exists && (scannedTargets[i].predictedPosition - radarTarget.predictedPosition).sqrMagnitude < sqrThresh)
					{
						float angle = Vector3.Angle(scannedTargets[i].predictedPosition - transform.position, transform.forward);
						if(angle < smallestAngle)
						{
							lockedTarget = scannedTargets[i];
							smallestAngle = angle;
						}


						activeRadar = true;
						return;
					}
				}

				if(lockedTarget.exists)
				{
					radarTarget = lockedTarget;
					targetAcquired = true;
					radarLOALSearching = false;
					targetPosition = radarTarget.predictedPosition + (radarTarget.velocity * Time.fixedDeltaTime);
					targetVelocity = radarTarget.velocity;
					targetAcceleration = radarTarget.acceleration;

					if(!activeRadar && Time.time - timeFired > 1)
					{
						RadarWarningReceiver.PingRWR(new Ray(transform.position, radarTarget.predictedPosition - transform.position), lockedSensorFOV, RadarWarningReceiver.RWRThreatTypes.MissileLaunch, 2f);
						Debug.Log("Pitbull! Radar missile has gone active.  Radar sig strength: " + radarTarget.signalStrength.ToString("0.0"));
					}
					return;
				}
				else
				{
					targetAcquired = true;
					targetPosition = transform.position + (startDirection * 500);
					targetVelocity = Vector3.zero;
					targetAcceleration = Vector3.zero;
					radarLOALSearching = true;
					return;
				}
			}

			if(!radarTarget.exists)
			{
				legacyTargetVessel = null;
			}
		}
Пример #12
0
        public static void UpdateRadarLock(MissileFire myWpnManager, float directionAngle, Transform referenceTransform, float fov, Vector3 position, float minSignature, ref TargetSignatureData[] dataArray, float dataPersistTime, bool pingRWR, RadarWarningReceiver.RWRThreatTypes rwrType, bool radarSnapshot)
        {
            Vector3d geoPos = VectorUtils.WorldPositionToGeoCoords(position, FlightGlobals.currentMainBody);
            Vector3 forwardVector = referenceTransform.forward;
            Vector3 upVector = referenceTransform.up;//VectorUtils.GetUpDirection(position);
            Vector3 lookDirection = Quaternion.AngleAxis(directionAngle, upVector) * forwardVector;

            int dataIndex = 0;
            foreach(var vessel in BDATargetManager.LoadedVessels)
            {
                if(vessel == null) continue;
                if(!vessel.loaded) continue;

                if(myWpnManager)
                {
                    if(vessel == myWpnManager.vessel) continue; //ignore self
                }
                else if((vessel.transform.position - position).sqrMagnitude < 3600) continue;

                Vector3 vesselDirection = Vector3.ProjectOnPlane(vessel.CoM - position, upVector);

                if(Vector3.Angle(vesselDirection, lookDirection) < fov / 2)
                {
                    if(TerrainCheck(referenceTransform.position, vessel.transform.position)) continue; //blocked by terrain

                    float sig = float.MaxValue;
                    if(radarSnapshot && minSignature > 0) sig = GetModifiedSignature(vessel, position);

                    RadarWarningReceiver.PingRWR(vessel, position, rwrType, dataPersistTime);

                    float detectSig = sig;

                    VesselECMJInfo vesselJammer = vessel.GetComponent<VesselECMJInfo>();
                    if(vesselJammer)
                    {
                        sig *= vesselJammer.rcsReductionFactor;
                        detectSig += vesselJammer.jammerStrength;
                    }

                    if(detectSig > minSignature)
                    {
                        if(vessel.vesselType == VesselType.Debris)
                        {
                            vessel.gameObject.AddComponent<TargetInfo>();
                        }
                        else if(myWpnManager != null)
                        {
                            BDATargetManager.ReportVessel(vessel, myWpnManager);
                        }

                        while(dataIndex < dataArray.Length - 1)
                        {
                            if((dataArray[dataIndex].exists && Time.time - dataArray[dataIndex].timeAcquired > dataPersistTime) || !dataArray[dataIndex].exists)
                            {
                                break;
                            }
                            dataIndex++;
                        }
                        if(dataIndex >= dataArray.Length) break;
                        dataArray[dataIndex] = new TargetSignatureData(vessel, sig);
                        dataIndex++;
                        if(dataIndex >= dataArray.Length) break;
                    }
                }
            }
        }
Пример #13
0
 public void SetActiveLock(TargetSignatureData target)
 {
     for(int i = 0; i < lockedTargets.Count; i++)
     {
         if(target.vessel == lockedTargets[i].vessel)
         {
             lockedTargetIndex = i;
             return;
         }
     }
 }
Пример #14
0
        public static TargetSignatureData GetHeatTarget(Ray ray, float scanRadius, float highpassThreshold, bool allAspect)
        {
            float minScore = highpassThreshold;
            float minMass = 0.5f;
            TargetSignatureData finalData = TargetSignatureData.noTarget;
            float finalScore = 0;
            foreach(var vessel in BDATargetManager.LoadedVessels)
            {
                if(!vessel || !vessel.loaded)
                {
                    continue;
                }
                if(vessel.GetTotalMass() < minMass)
                {
                    continue;
                }

                if(RadarUtils.TerrainCheck(ray.origin, vessel.transform.position))
                {
                    continue;
                }

                float angle = Vector3.Angle(vessel.CoM-ray.origin, ray.direction);
                if(angle < scanRadius)
                {
                    float score = 0;
                    foreach(var part in vessel.Parts)
                    {
                        if(!part) continue;
                        if(!allAspect)
                        {
                            if(!Misc.CheckSightLine(ray.origin, part.transform.position, 10000, 5, 5)) continue;
                        }

                        float thisScore = (float)(part.thermalInternalFluxPrevious+part.skinTemperature) * Mathf.Clamp01(15/angle);
                        thisScore *= Mathf.Pow(1400,2)/Mathf.Clamp((vessel.CoM-ray.origin).sqrMagnitude, 90000, 36000000);
                        score = Mathf.Max (score, thisScore);
                    }

                    if(vessel.LandedOrSplashed)
                    {
                        score /= 4;
                    }

                    score *= Mathf.Clamp(Vector3.Angle(vessel.transform.position-ray.origin, -VectorUtils.GetUpDirection(ray.origin))/90, 0.5f, 1.5f);

                    if(score > finalScore)
                    {
                        finalScore = score;
                        finalData = new TargetSignatureData(vessel, score);
                    }
                }
            }

            heatScore = finalScore;//DEBUG
            flareScore = 0; //DEBUG
            foreach(var flare in BDArmorySettings.Flares)
            {
                if(!flare) continue;

                float angle = Vector3.Angle(flare.transform.position-ray.origin, ray.direction);
                if(angle < scanRadius)
                {
                    float score = flare.thermal * Mathf.Clamp01(15/angle);
                    score *= Mathf.Pow(1400,2)/Mathf.Clamp((flare.transform.position-ray.origin).sqrMagnitude, 90000, 36000000);

                    score *= Mathf.Clamp(Vector3.Angle(flare.transform.position-ray.origin, -VectorUtils.GetUpDirection(ray.origin))/90, 0.5f, 1.5f);

                    if(score > finalScore)
                    {
                        flareScore = score;//DEBUG
                        finalScore = score;
                        finalData = new TargetSignatureData(flare, score);
                    }
                }
            }

            if(finalScore < minScore)
            {
                finalData = TargetSignatureData.noTarget;
            }

            return finalData;
        }
Пример #15
0
        public void TryLockTarget(Vector3 position)
        {
            if(!canLock)
            {
                if(linkedRadar && linkedRadar.radarEnabled)
                {
                    linkedRadar.TryLockTarget(position);
                    lockedTarget = linkedRadar.lockedTarget;
                    locked = true;
                }
                return;
            }
            Debug.Log ("Trying to radar lock target");

            Vector3 targetPlanarDirection = Vector3.ProjectOnPlane(position-referenceTransform.position, referenceTransform.up);
            float angle = Vector3.Angle(targetPlanarDirection, referenceTransform.forward);
            if(referenceTransform.InverseTransformPoint(position).x < 0)
            {
                angle = -angle;
            }
            //TargetSignatureData.ResetTSDArray(ref attemptedLocks);
            RadarUtils.ScanInDirection(weaponManager, angle, referenceTransform, lockAttemptFOV, referenceTransform.position, minLockedSignalThreshold, ref attemptedLocks, signalPersistTime, true, rwrType, true);

            for(int i = 0; i < attemptedLocks.Length; i++)
            {
                if(attemptedLocks[i].exists && (attemptedLocks[i].position-position).sqrMagnitude < Mathf.Pow(40,2))
                {
                    locked = true;
                    lockedTarget = attemptedLocks[i];
                    Debug.Log ("- Acquired lock on target.");
                    return;
                }
            }

            Debug.Log ("- Failed to lock on target.");
        }
Пример #16
0
        public override void OnStart(StartState state)
        {
            base.OnStart (state);

            if(HighLogic.LoadedSceneIsFlight)
            {
                RadarUtils.SetupRadarCamera();

                distanceStyle = new GUIStyle();
                distanceStyle.normal.textColor = new Color(0,1,0,0.75f);
                distanceStyle.alignment = TextAnchor.UpperLeft;

                lockStyle = new GUIStyle();
                lockStyle.normal.textColor = new Color(0,1,0,0.75f);
                lockStyle.alignment = TextAnchor.LowerCenter;
                lockStyle.fontSize = 16;

                radarTopStyle = new GUIStyle();
                radarTopStyle.normal.textColor = new Color(0, 1, 0, 0.65f);
                radarTopStyle.alignment = TextAnchor.UpperCenter;
                radarTopStyle.fontSize = 12;

                rIncrements = Misc.ParseToFloatArray(rangeIncrements);
                rangeIndex = Mathf.Clamp(rangeIndex, 0, rIncrements.Length-1);
                maxRange = rIncrements[rIncrements.Length-1];
                signalPersistTime = omnidirectional ? 360/(scanRotationSpeed+5) : directionalFieldOfView/(scanRotationSpeed+5);

                if(rotationTransformName!=string.Empty)
                {
                    rotationTransform = part.FindModelTransform(rotationTransformName);
                }

                if(!radarRectInitialized)
                {
                    float width = radarScreenSize + (2*windowBorder);
                    float height = radarScreenSize + (2*windowBorder) + headerHeight + controlsHeight;
                    radarWindowRect = new Rect(Screen.width - width, Screen.height - height, width, height);
                    radarRectInitialized = true;
                }

                lockedTarget = TargetSignatureData.noTarget;

                contacts = new TargetSignatureData[10];
                TargetSignatureData.ResetTSDArray(ref contacts);

                attemptedLocks = new TargetSignatureData[3];
                TargetSignatureData.ResetTSDArray(ref attemptedLocks);

                referenceTransform = (new GameObject()).transform;
                referenceTransform.parent = transform;
                referenceTransform.localPosition = Vector3.zero;

                lockingTurret = part.FindModuleImplementing<ModuleTurret> ();

                rwrType = (RadarWarningReceiver.RWRThreatTypes) rwrThreatType;

                unlinkNullRadar = false;

                foreach(var wm in vessel.FindPartModulesImplementing<MissileFire>())
                {
                    wm.radars.Add(this);
                }

                StartCoroutine(StartUpRoutine());

            }
        }
Пример #17
0
        void UpdateLock()
        {
            if(!canLock && linked && linkedRadar && linkedRadar.locked)
            {
                lockedTarget = linkedRadar.lockedTarget;
                if(!lockedTarget.exists)
                {
                    UnlockTarget();
                }
                return;
            }

            if(!canLock)
            {
                if(lockedTarget.exists)
                {
                    UnlockTarget();
                    return;
                }

                locked = false;
                return;
            }

            Vector3 targetPlanarDirection = Vector3.ProjectOnPlane(lockedTarget.predictedPosition-referenceTransform.position, referenceTransform.up);
            float lookAngle = Vector3.Angle(targetPlanarDirection, referenceTransform.forward);
            if(referenceTransform.InverseTransformPoint(lockedTarget.predictedPosition).x < 0)
            {
                lookAngle = -lookAngle;
            }

            if(omnidirectional)
            {
                if(lookAngle < 0) lookAngle += 360;
            }

            lockScanAngle = lookAngle + currentAngleLock;
            float angleDelta = lockRotationSpeed*Time.fixedDeltaTime;
            float lockedSignalPersist = lockRotationAngle/lockRotationSpeed;
            //RadarUtils.ScanInDirection(lockScanAngle, referenceTransform, angleDelta, referenceTransform.position, minLockedSignalThreshold, ref attemptedLocks, lockedSignalPersist);
            bool radarSnapshot = (snapshotTicker > 30);
            if(radarSnapshot)
            {
                snapshotTicker = 0;
            }
            else
            {
                snapshotTicker++;
            }
            RadarUtils.ScanInDirection (new Ray (referenceTransform.position, lockedTarget.predictedPosition - referenceTransform.position), lockRotationAngle * 2, minLockedSignalThreshold, ref attemptedLocks, lockedSignalPersist, true, rwrType, radarSnapshot);
            TargetSignatureData prevLock = lockedTarget;
            lockedTarget = TargetSignatureData.noTarget;
            for(int i = 0; i < attemptedLocks.Length; i++)
            {
                if(attemptedLocks[i].exists && (attemptedLocks[i].predictedPosition-prevLock.predictedPosition).sqrMagnitude < Mathf.Pow(20,2) && attemptedLocks[i].age < 2*lockedSignalPersist)
                {
                    lockedTarget = attemptedLocks[i];
                    break;
                }
            }

            if(!lockedTarget.exists) //if failed to maintain lock, get lock data from linked radar
            {
                if(linked && linkedRadar && linkedRadar.locked && (linkedRadar.lockedTarget.predictedPosition-prevLock.predictedPosition).sqrMagnitude < Mathf.Pow(20,2))
                {
                    lockedTarget = linkedRadar.lockedTarget;
                    //if(lockedTarget.exists) return;
                }
            }

            //if still failed or out of FOV, unlock.
            if(!lockedTarget.exists || (!omnidirectional && Vector3.Angle(lockedTarget.position-referenceTransform.position, transform.up) > directionalFieldOfView/2))
            {
                UnlockTarget();
                return;
            }

            //unlock if over-jammed
            if(lockedTarget.vesselJammer && lockedTarget.vesselJammer.lockBreakStrength > lockedTarget.signalStrength*lockedTarget.vesselJammer.rcsReductionFactor)
            {
                UnlockTarget();
                return;
            }

            //cycle scan direction
            currentAngleLock += radialScanDirection*angleDelta;
            if(Mathf.Abs(currentAngleLock) > lockRotationAngle/2)
            {
                currentAngleLock = Mathf.Sign(currentAngleLock) * lockRotationAngle/2;
                radialScanDirection = -radialScanDirection;
            }
        }
Пример #18
0
 void UnlockTarget()
 {
     lockedTarget = TargetSignatureData.noTarget;
     locked = false;
     if (!canTrackWhileScan)
     {
         currentAngle = lockScanAngle;
     }
 }
Пример #19
0
		public void FireMissile()
		{
			if(!hasFired)
			{
				

				hasFired = true;

				GameEvents.onPartDie.Add(PartDie);

				BDATargetManager.FiredMissiles.Add(this);

				if(GetComponentInChildren<KSPParticleEmitter>())
				{
					BDArmorySettings.numberOfParticleEmitters++;
				}
				
				foreach(var wpm in vessel.FindPartModulesImplementing<MissileFire>())
				{
					team = wpm.team;	
					break;
				}
				
				sfAudioSource.PlayOneShot(GameDatabase.Instance.GetAudioClip("BDArmory/Sounds/deployClick"));
				
				sourceVessel = vessel;



				//TARGETING
				targetPosition = transform.position + (transform.forward * 5000); //set initial target position so if no target update, missile will count a miss if it nears this point or is flying post-thrust
				startDirection = transform.forward;
				if(BDArmorySettings.ALLOW_LEGACY_TARGETING)
				{
					if(vessel.targetObject!=null && vessel.targetObject.GetVessel()!=null)
					{
						legacyTargetVessel = vessel.targetObject.GetVessel();

						foreach(var mf in legacyTargetVessel.FindPartModulesImplementing<MissileFire>())
						{
							targetMf = mf;
							break;
						}

						if(targetingMode == TargetingModes.Heat)
						{
							heatTarget = new TargetSignatureData(legacyTargetVessel, 9999);
						}
					}
				}
				if(targetingMode == TargetingModes.Laser)
				{
					laserStartPosition = transform.position;
					if(lockedCamera)
					{
						targetAcquired = true;
						targetPosition = lastLaserPoint = lockedCamera.groundTargetPosition;
						targetingPod = lockedCamera;
					}
				}
				else if(targetingMode == TargetingModes.AntiRad && targetAcquired)
				{
					RadarWarningReceiver.OnRadarPing += ReceiveRadarPing;
				}

				part.decouple(0);
				part.force_activate();
				part.Unpack();
				vessel.situation = Vessel.Situations.FLYING;
				part.rb.isKinematic = false;
				BDArmorySettings.Instance.ApplyNewVesselRanges(vessel);
				part.bodyLiftMultiplier = 0;
				part.dragModel = Part.DragModel.NONE;

				//add target info to vessel
				TargetInfo info = vessel.gameObject.AddComponent<TargetInfo>();
				info.team = BDATargetManager.BoolToTeam(team);
				info.isMissile = true;
				info.missileModule = this;

				StartCoroutine(DecoupleRoutine());
				

				

				vessel.vesselName = GetShortName();
				vessel.vesselType = VesselType.Probe;

				
				timeFired = Time.time;


				//setting ref transform for navball
				GameObject refObject = new GameObject();
				refObject.transform.rotation = Quaternion.LookRotation(-transform.up, transform.forward);
				refObject.transform.parent = transform;
				part.SetReferenceTransform(refObject.transform);
				vessel.SetReferenceTransform(part);
				vesselReferenceTransform = refObject.transform;

				MissileState = MissileStates.Drop;

				part.crashTolerance = 9999;


				StartCoroutine(MissileRoutine());
				
			}
		}
Пример #20
0
		public static TargetSignatureData GetHeatTarget(Ray ray, float scanRadius, float highpassThreshold, bool allAspect, MissileFire mf = null)
		{
			float minScore = highpassThreshold;
			float minMass = 0.5f;
			TargetSignatureData finalData = TargetSignatureData.noTarget;
			float finalScore = 0;
			foreach(var vessel in BDATargetManager.LoadedVessels)
			{
				if(!vessel || !vessel.loaded)
				{
					continue;
				}

				TargetInfo tInfo = vessel.gameObject.GetComponent<TargetInfo>();
				if(mf == null || 
					!tInfo || 
					!(mf && tInfo.isMissile && tInfo.team != BDATargetManager.BoolToTeam(mf.team) && (tInfo.missileModule.MissileState == MissileLauncher.MissileStates.Boost || tInfo.missileModule.MissileState == MissileLauncher.MissileStates.Cruise)))
				{
					if(vessel.GetTotalMass() < minMass)
					{
						continue;
					}
				}

				if(RadarUtils.TerrainCheck(ray.origin, vessel.transform.position))
				{
					continue;
				}

				float angle = Vector3.Angle(vessel.CoM-ray.origin, ray.direction);
				if(angle < scanRadius)
				{
					float score = 0;
					foreach(var part in vessel.Parts)
					{
						if(!part) continue;
						if(!allAspect)
						{
							if(!Misc.CheckSightLineExactDistance(ray.origin, part.transform.position+vessel.rb_velocity, Vector3.Distance(part.transform.position,ray.origin), 5, 5)) continue;
						}

						float thisScore = (float)(part.thermalInternalFluxPrevious+part.skinTemperature) * (15/Mathf.Max(15,angle));
						thisScore *= Mathf.Pow(1400,2)/Mathf.Clamp((vessel.CoM-ray.origin).sqrMagnitude, 90000, 36000000);
						score = Mathf.Max (score, thisScore);
					}

					if(vessel.LandedOrSplashed)
					{
						score /= 4;
					}

					score *= Mathf.Clamp(Vector3.Angle(vessel.transform.position-ray.origin, -VectorUtils.GetUpDirection(ray.origin))/90, 0.5f, 1.5f);

					if(score > finalScore)
					{
						finalScore = score;
						finalData = new TargetSignatureData(vessel, score);
					}
				}
			}

			heatScore = finalScore;//DEBUG
			flareScore = 0; //DEBUG
			foreach(var flare in BDArmorySettings.Flares)
			{
				if(!flare) continue;

				float angle = Vector3.Angle(flare.transform.position-ray.origin, ray.direction);
				if(angle < scanRadius)
				{
					float score = flare.thermal * Mathf.Clamp01(15/angle);
					score *= Mathf.Pow(1400,2)/Mathf.Clamp((flare.transform.position-ray.origin).sqrMagnitude, 90000, 36000000);

					score *= Mathf.Clamp(Vector3.Angle(flare.transform.position-ray.origin, -VectorUtils.GetUpDirection(ray.origin))/90, 0.5f, 1.5f);

					if(score > finalScore)
					{
						flareScore = score;//DEBUG
						finalScore = score;
						finalData = new TargetSignatureData(flare, score);
					}
				}
			}



			if(finalScore < minScore)
			{
				finalData = TargetSignatureData.noTarget;
			}

			return finalData;
		}
Пример #21
0
 IEnumerator LaunchWarningRoutine(TargetSignatureData data)
 {
     launchWarnings.Add(data);
     yield return new WaitForSeconds(2);
     launchWarnings.Remove(data);
 }
Пример #22
0
        public void SendTargetDataToMissile(MissileLauncher ml)
        {
            if(ml.targetingMode == MissileLauncher.TargetingModes.Laser && laserPointDetected)
            {
                ml.lockedCamera = foundCam;
            }
            else if(ml.targetingMode == MissileLauncher.TargetingModes.GPS)
            {
                if(BDArmorySettings.ALLOW_LEGACY_TARGETING)
                {
                    if(vessel.targetObject != null && vessel.targetObject.GetVessel() != null)
                    {
                        ml.targetAcquired = true;
                        ml.legacyTargetVessel = vessel.targetObject.GetVessel();
                    }
                }
                else if(designatedGPSCoords != Vector3d.zero)
                {
                    ml.targetGPSCoords = designatedGPSCoords;
                    ml.targetAcquired = true;
                }
            }
            else if(ml.targetingMode == MissileLauncher.TargetingModes.Heat && heatTarget.exists)
            {
                ml.heatTarget = heatTarget;
                heatTarget = TargetSignatureData.noTarget;
            }
            else if(ml.targetingMode == MissileLauncher.TargetingModes.Radar && radar && radar.lockedTarget.exists)
            {
                ml.radarTarget = radar.lockedTarget;
                if(radar.linked && radar.linkedRadar.locked)
                {
                    ml.radar = radar.linkedRadar;
                }
                else
                {
                    ml.radar = radar;
                }
                radar.lastMissile = ml;

            }
            else if(ml.targetingMode == MissileLauncher.TargetingModes.AntiRad && antiRadTargetAcquired)
            {
                ml.targetAcquired = true;
                ml.targetGPSCoords = VectorUtils.WorldPositionToGeoCoords(antiRadiationTarget, vessel.mainBody);
            }
        }
Пример #23
0
        void BoresightScan()
        {
            currentAngle = Mathf.Lerp(currentAngle, 0, 0.08f);
            RadarUtils.ScanInDirection (new Ray (transform.position, transform.up), boresightFOV, minSignalThreshold * 5, ref attemptedLocks, Time.fixedDeltaTime, true, rwrType, true);

            for(int i = 0; i < attemptedLocks.Length; i++)
            {
                if(attemptedLocks[i].exists && attemptedLocks[i].age < 0.1f)
                {
                    locked = true;
                    lockedTarget = attemptedLocks[i];
                    Debug.Log ("- Acquired lock on target.");
                    boresightScan = false;
                    return;
                }
            }
        }
Пример #24
0
        protected void UpdateRadarTarget()
        {
            TargetAcquired = false;

            float angleToTarget = Vector3.Angle(radarTarget.predictedPosition - transform.position, GetForwardTransform());

            if (radarTarget.exists)
            {
                // locked-on before launch, passive radar guidance or waiting till in active radar range:
                if (!ActiveRadar && ((radarTarget.predictedPosition - transform.position).sqrMagnitude > Mathf.Pow(activeRadarRange, 2) || angleToTarget > maxOffBoresight * 0.75f))
                {
                    if (vrd)
                    {
                        TargetSignatureData        t = TargetSignatureData.noTarget;
                        List <TargetSignatureData> possibleTargets = vrd.GetLockedTargets();
                        for (int i = 0; i < possibleTargets.Count; i++)
                        {
                            if (possibleTargets[i].vessel == radarTarget.vessel)
                            {
                                t = possibleTargets[i];
                            }
                        }

                        if (t.exists)
                        {
                            TargetAcquired     = true;
                            radarTarget        = t;
                            TargetPosition     = radarTarget.predictedPositionWithChaffFactor;
                            TargetVelocity     = radarTarget.velocity;
                            TargetAcceleration = radarTarget.acceleration;
                            _radarFailTimer    = 0;
                            return;
                        }
                        else
                        {
                            if (_radarFailTimer > maxRadarFailTime)
                            {
                                Debug.Log("[BDArmory]: Semi-Active Radar guidance failed. Parent radar lost target.");
                                radarTarget        = TargetSignatureData.noTarget;
                                legacyTargetVessel = null;
                                return;
                            }
                            else
                            {
                                if (_radarFailTimer == 0)
                                {
                                    Debug.Log("[BDArmory]: Semi-Active Radar guidance failed - waiting for data");
                                }
                                _radarFailTimer         += Time.fixedDeltaTime;
                                radarTarget.timeAcquired = Time.time;
                                radarTarget.position     = radarTarget.predictedPosition;
                                TargetPosition           = radarTarget.predictedPositionWithChaffFactor;
                                TargetVelocity           = radarTarget.velocity;
                                TargetAcceleration       = Vector3.zero;
                                TargetAcquired           = true;
                            }
                        }
                    }
                    else
                    {
                        Debug.Log("[BDArmory]: Semi-Active Radar guidance failed. Out of range and no data feed.");
                        radarTarget        = TargetSignatureData.noTarget;
                        legacyTargetVessel = null;
                        return;
                    }
                }
                else
                {
                    // active radar with target locked:
                    vrd = null;

                    if (angleToTarget > maxOffBoresight)
                    {
                        Debug.Log("[BDArmory]: Active Radar guidance failed.  Target is out of active seeker gimbal limits.");
                        radarTarget        = TargetSignatureData.noTarget;
                        legacyTargetVessel = null;
                        return;
                    }
                    else
                    {
                        if (scannedTargets == null)
                        {
                            scannedTargets = new TargetSignatureData[5];
                        }
                        TargetSignatureData.ResetTSDArray(ref scannedTargets);
                        Ray  ray     = new Ray(transform.position, radarTarget.predictedPosition - transform.position);
                        bool pingRWR = Time.time - lastRWRPing > 0.4f;
                        if (pingRWR)
                        {
                            lastRWRPing = Time.time;
                        }
                        bool radarSnapshot = (snapshotTicker > 10);
                        if (radarSnapshot)
                        {
                            snapshotTicker = 0;
                        }
                        else
                        {
                            snapshotTicker++;
                        }

                        //RadarUtils.UpdateRadarLock(ray, lockedSensorFOV, activeRadarMinThresh, ref scannedTargets, 0.4f, pingRWR, RadarWarningReceiver.RWRThreatTypes.MissileLock, radarSnapshot);
                        RadarUtils.RadarUpdateMissileLock(ray, lockedSensorFOV, ref scannedTargets, 0.4f, this);

                        float sqrThresh = radarLOALSearching ? Mathf.Pow(500, 2) : Mathf.Pow(40, 2);

                        if (radarLOAL && radarLOALSearching && !radarSnapshot)
                        {
                            //only scan on snapshot interval
                        }
                        else
                        {
                            for (int i = 0; i < scannedTargets.Length; i++)
                            {
                                if (scannedTargets[i].exists && (scannedTargets[i].predictedPosition - radarTarget.predictedPosition).sqrMagnitude < sqrThresh)
                                {
                                    //re-check engagement envelope, only lock appropriate targets
                                    if (CheckTargetEngagementEnvelope(scannedTargets[i].targetInfo))
                                    {
                                        radarTarget        = scannedTargets[i];
                                        TargetAcquired     = true;
                                        radarLOALSearching = false;
                                        TargetPosition     = radarTarget.predictedPositionWithChaffFactor + (radarTarget.velocity * Time.fixedDeltaTime);
                                        TargetVelocity     = radarTarget.velocity;
                                        TargetAcceleration = radarTarget.acceleration;
                                        _radarFailTimer    = 0;
                                        if (!ActiveRadar && Time.time - TimeFired > 1)
                                        {
                                            if (locksCount == 0)
                                            {
                                                if (weaponClass == WeaponClasses.SLW)
                                                {
                                                    RadarWarningReceiver.PingRWR(ray, lockedSensorFOV, RadarWarningReceiver.RWRThreatTypes.Torpedo, 2f);
                                                }
                                                else
                                                {
                                                    RadarWarningReceiver.PingRWR(ray, lockedSensorFOV, RadarWarningReceiver.RWRThreatTypes.MissileLaunch, 2f);
                                                }
                                                Debug.Log("[BDArmory]: Pitbull! Radar missilebase has gone active.  Radar sig strength: " + radarTarget.signalStrength.ToString("0.0"));
                                            }
                                            else if (locksCount > 2)
                                            {
                                                guidanceActive = false;
                                                checkMiss      = true;
                                                if (BDArmorySettings.DRAW_DEBUG_LABELS)
                                                {
                                                    Debug.Log("[BDArmory]: Active Radar guidance failed. Radar missileBase reached max re-lock attempts.");
                                                }
                                            }
                                            locksCount++;
                                        }
                                        ActiveRadar = true;
                                        return;
                                    }
                                }
                            }
                        }

                        if (radarLOAL)
                        {
                            radarLOALSearching = true;
                            TargetAcquired     = true;
                            TargetPosition     = radarTarget.predictedPositionWithChaffFactor + (radarTarget.velocity * Time.fixedDeltaTime);
                            TargetVelocity     = radarTarget.velocity;
                            TargetAcceleration = Vector3.zero;
                            ActiveRadar        = false;
                            _radarFailTimer    = 0;
                        }
                        else
                        {
                            Debug.Log("[BDArmory]: Active Radar guidance failed.  No target locked.");
                            radarTarget        = TargetSignatureData.noTarget;
                            legacyTargetVessel = null;
                            radarLOALSearching = false;
                            TargetAcquired     = false;
                            ActiveRadar        = false;
                        }
                    }
                }
            }
            else if (radarLOAL && radarLOALSearching)
            {
                // not locked on before launch, trying lock-on after launch:

                if (scannedTargets == null)
                {
                    scannedTargets = new TargetSignatureData[5];
                }
                TargetSignatureData.ResetTSDArray(ref scannedTargets);
                Ray  ray     = new Ray(transform.position, GetForwardTransform());
                bool pingRWR = Time.time - lastRWRPing > 0.4f;
                if (pingRWR)
                {
                    lastRWRPing = Time.time;
                }
                bool radarSnapshot = (snapshotTicker > 5);
                if (radarSnapshot)
                {
                    snapshotTicker = 0;
                }
                else
                {
                    snapshotTicker++;
                }

                //RadarUtils.UpdateRadarLock(ray, lockedSensorFOV * 3, activeRadarMinThresh * 2, ref scannedTargets, 0.4f, pingRWR, RadarWarningReceiver.RWRThreatTypes.MissileLock, radarSnapshot);
                RadarUtils.RadarUpdateMissileLock(ray, lockedSensorFOV * 3, ref scannedTargets, 0.4f, this);

                float sqrThresh = Mathf.Pow(300, 2);

                float smallestAngle = 360;
                TargetSignatureData lockedTarget = TargetSignatureData.noTarget;

                for (int i = 0; i < scannedTargets.Length; i++)
                {
                    if (scannedTargets[i].exists && (scannedTargets[i].predictedPosition - radarTarget.predictedPosition).sqrMagnitude < sqrThresh)
                    {
                        //re-check engagement envelope, only lock appropriate targets
                        if (CheckTargetEngagementEnvelope(scannedTargets[i].targetInfo))
                        {
                            float angle = Vector3.Angle(scannedTargets[i].predictedPosition - transform.position, GetForwardTransform());
                            if (angle < smallestAngle)
                            {
                                lockedTarget  = scannedTargets[i];
                                smallestAngle = angle;
                            }


                            ActiveRadar = true;
                            return;
                        }
                    }
                }

                if (lockedTarget.exists)
                {
                    radarTarget        = lockedTarget;
                    TargetAcquired     = true;
                    radarLOALSearching = false;
                    TargetPosition     = radarTarget.predictedPositionWithChaffFactor + (radarTarget.velocity * Time.fixedDeltaTime);
                    TargetVelocity     = radarTarget.velocity;
                    TargetAcceleration = radarTarget.acceleration;

                    if (!ActiveRadar && Time.time - TimeFired > 1)
                    {
                        if (weaponClass == WeaponClasses.SLW)
                        {
                            RadarWarningReceiver.PingRWR(new Ray(transform.position, radarTarget.predictedPosition - transform.position), lockedSensorFOV, RadarWarningReceiver.RWRThreatTypes.Torpedo, 2f);
                        }
                        else
                        {
                            RadarWarningReceiver.PingRWR(new Ray(transform.position, radarTarget.predictedPosition - transform.position), lockedSensorFOV, RadarWarningReceiver.RWRThreatTypes.MissileLaunch, 2f);
                        }

                        Debug.Log("[BDArmory]: Pitbull! Radar missileBase has gone active.  Radar sig strength: " + radarTarget.signalStrength.ToString("0.0"));
                    }
                    return;
                }
                else
                {
                    TargetAcquired     = true;
                    TargetPosition     = transform.position + (startDirection * 500);
                    TargetVelocity     = Vector3.zero;
                    TargetAcceleration = Vector3.zero;
                    radarLOALSearching = true;
                    _radarFailTimer   += Time.fixedDeltaTime;
                    if (_radarFailTimer > maxRadarFailTime)
                    {
                        Debug.Log("[BDArmory]: Active Radar guidance failed. LOAL could not lock a target.");
                        radarTarget        = TargetSignatureData.noTarget;
                        legacyTargetVessel = null;
                        radarLOALSearching = false;
                        TargetAcquired     = false;
                        ActiveRadar        = false;
                    }
                    return;
                }
            }

            if (!radarTarget.exists)
            {
                legacyTargetVessel = null;
            }
        }
Пример #25
0
        void DrawScannedContacts(ref TargetSignatureData[] scannedContacts, Rect radarRect)
        {
            float myAlt = (float)vessel.altitude;
            for (int i = 0; i < scannedContacts.Length; i++)
            {
                if(scannedContacts[i].exists)// && scannedContacts[i].signalStrength > minSignalThreshold)
                {
                    //ignore old target data
                    if(scannedContacts[i].age > signalPersistTime)
                    {
                        scannedContacts[i].exists = false;
                        continue;
                    }

                    //ignore targets outside of directional field of view
                    if(!omnidirectional && !linked && Vector3.Angle(scannedContacts[i].position - transform.position, transform.up) > directionalFieldOfView)
                    {
                        scannedContacts[i].exists = false;
                        continue;
                    }

                    //ignore locked target if tracking while scanning
                    if((canTrackWhileScan||(linked&&linkedRadar&&linkedRadar.canTrackWhileScan)) && locked && (scannedContacts[i].predictedPosition - lockedTarget.predictedPosition).sqrMagnitude < 100)
                    {
                        scannedContacts[i].exists = false;
                        continue;
                    }

                    float minusAlpha = (Mathf.Clamp01((Time.time - scannedContacts[i].timeAcquired) / signalPersistTime) * 2) - 1;

                    //dont draw self if reading remote data
                    if(linked && (scannedContacts[i].predictedPosition - transform.position).sqrMagnitude < Mathf.Pow(50, 2))
                    {
                        minusAlpha = 1;
                        continue;
                    }

                    //jamming
                    bool jammed = false;
                    if(scannedContacts[i].vesselJammer && scannedContacts[i].vesselJammer.jammerStrength > scannedContacts[i].signalStrength)
                    {
                        jammed = true;
                    }

                    Vector2 pingPosition;
                    if(pingPositionsDirty || scannedContacts[i].pingPosition == Vector2.zero)
                    {
                        if(omnidirectional || linked)
                        {
                            pingPosition = RadarUtils.WorldToRadar(scannedContacts[i].position, referenceTransform, radarRect, rIncrements[rangeIndex]);
                        }
                        else
                        {
                            pingPosition = RadarUtils.WorldToRadarRadial(scannedContacts[i].position, referenceTransform, radarRect, rIncrements[rangeIndex], directionalFieldOfView / 2);
                        }

                        scannedContacts[i].pingPosition = pingPosition;
                    }
                    else
                    {
                        pingPosition = scannedContacts[i].pingPosition;
                    }

                    Rect pingRect;
                    //draw missiles and debris as dots
                    if((scannedContacts[i].targetInfo && scannedContacts[i].targetInfo.isMissile) || scannedContacts[i].team == BDArmorySettings.BDATeams.None)
                    {
                        float mDotSize = 6;
                        pingRect = new Rect(pingPosition.x - (mDotSize / 2), pingPosition.y - (mDotSize / 2), mDotSize, mDotSize);
                        Color origGUIColor = GUI.color;
                        GUI.color = Color.white - new Color(0, 0, 0, minusAlpha);
                        GUI.DrawTexture(pingRect, BDArmorySettings.Instance.greenDotTexture, ScaleMode.StretchToFill, true);
                        GUI.color = origGUIColor;
                    }
                    //draw contacts with direction indicator
                    else if(!jammed && (showDirectionWhileScan || (linked&&linkedRadar&&linkedRadar.showDirectionWhileScan)) && scannedContacts[i].velocity.sqrMagnitude > 100)
                    {
                        pingRect = new Rect(pingPosition.x - (lockIconSize / 2), pingPosition.y - (lockIconSize / 2), lockIconSize, lockIconSize);
                        float vAngle = Vector3.Angle(Vector3.ProjectOnPlane(scannedContacts[i].velocity, referenceTransform.up), referenceTransform.forward);
                        if(referenceTransform.InverseTransformVector(scannedContacts[i].velocity).x < 0)
                        {
                            vAngle = -vAngle;
                        }
                        GUIUtility.RotateAroundPivot(vAngle, pingPosition);
                        Color origGUIColor = GUI.color;
                        GUI.color = Color.white - new Color(0, 0, 0, minusAlpha);
                        if(weaponManager && scannedContacts[i].team == BDATargetManager.BoolToTeam(weaponManager.team))
                        {
                            GUI.DrawTexture(pingRect, friendlyContactIcon, ScaleMode.StretchToFill, true);
                        }
                        else
                        {
                            GUI.DrawTexture(pingRect, radarContactIcon, ScaleMode.StretchToFill, true);
                        }

                        GUI.matrix = Matrix4x4.identity;
                        GUI.Label(new Rect(pingPosition.x + (lockIconSize * 0.35f) + 2, pingPosition.y, 100, 24), (scannedContacts[i].altitude / 1000).ToString("0"), distanceStyle);
                        GUI.color = origGUIColor;
                    }
                    else //draw contacts as rectangles
                    {
                        int drawCount = jammed ? 4 : 1;
                        pingRect = new Rect(pingPosition.x - (pingSize.x / 2), pingPosition.y - (pingSize.y / 2), pingSize.x, pingSize.y);
                        for(int d = 0; d < drawCount; d++)
                        {
                            Rect jammedRect = new Rect(pingRect);
                            Vector3 contactPosition = scannedContacts[i].position;
                            if(jammed)
                            {
                                //jamming
                                Vector3 jammedPosition = transform.position + ((scannedContacts[i].position - transform.position).normalized * UnityEngine.Random.Range(100, rIncrements[rangeIndex]));
                                float bearingVariation = Mathf.Clamp(Mathf.Pow(32000, 2) / (scannedContacts[i].position - transform.position).sqrMagnitude, 0, 80);
                                jammedPosition = transform.position + (Quaternion.AngleAxis(UnityEngine.Random.Range(-bearingVariation, bearingVariation), referenceTransform.up) * (jammedPosition - transform.position));
                                if(omnidirectional || linked)
                                {
                                    pingPosition = RadarUtils.WorldToRadar(jammedPosition, referenceTransform, radarRect, rIncrements[rangeIndex]);
                                }
                                else
                                {
                                    pingPosition = RadarUtils.WorldToRadarRadial(jammedPosition, referenceTransform, radarRect, rIncrements[rangeIndex], directionalFieldOfView / 2);
                                }

                                jammedRect = new Rect(pingPosition.x - (pingSize.x / 2), pingPosition.y - (pingSize.y / 2) - (pingSize.y / 3), pingSize.x, pingSize.y / 3);
                                contactPosition = jammedPosition;
                            }

                            Color iconColor = Color.green;
                            float contactAlt = scannedContacts[i].altitude;
                            if(!omnidirectional && !jammed)
                            {
                                if(contactAlt - myAlt > 1000)
                                {
                                    iconColor = new Color(0, 0.6f, 1f, 1);
                                }
                                else if(contactAlt - myAlt < -1000)
                                {
                                    iconColor = new Color(1f, 0.68f, 0, 1);
                                }
                            }

                            if(omnidirectional)
                            {
                                Vector3 localPos = referenceTransform.InverseTransformPoint(contactPosition);
                                localPos.y = 0;
                                float angleToContact = Vector3.Angle(localPos, Vector3.forward);
                                if(localPos.x < 0) angleToContact = -angleToContact;
                                GUIUtility.RotateAroundPivot(angleToContact, pingPosition);
                            }

                            BDGUIUtils.DrawRectangle(jammedRect, iconColor - new Color(0, 0, 0, minusAlpha));

                            GUI.matrix = Matrix4x4.identity;
                        }
                    }

                    if(GUI.RepeatButton(pingRect, GUIContent.none, GUIStyle.none))
                    {
                        TryLockTarget(scannedContacts[i].predictedPosition);
                        if(Event.current.isMouse && Event.current.type == EventType.mouseDown)
                        {
                            Event.current.Use();
                        }
                    }

                    if(BDArmorySettings.DRAW_DEBUG_LABELS)
                    {
                        GUI.Label(new Rect(pingPosition.x + (pingSize.x / 2), pingPosition.y, 100, 24), scannedContacts[i].signalStrength.ToString("0.0"));
                    }
                }
            }

            pingPositionsDirty = false;
        }
Пример #26
0
        public void ReceiveContactData(TargetSignatureData contactData, bool _locked)
        {
            if(vesselRadarData)
            {
                vesselRadarData.AddRadarContact(this, contactData, _locked);
            }

            foreach(var vrd in linkedToVessels)
            {
                if(vrd && vrd.canReceiveRadarData && vrd.vessel!=contactData.vessel)
                {
                    vrd.AddRadarContact(this, contactData, _locked);
                }
            }
        }
Пример #27
0
        void LinkToRadar(ModuleRadar mr)
        {
            if(!mr)
            {
                return;
            }

            linkedRadar = mr;
            linkedVesselID = mr.vessel.id.ToString();
            linked = true;
            if(mr.locked)
            {
                locked = true;
                lockedTarget = mr.lockedTarget;
            }
            CloseLinkRadarWindow();
        }
Пример #28
0
        public void UpdateLockedTargetInfo(TargetSignatureData newData)
        {
            int index = -1;
            for(int i = 0; i < lockedTargets.Count; i++)
            {
                if(lockedTargets[i].vessel == newData.vessel)
                {
                    index = i;
                    break;
                }
            }

            if(index >= 0)
            {
                lockedTargets[index] = newData;
            }
        }
Пример #29
0
        void UpdateHeatTarget()
        {
            targetAcquired = false;

            if(heatTarget.exists && lockFailTimer < 0)
            {
                lockFailTimer = 0;
            }
            if(lockFailTimer >= 0 && lockFailTimer < 1)
            {
                Ray lookRay = new Ray(transform.position, heatTarget.position+(heatTarget.velocity*Time.fixedDeltaTime)-transform.position);
                heatTarget = BDATargetManager.GetHeatTarget(lookRay, lockedSensorFOV/2, heatThreshold, allAspect);

                if(heatTarget.exists)
                {
                    targetAcquired = true;
                    targetPosition = heatTarget.position+(heatTarget.velocity*Time.fixedDeltaTime);
                    targetVelocity = heatTarget.velocity;
                    targetAcceleration = heatTarget.acceleration;
                    lockFailTimer = 0;
                }
                else
                {
                    if(FlightGlobals.ready)
                    {
                        lockFailTimer += Time.fixedDeltaTime;
                    }
                }
            }
            if(lockFailTimer > 1)
            {
                legacyTargetVessel = null;
            }
        }
Пример #30
0
        public static void UpdateRadarLock(Ray ray, float fov, float minSignature, ref TargetSignatureData[] dataArray, float dataPersistTime, bool pingRWR, RadarWarningReceiver.RWRThreatTypes rwrType, bool radarSnapshot)
        {
            int dataIndex = 0;
            foreach(var vessel in BDATargetManager.LoadedVessels)
            {
                if(vessel == null) continue;
                if(!vessel.loaded) continue;
                //if(vessel.Landed) continue;

                Vector3 vectorToTarget = vessel.transform.position - ray.origin;
                if((vectorToTarget).sqrMagnitude < 10) continue; //ignore self

                if(Vector3.Dot(vectorToTarget, ray.direction) < 0) continue; //ignore behind ray

                if(Vector3.Angle(vessel.CoM - ray.origin, ray.direction) < fov / 2)
                {
                    if(TerrainCheck(ray.origin, vessel.transform.position)) continue; //blocked by terrain
                    float sig = float.MaxValue;
                    if(radarSnapshot) sig = GetModifiedSignature(vessel, ray.origin);

                    if(pingRWR && sig > minSignature * 0.66f)
                    {
                        RadarWarningReceiver.PingRWR(vessel, ray.origin, rwrType, dataPersistTime);
                    }

                    if(sig > minSignature)
                    {
                        while(dataIndex < dataArray.Length - 1)
                        {
                            if((dataArray[dataIndex].exists && Time.time - dataArray[dataIndex].timeAcquired > dataPersistTime) || !dataArray[dataIndex].exists)
                            {
                                break;
                            }
                            dataIndex++;
                        }
                        if(dataIndex >= dataArray.Length) break;
                        dataArray[dataIndex] = new TargetSignatureData(vessel, sig);
                        dataIndex++;
                        if(dataIndex >= dataArray.Length) break;
                    }
                }

            }
        }
Пример #31
0
        void UpdateLock(int index)
        {
            TargetSignatureData lockedTarget = lockedTargets[index];

            Vector3 targetPlanarDirection =
                Vector3.ProjectOnPlane(lockedTarget.predictedPosition - referenceTransform.position,
                                       referenceTransform.up);
            float lookAngle = Vector3.Angle(targetPlanarDirection, referenceTransform.forward);

            if (referenceTransform.InverseTransformPoint(lockedTarget.predictedPosition).x < 0)
            {
                lookAngle = -lookAngle;
            }

            if (omnidirectional)
            {
                if (lookAngle < 0)
                {
                    lookAngle += 360;
                }
            }

            lockScanAngle = lookAngle + currentAngleLock;
            if (!canTrackWhileScan && index == lockedTargetIndex)
            {
                currentAngle = lockScanAngle;
            }
            float angleDelta          = lockRotationSpeed * Time.fixedDeltaTime;
            float lockedSignalPersist = lockRotationAngle / lockRotationSpeed;
            //RadarUtils.ScanInDirection(lockScanAngle, referenceTransform, angleDelta, referenceTransform.position, minLockedSignalThreshold, ref attemptedLocks, lockedSignalPersist);
            bool radarSnapshot = (snapshotTicker > 30);

            if (radarSnapshot)
            {
                snapshotTicker = 0;
            }
            else
            {
                snapshotTicker++;
            }
            //RadarUtils.ScanInDirection (new Ray (referenceTransform.position, lockedTarget.predictedPosition - referenceTransform.position), lockRotationAngle * 2, minLockedSignalThreshold, ref attemptedLocks, lockedSignalPersist, true, rwrType, radarSnapshot);

            if (
                Vector3.Angle(lockedTarget.position - referenceTransform.position,
                              this.lockedTarget.position - referenceTransform.position) > multiLockFOV / 2)
            {
                UnlockTargetAt(index, true);
                return;
            }

            RadarUtils.RadarUpdateLockTrack(
                new Ray(referenceTransform.position, lockedTarget.predictedPosition - referenceTransform.position),
                lockedTarget.predictedPosition, lockRotationAngle * 2, this, lockedSignalPersist, true, index, lockedTarget.vessel);

            //if still failed or out of FOV, unlock.
            if (!lockedTarget.exists ||
                (!omnidirectional &&
                 Vector3.Angle(lockedTarget.position - referenceTransform.position, transform.up) >
                 directionalFieldOfView / 2))
            {
                //UnlockAllTargets();
                UnlockTargetAt(index, true);
                return;
            }

            //unlock if over-jammed
            // MOVED TO RADARUTILS!

            //cycle scan direction
            if (index == lockedTargetIndex)
            {
                currentAngleLock += lockScanDirection * angleDelta;
                if (Mathf.Abs(currentAngleLock) > lockRotationAngle / 2)
                {
                    currentAngleLock  = Mathf.Sign(currentAngleLock) * lockRotationAngle / 2;
                    lockScanDirection = -lockScanDirection;
                }
            }
        }
Пример #32
0
        void ReceivePing(Vessel v, Vector3 source, RWRThreatTypes type, float persistTime)
        {
            if (v == null)
            {
                return;
            }
            if (referenceTransform == null)
            {
                return;
            }
            if (weaponManager == null)
            {
                return;
            }

            if (rwrEnabled && vessel && v == vessel)
            {
                //if we are airborne or on land, no Sonar or SLW type weapons on the RWR!
                if ((type == RWRThreatTypes.Torpedo || type == RWRThreatTypes.TorpedoLock || type == RWRThreatTypes.Sonar) && (vessel.situation != Vessel.Situations.SPLASHED))
                {
                    // rwr stays silent...
                    return;
                }

                if (type == RWRThreatTypes.MissileLaunch || type == RWRThreatTypes.Torpedo)
                {
                    StartCoroutine(
                        LaunchWarningRoutine(new TargetSignatureData(Vector3.zero,
                                                                     RadarUtils.WorldToRadar(source, referenceTransform, RwrDisplayRect, rwrDisplayRange),
                                                                     Vector3.zero, true, (float)type)));
                    PlayWarningSound(type, (source - vessel.transform.position).sqrMagnitude);
                    return;
                }
                else if (type == RWRThreatTypes.MissileLock)
                {
                    if (weaponManager && weaponManager.guardMode)
                    {
                        weaponManager.FireChaff();
                        // TODO: if torpedo inbound, also fire accoustic decoys (not yet implemented...)
                    }
                }

                int openIndex = -1;
                for (int i = 0; i < dataCount; i++)
                {
                    if (pingsData[i].exists &&
                        ((Vector2)pingsData[i].position -
                         RadarUtils.WorldToRadar(source, referenceTransform, RwrDisplayRect, rwrDisplayRange)).sqrMagnitude < 900f)    //prevent ping spam
                    {
                        break;
                    }

                    if (!pingsData[i].exists && openIndex == -1)
                    {
                        openIndex = i;
                    }
                }

                if (openIndex >= 0)
                {
                    referenceTransform.rotation = Quaternion.LookRotation(vessel.ReferenceTransform.up,
                                                                          VectorUtils.GetUpDirection(transform.position));

                    pingsData[openIndex] = new TargetSignatureData(Vector3.zero,
                                                                   RadarUtils.WorldToRadar(source, referenceTransform, RwrDisplayRect, rwrDisplayRange), Vector3.zero,
                                                                   true, (float)type); // HACK! Evil misuse of signalstrength for the threat type!
                    pingWorldPositions[openIndex] = source;
                    StartCoroutine(PingLifeRoutine(openIndex, persistTime));

                    PlayWarningSound(type, (source - vessel.transform.position).sqrMagnitude);
                }
            }
        }
Пример #33
0
        public static void ScanInDirection(Ray ray, float fov, float minSignature, ref TargetSignatureData[] dataArray, float dataPersistTime, bool pingRWR, RadarWarningReceiver.RWRThreatTypes rwrType)
        {
            int dataIndex = 0;
            foreach(var vessel in FlightGlobals.Vessels)
            {
                if(vessel && vessel.loaded && !vessel.Landed)
                {
                    if((vessel.transform.position-ray.origin).sqrMagnitude < 10) continue; //ignore self
                    if(TerrainCheck(ray.origin, vessel.transform.position)) continue; //blocked by terrain

                    if(Vector3.Angle(vessel.CoM-ray.origin, ray.direction) < fov/2)
                    {
                        float sig = GetModifiedSignature(vessel, ray.origin);

                        if(pingRWR && sig > minSignature * 0.66f)
                        {
                            RadarWarningReceiver.PingRWR(vessel, ray.origin, rwrType, dataPersistTime);
                        }

                        if(sig > minSignature)
                        {
                            TargetInfo ti = vessel.GetComponent<TargetInfo>();
                            if(!ti)
                            {
                                vessel.gameObject.AddComponent<TargetInfo>();
                            }

                            while(dataIndex < dataArray.Length-1)
                            {
                                if((dataArray[dataIndex].exists && Time.time-dataArray[dataIndex].timeAcquired > dataPersistTime) || !dataArray[dataIndex].exists)
                                {
                                    break;
                                }
                                dataIndex++;
                            }
                            if(dataIndex >= dataArray.Length) break;
                            dataArray[dataIndex] = new TargetSignatureData(vessel, sig);
                            dataIndex++;
                            if(dataIndex >= dataArray.Length) break;
                        }
                    }
                }
            }
        }
Пример #34
0
        public static TargetSignatureData GetHeatTarget(Ray ray, float scanRadius, float highpassThreshold, bool allAspect, MissileFire mf = null, bool favorGroundTargets = false)
        {
            float minMass = 0.05f;  //otherwise the RAMs have trouble shooting down incoming missiles
            TargetSignatureData finalData = TargetSignatureData.noTarget;
            float finalScore = 0;

            foreach (Vessel vessel in LoadedVessels)
            {
                if (!vessel || !vessel.loaded)
                {
                    continue;
                }

                if (favorGroundTargets && !vessel.LandedOrSplashed) // for AGM heat guidance
                {
                    continue;
                }

                TargetInfo tInfo = vessel.gameObject.GetComponent <TargetInfo>();
                if (mf == null ||
                    !tInfo ||
                    !(mf && tInfo.isMissile && tInfo.team != BoolToTeam(mf.team) && (tInfo.MissileBaseModule.MissileState == MissileBase.MissileStates.Boost || tInfo.MissileBaseModule.MissileState == MissileBase.MissileStates.Cruise)))
                {
                    if (vessel.GetTotalMass() < minMass)
                    {
                        continue;
                    }
                }


                float angle = Vector3.Angle(vessel.CoM - ray.origin, ray.direction);
                if (angle < scanRadius)
                {
                    if (RadarUtils.TerrainCheck(ray.origin, vessel.transform.position))
                    {
                        continue;
                    }


                    if (!allAspect)
                    {
                        if (!Misc.Misc.CheckSightLineExactDistance(ray.origin, vessel.CoM + vessel.Velocity(), Vector3.Distance(vessel.CoM, ray.origin), 5, 5))
                        {
                            continue;
                        }
                    }

                    float score = GetVesselHeatSignature(vessel) * Mathf.Clamp01(15 / angle);
                    score *= Mathf.Pow(1400, 2) / Mathf.Clamp((vessel.CoM - ray.origin).sqrMagnitude, 90000, 36000000);

                    if (vessel.LandedOrSplashed && !favorGroundTargets)
                    {
                        score /= 4;
                    }

                    score *= Mathf.Clamp(Vector3.Angle(vessel.transform.position - ray.origin, -VectorUtils.GetUpDirection(ray.origin)) / 90, 0.5f, 1.5f);

                    if (score > finalScore)
                    {
                        finalScore = score;
                        finalData  = new TargetSignatureData(vessel, score);
                    }
                }
            }

            // see if there are flares decoying us:
            TargetSignatureData flareData = GetFlareTarget(ray, scanRadius, highpassThreshold, allAspect, finalScore);

            if (finalScore < highpassThreshold)
            {
                finalData = TargetSignatureData.noTarget;
            }

            // return matching flare
            if (!flareData.Equals(TargetSignatureData.noTarget))
            {
                return(flareData);
            }

            //else return the target:
            return(finalData);
        }
Пример #35
0
        void SearchForHeatTarget()
        {
            MissileLauncher ml = currentMissile;
            if(!ml || ml.targetingMode != MissileLauncher.TargetingModes.Heat)
            {
                return;
            }

            float scanRadius = ml.lockedSensorFOV*2;
            float maxOffBoresight = ml.maxOffBoresight*0.85f;

            bool radarSlaved = false;
            if(radar && radar.radarEnabled && radar.locked)
            {
                heatTarget = radar.lockedTarget;
                radarSlaved = true;
            }

            Vector3 direction =
                heatTarget.exists && Vector3.Angle(heatTarget.position - ml.transform.position, ml.transform.forward) < maxOffBoresight ?
                heatTarget.predictedPosition - ml.transform.position
                : ml.transform.forward;

            float heatThresh = radarSlaved ? ml.heatThreshold*0.5f : ml.heatThreshold;

            heatTarget = BDATargetManager.GetHeatTarget(new Ray(ml.transform.position, direction), scanRadius, ml.heatThreshold, ml.allAspect);
        }
Пример #36
0
        void UpdateLegacyTarget()
        {
            if(legacyTargetVessel)
            {
                maxOffBoresight = 90;

                if(targetingMode == TargetingModes.Radar)
                {
                    activeRadarRange = 20000;
                    targetAcquired = true;
                    radarTarget = new TargetSignatureData(legacyTargetVessel, 500);
                    return;
                }
                else if(targetingMode == TargetingModes.Heat)
                {
                    targetAcquired = true;
                    heatTarget = new TargetSignatureData(legacyTargetVessel, 500);
                    return;
                }

                targetAcquired = true;
                targetPosition = legacyTargetVessel.CoM + (legacyTargetVessel.rb_velocity*Time.fixedDeltaTime);
                targetGPSCoords = VectorUtils.WorldPositionToGeoCoords(targetPosition, vessel.mainBody);
                targetVelocity = legacyTargetVessel.srf_velocity;
                targetAcceleration = legacyTargetVessel.acceleration;
                lastLaserPoint = targetPosition;
                lockFailTimer = 0;
            }
        }
Пример #37
0
        void ReceivePing(Vessel v, Vector3 source, RWRThreatTypes type, float persistTime)
        {
            if(rwrEnabled && vessel && v == vessel)
            {
                if(type == RWRThreatTypes.MissileLaunch)
                {
                    StartCoroutine(LaunchWarningRoutine(new TargetSignatureData(Vector3.zero, RadarUtils.WorldToRadar(source, referenceTransform, displayRect, rwrDisplayRange), Vector3.zero, true, (float)type)));
                    PlayWarningSound(type);
                    return;
                }
                else if(type == RWRThreatTypes.MissileLock)
                {
                    if(!BDArmorySettings.ALLOW_LEGACY_TARGETING && weaponManager && weaponManager.guardMode)
                    {
                        weaponManager.FireChaff();
                    }
                }

                int openIndex = -1;
                for(int i = 0; i < dataCount; i++)
                {
                    if(pingsData[i].exists && ((Vector2)pingsData[i].position - RadarUtils.WorldToRadar(source, referenceTransform, displayRect, rwrDisplayRange)).sqrMagnitude < Mathf.Pow(20, 2))
                    {
                        break;
                    }

                    if(!pingsData[i].exists && openIndex == -1)
                    {
                        openIndex = i;
                    }
                }

                if(openIndex >= 0)
                {
                    referenceTransform.rotation = Quaternion.LookRotation(vessel.ReferenceTransform.up, VectorUtils.GetUpDirection(transform.position));

                    pingsData[openIndex] = new TargetSignatureData(Vector3.zero, RadarUtils.WorldToRadar(source, referenceTransform, displayRect, rwrDisplayRange), Vector3.zero, true, (float)type);
                    pingWorldPositions[openIndex] = source;
                    StartCoroutine(PingLifeRoutine(openIndex, persistTime));

                    PlayWarningSound(type);
                }
            }
        }
Пример #38
0
        public override void OnStart(StartState state)
        {
            base.OnStart(state);

            if (HighLogic.LoadedSceneIsFlight)
            {
                myVesselID = vessel.id.ToString();
                RadarUtils.SetupResources();

                if (string.IsNullOrEmpty(radarName))
                {
                    radarName = part.partInfo.title;
                }

                linkedToVessels = new List <VesselRadarData>();

                signalPersistTime = omnidirectional
                    ? 360 / (scanRotationSpeed + 5)
                    : directionalFieldOfView / (scanRotationSpeed + 5);

                rwrType = (RadarWarningReceiver.RWRThreatTypes)rwrThreatType;
                if (rwrType == RadarWarningReceiver.RWRThreatTypes.Sonar)
                {
                    signalPersistTimeForRwr = RadarUtils.ACTIVE_MISSILE_PING_PERISTS_TIME;
                }
                else
                {
                    signalPersistTimeForRwr = signalPersistTime / 2;
                }

                if (rotationTransformName != string.Empty)
                {
                    rotationTransform = part.FindModelTransform(rotationTransformName);
                }

                attemptedLocks = new TargetSignatureData[3];
                TargetSignatureData.ResetTSDArray(ref attemptedLocks);
                lockedTargets = new List <TargetSignatureData>();

                referenceTransform               = (new GameObject()).transform;
                referenceTransform.parent        = transform;
                referenceTransform.localPosition = Vector3.zero;

                List <ModuleTurret> .Enumerator turr = part.FindModulesImplementing <ModuleTurret>().GetEnumerator();
                while (turr.MoveNext())
                {
                    if (turr.Current == null)
                    {
                        continue;
                    }
                    if (turr.Current.turretID != turretID)
                    {
                        continue;
                    }
                    lockingTurret = turr.Current;
                    break;
                }
                turr.Dispose();

                //GameEvents.onVesselGoOnRails.Add(OnGoOnRails);    //not needed
                EnsureVesselRadarData();
                StartCoroutine(StartUpRoutine());
            }
            else if (HighLogic.LoadedSceneIsEditor)
            {
                //Editor only:
                List <ModuleTurret> .Enumerator tur = part.FindModulesImplementing <ModuleTurret>().GetEnumerator();
                while (tur.MoveNext())
                {
                    if (tur.Current == null)
                    {
                        continue;
                    }
                    if (tur.Current.turretID != turretID)
                    {
                        continue;
                    }
                    lockingTurret = tur.Current;
                    break;
                }
                tur.Dispose();
                if (lockingTurret)
                {
                    lockingTurret.Fields["minPitch"].guiActiveEditor = false;
                    lockingTurret.Fields["maxPitch"].guiActiveEditor = false;
                    lockingTurret.Fields["yawRange"].guiActiveEditor = false;
                }
            }

            // check for not updated legacy part:
            if ((canScan && (radarMinDistanceDetect == float.MaxValue)) || (canLock && (radarMinDistanceLockTrack == float.MaxValue)))
            {
                Debug.Log("[BDArmory]: WARNING: " + part.name + " has legacy definition, missing new radarDetectionCurve and radarLockTrackCurve definitions! Please update for the part to be usable!");
            }
        }
Пример #39
0
        void UpdateRadarTarget()
        {
            targetAcquired = false;

            float angleToTarget = Vector3.Angle(radarTarget.position-transform.position,transform.forward);
            if(radarTarget.exists)
            {
                if((radarTarget.predictedPosition-transform.position).sqrMagnitude > Mathf.Pow(activeRadarRange, 2) || angleToTarget > maxOffBoresight*0.75f)
                {
                    if(radar
                        && radar.lockedTarget.exists
                        && (radarTarget.predictedPosition-radar.lockedTarget.predictedPosition).sqrMagnitude<Mathf.Pow(100,2)
                        && (radar.transform.position-transform.position).sqrMagnitude < Mathf.Pow(activeRadarRange,2))
                    {
                        targetAcquired = true;
                        radarTarget = radar.lockedTarget;
                        targetPosition = radarTarget.predictedPosition;
                        targetVelocity = radarTarget.velocity;
                        targetAcceleration = radarTarget.acceleration;
                        //radarTarget.signalStrength =
                        return;
                    }
                    else
                    {
                        Debug.Log ("Radar guidance failed. Out of range and no data feed.");
                        radarTarget = TargetSignatureData.noTarget;
                        legacyTargetVessel = null;
                        return;
                    }
                }
                else
                {
                    radar = null;

                    if(angleToTarget > maxOffBoresight)
                    {
                        Debug.Log ("Radar guidance failed.  Target is out of active seeker gimbal limits.");
                        radarTarget = TargetSignatureData.noTarget;
                        legacyTargetVessel = null;
                        return;
                    }
                    else
                    {
                        if(scannedTargets == null) scannedTargets = new TargetSignatureData[5];
                        TargetSignatureData.ResetTSDArray(ref scannedTargets);
                        Ray ray = new Ray(transform.position,radarTarget.predictedPosition-transform.position);
                        bool pingRWR = Time.time - lastRWRPing > 0.4f;
                        if(pingRWR) lastRWRPing = Time.time;
                        RadarUtils.ScanInDirection(ray, lockedSensorFOV, 100, ref scannedTargets, 0.4f, pingRWR, RadarWarningReceiver.RWRThreatTypes.MissileLock);
                        for(int i = 0; i < scannedTargets.Length; i++)
                        {
                            if(scannedTargets[i].exists && (scannedTargets[i].predictedPosition-radarTarget.predictedPosition).sqrMagnitude < Mathf.Pow(20,2))
                            {
                                radarTarget = scannedTargets[i];
                                targetAcquired = true;
                                targetPosition = radarTarget.predictedPosition + (radarTarget.velocity*Time.fixedDeltaTime);
                                targetVelocity = radarTarget.velocity;
                                targetAcceleration = radarTarget.acceleration;

                                if(!activeRadar)
                                {
                                    activeRadar = true;
                                    RadarWarningReceiver.PingRWR(ray, lockedSensorFOV, RadarWarningReceiver.RWRThreatTypes.MissileLaunch, 2f);
                                    Debug.Log ("Pitbull! Radar missile has gone active.  Radar sig strength: "+radarTarget.signalStrength.ToString("0.0"));
                                }
                                return;
                            }
                        }
                        radarTarget = TargetSignatureData.noTarget;

                    }
                }
            }

            if(!radarTarget.exists)
            {
                legacyTargetVessel = null;
            }
        }
Пример #40
0
        public void FireMissile()
        {
            if(!hasFired)
            {
                if(GetComponentInChildren<KSPParticleEmitter>())
                {
                    BDArmorySettings.numberOfParticleEmitters++;
                }

                foreach(var wpm in vessel.FindPartModulesImplementing<MissileFire>())
                {
                    team = wpm.team;
                    break;
                }

                sfAudioSource.PlayOneShot(GameDatabase.Instance.GetAudioClip("BDArmory/Sounds/deployClick"));

                sourceVessel = vessel;

                //TARGETING
                if(BDArmorySettings.ALLOW_LEGACY_TARGETING)
                {
                    if(vessel.targetObject!=null && vessel.targetObject.GetVessel()!=null)
                    {
                        legacyTargetVessel = vessel.targetObject.GetVessel();

                        if(targetingMode == TargetingModes.Heat)
                        {
                            heatTarget = new TargetSignatureData(legacyTargetVessel, 9999);
                        }
                    }
                }
                if(targetingMode == TargetingModes.Laser)
                {
                    laserStartPosition = transform.position;
                    laserStartDirection = transform.forward;
                    if(lockedCamera)
                    {
                        targetAcquired = true;
                        targetPosition = lastLaserPoint = lockedCamera.groundTargetPosition;
                    }
                }
                else if(targetingMode == TargetingModes.AntiRad && targetAcquired)
                {
                    RadarWarningReceiver.OnRadarPing += ReceiveRadarPing;
                }

                part.decouple(0);
                part.force_activate();
                part.Unpack();
                vessel.situation = Vessel.Situations.FLYING;
                rigidbody.isKinematic = false;
                BDArmorySettings.Instance.ApplyNewVesselRanges(vessel);
                part.bodyLiftMultiplier = 0;
                part.dragModel = Part.DragModel.NONE;

                //add target info to vessel
                if(legacyTargetVessel!=null && !vessel.gameObject.GetComponent<TargetInfo>())
                {
                    TargetInfo info = vessel.gameObject.AddComponent<TargetInfo>();
                    info.isMissile = true;
                    info.missileModule = this;

                    foreach(var mf in legacyTargetVessel.FindPartModulesImplementing<MissileFire>())
                    {
                        targetMf = mf;
                        break;
                    }
                }

                if(decoupleForward)
                {
                    part.rb.velocity += decoupleSpeed * part.transform.forward;
                }
                else
                {
                    part.rb.velocity += decoupleSpeed * -part.transform.up;
                }

                if(rndAngVel > 0)
                {
                    part.rb.angularVelocity += UnityEngine.Random.insideUnitSphere.normalized * rndAngVel;
                }

                vessel.vesselName = GetShortName();
                vessel.vesselType = VesselType.Probe;

                timeFired = Time.time;
                hasFired = true;

                previousRotation = transform.rotation;

                //setting ref transform for navball
                GameObject refObject = new GameObject();
                refObject.transform.rotation = Quaternion.LookRotation(-transform.up, transform.forward);
                refObject.transform.parent = transform;
                part.SetReferenceTransform(refObject.transform);
                vessel.SetReferenceTransform(part);

                MissileState = MissileStates.Drop;

                part.crashTolerance = 9999;

            }
        }
Пример #41
0
        public static void ScanInDirection(float directionAngle, Transform referenceTransform, float fov, Vector3 position, float minSignature, ref TargetSignatureData[] dataArray, float dataPersistTime, bool pingRWR, RadarWarningReceiver.RWRThreatTypes rwrType)
        {
            Vector3d geoPos = VectorUtils.WorldPositionToGeoCoords(position, FlightGlobals.currentMainBody);
            Vector3 forwardVector = referenceTransform.forward;
            Vector3 upVector = VectorUtils.GetUpDirection(position);
            Vector3 lookDirection = Quaternion.AngleAxis(directionAngle, upVector) * forwardVector;

            int dataIndex = 0;
            foreach(var vessel in FlightGlobals.Vessels)
            {
                if(vessel.loaded)
                {
                    if((vessel.transform.position-position).sqrMagnitude < 100) continue; //ignore self

                    if(TerrainCheck(referenceTransform.position, vessel.transform.position)) continue; //blocked by terrain

                    Vector3 vesselDirection = Vector3.ProjectOnPlane(vessel.CoM-position, upVector);

                    if(Vector3.Angle(vesselDirection,lookDirection) < fov/2)
                    {
                        float sig = GetModifiedSignature(vessel, position);

                        RadarWarningReceiver.PingRWR(vessel, position, rwrType, dataPersistTime);

                        if(sig > minSignature)
                        {
                            TargetInfo ti = vessel.GetComponent<TargetInfo>();
                            if(!ti)
                            {
                                vessel.gameObject.AddComponent<TargetInfo>();
                            }

                            while(dataIndex < dataArray.Length-1)
                            {
                                if((dataArray[dataIndex].exists && Time.time-dataArray[dataIndex].timeAcquired > dataPersistTime) || !dataArray[dataIndex].exists)
                                {
                                    break;
                                }
                                dataIndex++;
                            }
                            if(dataIndex >= dataArray.Length) break;
                            dataArray[dataIndex] = new TargetSignatureData(vessel, sig);
                            dataIndex++;
                            if(dataIndex >= dataArray.Length) break;
                        }
                    }
                }
            }
        }