void CommandTakeOff(IBDAIControl wingman, int index, object data) { wingman.CommandTakeOff(); }
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; }
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; }