public override void OnStart(StartState state) { if (state != StartState.Editor) { foreach (var wm in vessel.FindPartModulesImplementing<MissileFire>()) //make sure a weapons manager exists on the vessel after launch { weaponManager = wm; } } }
public static List<TargetInfo> GetAllTargetsExcluding(List<TargetInfo> excluding, MissileFire mf) { List<TargetInfo> finalTargets = new List<TargetInfo>(); BDArmorySettings.BDATeams team = BoolToTeam(mf.team); foreach(var target in TargetDatabase[team]) { if(target && target.Vessel && mf.CanSeeTarget(target.Vessel) && !excluding.Contains(target)) { finalTargets.Add(target); } } return finalTargets; }
public static TargetInfo GetAirToAirTarget(MissileFire mf) { BDArmorySettings.BDATeams team = mf.team ? BDArmorySettings.BDATeams.B : BDArmorySettings.BDATeams.A; TargetInfo finalTarget = null; foreach(var target in TargetDatabase[team]) { if(target && target.Vessel && !target.isLanded && !target.isMissile) { if(finalTarget == null || target.numFriendliesEngaging < finalTarget.numFriendliesEngaging) { finalTarget = target; } } } return finalTarget; }
public static TargetInfo GetClosestMissileTarget(MissileFire mf) { BDArmorySettings.BDATeams team = BoolToTeam(mf.team); TargetInfo finalTarget = null; foreach(var target in TargetDatabase[team]) { if(target && target.Vessel && mf.CanSeeTarget(target.Vessel) && target.isMissile) { bool isHostile = false; if(target.missileModule && target.missileModule.targetMf && target.missileModule.targetMf.team == mf.team) { isHostile = true; } if(isHostile && (finalTarget == null || target.IsCloser(finalTarget, mf))) { finalTarget = target; } } } return finalTarget; }
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; } } } }
public static void ReportVessel(Vessel v, MissileFire reporter) { if(!v) return; if(!reporter) return; TargetInfo info = v.gameObject.GetComponent<TargetInfo>(); if(!info) { foreach(var mf in v.FindPartModulesImplementing<MissileFire>()) { if(mf.team != reporter.team) { info = v.gameObject.AddComponent<TargetInfo>(); } return; } foreach(var ml in v.FindPartModulesImplementing<MissileLauncher>()) { if(ml.hasFired) { if(ml.team != reporter.team) { info = v.gameObject.AddComponent<TargetInfo>(); } } return; } } }
void GetWeaponManager() { foreach(var mf in FlightGlobals.ActiveVessel.FindPartModulesImplementing<MissileFire>()) { ActiveWeaponManager = mf; return; } ActiveWeaponManager = null; return; }
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; } }
public static TargetInfo GetUnengagedMissileTarget(MissileFire mf) { BDArmorySettings.BDATeams team = mf.team ? BDArmorySettings.BDATeams.B : BDArmorySettings.BDATeams.A; foreach(var target in TargetDatabase[team]) { if(target && target.Vessel && mf.CanSeeTarget(target.Vessel) && target.isMissile) { bool isHostile = false; if(target.isThreat) { isHostile = true; } if(isHostile && target.numFriendliesEngaging == 0) { return target; } } } return null; }
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); } } } }
IEnumerator StartupRoutine() { while(vessel.packed) { yield return null; } weaponManager = part.FindModuleImplementing<MissileFire>(); RefreshFriendlies(); RefreshWingmen(); LoadWingmen(); }
void Start() { if(HighLogic.LoadedSceneIsFlight) { part.OnJustAboutToBeDestroyed += DeactivatePilot; vessel.OnJustAboutToBeDestroyed += DeactivatePilot; MissileFire.OnToggleTeam += OnToggleTeam; vesselTransform = vessel.ReferenceTransform; foreach(var wm in vessel.FindPartModulesImplementing<MissileFire>()) { weaponManager = wm; break; } if(pilotEnabled) { ActivatePilot(); } maxAllowedCosAoA = (float)Math.Cos(maxAllowedAoA * Math.PI / 180.0); lastAllowedAoA = maxAllowedAoA; } RefreshPartWindow(); }
public static void ReportVessel(Vessel v, MissileFire reporter) { if(!v) return; TargetInfo info = v.gameObject.GetComponent<TargetInfo>(); if(!info) { TargetInfo newInfo = v.gameObject.AddComponent<TargetInfo>(); newInfo.Vessel = v; info = newInfo; } BDArmorySettings.BDATeams team = BoolToTeam(reporter.team); if(info && !TargetDatabase[team].Contains(info)) { TargetDatabase[team].Add(info); } }
public bool IsCloser(TargetInfo otherTarget, MissileFire myMf) { float thisSqrDist = (position-myMf.transform.position).sqrMagnitude; float otherSqrDist = (otherTarget.position-myMf.transform.position).sqrMagnitude; return thisSqrDist < otherSqrDist; }
void Awake() { if(!vessel) { vessel = GetComponent<Vessel>(); } if(!vessel) { Debug.Log ("TargetInfo was added to a non-vessel"); Destroy (this); return; } //destroy this if a target info is already attached to the vessel foreach(var otherInfo in vessel.gameObject.GetComponents<TargetInfo>()) { if(otherInfo != this) { Destroy(this); return; } } team = BDArmorySettings.BDATeams.None; bool foundMf = false; foreach(var mf in vessel.FindPartModulesImplementing<MissileFire>()) { foundMf = true; team = BDATargetManager.BoolToTeam(mf.team); weaponManager = mf; break; } if(!foundMf) { foreach(var ml in vessel.FindPartModulesImplementing<MissileLauncher>()) { isMissile = true; missileModule = ml; team = BDATargetManager.BoolToTeam(ml.team); break; } } if(team != BDArmorySettings.BDATeams.None) { if(!BDATargetManager.TargetDatabase[BDATargetManager.OtherTeam(team)].Contains(this)) { BDATargetManager.TargetDatabase[BDATargetManager.OtherTeam(team)].Add(this); } } friendliesEngaging = new List<MissileFire>(); vessel.OnJustAboutToBeDestroyed += AboutToBeDestroyed; lifeRoutine = StartCoroutine(LifetimeRoutine()); //add delegate to peace enable event BDArmorySettings.OnPeaceEnabled += OnPeaceEnabled; if(!isMissile && team != BDArmorySettings.BDATeams.None) { massRoutine = StartCoroutine(MassRoutine()); } }
public void Disengage(MissileFire mf) { friendliesEngaging.Remove(mf); }
public void Engage(MissileFire mf) { /* if(!hasStarted) { Start(); } */ if(!friendliesEngaging.Contains(mf)) { friendliesEngaging.Add(mf); } }
public override void OnFixedUpdate() { debugString = ""; if(hasFired && !hasExploded && part!=null) { part.rb.isKinematic = false; AntiSpin(); //deploy stuff if(deployAnimationName != "" && timeIndex > deployTime && !deployed) { deployed = true; deployedTime = Time.time; } if(deployed) { foreach(var anim in deployStates) { anim.speed = 1; part.maximum_drag = deployedDrag; part.minimum_drag = deployedDrag; } } //simpleDrag if(useSimpleDrag) { SimpleDrag(); } //flybyaudio float mCamDistanceSqr = (FlightCamera.fetch.mainCamera.transform.position-transform.position).sqrMagnitude; float mCamRelVSqr = (float)(FlightGlobals.ActiveVessel.srf_velocity-vessel.srf_velocity).sqrMagnitude; if(!hasPlayedFlyby && FlightGlobals.ActiveVessel != vessel && FlightGlobals.ActiveVessel != sourceVessel && mCamDistanceSqr < 400*400 && mCamRelVSqr > 300*300 && mCamRelVSqr < 800*800 && Vector3.Angle(vessel.srf_velocity, FlightGlobals.ActiveVessel.transform.position-transform.position)<60) { sfAudioSource.PlayOneShot (GameDatabase.Instance.GetAudioClip("BDArmory/Sounds/missileFlyby")); hasPlayedFlyby = true; } if(vessel.isActiveVessel) { audioSource.dopplerLevel = 0; } else { audioSource.dopplerLevel = 1f; } if(BDArmorySettings.ALLOW_LEGACY_TARGETING && legacyTargetVessel) { UpdateLegacyTarget(); } if(targetingMode == TargetingModes.Heat) { UpdateHeatTarget(); } else if(targetingMode == TargetingModes.Radar) { UpdateRadarTarget(); } else if(targetingMode == TargetingModes.Laser) { UpdateLaserTarget(); } else if(targetingMode == TargetingModes.GPS) { UpdateGPSTarget(); } else if(targetingMode == TargetingModes.AntiRad) { UpdateAntiRadiationTarget(); } //Missile State timeIndex = Time.time - timeFired; if(timeIndex < dropTime) { MissileState = MissileStates.Drop; } else if(timeIndex < dropTime + boostTime) { MissileState = MissileStates.Boost; } else if(timeIndex < dropTime+boostTime+cruiseTime) { MissileState = MissileStates.Cruise; } else { MissileState = MissileStates.PostThrust; } if(timeIndex > 0.5f) { part.crashTolerance = 1; } if(MissileState == MissileStates.Drop) //drop phase { } else if(MissileState == MissileStates.Boost) //boost phase { //light, sound & particle fx if(boostAudio||thrustAudio) { if(!PauseMenu.isOpen) { if(!audioSource.isPlaying) { if(boostAudio) { audioSource.clip = boostAudio; } else if(thrustAudio) { audioSource.clip = thrustAudio; } audioSource.Play(); } } else if(audioSource.isPlaying) { audioSource.Stop(); } } foreach(Light light in gameObject.GetComponentsInChildren<Light>()) { light.intensity = 1.5f; } if(spoolEngine) { currentThrust = Mathf.MoveTowards(currentThrust, thrust, thrust/10); } else { currentThrust = thrust; } if(boostTransformName != string.Empty) { foreach(var emitter in boostEmitters) { emitter.emit = true; } } part.rb.AddRelativeForce(currentThrust * Vector3.forward); if(hasRCS) forwardRCS.emit = true; if(!startedEngine && thrust > 0) { startedEngine = true; sfAudioSource.PlayOneShot(GameDatabase.Instance.GetAudioClip("BDArmory/Sounds/launch")); } } else if(MissileState == MissileStates.Cruise) //cruise phase { part.crashTolerance = 1; if(thrustAudio) { if(!PauseMenu.isOpen) { if(!audioSource.isPlaying || audioSource.clip!=thrustAudio) { audioSource.clip = thrustAudio; audioSource.Play(); } } else if(audioSource.isPlaying) { audioSource.Stop(); } } if(spoolEngine) { currentThrust = Mathf.MoveTowards(currentThrust, cruiseThrust, thrust/10); } else { currentThrust = cruiseThrust; } if(!hasRCS) { part.rb.AddRelativeForce(cruiseThrust * Vector3.forward); } else { forwardRCS.emit = false; audioSource.Stop(); } if(boostTransformName != string.Empty) { foreach(var emitter in boostEmitters) { if(!emitter) continue; emitter.emit = false; } } if(decoupleBoosters && !hasDecoupledBoosters) { hasDecoupledBoosters = true; part.mass -= boosterMass; foreach(var booster in boosters) { if(!booster) continue; (booster.AddComponent<DecoupledBooster>()).DecoupleBooster(part.rb.velocity, boosterDecoupleSpeed); } } } if(MissileState != MissileStates.Idle && MissileState != MissileStates.PostThrust && MissileState != MissileStates.Drop) //all thrust { if(!hasRCS) { foreach(KSPParticleEmitter pe in pEmitters) { pe.emit = true; } foreach(var gpe in gaplessEmitters) { if(vessel.atmDensity > 0) { gpe.emit = true; gpe.pEmitter.worldVelocity = 2*ParticleTurbulence.Turbulence; } else { gpe.emit = false; } } } foreach(KSPParticleEmitter pe in pEmitters) { if(!pe.gameObject.name.Contains("rcs") && !pe.useWorldSpace) { pe.sizeGrow = Mathf.Lerp(pe.sizeGrow, 1, 0.4f); } } } else { if(thrustAudio && audioSource.isPlaying) { audioSource.volume = Mathf.Lerp(audioSource.volume, 0, 0.1f); audioSource.pitch = Mathf.Lerp(audioSource.pitch, 0, 0.1f); } foreach(Light light in gameObject.GetComponentsInChildren<Light>()) { light.intensity = 0; } } if(timeIndex > dropTime + boostTime + cruiseTime && !hasRCS) { foreach(KSPParticleEmitter pe in pEmitters) { pe.maxEmission = Mathf.FloorToInt(pe.maxEmission * 0.8f); pe.minEmission = Mathf.FloorToInt(pe.minEmission * 0.8f); } foreach(var gpe in gaplessEmitters) { gpe.pEmitter.maxSize = Mathf.MoveTowards(gpe.pEmitter.maxSize, 0, 0.005f); gpe.pEmitter.minSize = Mathf.MoveTowards(gpe.pEmitter.minSize, 0, 0.008f); gpe.pEmitter.worldVelocity = 2*ParticleTurbulence.Turbulence; } } if(MissileState != MissileStates.Idle && MissileState != MissileStates.Drop) //guidance { //guidance and attitude stabilisation scales to atmospheric density. //use part.atmDensity float atmosMultiplier = Mathf.Clamp01 (2.5f*(float)FlightGlobals.getAtmDensity(FlightGlobals.getStaticPressure(transform.position), FlightGlobals.getExternalTemperature(), FlightGlobals.currentMainBody)); if(vessel.srfSpeed < optimumAirspeed) { float optimumSpeedFactor = (float)vessel.srfSpeed / (2 * optimumAirspeed); controlAuthority = Mathf.Clamp01(atmosMultiplier * (-Mathf.Abs(2 * optimumSpeedFactor - 1) + 1)); } else { controlAuthority = Mathf.Clamp01(atmosMultiplier); } debugString += "\ncontrolAuthority: "+controlAuthority; if(guidanceActive)// && timeIndex - dropTime > 0.5f) { WarnTarget(); Vector3 targetPosition = Vector3.zero; if(legacyTargetVessel && legacyTargetVessel.loaded) { Vector3 targetCoMPos = legacyTargetVessel.findWorldCenterOfMass(); targetPosition = targetCoMPos+legacyTargetVessel.rb_velocity*Time.fixedDeltaTime; } //increaseTurnRate after launch float turnRateDPS = Mathf.Clamp(((timeIndex-dropTime)/boostTime)*maxTurnRateDPS * 25f, 0, maxTurnRateDPS); float turnRatePointDPS = turnRateDPS; if(!hasRCS) { turnRateDPS *= controlAuthority; } //decrease turn rate after thrust cuts out if(timeIndex > dropTime+boostTime+cruiseTime) { turnRateDPS = atmosMultiplier * Mathf.Clamp(maxTurnRateDPS - ((timeIndex-dropTime-boostTime-cruiseTime)*0.45f), 1, maxTurnRateDPS); if(hasRCS) { turnRateDPS = 0; } } if(hasRCS) { if(turnRateDPS > 0) { DoRCS(); } else { KillRCS(); } } debugTurnRate = turnRateDPS; float radiansDelta = turnRateDPS*Mathf.Deg2Rad*Time.fixedDeltaTime; finalMaxTorque = Mathf.Clamp((timeIndex-dropTime)*30, 0, maxTorque); //ramp up torque if(guidanceMode == GuidanceModes.AAMLead) { AAMGuidance(); } else if(guidanceMode == GuidanceModes.AGM) { AGMGuidance(); } else if(guidanceMode == GuidanceModes.AGMBallistic) { AGMBallisticGuidance(); } else if(guidanceMode == GuidanceModes.RCS) { if(legacyTargetVessel!=null) { transform.rotation = Quaternion.RotateTowards(transform.rotation, Quaternion.LookRotation(targetPosition-transform.position, transform.up), turnRateDPS*Time.fixedDeltaTime); } } else if(guidanceMode == GuidanceModes.Cruise) { CruiseGuidance(); } } else { targetMf = null; if(!aero) { if(!hasRCS && !useSimpleDrag) { transform.rotation = Quaternion.RotateTowards(transform.rotation, Quaternion.LookRotation(vessel.srf_velocity, transform.up), atmosMultiplier * (0.5f*(timeIndex-dropTime)) * 50*Time.fixedDeltaTime); } } else { aeroTorque = MissileGuidance.DoAeroForces(this, transform.position + 20*vessel.srf_velocity, liftArea, .25f, aeroTorque, maxTorque, maxAoA); } } if(hasRCS && !guidanceActive) { KillRCS(); } } //Timed detonation if(isTimed && timeIndex > detonationTime) { Detonate(); } } }
public void EnableRadar() { EnsureVesselRadarData(); radarEnabled = true; foreach(var mf in vessel.FindPartModulesImplementing<MissileFire>()) { weaponManager = mf; if(vesselRadarData) { vesselRadarData.weaponManager = mf; } break; } UpdateToggleGuiName(); vesselRadarData.AddRadar(this); }
void OnToggleTeam(MissileFire wm, BDArmorySettings.BDATeams team) { if(!weaponManager || !wm) return; if(team != BDATargetManager.BoolToTeam(weaponManager.team)) { if(wm.vesselRadarData) { UnlinkVRD(wm.vesselRadarData); } } else if(wm.vessel == vessel) { UnlinkAllExternalRadars(); } RemoveDisconnectedRadars(); }
/// <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; 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; 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) { //Debug.Log("found missile targeting me"); 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) { 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; results.threatPosition = weapon.vessel.transform.position; } } } } } } } } return lookDirection; }
void OnToggleTeam(MissileFire mf, BDArmorySettings.BDATeams team) { if(mf.vessel == vessel || (commandLeader && commandLeader.vessel == mf.vessel)) { ReleaseCommand(); } }
void OnToggleTeam(MissileFire mf, BDArmorySettings.BDATeams team) { RefreshFriendlies(); RefreshWingmen(); }
public void EnableRadar() { foreach(var radar in vessel.FindPartModulesImplementing<ModuleRadar>()) { if(radar!=this) { radar.DisableRadar(); } } radarEnabled = true; foreach(var mf in vessel.FindPartModulesImplementing<MissileFire>()) { mf.radar = this; weaponManager = mf; break; } }
void Start() { rangeIndex = rIncrements.Length - 1; UpdateLockedTargets(); foreach(var mf in vessel.FindPartModulesImplementing<MissileFire>()) { mf.vesselRadarData = this; } GameEvents.onVesselDestroy.Add(OnVesselDestroyed); GameEvents.onVesselCreate.Add(OnVesselDestroyed); MissileFire.OnToggleTeam += OnToggleTeam; GameEvents.onGameStateSave.Add(OnGameStateSave); GameEvents.onPartDestroyed.Add(PartDestroyed); if(!weaponManager) { foreach(var mf in vessel.FindPartModulesImplementing<MissileFire>()) { weaponManager = mf; break; } } StartCoroutine(StartupRoutine()); }
void CheckMiss() { float sqrDist = ((targetPosition+(targetVelocity*Time.fixedDeltaTime))-(transform.position+(part.rb.velocity*Time.fixedDeltaTime))).sqrMagnitude; if(sqrDist < 200*200 || MissileState == MissileStates.PostThrust) { checkMiss = true; } //kill guidance if missile has missed if(checkMiss && (Vector3.Angle(targetPosition-transform.position, vessel.srf_velocity-targetVelocity) > 45)) { Debug.Log ("Missile CheckMiss showed miss"); guidanceActive = false; targetMf = null; if(hasRCS) KillRCS(); if(sqrDist < Mathf.Pow(blastRadius*.45f, 2)) Detonate(); return; } }
void GetGuardTarget() { if(weaponManager!=null && weaponManager.vessel == vessel) { if(weaponManager.guardMode && weaponManager.currentTarget!=null) { targetVessel = weaponManager.currentTarget.Vessel; } else { targetVessel = null; } weaponManager.pilotAI = this; return; } else { foreach(var mf in vessel.FindPartModulesImplementing<MissileFire>()) { if(mf.currentTarget!=null) { targetVessel = mf.currentTarget.Vessel; } else { targetVessel = null; } weaponManager = mf; mf.pilotAI = this; return; } } }
public static TargetInfo GetClosestTarget(MissileFire mf) { BDArmorySettings.BDATeams team = mf.team ? BDArmorySettings.BDATeams.B : BDArmorySettings.BDATeams.A; TargetInfo finalTarget = null; foreach(var target in TargetDatabase[team]) { if(target && target.Vessel && mf.CanSeeTarget(target.Vessel) && !target.isMissile) { if(finalTarget == null || (target.IsCloser(finalTarget, mf))) { finalTarget = target; } } } return finalTarget; }
public bool GetLaunchAuthorization(Vessel targetV, MissileFire mf) { bool launchAuthorized = false; Vector3 target = targetV.transform.position; MissileLauncher missile = mf.currentMissile; if(missile != null) { if(!targetV.LandedOrSplashed) { target = MissileGuidance.GetAirToAirFireSolution(missile, targetV); } float boresightFactor = targetV.LandedOrSplashed ? 0.75f : 0.35f; float maxOffBoresight = missile.maxOffBoresight; if(missile.targetingMode == MissileLauncher.TargetingModes.GPS) maxOffBoresight = 45; float fTime = 2f; Vector3 futurePos = target + (targetV.srf_velocity * fTime); Vector3 myFuturePos = vesselTransform.position + (vessel.srf_velocity * fTime); bool fDot = Vector3.Dot(vesselTransform.up, futurePos - myFuturePos) > 0; //check target won't likely be behind me soon if(fDot && Vector3.Angle(missile.transform.forward, target - missile.transform.position) < maxOffBoresight * boresightFactor) { launchAuthorized = true; } } return launchAuthorized; }
public static TargetInfo GetMissileTarget(MissileFire mf) { BDArmorySettings.BDATeams team = mf.team ? BDArmorySettings.BDATeams.B : BDArmorySettings.BDATeams.A; TargetInfo finalTarget = null; foreach(var target in TargetDatabase[team]) { if(target && target.Vessel && mf.CanSeeTarget(target.Vessel) && target.isMissile) { bool isHostile = false; if(target.missileModule && target.missileModule.targetMf && target.missileModule.targetMf.team == mf.team) { isHostile = true; } if(isHostile && ((finalTarget == null && target.numFriendliesEngaging < 2) || target.numFriendliesEngaging < finalTarget.numFriendliesEngaging)) { finalTarget = target; } } } return finalTarget; }