/// <summary> /// Gets the dynamic launch parameters. /// </summary> /// <returns>The dynamic launch parameters.</returns> /// <param name="launcherVelocity">Launcher velocity.</param> /// <param name="targetVelocity">Target velocity.</param> public static MissileLaunchParams GetDynamicLaunchParams(MissileLauncher missile, Vector3 targetVelocity, Vector3 targetPosition) { Vector3 launcherVelocity = missile.vessel.srf_velocity; float launcherSpeed = (float)missile.vessel.srfSpeed; float minLaunchRange = missile.minStaticLaunchRange; float maxLaunchRange = missile.maxStaticLaunchRange; float rangeAddMin = 0; float rangeAddMax = 0; float relSpeed; Vector3 relV = targetVelocity - launcherVelocity; Vector3 vectorToTarget = targetPosition - missile.part.transform.position; Vector3 relVProjected = Vector3.Project(relV, vectorToTarget); relSpeed = -Mathf.Sign(Vector3.Dot(relVProjected, vectorToTarget)) * relVProjected.magnitude; rangeAddMin += relSpeed * 2; rangeAddMax += relSpeed * 8; rangeAddMin += launcherSpeed * 2; rangeAddMax += launcherSpeed * 2; double diffAlt = missile.vessel.altitude - FlightGlobals.getAltitudeAtPos(targetPosition); rangeAddMax += (float)diffAlt; float min = Mathf.Clamp(minLaunchRange + rangeAddMin, 0, 20000); float max = Mathf.Clamp(maxLaunchRange + rangeAddMax, min+100, 20000); return new MissileLaunchParams(min, max); }
public static Vector3 DoAeroForces(MissileLauncher ml, Vector3 targetPosition, float liftArea, float steerMult, Vector3 previousTorque, float maxTorque, float maxAoA) { if(DefaultLiftCurve == null) { DefaultLiftCurve = new FloatCurve(); DefaultLiftCurve.Add(0, .1f); DefaultLiftCurve.Add(8, .45f); DefaultLiftCurve.Add(19, 1); DefaultLiftCurve.Add(23, .9f); DefaultLiftCurve.Add(29, 0.85f); DefaultLiftCurve.Add(35, 0.65f); DefaultLiftCurve.Add(65, .6f); DefaultLiftCurve.Add(90, .7f); } if(DefaultDragCurve == null) { DefaultDragCurve = new FloatCurve(); DefaultDragCurve.Add(0, 0.00225f); DefaultDragCurve.Add(5, .0035f); DefaultDragCurve.Add(15, .015f); DefaultDragCurve.Add(29, .025f); DefaultDragCurve.Add(55, .3f); DefaultDragCurve.Add(90, .5f); } FloatCurve liftCurve = DefaultLiftCurve; FloatCurve dragCurve = DefaultDragCurve; return DoAeroForces(ml, targetPosition, liftArea, steerMult, previousTorque, maxTorque, maxAoA, liftCurve, dragCurve); }
public override void OnStart(PartModule.StartState state) { submunitions = new List<GameObject>(); foreach(var sub in part.FindModelTransforms("submunition")) { submunitions.Add(sub.gameObject); if(HighLogic.LoadedSceneIsFlight) { Rigidbody subRb = sub.gameObject.GetComponent<Rigidbody>(); if(!subRb) { subRb = sub.gameObject.AddComponent<Rigidbody>(); } subRb.isKinematic = true; subRb.mass = part.mass / part.FindModelTransforms("submunition").Length; } sub.gameObject.SetActive(false); } fairings = new List<GameObject>(); foreach(var fairing in part.FindModelTransforms("fairing")) { fairings.Add(fairing.gameObject); if(HighLogic.LoadedSceneIsFlight) { Rigidbody fairingRb = fairing.gameObject.GetComponent<Rigidbody>(); if(!fairingRb) { fairingRb = fairing.gameObject.AddComponent<Rigidbody>(); } fairingRb.isKinematic = true; fairingRb.mass = 0.05f; } } missileLauncher = part.GetComponent<MissileLauncher>(); //missileLauncher.deployTime = deployDelay; }
void FireCurrentMissile(bool checkClearance) { MissileLauncher ml = currentMissile; if(ml == null) return; if(checkClearance && (!CheckBombClearance(ml) || (ml.rotaryRail&&!ml.rotaryRail.readyMissile==ml))) { foreach(var otherMissile in vessel.FindPartModulesImplementing<MissileLauncher>()) { if(otherMissile != ml && otherMissile.GetShortName() == ml.GetShortName() && CheckBombClearance(otherMissile)) { currentMissile = otherMissile; selectedWeapon = otherMissile; FireCurrentMissile(false); return; } } currentMissile = ml; selectedWeapon = ml; return; } //Part partSym = FindSym(ml.part); if(ml.missileTurret) { ml.missileTurret.FireMissile(ml); } else if(ml.rotaryRail) { ml.rotaryRail.FireMissile(ml); } else { SendTargetDataToMissile(ml); ml.FireMissile(); } if(guardMode) { if(ml.GetWeaponClass() == WeaponClasses.Bomb) { StartCoroutine(BombsAwayRoutine(ml)); } } else { if(vesselRadarData && vesselRadarData.autoCycleLockOnFire) { vesselRadarData.CycleActiveLock(); } } UpdateList(); }
private int IndexOfMissile(MissileLauncher ml) { if(missileCount == 0) return -1; for(int i = 0; i < missileCount; i++) { if(missileChildren[i] && missileChildren[i] == ml) { return i; } } return -1; }
public void FireMissile(int missileIndex) { int nextRailIndex = 0; if(!readyToFire) { return; } if(missileIndex >= missileChildren.Length) { return; } if(missileIndex < missileCount && missileChildren != null && missileChildren[missileIndex] != null) { if(missileChildren[missileIndex] != readyMissile) return; PrepMissileForFire(missileIndex); if(weaponManager) { wm.SendTargetDataToMissile(missileChildren[missileIndex]); } string firedMissileName = missileChildren[missileIndex].part.name; missileChildren[missileIndex].FireMissile(); rdyMissile = null; rdyToFire = false; //StartCoroutine(MissileRailRoutine(missileChildren[missileIndex])); nextRailIndex = Mathf.RoundToInt(Mathf.Repeat(missileToRailIndex[missileIndex] + 1, numberOfRails)); UpdateMissileChildren(); if(wm) { wm.UpdateList(); } if(railToMissileIndex.ContainsKey(nextRailIndex) && railToMissileIndex[nextRailIndex] < missileCount && missileChildren[railToMissileIndex[nextRailIndex]].part.name == firedMissileName) { RotateToIndex(nextRailIndex, false); } } //StartCoroutine(RotateToIndexAtEndOfFrame(nextRailIndex, false)); }
IEnumerator RotateToIndexRoutine(int index, bool instant) { rdyToFire = false; rdyMissile = null; railIndex = index; /* MissileLauncher foundMissile = null; foreach(var mIndex in missileToRailIndex.Keys) { if(missileToRailIndex[mIndex] == index) { foundMissile = missileChildren[mIndex]; } } nextMissile = foundMissile; */ yield return new WaitForSeconds(rotationDelay); Quaternion targetRot = Quaternion.Euler(0, 0, (float)index * -railAngle); if(instant) { for(int i = 0; i < rotationTransforms.Count; i++) { rotationTransforms[i].localRotation = targetRot; } UpdateMissilePositions(); //yield break; } else { while(rotationTransforms[0].localRotation != targetRot) { for(int i = 0; i < rotationTransforms.Count; i++) { rotationTransforms[i].localRotation = Quaternion.RotateTowards(rotationTransforms[i].localRotation, targetRot, rotationSpeed * Time.fixedDeltaTime); } UpdateMissilePositions(); yield return new WaitForFixedUpdate(); } } if(nextMissile) { rdyMissile = nextMissile; rdyToFire = true; nextMissile = null; if(weaponManager) { if(wm.weaponIndex > 0 && wm.selectedWeapon.GetPart().name == rdyMissile.part.name) { wm.selectedWeapon = rdyMissile; wm.currentMissile = rdyMissile; } } } }
public void RotateToMissile(MissileLauncher ml) { if(missileCount == 0) return; if(!ml) return; if(readyMissile == ml) return; //rotate to this missile specifically for(int i = 0; i < missileChildren.Length; i++) { if(missileChildren[i] == ml) { RotateToIndex(missileToRailIndex[i], false); nextMissile = ml; return; } } //specific missile isnt here, but check if this type exists here if(readyMissile && readyMissile.part.name == ml.part.name) return; //current missile is correct type //look for missile type for(int i = 0; i < missileChildren.Length; i++) { if(missileChildren[i].GetShortName() == ml.GetShortName()) { RotateToIndex(missileToRailIndex[i], false); nextMissile = missileChildren[i]; return; } } }
public static Vector3 GetAirToAirFireSolution(MissileLauncher missile, Vessel targetVessel) { if(!targetVessel) { return missile.transform.position + (missile.transform.forward*1000); } Vector3 targetPosition = targetVessel.transform.position; float leadTime = 0; float targetDistance = Vector3.Distance(targetVessel.transform.position, missile.transform.position); Vector3 simMissileVel = missile.optimumAirspeed * (targetPosition-missile.transform.position).normalized; leadTime = targetDistance/(float)(targetVessel.srf_velocity-simMissileVel).magnitude; leadTime = Mathf.Clamp (leadTime, 0f, 8f); targetPosition = targetPosition + (targetVessel.srf_velocity*leadTime); if(targetVessel && targetDistance < 800) { targetPosition += (Vector3)targetVessel.acceleration * 0.05f * leadTime * leadTime; } return targetPosition; }
public void FireMissile(MissileLauncher ml) { int index = IndexOfMissile(ml); if(index >= 0) { Debug.Log("Firing missile index: " + index); FireMissile(index); } else { Debug.Log("Tried to fire a missile that doesn't exist or is not attached to the turret."); } }
void SendTargetDataToMissile(MissileLauncher ml) { if(ml.targetingMode == MissileLauncher.TargetingModes.Laser && laserPointDetected) { ml.lockedCamera = foundCam; } else if(ml.targetingMode == MissileLauncher.TargetingModes.GPS) { ml.targetGPSCoords = designatedGPSCoords; ml.targetAcquired = true; } else if(ml.targetingMode == MissileLauncher.TargetingModes.Heat && heatTarget.exists) { ml.heatTarget = heatTarget; } 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); } }
IEnumerator GuardMissileRoutine(MissileLauncher ml) { if(ml && !guardFiringMissile) { guardFiringMissile = true; if(BDArmorySettings.ALLOW_LEGACY_TARGETING) { Debug.Log("Firing on target: " + guardTarget.GetName()+", (legacy targeting)"); ml.FireMissileOnTarget(guardTarget); UpdateList(); } else if(ml.targetingMode == MissileLauncher.TargetingModes.Radar && radar) { if(!radar.locked || (radar.lockedTarget.predictedPosition - guardTarget.transform.position).sqrMagnitude > Mathf.Pow(40, 2)) { radar.TryLockTarget(guardTarget.transform.position); yield return new WaitForSeconds(Mathf.Clamp(2, 0.2f, targetScanInterval / 2)); } if(guardTarget && radar.locked) { Debug.Log("Firing on target: " + guardTarget.GetName()); SendTargetDataToMissile(ml); ml.FireMissile(); UpdateList(); } } else if(ml.targetingMode == MissileLauncher.TargetingModes.Heat) { float attemptStartTime = Time.time; while(ml && Time.time-attemptStartTime < targetScanInterval*0.75f && (!heatTarget.exists || (heatTarget.predictedPosition - guardTarget.transform.position).sqrMagnitude > Mathf.Pow(40, 2))) { yield return null; } //try uncaged IR lock with radar if(guardTarget && !heatTarget.exists && radar && radar.radarEnabled) { if(!radar.locked || (radar.lockedTarget.predictedPosition - guardTarget.transform.position).sqrMagnitude > Mathf.Pow(40, 2)) { radar.TryLockTarget(guardTarget.transform.position); yield return new WaitForSeconds(Mathf.Clamp(1, 0.1f, (targetScanInterval*0.25f) / 2)); } } if(guardTarget && ml && heatTarget.exists) { Debug.Log("Firing on target: " + guardTarget.GetName()); SendTargetDataToMissile(ml); ml.FireMissile(); UpdateList(); } } guardFiringMissile = false; } }
/// <summary> /// Gets the laser target painter with the least angle off boresight. Set the missile as the reference transform. /// </summary> /// <returns>The laser target painter.</returns> /// <param name="referenceTransform">Reference transform.</param> /// <param name="maxBoreSight">Max bore sight.</param> public static ModuleTargetingCamera GetLaserTarget(MissileLauncher ml, bool parentOnly) { Transform referenceTransform = ml.transform; float maxOffBoresight = ml.maxOffBoresight; ModuleTargetingCamera finalCam = null; float smallestAngle = 360; foreach(var cam in ActiveLasers) { if(!cam) { continue; } if(parentOnly && !(cam.vessel == ml.vessel || cam.vessel == ml.sourceVessel)) { continue; } if(cam.cameraEnabled && cam.groundStabilized && cam.surfaceDetected && !cam.gimbalLimitReached) { /* if(ml.guidanceMode == MissileLauncher.GuidanceModes.BeamRiding && Vector3.Dot(ml.transform.position - cam.transform.position, ml.transform.forward) < 0) { continue; } */ float angle = Vector3.Angle(referenceTransform.forward, cam.groundTargetPosition-referenceTransform.position); if(angle < maxOffBoresight && angle < smallestAngle && ml.CanSeePosition(cam.groundTargetPosition)) { smallestAngle = angle; finalCam = cam; } } } return finalCam; }
IEnumerator BombsAwayRoutine(MissileLauncher ml) { missilesAway++; float timeStart = Time.time; float timeLimit = 3; while(ml) { if(Time.time - timeStart < timeLimit) { yield return null; } else { break; } } missilesAway--; }
IEnumerator MissileAwayRoutine(MissileLauncher ml) { missilesAway++; float missileThrustTime = ml.dropTime + ml.cruiseTime + ml.boostTime; float timeStart = Time.time; float timeLimit = Mathf.Max(missileThrustTime + 4, 10); while(ml) { if(ml.guidanceActive && Time.time-timeStart < timeLimit) { yield return null; } else { break; } } missilesAway--; }
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()); } }
/// <summary> /// Gets the laser target painter with the least angle off boresight. Set the missile as the reference transform. /// </summary> /// <returns>The laser target painter.</returns> /// <param name="referenceTransform">Reference transform.</param> /// <param name="maxBoreSight">Max bore sight.</param> public static ModuleTargetingCamera GetLaserTarget(MissileLauncher ml) { Transform referenceTransform = ml.transform; float maxOffBoresight = ml.maxOffBoresight; ModuleTargetingCamera finalCam = null; float smallestAngle = 360; foreach(var cam in ActiveLasers) { if(!cam) { continue; } if(cam.cameraEnabled && cam.groundStabilized && cam.surfaceDetected && !cam.gimbalLimitReached) { float angle = Vector3.Angle(referenceTransform.forward, cam.groundTargetPosition-referenceTransform.position); if(angle < maxOffBoresight && angle < smallestAngle && ml.CanSeePosition(cam.groundTargetPosition)) { smallestAngle = angle; finalCam = cam; } } } return finalCam; }
public void PrepMissileForFire(MissileLauncher ml) { int index = IndexOfMissile(ml); if(index >= 0) { PrepMissileForFire(index); } else { Debug.Log("Tried to prep a missile for firing that doesn't exist or is not attached to the turret."); } }
public static Vector3 GetAirToAirFireSolution(MissileLauncher missile, Vector3 targetPosition, Vector3 targetVelocity) { float leadTime = 0; float targetDistance = Vector3.Distance(targetPosition, missile.transform.position); Vector3 simMissileVel = missile.optimumAirspeed * (targetPosition-missile.transform.position).normalized; leadTime = targetDistance/(targetVelocity-simMissileVel).magnitude; leadTime = Mathf.Clamp (leadTime, 0f, 8f); targetPosition = targetPosition + (targetVelocity*leadTime); return targetPosition; }
IEnumerator MissileRailRoutine(MissileLauncher ml) { yield return null; Ray ray = new Ray(ml.transform.position, ml.missileReferenceTransform.forward); Vector3 localOrigin = turret.pitchTransform.InverseTransformPoint(ray.origin); Vector3 localDirection = turret.pitchTransform.InverseTransformDirection(ray.direction); float forwardSpeed = ml.decoupleSpeed; while(ml && Vector3.SqrMagnitude(ml.transform.position - ray.origin) < railLength*railLength) { float thrust = ml.timeIndex < ml.boostTime ? ml.thrust : ml.cruiseThrust; thrust = ml.timeIndex < ml.boostTime + ml.cruiseTime ? thrust : 0; float accel = thrust / ml.part.mass; forwardSpeed += accel * Time.fixedDeltaTime; ray.origin = turret.pitchTransform.TransformPoint(localOrigin); ray.direction = turret.pitchTransform.TransformDirection(localDirection); Vector3 projPos = Vector3.Project(ml.vessel.transform.position - ray.origin, ray.direction) + ray.origin; Vector3 railVel = part.rb.GetPointVelocity(projPos); //Vector3 projVel = Vector3.Project(ml.vessel.srf_velocity-railVel, ray.direction); ml.vessel.SetPosition(projPos); ml.vessel.SetWorldVelocity(railVel + (forwardSpeed*ray.direction)); yield return new WaitForFixedUpdate(); ray.origin = turret.pitchTransform.TransformPoint(localOrigin); ray.direction = turret.pitchTransform.TransformDirection(localDirection); } }
public static Vector3 DoAeroForces(MissileLauncher ml, Vector3 targetPosition, float liftArea, float steerMult, Vector3 previousTorque, float maxTorque, float maxAoA, FloatCurve liftCurve, FloatCurve dragCurve) { Rigidbody rb = ml.part.rb; double airDensity = ml.vessel.atmDensity; double airSpeed = ml.vessel.srfSpeed; Vector3d velocity = ml.vessel.srf_velocity; //temp values Vector3 CoL = new Vector3(0, 0, -1f); float liftMultiplier = BDArmorySettings.GLOBAL_LIFT_MULTIPLIER; float dragMultiplier = BDArmorySettings.GLOBAL_DRAG_MULTIPLIER; //lift float AoA = Mathf.Clamp(Vector3.Angle(ml.transform.forward, velocity.normalized), 0, 90); if(AoA > 0) { double liftForce = 0.5 * airDensity * Math.Pow(airSpeed, 2) * liftArea * liftMultiplier * liftCurve.Evaluate(AoA); Vector3 forceDirection = Vector3.ProjectOnPlane(-velocity, ml.transform.forward).normalized; rb.AddForceAtPosition((float)liftForce * forceDirection, ml.transform.TransformPoint(CoL)); } //drag if(airSpeed > 0) { double dragForce = 0.5 * airDensity * Math.Pow(airSpeed, 2) * liftArea * dragMultiplier * dragCurve.Evaluate(AoA); rb.AddForceAtPosition((float)dragForce * -velocity.normalized, ml.transform.TransformPoint(CoL)); } //guidance if(airSpeed > 1) { Vector3 targetDirection; float targetAngle; if(AoA < maxAoA) { targetDirection = (targetPosition - ml.transform.position); targetAngle = Vector3.Angle(velocity.normalized, targetDirection) * 4; } else { targetDirection = velocity.normalized; targetAngle = AoA; } Vector3 torqueDirection = -Vector3.Cross(targetDirection, velocity.normalized).normalized; torqueDirection = ml.transform.InverseTransformDirection(torqueDirection); float torque = Mathf.Clamp(targetAngle * steerMult, 0, maxTorque); Vector3 finalTorque = Vector3.ProjectOnPlane(Vector3.Lerp(previousTorque, torqueDirection*torque, 0.86f), Vector3.forward); rb.AddRelativeTorque(finalTorque); return finalTorque; } else { Vector3 finalTorque = Vector3.ProjectOnPlane(Vector3.Lerp(previousTorque, Vector3.zero, 0.25f), Vector3.forward); rb.AddRelativeTorque(finalTorque); return finalTorque; } }
public bool ContainsMissileOfType(MissileLauncher ml) { if(!ml) return false; if(missileCount == 0) return false; for(int i = 0; i < missileCount; i++) { if((missileChildren[i]) && missileChildren[i].part.name == ml.part.name) { return true; } } return false; }
void RotateToIndex(int index, bool instant) { //Debug.Log("Rotary rail is rotating to index: " + index); if(rotationRoutine != null) { StopCoroutine(rotationRoutine); } // if(railIndex == index && readyToFire) return; if(missileCount > 0) { if(railToMissileIndex.ContainsKey(index)) { nextMissile = missileChildren[railToMissileIndex[index]]; } } else { nextMissile = null; } if(!nextMissile && missileCount > 0) { RotateToIndex(Mathf.RoundToInt(Mathf.Repeat(index + 1, numberOfRails)), instant); return; } rotationRoutine = StartCoroutine(RotateToIndexRoutine(index, instant)); }
bool CheckBombClearance(MissileLauncher ml) { if(!BDArmorySettings.BOMB_CLEARANCE_CHECK) return true; if(ml.part.ShieldedFromAirstream) { return false; } if(ml.dropTime > 0.3f) { //debug lines LineRenderer lr = null; if(BDArmorySettings.DRAW_DEBUG_LINES && BDArmorySettings.DRAW_AIMERS) { lr = GetComponent<LineRenderer>(); if(!lr) { lr = gameObject.AddComponent<LineRenderer>(); } lr.enabled = true; lr.SetWidth(.1f, .1f); } else { if(gameObject.GetComponent<LineRenderer>()) { gameObject.GetComponent<LineRenderer>().enabled = false; } } float radius = 0.28f / 2; float time = ml.dropTime; Vector3 direction = ((ml.decoupleForward ? ml.transform.forward : -ml.transform.up) * ml.decoupleSpeed * time) + ((FlightGlobals.getGeeForceAtPosition(transform.position) - vessel.acceleration) * 0.5f * time*time); Vector3 crossAxis = Vector3.Cross(direction, ml.transform.forward).normalized; float rayDistance; if(ml.thrust == 0 || ml.cruiseThrust == 0) { rayDistance = 8; } else { //distance till engine starts based on grav accel and vessel accel rayDistance = direction.magnitude; } Ray[] rays = new Ray[] { new Ray(ml.transform.position - (radius * crossAxis), direction), new Ray(ml.transform.position + (radius * crossAxis), direction), new Ray(ml.transform.position, direction) }; if(lr) { lr.useWorldSpace = false; lr.SetVertexCount(4); lr.SetPosition(0, transform.InverseTransformPoint(rays[0].origin)); lr.SetPosition(1, transform.InverseTransformPoint(rays[0].GetPoint(rayDistance))); lr.SetPosition(2, transform.InverseTransformPoint(rays[1].GetPoint(rayDistance))); lr.SetPosition(3, transform.InverseTransformPoint(rays[1].origin)); } for(int i = 0; i < rays.Length; i++) { RaycastHit[] hits = Physics.RaycastAll(rays[i], rayDistance, 557057); for(int h = 0; h < hits.Length; h++) { Part p = hits[h].collider.GetComponentInParent<Part>(); if((p != null && p != ml.part) || p == null) return false; } } return true; } else { //forward check for no-drop missiles if(Physics.Raycast(new Ray(ml.transform.position, ml.transform.forward), 50, 557057)) { return false; } } return true; }
public void PrepMissileForFire(MissileLauncher ml) { if(ml != readyMissile) { //Debug.Log("Rotary rail tried prepping a missile for fire, but it is not in firing position"); return; } int index = IndexOfMissile(ml); if(index >= 0) { PrepMissileForFire(index); } else { //Debug.Log("Tried to prep a missile for firing that doesn't exist or is not attached to the turret."); } }
//give distance parameter IEnumerator WarningSoundRoutine(float distance, MissileLauncher ml) { if(distance < 4000) { warningSounding = true; BDArmorySettings.Instance.missileWarningTime = Time.time; BDArmorySettings.Instance.missileWarning = true; warningAudioSource.pitch = distance < 800 ? 1.45f : 1f; warningAudioSource.PlayOneShot(warningSound); float waitTime = distance < 800 ? .25f : 1.5f; yield return new WaitForSeconds(waitTime); if(ml.vessel && CanSeeTarget(ml.vessel)) { BDATargetManager.ReportVessel(ml.vessel, this); } } warningSounding = false; }
public void FireMissile(MissileLauncher ml) { if(!readyToFire || ml != readyMissile) { return; } int index = IndexOfMissile(ml); if(index >= 0) { //Debug.Log("Firing missile index: " + index); FireMissile(index); } else { //Debug.Log("Tried to fire a missile that doesn't exist or is not attached to the rail."); } }
//take distance parameter public void MissileWarning(float distance, MissileLauncher ml) { if(vessel.isActiveVessel && !warningSounding) { StartCoroutine(WarningSoundRoutine(distance, ml)); } missileIsIncoming = true; incomingMissileDistance = distance; }
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); } }
public void UpdateList() { weaponTypes.Clear(); foreach(IBDWeapon weapon in vessel.FindPartModulesImplementing<IBDWeapon>()) { string weaponName = weapon.GetShortName(); bool alreadyAdded = false; foreach(var weap in weaponTypes) { if(weap.GetShortName() == weaponName) { alreadyAdded = true; break; } } //dont add empty rocket pods if(weapon.GetWeaponClass() == WeaponClasses.Rocket && weapon.GetPart().FindModuleImplementing<RocketLauncher>().GetRocketResource().amount < 1) { continue; } if(!alreadyAdded) { weaponTypes.Add(weapon); } } //weaponTypes.Sort(); weaponTypes = weaponTypes.OrderBy(w => w.GetShortName()).ToList(); List<IBDWeapon> tempList = new List<IBDWeapon>(); tempList.Add (null); tempList.AddRange(weaponTypes); weaponArray = tempList.ToArray(); if(weaponIndex >= weaponArray.Length) { hasSingleFired = true; triggerTimer = 0; } weaponIndex = Mathf.Clamp(weaponIndex, 0, weaponArray.Length - 1); if(selectedWeapon == null || selectedWeapon.GetPart() == null || selectedWeapon.GetPart().vessel!=vessel || GetWeaponName(selectedWeapon) != GetWeaponName(weaponArray[weaponIndex])) { selectedWeapon = weaponArray[weaponIndex]; if(vessel.isActiveVessel && Time.time - startTime > 1) { hasSingleFired = true; } if(vessel.isActiveVessel && weaponIndex!=0) { DisplaySelectedWeaponMessage(); } } if(weaponIndex == 0) { selectedWeapon = null; hasSingleFired = true; } MissileLauncher aMl = GetAsymMissile(); if(aMl) { //Debug.Log("setting asym missile: " + aMl.part.name); selectedWeapon = aMl; currentMissile = aMl; } MissileLauncher rMl = GetRotaryReadyMissile(); if(rMl) { //Debug.Log("setting rotary ready missile: " + rMl.part.name); selectedWeapon = rMl; currentMissile = rMl; } if(selectedWeapon != null && (selectedWeapon.GetWeaponClass() == WeaponClasses.Bomb || selectedWeapon.GetWeaponClass() == WeaponClasses.Missile)) { //Debug.Log("=====selected weapon: " + selectedWeapon.GetPart().name); if(!currentMissile || currentMissile.part.name != selectedWeapon.GetPart().name) { currentMissile = selectedWeapon.GetPart().FindModuleImplementing<MissileLauncher>(); } } else { currentMissile = null; } //selectedWeapon = weaponArray[weaponIndex]; //bomb stuff if(selectedWeapon != null && selectedWeapon.GetWeaponClass() == WeaponClasses.Bomb) { bombPart = selectedWeapon.GetPart(); } else { bombPart = null; } //gun ripple stuff if(selectedWeapon != null && selectedWeapon.GetWeaponClass() == WeaponClasses.Gun && currentGun.roundsPerMinute < 1500) { float counter = 0; float weaponRPM = 0; gunRippleIndex = 0; rippleGunCount = 0; List<ModuleWeapon> tempListModuleWeapon = vessel.FindPartModulesImplementing<ModuleWeapon>(); foreach (ModuleWeapon weapon in tempListModuleWeapon) { if (selectedWeapon.GetShortName() == weapon.GetShortName()) { weapon.rippleIndex = Mathf.RoundToInt(counter); weaponRPM = weapon.roundsPerMinute; ++counter; rippleGunCount++; } } gunRippleRpm = weaponRPM * counter; float timeDelayPerGun = 60f / (weaponRPM * counter); //number of seconds between each gun firing; will reduce with increasing RPM or number of guns foreach (ModuleWeapon weapon in tempListModuleWeapon) { if (selectedWeapon.GetShortName() == weapon.GetShortName()) { weapon.initialFireDelay = timeDelayPerGun; //set the time delay for moving to next index } } RippleOption ro; //ripplesetup and stuff if (rippleDictionary.ContainsKey(selectedWeapon.GetShortName())) { ro = rippleDictionary[selectedWeapon.GetShortName()]; } else { ro = new RippleOption(currentGun.useRippleFire, 650); //take from gun's persistant value rippleDictionary.Add(selectedWeapon.GetShortName(), ro); } foreach (ModuleWeapon w in vessel.FindPartModulesImplementing<ModuleWeapon>()) { if (w.GetShortName() == selectedWeapon.GetShortName()) w.useRippleFire = ro.rippleFire; } } //rocket FindNextRocket(null); ToggleTurret(); SetMissileTurrets(); SetRocketTurrets(); SetRotaryRails(); }