public TargetSignatureData(Vessel v, float _signalStrength) { velocity = v.srf_velocity; geoPos = VectorUtils.WorldPositionToGeoCoords(v.CoM, v.mainBody); acceleration = v.acceleration; exists = true; timeAcquired = Time.time; signalStrength = _signalStrength; targetInfo = v.gameObject.GetComponent <TargetInfo> (); team = BDArmorySettings.BDATeams.None; if (targetInfo) { team = targetInfo.team; } else { foreach (var mf in v.FindPartModulesImplementing <MissileFire>()) { team = BDATargetManager.BoolToTeam(mf.team); break; } } vesselJammer = v.gameObject.GetComponent <VesselECMJInfo>(); pingPosition = Vector2.zero; }
public void ReleaseCommand() { Debug.Log(vessel.vesselName + " was released from command."); command = PilotCommands.Free; defaultOrbitCoords = VectorUtils.WorldPositionToGeoCoords(vesselTransform.position, vessel.mainBody); }
public static Vector3 GetNorthVector(Vector3 position, CelestialBody body) { Vector3 geoPosA = VectorUtils.WorldPositionToGeoCoords(position, body); Vector3 geoPosB = new Vector3(geoPosA.x + 1, geoPosA.y, geoPosA.z); Vector3 north = GetWorldSurfacePostion(geoPosB, body) - GetWorldSurfacePostion(geoPosA, body); return(Vector3.ProjectOnPlane(north, body.GetSurfaceNVector(geoPosA.x, geoPosA.y)).normalized); }
void GetHitPoint() { if (vessel.packed) { return; } if (delayedEnabling) { return; } RaycastHit rayHit; Ray ray = new Ray(cameraParentTransform.position + (50 * cameraParentTransform.forward), cameraParentTransform.forward); if (Physics.Raycast(ray, out rayHit, maxRayDistance - 50, 557057)) { targetPointPosition = rayHit.point; if (!surfaceDetected && groundStabilized && !gimbalLimitReached) { groundStabilized = true; groundTargetPosition = rayHit.point; if (CoMLock) { Part p = rayHit.collider.GetComponentInParent <Part>(); if (p && p.vessel && p.vessel.Landed) { groundTargetPosition = p.vessel.CoM; } } Vector3d newGTP = VectorUtils.WorldPositionToGeoCoords(groundTargetPosition, vessel.mainBody); if (newGTP != Vector3d.zero) { bodyRelativeGTP = newGTP; } } surfaceDetected = true; if (groundStabilized && !gimbalLimitReached && CMDropper.smokePool != null) { if (CMSmoke.RaycastSmoke(ray)) { surfaceDetected = false; } } } else { targetPointPosition = cameraParentTransform.position + (maxRayDistance * cameraParentTransform.forward); surfaceDetected = false; } }
void GroundStabilize() { if (vessel.packed) { return; } StopResetting(); RaycastHit rayHit; Ray ray = new Ray(cameraParentTransform.position + (50 * cameraParentTransform.forward), cameraParentTransform.forward); if (Physics.Raycast(ray, out rayHit, maxRayDistance - 50, 557057)) { groundStabilized = true; groundTargetPosition = rayHit.point; if (CoMLock) { Part p = rayHit.collider.GetComponentInParent <Part>(); if (p && p.vessel && p.vessel.CoM != Vector3.zero) { groundTargetPosition = p.vessel.CoM; StartCoroutine(StabilizeNextFrame()); } } Vector3d newGTP = VectorUtils.WorldPositionToGeoCoords(groundTargetPosition, vessel.mainBody); if (newGTP != Vector3d.zero) { bodyRelativeGTP = newGTP; } } else { Vector3 upDir = VectorUtils.GetUpDirection(transform.position); float altitude = (float)vessel.altitude; //MissileGuidance.GetRadarAltitude(vessel); Plane surfacePlane = new Plane(upDir, vessel.transform.position - (altitude * upDir)); float enter; if (surfacePlane.Raycast(ray, out enter)) { if (enter > 0) { groundStabilized = true; groundTargetPosition = ray.GetPoint(enter); Vector3d newGTP = VectorUtils.WorldPositionToGeoCoords(groundTargetPosition, vessel.mainBody); if (newGTP != Vector3d.zero) { bodyRelativeGTP = newGTP; } } } } }
public TargetSignatureData(CMFlare flare, float _signalStrength) { velocity = flare.velocity; geoPos = VectorUtils.WorldPositionToGeoCoords(flare.transform.position, FlightGlobals.currentMainBody); exists = true; acceleration = Vector3.zero; timeAcquired = Time.time; signalStrength = _signalStrength; targetInfo = null; vesselJammer = null; team = BDArmorySettings.BDATeams.None; pingPosition = Vector2.zero; }
public TargetSignatureData(Vector3 _velocity, Vector3 _position, Vector3 _acceleration, bool _exists, float _signalStrength) { velocity = _velocity; geoPos = VectorUtils.WorldPositionToGeoCoords(_position, FlightGlobals.currentMainBody); acceleration = _acceleration; exists = _exists; timeAcquired = Time.time; signalStrength = _signalStrength; targetInfo = null; vesselJammer = null; team = BDArmorySettings.BDATeams.None; pingPosition = Vector2.zero; }
protected void ReceiveRadarPing(Vessel v, Vector3 source, RadarWarningReceiver.RWRThreatTypes type, float persistTime) { if (TargetingMode == TargetingModes.AntiRad && TargetAcquired && v == vessel) { if ((source - VectorUtils.GetWorldSurfacePostion(targetGPSCoords, vessel.mainBody)).sqrMagnitude < Mathf.Pow(maxStaticLaunchRange / 4, 2) && //drastically increase update range for anti-radiation missile to track moving targets! Vector3.Angle(source - transform.position, GetForwardTransform()) < maxOffBoresight) { TargetAcquired = true; TargetPosition = source; targetGPSCoords = VectorUtils.WorldPositionToGeoCoords(TargetPosition, vessel.mainBody); TargetVelocity = Vector3.zero; TargetAcceleration = Vector3.zero; lockFailTimer = 0; } } }
public TargetSignatureData(Vessel v, float _signalStrength) { /* * if(v.situation == Vessel.Situations.SUB_ORBITAL || v.situation == Vessel.Situations.ESCAPING || v.situation == Vessel.Situations.SUB_ORBITAL) * { * velocity = v.obt_velocity; * orbit = v.orbit; * orbital = true; * } * else * { */ orbital = false; orbit = null; velocity = v.srf_velocity; //} vessel = v; geoPos = VectorUtils.WorldPositionToGeoCoords(v.CoM, v.mainBody); acceleration = v.acceleration; exists = true; timeAcquired = Time.time; signalStrength = _signalStrength; targetInfo = v.gameObject.GetComponent <TargetInfo> (); team = BDArmorySettings.BDATeams.None; if (targetInfo) { team = targetInfo.team; } else { foreach (var mf in v.FindPartModulesImplementing <MissileFire>()) { team = BDATargetManager.BoolToTeam(mf.team); break; } } vesselJammer = v.gameObject.GetComponent <VesselECMJInfo>(); pingPosition = Vector2.zero; lockedByRadar = null; }
IEnumerator LifeRoutine() { geoPos = VectorUtils.WorldPositionToGeoCoords(transform.position, body); pe.EmitParticle(); float startTime = Time.time; while (Time.time - startTime < pe.maxEnergy) { transform.position = body.GetWorldSurfacePosition(geoPos.x, geoPos.y, geoPos.z); velocity += FlightGlobals.getGeeForceAtPosition(transform.position) * Time.fixedDeltaTime; Vector3 dragForce = (0.008f) * drag * 0.5f * velocity.sqrMagnitude * (float)FlightGlobals.getAtmDensity(FlightGlobals.getStaticPressure(transform.position), FlightGlobals.getExternalTemperature(), body) * velocity.normalized; velocity -= (dragForce) * Time.fixedDeltaTime; transform.position += velocity * Time.fixedDeltaTime; geoPos = VectorUtils.WorldPositionToGeoCoords(transform.position, body); yield return(new WaitForFixedUpdate()); } gameObject.SetActive(false); }
public void ActivatePilot() { pilotEnabled = true; vessel.OnFlyByWire -= AutoPilot; vessel.OnFlyByWire += AutoPilot; startedLanded = vessel.Landed; if (!speedController) { speedController = gameObject.AddComponent <BDAirspeedControl>(); speedController.vessel = vessel; } speedController.Activate(); GameEvents.onVesselDestroy.Remove(RemoveAutopilot); GameEvents.onVesselDestroy.Add(RemoveAutopilot); defaultOrbitCoords = VectorUtils.WorldPositionToGeoCoords(vessel.ReferenceTransform.position, vessel.mainBody); RefreshPartWindow(); }
void TakeOff(FlightCtrlState s) { threatLevel = 1; debugString += "\nTaking off/Gaining altitude"; if (vessel.Landed && vessel.srfSpeed < takeOffSpeed) { defaultOrbitCoords = VectorUtils.WorldPositionToGeoCoords(vessel.transform.position, vessel.mainBody); return; } steerMode = SteerModes.Aiming; float radarAlt = MissileGuidance.GetRadarAltitude(vessel); Vector3 forwardPoint = vessel.transform.position + Vector3.ProjectOnPlane(vesselTransform.up * 100, upDirection); float terrainDiff = MissileGuidance.GetRaycastRadarAltitude(forwardPoint) - radarAlt; terrainDiff = Mathf.Max(terrainDiff, 0); float rise = Mathf.Clamp((float)vessel.srfSpeed * 0.3f, 5, 100); if (radarAlt > 70) { vessel.ActionGroups.SetGroup(KSPActionGroup.Gear, false); } else { vessel.ActionGroups.SetGroup(KSPActionGroup.Gear, true); } FlyToPosition(s, forwardPoint + (upDirection * (rise + terrainDiff))); if (radarAlt > minAltitude) { startedLanded = false; } }
IEnumerator DogfightCompetitionModeRoutine(float distance) { competitionStarting = true; competitionStatus = "Competition: Pilots are taking off."; Dictionary <BDArmorySettings.BDATeams, List <BDModulePilotAI> > pilots = new Dictionary <BDArmorySettings.BDATeams, List <BDModulePilotAI> >(); pilots.Add(BDArmorySettings.BDATeams.A, new List <BDModulePilotAI>()); pilots.Add(BDArmorySettings.BDATeams.B, new List <BDModulePilotAI>()); foreach (var v in BDATargetManager.LoadedVessels) { if (!v || !v.loaded) { continue; } BDModulePilotAI pilot = null; foreach (var p in v.FindPartModulesImplementing <BDModulePilotAI>()) { pilot = p; break; } if (!pilot || !pilot.weaponManager) { continue; } pilots[BDATargetManager.BoolToTeam(pilot.weaponManager.team)].Add(pilot); pilot.ActivatePilot(); pilot.standbyMode = false; if (pilot.weaponManager.guardMode) { pilot.weaponManager.ToggleGuardMode(); } } //clear target database so pilots don't attack yet BDATargetManager.ClearDatabase(); if (pilots[BDArmorySettings.BDATeams.A].Count == 0 || pilots[BDArmorySettings.BDATeams.B].Count == 0) { Debug.Log("Unable to start competition mode - one or more teams is empty"); competitionStatus = "Competition: Failed! One or more teams is empty."; yield return(new WaitForSeconds(2)); competitionStarting = false; yield break; } BDModulePilotAI aLeader = pilots[BDArmorySettings.BDATeams.A][0]; BDModulePilotAI bLeader = pilots[BDArmorySettings.BDATeams.B][0]; aLeader.weaponManager.wingCommander.CommandAllFollow(); bLeader.weaponManager.wingCommander.CommandAllFollow(); //wait till the leaders are airborne while (aLeader && bLeader && (aLeader.vessel.LandedOrSplashed || bLeader.vessel.LandedOrSplashed)) { yield return(null); } if (!aLeader || !bLeader) { StopCompetition(); } competitionStatus = "Competition: Sending pilots to start position."; Vector3 aDirection = Vector3.ProjectOnPlane(aLeader.vessel.CoM - bLeader.vessel.CoM, aLeader.vessel.upAxis).normalized; Vector3 bDirection = Vector3.ProjectOnPlane(bLeader.vessel.CoM - aLeader.vessel.CoM, bLeader.vessel.upAxis).normalized; Vector3 center = (aLeader.vessel.CoM + bLeader.vessel.CoM) / 2f; Vector3 aDestination = center + (aDirection * (distance + 1250f)); Vector3 bDestination = center + (bDirection * (distance + 1250f)); aDestination = VectorUtils.WorldPositionToGeoCoords(aDestination, FlightGlobals.currentMainBody); bDestination = VectorUtils.WorldPositionToGeoCoords(bDestination, FlightGlobals.currentMainBody); aLeader.CommandFlyTo(aDestination); bLeader.CommandFlyTo(bDestination); Vector3 centerGPS = VectorUtils.WorldPositionToGeoCoords(center, FlightGlobals.currentMainBody); //wait till everyone is in position bool waiting = true; while (waiting) { waiting = false; if (!aLeader || !bLeader) { StopCompetition(); } if (Vector3.Distance(aLeader.transform.position, bLeader.transform.position) < distance * 1.95f) { waiting = true; } else { foreach (var t in pilots.Keys) { foreach (var p in pilots[t]) { if (p.currentCommand == BDModulePilotAI.PilotCommands.Follow && Vector3.Distance(p.vessel.CoM, p.commandLeader.vessel.CoM) > 1000f) { competitionStatus = "Competition: Waiting for teams to get in position."; waiting = true; } } } } yield return(null); } //start the match foreach (var t in pilots.Keys) { foreach (var p in pilots[t]) { if (!p) { continue; } //enable guard mode if (!p.weaponManager.guardMode) { p.weaponManager.ToggleGuardMode(); } //report all vessels if (BDATargetManager.BoolToTeam(p.weaponManager.team) == BDArmorySettings.BDATeams.B) { BDATargetManager.ReportVessel(p.vessel, aLeader.weaponManager); } else { BDATargetManager.ReportVessel(p.vessel, bLeader.weaponManager); } //release command p.ReleaseCommand(); p.defaultOrbitCoords = centerGPS; } } competitionStatus = "Competition starting! Good luck!"; yield return(new WaitForSeconds(2)); competitionStarting = false; }
IEnumerator CommandPosition(BDModulePilotAI wingman, BDModulePilotAI.PilotCommands command) { if (focusIndexes.Count == 0 && !commandSelf) { yield break; } DisplayScreenMessage("Select target coordinates.\nRight-click to cancel."); if (command == BDModulePilotAI.PilotCommands.FlyTo) { waitingForFlytoPos = true; } else if (command == BDModulePilotAI.PilotCommands.Attack) { waitingForAttackPos = true; } yield return(null); bool waitingForPos = true; drawMouseDiamond = true; while (waitingForPos) { if (Input.GetMouseButtonDown(1)) { break; } if (Input.GetMouseButtonDown(0)) { Vector3 mousePos = new Vector3(Input.mousePosition.x / Screen.width, Input.mousePosition.y / Screen.height, 0); Plane surfPlane = new Plane(vessel.upAxis, vessel.transform.position - (vessel.altitude * vessel.upAxis)); Ray ray = FlightCamera.fetch.mainCamera.ViewportPointToRay(mousePos); float dist; if (surfPlane.Raycast(ray, out dist)) { Vector3 worldPoint = ray.GetPoint(dist); Vector3d gps = VectorUtils.WorldPositionToGeoCoords(worldPoint, vessel.mainBody); if (command == BDModulePilotAI.PilotCommands.FlyTo) { wingman.CommandFlyTo(gps); } else if (command == BDModulePilotAI.PilotCommands.Attack) { wingman.CommandAttack(gps); } StartCoroutine(CommandPositionGUIRoutine(wingman, new GPSTargetInfo(gps, command.ToString()))); } break; } yield return(null); } waitingForAttackPos = false; waitingForFlytoPos = false; drawMouseDiamond = false; ScreenMessages.RemoveMessage(screenMessage); }
public static void ScanInDirection(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; } } } } }
/// <summary> /// Scans for targets in direction with field of view. /// Returns the direction scanned for debug /// </summary> /// <returns>The scan direction.</returns> /// <param name="myWpnManager">My wpn manager.</param> /// <param name="directionAngle">Direction angle.</param> /// <param name="referenceTransform">Reference transform.</param> /// <param name="fov">Fov.</param> /// <param name="results">Results.</param> /// <param name="maxDistance">Max distance.</param> public static Vector3 GuardScanInDirection(MissileFire myWpnManager, float directionAngle, Transform referenceTransform, float fov, out ViewScanResults results, float maxDistance) { results = new ViewScanResults(); results.foundMissile = false; results.foundHeatMissile = false; results.foundAGM = false; results.firingAtMe = false; if (!myWpnManager || !referenceTransform) { return(Vector3.zero); } Vector3 position = referenceTransform.position; Vector3d geoPos = VectorUtils.WorldPositionToGeoCoords(position, FlightGlobals.currentMainBody); Vector3 forwardVector = referenceTransform.forward; Vector3 upVector = referenceTransform.up; Vector3 lookDirection = Quaternion.AngleAxis(directionAngle, upVector) * forwardVector; foreach (var vessel in BDATargetManager.LoadedVessels) { if (vessel == null) { continue; } if (vessel.loaded) { if (vessel == myWpnManager.vessel) { continue; //ignore self } Vector3 vesselProjectedDirection = Vector3.ProjectOnPlane(vessel.transform.position - position, upVector); Vector3 vesselDirection = vessel.transform.position - position; if (Vector3.Dot(vesselDirection, lookDirection) < 0) { continue; } float vesselDistance = (vessel.transform.position - position).magnitude; if (vesselDistance < maxDistance && Vector3.Angle(vesselProjectedDirection, lookDirection) < fov / 2 && Vector3.Angle(vessel.transform.position - position, -myWpnManager.transform.forward) < myWpnManager.guardAngle / 2) { //Debug.Log("Found vessel: " + vessel.vesselName); if (TerrainCheck(referenceTransform.position, vessel.transform.position)) { continue; //blocked by terrain } BDATargetManager.ReportVessel(vessel, myWpnManager); TargetInfo tInfo; if ((tInfo = vessel.GetComponent <TargetInfo>())) { if (tInfo.isMissile) { MissileLauncher missile; if (missile = tInfo.missileModule) { results.foundMissile = true; if (missile.hasFired && (missile.targetPosition - (myWpnManager.vessel.CoM + (myWpnManager.vessel.rb_velocity * Time.fixedDeltaTime))).sqrMagnitude < 3600) { //Debug.Log("found missile targeting me"); if (missile.targetingMode == MissileLauncher.TargetingModes.Heat) { results.foundHeatMissile = true; break; } else if (missile.targetingMode == MissileLauncher.TargetingModes.Laser) { results.foundAGM = true; break; } } else { break; } } } else { //check if its shooting guns at me if (!results.firingAtMe) { foreach (var weapon in vessel.FindPartModulesImplementing <ModuleWeapon>()) { if (!weapon.isFiring) { continue; } if (Vector3.Dot(weapon.fireTransforms[0].forward, vesselDirection) > 0) { continue; } if (Vector3.Angle(weapon.fireTransforms[0].forward, -vesselDirection) < 6500 / vesselDistance) { results.firingAtMe = true; } } } } } } } } return(lookDirection); }
public static void UpdateRadarLock(MissileFire myWpnManager, float directionAngle, Transform referenceTransform, float fov, Vector3 position, float minSignature, ModuleRadar radar, 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; 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, radar.signalPersistTime); 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); } //radar.vesselRadarData.AddRadarContact(radar, new TargetSignatureData(vessel, detectSig), false); radar.ReceiveContactData(new TargetSignatureData(vessel, detectSig), false); } } } }
/// <summary> /// Scans for targets in direction with field of view. /// Returns the direction scanned for debug /// </summary> /// <returns>The scan direction.</returns> /// <param name="myWpnManager">My wpn manager.</param> /// <param name="directionAngle">Direction angle.</param> /// <param name="referenceTransform">Reference transform.</param> /// <param name="fov">Fov.</param> /// <param name="results">Results.</param> /// <param name="maxDistance">Max distance.</param> public static Vector3 GuardScanInDirection(MissileFire myWpnManager, float directionAngle, Transform referenceTransform, float fov, out ViewScanResults results, float maxDistance) { fov *= 1.1f; results = new ViewScanResults(); results.foundMissile = false; results.foundHeatMissile = false; results.foundRadarMissile = false; results.foundAGM = false; results.firingAtMe = false; results.missileThreatDistance = float.MaxValue; results.threatVessel = null; results.threatWeaponManager = null; if (!myWpnManager || !referenceTransform) { return(Vector3.zero); } Vector3 position = referenceTransform.position; Vector3d geoPos = VectorUtils.WorldPositionToGeoCoords(position, FlightGlobals.currentMainBody); Vector3 forwardVector = referenceTransform.forward; Vector3 upVector = referenceTransform.up; Vector3 lookDirection = Quaternion.AngleAxis(directionAngle, upVector) * forwardVector; foreach (var vessel in BDATargetManager.LoadedVessels) { if (vessel == null) { continue; } if (vessel.loaded) { if (vessel == myWpnManager.vessel) { continue; //ignore self } Vector3 vesselProjectedDirection = Vector3.ProjectOnPlane(vessel.transform.position - position, upVector); Vector3 vesselDirection = vessel.transform.position - position; if (Vector3.Dot(vesselDirection, lookDirection) < 0) { continue; } float vesselDistance = (vessel.transform.position - position).magnitude; if (vesselDistance < maxDistance && Vector3.Angle(vesselProjectedDirection, lookDirection) < fov / 2 && Vector3.Angle(vessel.transform.position - position, -myWpnManager.transform.forward) < myWpnManager.guardAngle / 2) { //Debug.Log("Found vessel: " + vessel.vesselName); if (TerrainCheck(referenceTransform.position, vessel.transform.position)) { continue; //blocked by terrain } BDATargetManager.ReportVessel(vessel, myWpnManager); TargetInfo tInfo; if ((tInfo = vessel.GetComponent <TargetInfo>())) { if (tInfo.isMissile) { MissileLauncher missile; if (missile = tInfo.missileModule) { results.foundMissile = true; results.threatVessel = missile.vessel; Vector3 vectorFromMissile = myWpnManager.vessel.CoM - missile.part.transform.position; Vector3 relV = missile.vessel.srf_velocity - myWpnManager.vessel.srf_velocity; bool approaching = Vector3.Dot(relV, vectorFromMissile) > 0; if (missile.hasFired && missile.timeIndex > 1 && approaching && (missile.targetPosition - (myWpnManager.vessel.CoM + (myWpnManager.vessel.rb_velocity * Time.fixedDeltaTime))).sqrMagnitude < 3600) { if (missile.targetingMode == MissileLauncher.TargetingModes.Heat) { results.foundHeatMissile = true; results.missileThreatDistance = Mathf.Min(results.missileThreatDistance, Vector3.Distance(missile.part.transform.position, myWpnManager.part.transform.position)); results.threatPosition = missile.transform.position; break; } else if (missile.targetingMode == MissileLauncher.TargetingModes.Radar) { results.foundRadarMissile = true; results.missileThreatDistance = Mathf.Min(results.missileThreatDistance, Vector3.Distance(missile.part.transform.position, myWpnManager.part.transform.position)); results.threatPosition = missile.transform.position; } else if (missile.targetingMode == MissileLauncher.TargetingModes.Laser) { results.foundAGM = true; results.missileThreatDistance = Mathf.Min(results.missileThreatDistance, Vector3.Distance(missile.part.transform.position, myWpnManager.part.transform.position)); break; } } else { break; } } } else { //check if its shooting guns at me //if(!results.firingAtMe) //more work, but we can't afford to be incorrect picking the closest threat //{ foreach (var weapon in vessel.FindPartModulesImplementing <ModuleWeapon>()) { if (!weapon.recentlyFiring) { continue; } if (Vector3.Dot(weapon.fireTransforms[0].forward, vesselDirection) > 0) { continue; } if (Vector3.Angle(weapon.fireTransforms[0].forward, -vesselDirection) < 6500 / vesselDistance && (!results.firingAtMe || (weapon.vessel.ReferenceTransform.position - position).magnitude < (results.threatPosition - position).magnitude)) { results.firingAtMe = true; results.threatPosition = weapon.vessel.transform.position; results.threatVessel = weapon.vessel; results.threatWeaponManager = weapon.weaponManager; break; } } //} } } } } } return(lookDirection); }