public void SetThermal(Vessel sourceVessel) { // OLD: //thermal = BDArmorySetup.FLARE_THERMAL*UnityEngine.Random.Range(0.45f, 1.25f); // NEW: generate flare within spectrum of emitting vessel's heat signature thermal = BDATargetManager.GetVesselHeatSignature(sourceVessel) * UnityEngine.Random.Range(0.65f, 1.75f); }
public void SetThermal(Vessel sourceVessel) { // OLD: //thermal = BDArmorySetup.FLARE_THERMAL*UnityEngine.Random.Range(0.45f, 1.25f); // NEW (1.9.1 and before): generate flare within spectrum of emitting vessel's heat signature //thermal = BDATargetManager.GetVesselHeatSignature(sourceVessel) * UnityEngine.Random.Range(0.65f, 1.75f); // NEW NEW: Dynamic min/max based on engine heat, with larger multiplier for colder engines, and smaller for naturally hot engines // since range of values are too small for smaller heat values, and flares tend to decay to even colder values, rendering them useless /* Alternate flare gen code, adjusts curve towards high end up to 5000K heat engines. Polynomial versions available. * * thermal = BDATargetManager.GetVesselHeatSignature(sourceVessel); * //float thermalMinMult = Mathf.Clamp(-0.166f * (float)Math.Log(thermal) + 1.9376f, 0.5f, 0.82f); * //float thermalMaxMult = Mathf.Clamp(0.3534f * (float)Math.Log(thermal) - 1.0251f, 1.35f, 2.0f); * * thermal *= UnityEngine.Random.Range(thermalMinMult, thermalMaxMult); * * if (BDArmorySettings.DRAW_DEBUG_LABELS) * Debug.Log("[BDArmory]: New flare generated from " + sourceVessel.GetDisplayName() + ":" + BDATargetManager.GetVesselHeatSignature(sourceVessel).ToString("0.0") + ", heat: " + thermal.ToString("0.0") + " mult: " + thermalMinMult + "-" + thermalMaxMult); */ // NEW (1.10 and later): generate flare within spectrum of emitting vessel's heat signature, but narrow range for low heats thermal = BDATargetManager.GetVesselHeatSignature(sourceVessel); // float minMult = Mathf.Clamp(-0.265f * Mathf.Log(sourceHeat) + 2.3f, 0.65f, 0.8f); float thermalMinMult = Mathf.Clamp(((0.00093f * thermal * thermal - 1.4457f * thermal + 1141.95f) / 1000f), 0.65f, 0.8f); // Equivalent to above, but uses polynomial for speed thermal *= UnityEngine.Random.Range(thermalMinMult, 1.75f - thermalMinMult + 0.65f); if (BDArmorySettings.DRAW_DEBUG_LABELS) { Debug.Log("[BDArmory]: New flare generated from " + sourceVessel.GetDisplayName() + ":" + BDATargetManager.GetVesselHeatSignature(sourceVessel).ToString("0.0") + ", heat: " + thermal.ToString("0.0")); } }
protected void AddTargetInfoToVessel() { TargetInfo info = vessel.gameObject.AddComponent <TargetInfo>(); info.team = BDATargetManager.BoolToTeam(Team); info.isMissile = true; info.MissileBaseModule = this; }
void OnDestroy() { //remove delegate from peace enable event BDArmorySetup.OnPeaceEnabled -= OnPeaceEnabled; vessel.OnJustAboutToBeDestroyed -= AboutToBeDestroyed; GameEvents.onVesselPartCountChanged.Remove(VesselModified); GameEvents.onVesselDestroy.Remove(CleanFriendliesEngaging); BDATargetManager.RemoveTarget(this); }
IEnumerator GPSRoutine() { GetSatInfo(); scanning = true; targetCount = 0; ScreenMsg("Initializing Scan ......"); yield return(new WaitForSeconds(1.5f)); ScreenMsg("Initializing Scan ......"); yield return(new WaitForSeconds(1.5f)); ScreenMsg("Scanning in Progress ......"); yield return(new WaitForSeconds(1.5f)); ScreenMsg("Scanning in Progress ......"); yield return(new WaitForSeconds(1.5f)); ScreenMsg("Scanning in Progress ......"); yield return(new WaitForSeconds(1.5f)); foreach (Vessel v in FlightGlobals.Vessels) { if (v.LandedOrSplashed && !v.HoldPhysics) { List <MissileFire> targets = new List <MissileFire>(200); foreach (Part t in v.Parts) { targets.AddRange(t.FindModulesImplementing <MissileFire>()); } foreach (MissileFire target in targets) { if (myTeam != target.team) { _altitude = v.altitude; _latitude = v.latitude; _longitude = v.longitude; targetCount += 1; ScreenMsg2("Retrieving GPS Coords for " + v.vesselName); yield return(new WaitForSeconds(1.5f)); BDATargetManager.GPSTargets[BDATargetManager.BoolToTeam(myTeam)].Add(new GPSTargetInfo(getTargetCoords, v.vesselName)); ScreenMsg2(v.vesselName + " added to GPS Database"); yield return(new WaitForSeconds(1.5f)); } } } } yield return(new WaitForSeconds(1.5f)); ScreenMsg2("Scan Complete ... " + targetCount + " Targets added to GPS Database"); scan = false; scanning = false; }
/// <summary> /// If guard mode is set but no target is selected, pick something /// </summary> protected virtual void GetGuardNonTarget() { if (weaponManager && weaponManager.guardMode && !targetVessel) { TargetInfo potentialTarget = BDATargetManager.GetLeastEngagedTarget(weaponManager); if (potentialTarget && potentialTarget.Vessel) { targetVessel = potentialTarget.Vessel; } } }
void Update() { if (!vessel) { AboutToBeDestroyed(); } else { if ((vessel.vesselType == VesselType.Debris) && (weaponManager == null)) { BDATargetManager.RemoveTarget(this); Team = null; } } }
protected void UpdateLaserTarget() { if (TargetAcquired) { if (lockedCamera && lockedCamera.groundStabilized && !lockedCamera.gimbalLimitReached && lockedCamera.surfaceDetected) //active laser target { TargetPosition = lockedCamera.groundTargetPosition; TargetVelocity = (TargetPosition - lastLaserPoint) / Time.fixedDeltaTime; TargetAcceleration = Vector3.zero; lastLaserPoint = TargetPosition; if (GuidanceMode == GuidanceModes.BeamRiding && TimeIndex > 0.25f && Vector3.Dot(GetForwardTransform(), part.transform.position - lockedCamera.transform.position) < 0) { TargetAcquired = false; lockedCamera = null; } } else //lost active laser target, home on last known position { if (CMSmoke.RaycastSmoke(new Ray(transform.position, lastLaserPoint - transform.position))) { //Debug.Log("Laser missileBase affected by smoke countermeasure"); float angle = VectorUtils.FullRangePerlinNoise(0.75f * Time.time, 10) * BDArmorySettings.SMOKE_DEFLECTION_FACTOR; TargetPosition = VectorUtils.RotatePointAround(lastLaserPoint, transform.position, VectorUtils.GetUpDirection(transform.position), angle); TargetVelocity = Vector3.zero; TargetAcceleration = Vector3.zero; lastLaserPoint = TargetPosition; } else { TargetPosition = lastLaserPoint; } } } else { ModuleTargetingCamera foundCam = null; bool parentOnly = (GuidanceMode == GuidanceModes.BeamRiding); foundCam = BDATargetManager.GetLaserTarget(this, parentOnly); if (foundCam != null && foundCam.cameraEnabled && foundCam.groundStabilized && BDATargetManager.CanSeePosition(foundCam.groundTargetPosition, vessel.transform.position, MissileReferenceTransform.position)) { Debug.Log("[BDArmory]: Laser guided missileBase actively found laser point. Enabling guidance."); lockedCamera = foundCam; TargetAcquired = true; } } }
public TargetSignatureData(Vessel v, float _signalStrength) { orbital = false; orbit = null; timeAcquired = Time.time; vessel = v; velocity = v.Velocity(); geoPos = VectorUtils.WorldPositionToGeoCoords(v.CoM, v.mainBody); acceleration = v.acceleration; exists = true; signalStrength = _signalStrength; targetInfo = v.gameObject.GetComponent <TargetInfo> (); // vessel never been picked up on radar before: create new targetinfo record if (targetInfo == null) { targetInfo = v.gameObject.AddComponent <TargetInfo>(); } team = BDArmorySettings.BDATeams.None; if (targetInfo) { team = targetInfo.team; targetInfo.detectedTime = Time.time; } else { List <MissileFire> .Enumerator mf = v.FindPartModulesImplementing <MissileFire>().GetEnumerator(); while (mf.MoveNext()) { team = BDATargetManager.BoolToTeam(mf.Current.team); break; } mf.Dispose(); } vesselJammer = v.gameObject.GetComponent <VesselECMJInfo>(); pingPosition = Vector2.zero; lockedByRadar = null; }
/// <summary> /// GPS /// </summary> /// private void SaveGPS() { List <MissileFire> wmParts = new List <MissileFire>(200); foreach (Part p in FlightGlobals.ActiveVessel.Parts) { wmParts.AddRange(p.FindModulesImplementing <MissileFire>()); } foreach (MissileFire wmPart in wmParts) { var _latitude_ = double.Parse(_guiX); var _longitude_ = double.Parse(_guiY); var _altitude_ = double.Parse(_guiZ); _latitude = _latitude_; _longitude = _longitude_; _altitude = _altitude_; BDATargetManager.GPSTargets[BDATargetManager.BoolToTeam(wmPart.team)].Add(new GPSTargetInfo(getTargetCoords, "Saved GPS")); ScreenMsg("GPS Target Saved"); } }
void Update() { if (!vessel) { AboutToBeDestroyed(); } else { if ((vessel.vesselType == VesselType.Debris) && (weaponManager == null)) { BDATargetManager.RemoveTarget(this); Team = null; } } if (HighLogic.LoadedSceneIsFlight) { if (BDArmorySetup.windowSettingsEnabled) { UpdateTargetPartList(); } } }
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; } } } }
void AboutToBeDestroyed() { BDATargetManager.RemoveTarget(this); Destroy(this); }
void OnEnable() { // OLD: //thermal = BDArmorySettings.FLARE_THERMAL*UnityEngine.Random.Range(0.45f, 1.25f); // NEW: generate flare within spectrum of emitting vessel's heat signature thermal = BDATargetManager.GetVesselHeatSignature(sourceVessel) * UnityEngine.Random.Range(0.65f, 1.75f); startThermal = thermal; minThermal = startThermal * 0.3f; if (gaplessEmitters == null || pEmitters == null) { gaplessEmitters = new List <BDAGaplessParticleEmitter>(); pEmitters = new List <KSPParticleEmitter>(); IEnumerator <KSPParticleEmitter> pe = gameObject.GetComponentsInChildren <KSPParticleEmitter>().Cast <KSPParticleEmitter>().GetEnumerator(); while (pe.MoveNext()) { if (pe.Current == null) { continue; } if (pe.Current.useWorldSpace) { BDAGaplessParticleEmitter gpe = pe.Current.gameObject.AddComponent <BDAGaplessParticleEmitter>(); gaplessEmitters.Add(gpe); gpe.emit = true; } else { EffectBehaviour.AddParticleEmitter(pe.Current); pEmitters.Add(pe.Current); pe.Current.emit = true; } } pe.Dispose(); } List <BDAGaplessParticleEmitter> .Enumerator gEmitter = gaplessEmitters.GetEnumerator(); while (gEmitter.MoveNext()) { if (gEmitter.Current == null) { continue; } gEmitter.Current.emit = true; } gEmitter.Dispose(); List <KSPParticleEmitter> .Enumerator pEmitter = pEmitters.GetEnumerator(); while (pEmitter.MoveNext()) { if (pEmitter.Current == null) { continue; } pEmitter.Current.emit = true; } pEmitter.Dispose(); BDArmorySettings.numberOfParticleEmitters++; if (lights == null) { lights = gameObject.GetComponentsInChildren <Light>(); } IEnumerator <Light> lgt = lights.AsEnumerable().GetEnumerator(); while (lgt.MoveNext()) { if (lgt.Current == null) { continue; } lgt.Current.enabled = true; } lgt.Dispose(); startTime = Time.time; //ksp force applier //gameObject.AddComponent<KSPForceApplier>().drag = 0.4f; BDArmorySettings.Flares.Add(this); if (sourceVessel != null) { relativePos = transform.position - sourceVessel.transform.position; } upDirection = VectorUtils.GetUpDirection(transform.position); velocity = startVelocity; }
IEnumerator DogfightCompetitionModeRoutine(float distance) { competitionStarting = true; competitionStatus = "Competition: Pilots are taking off."; Dictionary <BDArmorySetup.BDATeams, List <IBDAIControl> > pilots = new Dictionary <BDArmorySetup.BDATeams, List <IBDAIControl> >(); pilots.Add(BDArmorySetup.BDATeams.A, new List <IBDAIControl>()); pilots.Add(BDArmorySetup.BDATeams.B, new List <IBDAIControl>()); List <Vessel> .Enumerator loadedVessels = BDATargetManager.LoadedVessels.GetEnumerator(); while (loadedVessels.MoveNext()) { if (loadedVessels.Current == null) { continue; } if (!loadedVessels.Current.loaded) { continue; } IBDAIControl pilot = null; IEnumerator <IBDAIControl> ePilots = loadedVessels.Current.FindPartModulesImplementing <IBDAIControl>().AsEnumerable().GetEnumerator(); while (ePilots.MoveNext()) { pilot = ePilots.Current; break; } ePilots.Dispose(); if (pilot == null || !pilot.weaponManager) { continue; } pilots[BDATargetManager.BoolToTeam(pilot.weaponManager.team)].Add(pilot); pilot.CommandTakeOff(); if (pilot.weaponManager.guardMode) { pilot.weaponManager.ToggleGuardMode(); } } loadedVessels.Dispose(); //clear target database so pilots don't attack yet BDATargetManager.ClearDatabase(); if (pilots[BDArmorySetup.BDATeams.A].Count == 0 || pilots[BDArmorySetup.BDATeams.B].Count == 0) { Debug.Log("[BDArmory]: 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; } IBDAIControl aLeader = pilots[BDArmorySetup.BDATeams.A][0]; IBDAIControl bLeader = pilots[BDArmorySetup.BDATeams.B][0]; aLeader.weaponManager.wingCommander.CommandAllFollow(); bLeader.weaponManager.wingCommander.CommandAllFollow(); //wait till the leaders are ready to engage (airborne for PilotAI) while (aLeader != null && bLeader != null && (!aLeader.CanEngage() || !bLeader.CanEngage())) { yield return(null); } if (aLeader == null || bLeader == null) { 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 == null || bLeader == null) { StopCompetition(); } if (Vector3.Distance(aLeader.transform.position, bLeader.transform.position) < distance * 1.95f) { waiting = true; } else { Dictionary <BDArmorySetup.BDATeams, List <IBDAIControl> > .KeyCollection.Enumerator keys = pilots.Keys.GetEnumerator(); while (keys.MoveNext()) { List <IBDAIControl> .Enumerator ePilots = pilots[keys.Current].GetEnumerator(); while (ePilots.MoveNext()) { if (ePilots.Current == null) { continue; } if (ePilots.Current.currentCommand != PilotCommands.Follow || !(Vector3.ProjectOnPlane( ePilots.Current.vessel.CoM - ePilots.Current.commandLeader.vessel.CoM, VectorUtils.GetUpDirection(ePilots.Current.commandLeader.vessel.transform.position) ).sqrMagnitude > 1000f * 1000f)) { continue; } competitionStatus = "Competition: Waiting for teams to get in position."; waiting = true; } ePilots.Dispose(); } keys.Dispose(); } yield return(null); } //start the match Dictionary <BDArmorySetup.BDATeams, List <IBDAIControl> > .KeyCollection.Enumerator pKeys = pilots.Keys.GetEnumerator(); while (pKeys.MoveNext()) { List <IBDAIControl> .Enumerator pPilots = pilots[pKeys.Current].GetEnumerator(); while (pPilots.MoveNext()) { if (pPilots.Current == null) { continue; } //enable guard mode if (!pPilots.Current.weaponManager.guardMode) { pPilots.Current.weaponManager.ToggleGuardMode(); } //report all vessels if (BDATargetManager.BoolToTeam(pPilots.Current.weaponManager.team) == BDArmorySetup.BDATeams.B) { BDATargetManager.ReportVessel(pPilots.Current.vessel, aLeader.weaponManager); } else { BDATargetManager.ReportVessel(pPilots.Current.vessel, bLeader.weaponManager); } //release command pPilots.Current.ReleaseCommand(); pPilots.Current.CommandAttack(centerGPS); } } pKeys.Dispose(); competitionStatus = "Competition starting! Good luck!"; yield return(new WaitForSeconds(2)); competitionStarting = false; }
/// <summary> /// If guard mode is set but no target is selected, pick something /// </summary> protected virtual void GetGuardNonTarget() { if (weaponManager && weaponManager.guardMode && !targetVessel) { // select target based on competition style TargetInfo potentialTarget = BDArmorySettings.DEFAULT_FFA_TARGETING ? BDATargetManager.GetClosestTargetWithBiasAndHysteresis(weaponManager) : BDATargetManager.GetLeastEngagedTarget(weaponManager); if (potentialTarget && potentialTarget.Vessel) { targetVessel = potentialTarget.Vessel; } } }
void Awake() { if (!vessel) { vessel = GetComponent <Vessel>(); } if (!vessel) { //Debug.Log ("[BDArmory]: TargetInfo was added to a non-vessel"); Destroy(this); return; } //destroy this if a target info is already attached to the vessel IEnumerator otherInfo = vessel.gameObject.GetComponents <TargetInfo>().GetEnumerator(); while (otherInfo.MoveNext()) { if ((object)otherInfo.Current != this) { Destroy(this); return; } } team = BDArmorySetup.BDATeams.None; bool foundMf = false; List <MissileFire> .Enumerator mf = vessel.FindPartModulesImplementing <MissileFire>().GetEnumerator(); while (mf.MoveNext()) { foundMf = true; team = BDATargetManager.BoolToTeam(mf.Current.team); weaponManager = mf.Current; break; } mf.Dispose(); if (!foundMf) { List <MissileBase> .Enumerator ml = vessel.FindPartModulesImplementing <MissileBase>().GetEnumerator(); while (ml.MoveNext()) { isMissile = true; MissileBaseModule = ml.Current; team = BDATargetManager.BoolToTeam(ml.Current.Team); break; } ml.Dispose(); } if (team != BDArmorySetup.BDATeams.None) { BDATargetManager.AddTarget(this); } friendliesEngaging = new List <MissileFire>(); vessel.OnJustAboutToBeDestroyed += AboutToBeDestroyed; //add delegate to peace enable event BDArmorySetup.OnPeaceEnabled += OnPeaceEnabled; //lifeRoutine = StartCoroutine(LifetimeRoutine()); // TODO: CHECK BEHAVIOUR AND SIDE EFFECTS! if (!isMissile && team != BDArmorySetup.BDATeams.None) { GameEvents.onVesselPartCountChanged.Add(VesselModified); //massRoutine = StartCoroutine(MassRoutine()); // TODO: CHECK BEHAVIOUR AND SIDE EFFECTS! } }
IEnumerator DogfightCompetitionModeRoutine(float distance) { competitionStarting = true; competitionStatus = "Competition: Pilots are taking off."; var pilots = new Dictionary <BDTeam, List <IBDAIControl> >(); using (var loadedVessels = BDATargetManager.LoadedVessels.GetEnumerator()) while (loadedVessels.MoveNext()) { if (loadedVessels.Current == null || !loadedVessels.Current.loaded) { continue; } IBDAIControl pilot = loadedVessels.Current.FindPartModuleImplementing <IBDAIControl>(); if (pilot == null || !pilot.weaponManager || pilot.weaponManager.Team.Neutral) { continue; } if (!pilots.TryGetValue(pilot.weaponManager.Team, out List <IBDAIControl> teamPilots)) { teamPilots = new List <IBDAIControl>(); pilots.Add(pilot.weaponManager.Team, teamPilots); } teamPilots.Add(pilot); pilot.CommandTakeOff(); if (pilot.weaponManager.guardMode) { pilot.weaponManager.ToggleGuardMode(); } } //clear target database so pilots don't attack yet BDATargetManager.ClearDatabase(); if (pilots.Count < 2) { Debug.Log("[BDArmory]: 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; } var leaders = new List <IBDAIControl>(); using (var pilotList = pilots.GetEnumerator()) while (pilotList.MoveNext()) { leaders.Add(pilotList.Current.Value[0]); pilotList.Current.Value[0].weaponManager.wingCommander.CommandAllFollow(); } //wait till the leaders are ready to engage (airborne for PilotAI) bool ready = false; while (!ready) { ready = true; using (var leader = leaders.GetEnumerator()) while (leader.MoveNext()) { if (leader.Current != null && !leader.Current.CanEngage()) { ready = false; yield return(null); break; } } } using (var leader = leaders.GetEnumerator()) while (leader.MoveNext()) { if (leader.Current == null) { StopCompetition(); } } competitionStatus = "Competition: Sending pilots to start position."; Vector3 center = Vector3.zero; using (var leader = leaders.GetEnumerator()) while (leader.MoveNext()) { center += leader.Current.vessel.CoM; } center /= leaders.Count; Vector3 startDirection = Vector3.ProjectOnPlane(leaders[0].vessel.CoM - center, VectorUtils.GetUpDirection(center)).normalized; startDirection *= (distance * leaders.Count / 4) + 1250f; Quaternion directionStep = Quaternion.AngleAxis(360f / leaders.Count, VectorUtils.GetUpDirection(center)); for (var i = 0; i < leaders.Count; ++i) { leaders[i].CommandFlyTo(VectorUtils.WorldPositionToGeoCoords(startDirection, FlightGlobals.currentMainBody)); startDirection = directionStep * startDirection; } Vector3 centerGPS = VectorUtils.WorldPositionToGeoCoords(center, FlightGlobals.currentMainBody); //wait till everyone is in position competitionStatus = "Competition: Waiting for teams to get in position."; bool waiting = true; var sqrDistance = distance * distance; while (waiting) { waiting = false; using (var leader = leaders.GetEnumerator()) while (leader.MoveNext()) { if (leader.Current == null) { StopCompetition(); } using (var otherLeader = leaders.GetEnumerator()) while (otherLeader.MoveNext()) { if (leader.Current == otherLeader.Current) { continue; } if ((leader.Current.transform.position - otherLeader.Current.transform.position).sqrMagnitude < sqrDistance) { waiting = true; } } // Increase the distance for large teams var sqrTeamDistance = (800 + 100 * pilots[leader.Current.weaponManager.Team].Count) * (800 + 100 * pilots[leader.Current.weaponManager.Team].Count); using (var pilot = pilots[leader.Current.weaponManager.Team].GetEnumerator()) while (pilot.MoveNext()) { if (pilot.Current != null && pilot.Current.currentCommand == PilotCommands.Follow && (pilot.Current.vessel.CoM - pilot.Current.commandLeader.vessel.CoM).sqrMagnitude > 1000f * 1000f) { waiting = true; } } if (waiting) { break; } } yield return(null); } //start the match using (var teamPilots = pilots.GetEnumerator()) while (teamPilots.MoveNext()) { using (var pilot = teamPilots.Current.Value.GetEnumerator()) while (pilot.MoveNext()) { if (pilot.Current == null) { continue; } if (!pilot.Current.weaponManager.guardMode) { pilot.Current.weaponManager.ToggleGuardMode(); } using (var leader = leaders.GetEnumerator()) while (leader.MoveNext()) { BDATargetManager.ReportVessel(pilot.Current.vessel, leader.Current.weaponManager); } pilot.Current.ReleaseCommand(); pilot.Current.CommandAttack(centerGPS); } } competitionStatus = "Competition starting! Good luck!"; yield return(new WaitForSeconds(2)); competitionStarting = false; }