/// <summary> /// Returns the proper payload for a given task, or the default payload if required payload is not available. /// </summary> /// <param name="taskPayload">Task the aircraft should perform</param> /// <returns>An array of strings describing the weapon on each pylon</returns> public string[] GetPayload(UnitTaskPayload taskPayload) { if (TaskPayloadExists(taskPayload)) { return(PayloadTasks[(int)taskPayload]); } return(PayloadTasks[(int)UnitTaskPayload.Default]); }
/// <summary> /// Is a payload available for the given task? /// Basically used to know if the default task should be used instead of the required task. /// </summary> /// <param name="task">A task</param> /// <returns>True if a payload have been defined for this task, false otherwise</returns> private bool TaskPayloadExists(UnitTaskPayload task, Decade decade) { // If at least one pylon has been defined for this task, return true for (int i = 0; i < MAX_PYLONS; i++) { if (!string.IsNullOrEmpty(PayloadTasks[decade][task][i])) { return(true); } } return(false); }
/// <summary> /// Returns the proper payload for a given task, or the default payload if required payload is not available. /// </summary> /// <param name="taskPayload">Task the aircraft should perform</param> /// <returns>An array of strings describing the weapon on each pylon</returns> public string[] GetPayload(UnitTaskPayload taskPayload, Decade decade) { if (TaskPayloadExists(taskPayload, decade)) { return(PayloadTasks[decade][taskPayload]); } if (TaskPayloadExists(UnitTaskPayload.Default, decade)) { return(PayloadTasks[decade][UnitTaskPayload.Default]); } return(PayloadTasks[Decade.Decade2000][UnitTaskPayload.Default]); }
/// <summary> /// Creates multiplayer client flight groups. /// </summary> /// <param name="mission">Mission to which generated units should be added</param> /// <param name="template">Mission template to use</param> /// <param name="objectiveDB">Mission objective database entry</param> /// <returns>An array of <see cref="UnitFlightGroupBriefingDescription"/> describing the flight groups, to be used in the briefing</returns> private UnitFlightGroupBriefingDescription[] GenerateMultiplayerFlightGroups(DCSMission mission, MissionTemplate template, DBEntryObjective objectiveDB) { int totalGroupsCreated = 0; List <UnitFlightGroupBriefingDescription> briefingFGList = new List <UnitFlightGroupBriefingDescription>(); foreach (MissionTemplateFlightGroup fg in template.PlayerFlightGroups) { // Select proper payload for the flight group according to its tasking UnitTaskPayload payload = GetPayloadByTask(fg.Tasking, objectiveDB); bool hasCarrier = !string.IsNullOrEmpty(fg.Carrier); DCSMissionUnitGroup group = UnitMaker.AddUnitGroup( mission, Enumerable.Repeat(fg.Aircraft, fg.Count).ToArray(), Side.Ally, hasCarrier ? mission.Carriers.First(x => x.Units[0].Name == fg.Carrier).Coordinates : mission.InitialPosition, hasCarrier ? "GroupAircraftPlayerCarrier" : "GroupAircraftPlayer", "UnitAircraft", DCSSkillLevel.Client, 0, payload, null, hasCarrier ? -99 : mission.InitialAirbaseID, true, country: fg.Country, startLocation: fg.StartLocation == PlayerStartLocation.Runway ? PlayerStartLocation.ParkingHot : fg.StartLocation); if (group == null) { DebugLog.Instance.WriteLine($"Failed to create group of player aircraft of type \"{fg.Aircraft}\".", 1, DebugLogMessageErrorLevel.Warning); continue; } if (hasCarrier) { group.CarrierId = mission.Carriers.First(x => x.Units[0].Name == fg.Carrier).Units[0].ID; } briefingFGList.Add( new UnitFlightGroupBriefingDescription( group.Name, group.Units.Length, fg.Aircraft, GetTaskingDescription(fg.Tasking, objectiveDB), Database.Instance.GetEntry <DBEntryUnit>(fg.Aircraft).AircraftData.GetRadioAsString())); totalGroupsCreated++; } // Not a single player flight group was created succesfully, abort mission generation if (totalGroupsCreated == 0) { throw new Exception("No player flight groups could be created, mission generation failed."); } return(briefingFGList.ToArray()); }
/// <summary> /// Creates an AI escort flight group in a single-player mission. /// </summary> /// <param name="mission">Mission to which generated units should be added</param> /// <param name="template">Mission template to use</param> /// <param name="count">Number of aircraft in the flight group</param> /// <param name="task">Escort task the flight group will be assigned with</param> /// <param name="playerCoalitionDB">Player coalition database entry</param> /// <returns>A <see cref="UnitFlightGroupBriefingDescription"/> describing the flight group, to be used in the briefing</returns> private UnitFlightGroupBriefingDescription?GenerateAIEscort(DCSMission mission, MissionTemplate template, int count, MissionTemplateFlightGroupTask task, DBEntryCoalition playerCoalitionDB) { if (count < 1) { return(null); // No aircraft, nothing to generate. } // Select proper payload for the flight group according to its tasking UnitTaskPayload payload = GetPayloadByTask(task, null); string groupLua; string[] aircraft; switch (task) { default: return(null); // Should never happen case MissionTemplateFlightGroupTask.SupportCAP: //groupLua = (template.GetMissionType() == MissionType.SinglePlayer) ? "GroupAircraftPlayerEscortCAP" : "GroupAircraftCAP"; groupLua = "GroupAircraftCAP"; aircraft = playerCoalitionDB.GetRandomUnits(UnitFamily.PlaneFighter, mission.DateTime.Decade, count, template.UnitMods); break; case MissionTemplateFlightGroupTask.SupportSEAD: //groupLua = (template.GetMissionType() == MissionType.SinglePlayer) ? "GroupAircraftPlayerEscortSEAD" : "GroupAircraftSEAD"; groupLua = "GroupAircraftSEAD"; aircraft = playerCoalitionDB.GetRandomUnits(UnitFamily.PlaneSEAD, mission.DateTime.Decade, count, template.UnitMods); break; } Coordinates position = mission.InitialPosition; // Player starts on runway, so escort starts in the air above the airfield (so player doesn't have to wait for them to take off) // OR mission is MP, so escorts start in air (but won't be spawned until at least one player takes off) // Add a random distance so they don't crash into each other. if ((template.PlayerFlightGroups[0].StartLocation == PlayerStartLocation.Runway) || (template.MissionType != MissionType.SinglePlayer)) { position += Coordinates.CreateRandom(2, 4) * Toolbox.NM_TO_METERS; } DCSMissionUnitGroup group; //if (template.GetMissionType() == MissionType.SinglePlayer) // group = UnitMaker.AddUnitGroup( // mission, aircraft, // Side.Ally, position, // groupLua, "UnitAircraft", // Toolbox.BRSkillLevelToDCSSkillLevel(template.PlayerAISkillLevel), 0, // payload, null, mission.InitialAirbaseID, true); //else group = UnitMaker.AddUnitGroup( mission, aircraft, Side.Ally, position, groupLua, "UnitAircraft", Toolbox.BRSkillLevelToDCSSkillLevel(template.SituationFriendlyAISkillLevel), 0, payload, mission.ObjectivesCenter); if (group == null) { DebugLog.Instance.WriteLine($"Failed to create AI escort flight group tasked with {task} with aircraft of type \"{aircraft[0]}\".", 1, DebugLogMessageErrorLevel.Warning); return(null); } switch (task) { default: return(null); // Should never happen case MissionTemplateFlightGroupTask.SupportCAP: mission.EscortCAPGroupId = group.GroupID; break; case MissionTemplateFlightGroupTask.SupportSEAD: mission.EscortSEADGroupId = group.GroupID; break; } return (new UnitFlightGroupBriefingDescription( group.Name, group.Units.Length, aircraft[0], GetTaskingDescription(task, null), Database.Instance.GetEntry <DBEntryUnit>(aircraft[0]).AircraftData.GetRadioAsString())); }
public DCSMissionUnitGroup AddUnitGroup( DCSMission mission, string[] units, Side side, Coordinates coordinates, string groupLua, string unitLua, DCSSkillLevel skill, DCSMissionUnitGroupFlags flags = 0, UnitTaskPayload payload = UnitTaskPayload.Default, Coordinates?coordinates2 = null, int airbaseID = 0, bool requiresParkingSpots = false, bool requiresOpenAirParking = false, Country?country = null, PlayerStartLocation startLocation = PlayerStartLocation.Runway) { if (units.Length == 0) { return(null); // No units database entries ID provided, cancel group creation } // TODO: check for missing units DBEntryUnit[] unitsBP = (from string u in units where Database.Instance.EntryExists <DBEntryUnit>(u) select Database.Instance.GetEntry <DBEntryUnit>(u)).ToArray(); unitsBP = (from DBEntryUnit u in unitsBP where u != null select u).ToArray(); if (unitsBP.Length == 0) { return(null); // All database entries were null, cancel group creation } Coalition coalition = (side == Side.Ally) ? mission.CoalitionPlayer : mission.CoalitionEnemy; // Pick group coalition if (!country.HasValue) { country = coalition == Coalition.Blue? Country.CJTFBlue : Country.CJTFRed; } double groupHeading = unitsBP[0].IsAircraft ? 0 : Toolbox.RandomDouble(Toolbox.TWO_PI); // Generate global group heading // Generate units in the group int unitIndex = 0; Coordinates?lastSpot = null; List <DCSMissionUnitGroupUnit> groupUnits = new List <DCSMissionUnitGroupUnit>(); foreach (DBEntryUnit unitBP in unitsBP) { if (unitBP == null) { continue; } for (int i = 0; i < unitBP.DCSIDs.Length; i++) { // Set unit coordinates and heading Coordinates unitCoordinates = coordinates; double unitHeading = groupHeading; SetUnitCoordinatesAndHeading(ref unitCoordinates, ref unitHeading, unitBP, unitIndex); // Get parking spot for the unit, if unit is parked at an airdrome int parkingSpot = 0; if (airbaseID > 0) { if (requiresParkingSpots) { parkingSpot = SpawnPointSelector.GetFreeParkingSpot(airbaseID, lastSpot, out Coordinates parkingCoordinates, requiresOpenAirParking); if (parkingSpot >= 0) { unitCoordinates = parkingCoordinates; } else { parkingSpot = 0; } lastSpot = unitCoordinates; } } else if (airbaseID == -99) //carrier code always parks 1 maybe will need more { parkingSpot = 1; } // Add unit to the list of units DCSMissionUnitGroupUnit unit = new DCSMissionUnitGroupUnit { Coordinates = unitCoordinates, Heading = unitHeading, ID = NextUnitID, Type = unitBP.DCSIDs[i], ParkingSpot = parkingSpot, Name = unitBP.ID }; groupUnits.Add(unit); unitIndex++; NextUnitID++; } } // Generate group name string groupName; UnitCallsign callsign = new UnitCallsign(); if (unitsBP[0].IsAircraft) // Aircraft group, name is a callsign { callsign = CallsignGenerator.GetCallsign(unitsBP[0].Families[0], coalition); groupName = callsign.GroupName; } else // Vehicle/ship/static group, name is a random group name { groupName = GetGroupName(unitsBP[0].Families[0]); } // Add group to the mission DCSMissionUnitGroup group = new DCSMissionUnitGroup { AirbaseID = airbaseID, CallsignLua = callsign.Lua, Category = unitsBP[0].Category, Coalition = coalition, Country = country.Value, Coordinates = airbaseID != 0? groupUnits[0].Coordinates : coordinates, Coordinates2 = coordinates2 ?? coordinates + Coordinates.CreateRandom(1, 2) * Toolbox.NM_TO_METERS, Flags = flags, GroupID = NextGroupID, LuaGroup = groupLua, Name = groupName, Skill = skill, Payload = payload, UnitID = units[0], LuaUnit = unitLua, Units = groupUnits.ToArray(), StartLocation = startLocation }; mission.UnitGroups.Add(group); NextGroupID++; DebugLog.Instance.WriteLine($"Added \"{group.Units[0].Type}\" unit group \"{group.Name}\" for coalition {group.Coalition.ToString().ToUpperInvariant()}", 2); return(group); }