/// <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]);
        }
예제 #2
0
        /// <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);
        }
예제 #3
0
        /// <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()));
        }
예제 #6
0
        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);
        }