예제 #1
0
        private static void CreateLua(DCSMission mission, MissionTemplateRecord template, DBEntryObjectiveTarget targetDB, DBEntryObjectiveTask taskDB, int objectiveIndex, string objectiveName, UnitMakerGroupInfo?targetGroupInfo, string taskString)
        {
            // Add Lua table for this objective
            string objectiveLua = $"briefingRoom.mission.objectives[{objectiveIndex + 1}] = {{ ";

            objectiveLua += $"complete = false, ";
            objectiveLua += $"groupID = {targetGroupInfo.Value.GroupID}, ";
            objectiveLua += $"hideTargetCount = false, ";
            objectiveLua += $"name = \"{objectiveName}\", ";
            objectiveLua += $"targetCategory = Unit.Category.{targetDB.UnitCategory.ToLuaName()}, ";
            objectiveLua += $"taskType = \"{taskDB.ID}\", ";
            objectiveLua += $"task = \"{taskString}\", ";
            objectiveLua += $"unitsCount = {targetGroupInfo.Value.UnitsID.Length}, ";
            objectiveLua += $"unitsID = {{ {string.Join(", ", targetGroupInfo.Value.UnitsID)} }} ";
            objectiveLua += "}\n";

            // Add F10 sub-menu for this objective
            objectiveLua += $"briefingRoom.f10Menu.objectives[{objectiveIndex + 1}] = missionCommands.addSubMenuForCoalition(coalition.side.{template.ContextPlayerCoalition.ToString().ToUpperInvariant()}, \"Objective {objectiveName}\", nil)\n";
            mission.AppendValue("ScriptObjectives", objectiveLua);

            // Add objective trigger Lua for this objective
            string triggerLua = Toolbox.ReadAllTextIfFileExists($"{BRPaths.INCLUDE_LUA_OBJECTIVETRIGGERS}{taskDB.CompletionTriggerLua}");

            GeneratorTools.ReplaceKey(ref triggerLua, "ObjectiveIndex", objectiveIndex + 1);
            mission.AppendValue("ScriptObjectivesTriggers", triggerLua);
        }
예제 #2
0
        private string CreateGroup(
            string groupTypeLua,
            Coordinates coordinates,
            string groupName,
            params KeyValuePair <string, object>[] extraSettings
            )
        {
            string lua = File.ReadAllText($"{BRPaths.INCLUDE_LUA_UNITS}{Toolbox.AddMissingFileExtension(groupTypeLua, ".lua")}");

            foreach (KeyValuePair <string, object> extraSetting in extraSettings) // Replace custom values first so they override other replacements
            {
                if (!(extraSetting.Value is Array))                               // Array extra settings are treated on a per-unit basis
                {
                    GeneratorTools.ReplaceKey(ref lua, extraSetting.Key, extraSetting.Value);
                }
            }

            GeneratorTools.ReplaceKey(ref lua, "GroupID", GroupID);
            GeneratorTools.ReplaceKey(ref lua, "GroupX", coordinates.X);
            GeneratorTools.ReplaceKey(ref lua, "GroupY", coordinates.Y);
            GeneratorTools.ReplaceKey(ref lua, "GroupX2", coordinates.X); // GroupX2 and GroupY2 are replaced by the default coordinates only if they were not replaced earlier in extraSetting replacements.
            GeneratorTools.ReplaceKey(ref lua, "GroupY2", coordinates.Y);
            GeneratorTools.ReplaceKey(ref lua, "Name", groupName);

            return(lua);
        }
예제 #3
0
        private static string ConstructTaskDescriptions(Dictionary <string, List <string> > descriptionsMap, DCSMission mission)
        {
            var briefingDescriptionList = new List <string>();
            var maxDescriptionCount     = Database.Instance.Common.Briefing.MaxObjectiveDescriptionCount;

            while (descriptionsMap.Keys.Count > 0 && briefingDescriptionList.Count < maxDescriptionCount)
            {
                var task = descriptionsMap.Keys.First();
                if (descriptionsMap.Keys.Count > 1)
                {
                    task = Out.Of()
                           .Values(descriptionsMap.Keys.ToList())
                           .WithWeights(descriptionsMap.Values.Select(x => x.Count).ToList())
                           .PickOne();
                }

                var item = descriptionsMap[task].GroupBy(i => i).OrderByDescending(grp => grp.Count()).Select(grp => grp.Key).First();
                descriptionsMap[task].Remove(item);
                if (descriptionsMap[task].Count == 0)
                {
                    descriptionsMap.Remove(task);
                }
                briefingDescriptionList.Add(item);
            }

            var description = GeneratorTools.ParseRandomString(JoinObjectiveDescriptions(briefingDescriptionList), mission);

            if (descriptionsMap.Keys.Count > 0 && briefingDescriptionList.Count == maxDescriptionCount)
            {
                description = $"{description} {Database.Instance.Common.Briefing.OverflowObjectiveDescriptionText}";
            }
            return(description);
        }
예제 #4
0
        protected void AddBriefingRemarkFromFeature(T featureDB, DCSMission mission, bool useEnemyRemarkIfAvailable, UnitMakerGroupInfo?groupInfo, Dictionary <string, object> stringReplacements)
        {
            string[] remarks;
            if (useEnemyRemarkIfAvailable && featureDB.BriefingRemarks[(int)Side.Enemy].Length > 0)
            {
                remarks = featureDB.BriefingRemarks[(int)Side.Enemy].ToArray();
            }
            else
            {
                remarks = featureDB.BriefingRemarks[(int)Side.Ally].ToArray();
            }
            if (remarks.Length == 0)
            {
                return;                      // No briefing remarks for this feature
            }
            string remark = Toolbox.RandomFrom(remarks);

            foreach (KeyValuePair <string, object> stringReplacement in stringReplacements)
            {
                GeneratorTools.ReplaceKey(ref remark, stringReplacement.Key, stringReplacement.Value.ToString());
            }

            if (groupInfo.HasValue)
            {
                GeneratorTools.ReplaceKey(ref remark, "GroupName", groupInfo.Value.Name);
                GeneratorTools.ReplaceKey(ref remark, "GroupFrequency", GeneratorTools.FormatRadioFrequency(groupInfo.Value.Frequency));
                GeneratorTools.ReplaceKey(ref remark, "GroupUnitName", groupInfo.Value.UnitDB.UIDisplayName);
            }

            mission.Briefing.AddItem(DCSMissionBriefingItemType.Remark, remark, featureDB is DBEntryFeatureMission);
        }
예제 #5
0
        private static void GenerateFOB(
            UnitMaker unitMaker, ZoneMaker zoneMaker, MissionTemplateFlightGroupRecord flightGroup, Dictionary <string, UnitMakerGroupInfo> carrierDictionary,
            DCSMission mission, MissionTemplateRecord template, Coordinates landbaseCoordinates, Coordinates objectivesCenter)
        {
            DBEntryTheater theaterDB = Database.Instance.GetEntry <DBEntryTheater>(template.ContextTheater);

            if (theaterDB == null)
            {
                return;                    // Theater doesn't exist. Should never happen.
            }
            Coordinates?spawnPoint =
                unitMaker.SpawnPointSelector.GetRandomSpawnPoint(
                    new SpawnPointType[] { SpawnPointType.LandLarge },
                    landbaseCoordinates,
                    new MinMaxD(5, template.FlightPlanObjectiveDistance),
                    objectivesCenter,
                    new MinMaxD(10, template.FlightPlanObjectiveDistance / 2), template.ContextPlayerCoalition);

            if (!spawnPoint.HasValue)
            {
                BriefingRoom.PrintToLog($"No spawn point found for FOB air defense unit groups", LogMessageErrorLevel.Warning);
                return;
            }

            DBEntryUnit unitDB = Database.Instance.GetEntry <DBEntryUnit>(flightGroup.Carrier);

            if (unitDB == null)
            {
                return;                 // Unit doesn't exist or is not a carrier
            }
            double radioFrequency = 127.5 + carrierDictionary.Count;
            var    FOBNames       = new List <string> {
                "FOB_London",
                "FOB_Dallas",
                "FOB_Paris",
                "FOB_Moscow",
                "FOB_Berlin"
            };

            UnitMakerGroupInfo?groupInfo =
                unitMaker.AddUnitGroup(
                    unitDB.Families[0], 1, Side.Ally,
                    "GroupStatic", "UnitStaticFOB",
                    spawnPoint.Value, 0,
                    "FOBCallSignIndex".ToKeyValuePair(FOBNames.IndexOf(flightGroup.Carrier) + 1),
                    "RadioBand".ToKeyValuePair((int)RadioModulation.AM),
                    "RadioFrequency".ToKeyValuePair(GeneratorTools.GetRadioFrenquency(radioFrequency)));

            if (!groupInfo.HasValue || (groupInfo.Value.UnitsID.Length == 0))
            {
                return;                                                               // Couldn't generate group
            }
            zoneMaker.AddCTLDPickupZone(spawnPoint.Value, true);
            mission.Briefing.AddItem(
                DCSMissionBriefingItemType.Airbase,
                $"{unitDB.UIDisplayName}\t-\t{GeneratorTools.FormatRadioFrequency(radioFrequency)}\t\t");
            carrierDictionary.Add(flightGroup.Carrier, groupInfo.Value); // This bit limits FOBS to one per game think about how we can fix this
        }
예제 #6
0
        private static Tuple <Coordinates, Coordinates> GetSpawnAndDestination(
            UnitMaker unitMaker, MissionTemplateRecord template, DBEntryTheater theaterDB,
            List <Coordinates> usedCoordinates, Coordinates landbaseCoordinates, Coordinates objectivesCenter,
            double carrierPathDeg)
        {
            var         travelMinMax            = new MinMaxD(Database.Instance.Common.CarrierGroup.CourseLength, Database.Instance.Common.CarrierGroup.CourseLength * 2);
            Coordinates?carrierGroupCoordinates = null;
            Coordinates?destinationPath         = null;
            var         iteration   = 0;
            var         maxDistance = 25;

            while (iteration < 100)
            {
                carrierGroupCoordinates = unitMaker.SpawnPointSelector.GetRandomSpawnPoint(
                    new SpawnPointType[] { SpawnPointType.Sea },
                    landbaseCoordinates,
                    new MinMaxD(10, maxDistance),
                    objectivesCenter,
                    new MinMaxD(10, 99999),
                    GeneratorTools.GetSpawnPointCoalition(template, Side.Ally));
                if (!carrierGroupCoordinates.HasValue)
                {
                    maxDistance += 25;
                    continue;
                }
                var minDist = usedCoordinates.Aggregate(99999999.0, (acc, x) => x.GetDistanceFrom(carrierGroupCoordinates.Value) < acc ? x.GetDistanceFrom(carrierGroupCoordinates.Value) : acc);
                if (minDist < Database.Instance.Common.CarrierGroup.ShipSpacing)
                {
                    continue;
                }

                destinationPath = Coordinates.FromAngleAndDistance(carrierGroupCoordinates.Value, travelMinMax, carrierPathDeg);
                if (ShapeManager.IsPosValid(destinationPath.Value, theaterDB.WaterCoordinates, theaterDB.WaterExclusionCoordinates))
                {
                    break;
                }
                iteration++;
                if (iteration > 10)
                {
                    maxDistance += 1;
                }
            }

            if (!carrierGroupCoordinates.HasValue)
            {
                throw new BriefingRoomException($"Carrier spawnpoint could not be found.");
            }
            if (!destinationPath.HasValue)
            {
                throw new BriefingRoomException($"Carrier destination could not be found.");
            }
            if (!ShapeManager.IsPosValid(destinationPath.Value, theaterDB.WaterCoordinates, theaterDB.WaterExclusionCoordinates))
            {
                throw new BriefingRoomException($"Carrier waypoint is on shore");
            }

            return(new(carrierGroupCoordinates.Value, destinationPath.Value));
        }
예제 #7
0
 private void AddToList(string UIName, string template, Coordinates coordinates, DrawingColour colour, DrawingColour fillColour)
 {
     GeneratorTools.ReplaceKey(ref template, "UIName", UIName);
     GeneratorTools.ReplaceKey(ref template, "X", coordinates.X);
     GeneratorTools.ReplaceKey(ref template, "Y", coordinates.Y);
     GeneratorTools.ReplaceKey(ref template, "Colour", colour.ToValue());
     GeneratorTools.ReplaceKey(ref template, "FillColour", fillColour.ToValue());
     LuaDrawings.Add(template);
 }
예제 #8
0
 private string ApplyAircraftFields(string groupLua, DBEntryUnit firstUnitDB, params KeyValuePair <string, object>[] extraSettings)
 {
     GeneratorTools.ReplaceKey(ref groupLua, "Altitude", firstUnitDB.AircraftData.CruiseAltitude);
     GeneratorTools.ReplaceKey(ref groupLua, "AltitudeHalf", firstUnitDB.AircraftData.CruiseAltitude / 2);
     GeneratorTools.ReplaceKey(ref groupLua, "EPLRS", firstUnitDB.Flags.HasFlag(DBEntryUnitFlags.EPLRS));
     GeneratorTools.ReplaceKey(ref groupLua, "RadioBand", (int)firstUnitDB.AircraftData.RadioModulation);
     GeneratorTools.ReplaceKey(ref groupLua, "RadioFrequency", firstUnitDB.AircraftData.RadioFrequency);
     GeneratorTools.ReplaceKey(ref groupLua, "Speed", firstUnitDB.AircraftData.CruiseSpeed);
     return(groupLua);
 }
예제 #9
0
        private void AddTextBox(string UIName, Coordinates coordinates, params KeyValuePair <string, object>[] extraSettings)
        {
            string drawingLuaTemplate = File.ReadAllText($"{BRPaths.INCLUDE_LUA_MISSION}\\Drawing\\TextBox.lua");

            GeneratorTools.ReplaceKey(ref drawingLuaTemplate, "Text", extraSettings.First(x => x.Key == "Text").Value);
            DrawingColour colour     = (DrawingColour)(extraSettings.FirstOrDefault(x => x.Key == "Colour").Value ?? DrawingColour.Red);
            DrawingColour fillColour = (DrawingColour)(extraSettings.FirstOrDefault(x => x.Key == "FillColour").Value ?? DrawingColour.White);

            AddToList(UIName, drawingLuaTemplate, coordinates, colour, fillColour);
        }
예제 #10
0
 private static void CreateTaskString(DCSMission mission, int pluralIndex, ref string taskString, string objectiveName, UnitFamily objectiveTargetUnitFamily)
 {
     // Get tasking string for the briefing
     if (string.IsNullOrEmpty(taskString))
     {
         taskString = "Complete objective $OBJECTIVENAME$";
     }
     GeneratorTools.ReplaceKey(ref taskString, "ObjectiveName", objectiveName);
     GeneratorTools.ReplaceKey(ref taskString, "UnitFamily", Database.Instance.Common.Names.UnitFamilies[(int)objectiveTargetUnitFamily][pluralIndex]);
     mission.Briefing.AddItem(DCSMissionBriefingItemType.Task, taskString);
 }
예제 #11
0
        private void AddToList(string UIName, Coordinates coordinates, int radius)
        {
            string template = File.ReadAllText($"{BRPaths.INCLUDE_LUA_MISSION}\\Zone.lua");

            GeneratorTools.ReplaceKey(ref template, "NAME", UIName);
            GeneratorTools.ReplaceKey(ref template, "RADIUS", radius);
            GeneratorTools.ReplaceKey(ref template, "X", coordinates.X);
            GeneratorTools.ReplaceKey(ref template, "Y", coordinates.Y);
            GeneratorTools.ReplaceKey(ref template, "zoneId", new Random().Next(100, 500));
            LuaZones.Add(template);
        }
예제 #12
0
 private static void SaveFlightGroup(DCSMission mission, UnitMakerGroupInfo?groupInfo, MissionTemplateFlightGroupRecord flightGroup, DBEntryUnit unitDB, string homeBase)
 {
     mission.Briefing.AddItem(DCSMissionBriefingItemType.FlightGroup,
                              $"{groupInfo.Value.Name}(P)\t" +
                              $"{flightGroup.Count}× {unitDB.UIDisplayName}\t" +
                              $"{GeneratorTools.FormatRadioFrequency(unitDB.AircraftData.RadioFrequency)}\t" +
                              $"{Toolbox.FormatPayload(flightGroup.Payload)}\t" +
                              $"{homeBase}");
     for (int i = 0; i < flightGroup.Count; i++)
     {
         mission.AppendValue("SCRIPTCLIENTPILOTNAMES", $"\"{groupInfo.Value.Name} {i + 2}\",");
     }
 }
예제 #13
0
        internal string GetLuaDrawings()
        {
            string luaDrawings = "";

            var index = 1;

            foreach (var drawing in LuaDrawings)
            {
                var drawingLua = drawing;
                GeneratorTools.ReplaceKey(ref drawingLua, "Index", index);
                luaDrawings += $"{drawingLua}\n";
                index++;
            }
            return(luaDrawings);
        }
예제 #14
0
        internal string GetLuaZones()
        {
            string luaDrawings = "";

            var index = 1;

            foreach (var zone in LuaZones)
            {
                var zoneLua = zone;
                GeneratorTools.ReplaceKey(ref zoneLua, "Index", index);
                luaDrawings += $"{zoneLua}\n";
                index++;
            }
            return(luaDrawings);
        }
예제 #15
0
        private void AddEmbeddedAirDefenseUnits(MissionTemplateRecord template, DBEntryObjectiveTarget targetDB, DBEntryObjectiveTargetBehavior targetBehaviorDB, DBEntryObjectiveTask taskDB, ObjectiveOption[] objectiveOptions, Coordinates objectiveCoordinates, UnitMakerGroupFlags groupFlags, List <KeyValuePair <string, object> > extraSettings)
        {
            // Static targets (aka buildings) need to have their "embedded" air defenses spawned in another group
            string[] airDefenseUnits = GeneratorTools.GetEmbeddedAirDefenseUnits(template, taskDB.TargetSide);

            if (airDefenseUnits.Length > 0)
            {
                UnitMaker.AddUnitGroup(
                    airDefenseUnits,
                    taskDB.TargetSide, UnitFamily.VehicleAAA,
                    targetBehaviorDB.GroupLua[(int)targetDB.UnitCategory], targetBehaviorDB.UnitLua[(int)targetDB.UnitCategory],
                    objectiveCoordinates + Coordinates.CreateRandom(100, 500),
                    groupFlags,
                    extraSettings.ToArray());
            }
        }
예제 #16
0
 private string GetExtraSettingsFromFeature(T featureDB, ref Dictionary <string, object> extraSettings)
 {
     // TODO: Improve
     if (featureDB.UnitGroupFlags.HasFlag(FeatureUnitGroupFlags.TACAN) && (featureDB.UnitGroupFamilies.Length > 0))
     {
         var callsign = $"{GeneratorTools.GetTACANCallsign(featureDB.UnitGroupFamilies[0])}{TACANIndex}";
         var channel  = ((GetType() == typeof(MissionGeneratorFeaturesObjectives)) ? 30 : 20) + TACANIndex;
         extraSettings.AddIfKeyUnused("TACANFrequency", 1108000000);
         extraSettings.AddIfKeyUnused("TACANCallsign", callsign);
         extraSettings.AddIfKeyUnused("TACANChannel", channel);
         if (TACANIndex < 9)
         {
             TACANIndex++;
         }
         return($",\n{channel}X (callsign {callsign})");
     }
     return("");
 }
예제 #17
0
        internal static Month GenerateMissionDate(DCSMission mission, MissionTemplateRecord template)
        {
            int   day;
            Month month;

            // Select a random year from the most recent coalition's decade.
            var year = Toolbox.GetRandomYearFromDecade(template.ContextDecade);

            BriefingRoom.PrintToLog($"No fixed date provided in the mission template, generating date in decade {template.ContextDecade}");

            if (template.EnvironmentSeason == Season.Random) // Random season, pick any day of the year.
            {
                month = (Month)Toolbox.RandomInt(12);
                day   = Toolbox.RandomMinMax(1, GeneratorTools.GetDaysPerMonth(month, year));
            }
            else // Pick a date according to the desired season
            {
                Month[] seasonMonths = GetMonthsForSeason(template.EnvironmentSeason);

                int monthIndex = Toolbox.RandomInt(4);
                month = seasonMonths[monthIndex];
                switch (monthIndex)
                {
                case 0:     // First month of the season, season begins on the 21st
                    day = Toolbox.RandomMinMax(21, GeneratorTools.GetDaysPerMonth(month, year)); break;

                case 3:     // Last month of the season, season ends on the 20th
                    day = Toolbox.RandomMinMax(1, 20); break;

                default:
                    day = Toolbox.RandomMinMax(1, GeneratorTools.GetDaysPerMonth(month, year)); break;
                }
            }

            mission.SetValue("DateDay", day);
            mission.SetValue("DateMonth", (int)month + 1);
            mission.SetValue("DateYear", year);
            mission.SetValue("BriefingDate", $"{(int)month + 1:00}/{day:00}/{year:0000}");

            BriefingRoom.PrintToLog($"Misson date set to {day} {month} {year}.");
            return(month);
        }
예제 #18
0
        private void SpawnExtraGroups(T featureDB, DCSMission mission, Side groupSide, UnitMakerGroupFlags groupFlags, Coordinates coordinates, Coordinates coordinates2, Dictionary <string, object> extraSettings)
        {
            foreach (var i in Enumerable.Range(1, featureDB.ExtraGroups.GetValue()))
            {
                var groupLua    = featureDB.UnitGroupLuaGroup;
                var unitCount   = featureDB.UnitGroupSize.GetValue();
                var unitFamily  = Toolbox.RandomFrom(featureDB.UnitGroupFamilies);
                var luaUnit     = featureDB.UnitGroupLuaUnit;
                var spawnCoords = _unitMaker.SpawnPointSelector.GetRandomSpawnPoint(
                    featureDB.UnitGroupValidSpawnPoints, coordinates,
                    new MinMaxD(0, 5),
                    coalition: GeneratorTools.GetSpawnPointCoalition(_template, groupSide)
                    );
                if (!spawnCoords.HasValue)
                {
                    continue;
                }

                SetAirbase(featureDB, unitFamily, ref groupLua, ref luaUnit, groupSide, ref coordinates, coordinates2, unitCount, ref extraSettings);

                var groupInfo = _unitMaker.AddUnitGroup(
                    unitFamily, unitCount,
                    groupSide,
                    groupLua, luaUnit,
                    spawnCoords.Value, groupFlags,
                    extraSettings.ToArray());

                if (
                    groupSide == Side.Ally &&
                    groupInfo.HasValue &&
                    groupInfo.Value.UnitDB != null &&
                    groupInfo.Value.UnitDB.IsAircraft)
                {
                    mission.Briefing.AddItem(DCSMissionBriefingItemType.FlightGroup,
                                             $"{groupInfo.Value.Name}\t" +
                                             $"{unitCount}× {groupInfo.Value.UnitDB.UIDisplayName}\t" +
                                             $"{GeneratorTools.FormatRadioFrequency(groupInfo.Value.Frequency)}\t" +
                                             $"{Toolbox.FormatPayload(featureDB.UnitGroupPayload)}");
                }
            }
        }
예제 #19
0
        internal static void GenerateWarehouses(DCSMission mission)
        {
            string warehousesAirportLua = "";

            if (!File.Exists(AIRPORT_TEMPLATE_FILEPATH))
            {
                throw new Exception("Airport warehouse template file (Include\\Lua\\Warehouses\\Airport.lua) not found.");
            }

            string airportLuaTemplate = File.ReadAllText(AIRPORT_TEMPLATE_FILEPATH);

            foreach (int airbaseID in mission.Airbases.Keys)
            {
                string airportLua = airportLuaTemplate;
                GeneratorTools.ReplaceKey(ref airportLua, "index", airbaseID);
                GeneratorTools.ReplaceKey(ref airportLua, "coalition", mission.Airbases[airbaseID].ToString().ToUpperInvariant());

                warehousesAirportLua += airportLua + "\r\n";
            }

            mission.SetValue("WarehousesAirports", warehousesAirportLua);
        }
예제 #20
0
        internal static void GenerateMissionBriefingDescription(DCSMission mission, MissionTemplateRecord template, List <UnitFamily> objectiveTargetUnitFamilies, DBEntrySituation situationDB)
        {
            // Try to get the provided custom mission description.
            string briefingDescription = (template.BriefingMissionDescription ?? "").Replace("\r\n", "\n").Replace("\n", " ").Trim();

            // No custom description found, generate one from the most frequent objective task/target combination.
            if (string.IsNullOrEmpty(briefingDescription))
            {
                if (template.Objectives.Count == 0)
                {
                    briefingDescription = "";
                }
                else
                {
                    var familyCount = 0;
                    Dictionary <string, List <string> > descriptionsMap = new Dictionary <string, List <string> >();
                    foreach (var obj in template.Objectives)
                    {
                        DBEntryBriefingDescription descriptionDB =
                            Database.Instance.GetEntry <DBEntryBriefingDescription>(
                                Database.Instance.GetEntry <DBEntryObjectiveTask>(obj.Task).BriefingDescription);
                        AppendDescription(obj.Task, descriptionDB.DescriptionText[(int)objectiveTargetUnitFamilies[familyCount]], ref descriptionsMap);
                        familyCount++;
                        AddSubTasks(obj, objectiveTargetUnitFamilies, ref descriptionsMap, ref familyCount);
                    }

                    briefingDescription = ConstructTaskDescriptions(descriptionsMap, mission);
                }
            }

            if (situationDB.BriefingDescriptions != null && situationDB.BriefingDescriptions.Count > 0)
            {
                briefingDescription = GeneratorTools.ParseRandomString(string.Join(" ", Toolbox.RandomFrom(situationDB.BriefingDescriptions), briefingDescription), mission);
            }

            mission.Briefing.Description = briefingDescription;
            mission.SetValue("BRIEFINGDESCRIPTION", briefingDescription);
        }
예제 #21
0
        private void AddFree(string UIName, Coordinates coordinates, params KeyValuePair <string, object>[] extraSettings)
        {
            string drawingLuaTemplate = File.ReadAllText($"{BRPaths.INCLUDE_LUA_MISSION}\\Drawing\\Free.lua");
            string freePosLuaTemplate = File.ReadAllText($"{BRPaths.INCLUDE_LUA_MISSION}\\Drawing\\FreePos.lua");

            var points = "";
            var index  = 1;

            foreach (Coordinates pos in (List <Coordinates>)extraSettings.First(x => x.Key == "Points").Value)
            {
                var templateLua = new String(freePosLuaTemplate);
                GeneratorTools.ReplaceKey(ref templateLua, "Index", index);
                GeneratorTools.ReplaceKey(ref templateLua, "X", pos.X);
                GeneratorTools.ReplaceKey(ref templateLua, "Y", pos.Y);
                points += $"{templateLua}\n";
                index++;
            }
            GeneratorTools.ReplaceKey(ref drawingLuaTemplate, "POINTS", points);
            DrawingColour colour     = (DrawingColour)(extraSettings.FirstOrDefault(x => x.Key == "Colour").Value ?? DrawingColour.Red);
            DrawingColour fillColour = (DrawingColour)(extraSettings.FirstOrDefault(x => x.Key == "FillColour").Value ?? DrawingColour.RedFill);

            AddToList(UIName, drawingLuaTemplate, coordinates, colour, fillColour);
        }
예제 #22
0
        private static string GenerateFlightPlanLua(List <Waypoint> waypoints)
        {
            string flightPlanLua       = "";
            string waypointLuaTemplate = File.ReadAllText($"{BRPaths.INCLUDE_LUA_MISSION}WaypointPlayer.lua");

            for (int i = 0; i < waypoints.Count; i++)
            {
                string waypointLua = waypointLuaTemplate;

                GeneratorTools.ReplaceKey(ref waypointLua, "Index", i + 2);
                GeneratorTools.ReplaceKey(ref waypointLua, "Name", waypoints[i].Name);
                GeneratorTools.ReplaceKey(ref waypointLua, "X", waypoints[i].Coordinates.X);
                GeneratorTools.ReplaceKey(ref waypointLua, "Y", waypoints[i].Coordinates.Y);
                if (waypoints[i].OnGround)
                {
                    GeneratorTools.ReplaceKey(ref waypointLua, "Altitude", "0");
                }

                flightPlanLua += waypointLua + "\n";
            }

            return(flightPlanLua);
        }
예제 #23
0
        private Coordinates GetSpawnCoordinates(MissionTemplateRecord template, Coordinates lastCoordinates, DBEntryAirbase playerAirbase, DBEntryObjectiveTarget targetDB)
        {
            int objectiveDistance = template.FlightPlanObjectiveDistance;

            if (objectiveDistance < 1)
            {
                objectiveDistance = Toolbox.RandomInt(40, 160);
            }

            int objectiveSeperation = template.FlightPlanObjectiveSeperation;

            if (objectiveSeperation < 1)
            {
                objectiveSeperation = Toolbox.RandomInt(10, 100);
            }

            Coordinates?spawnPoint = UnitMaker.SpawnPointSelector.GetRandomSpawnPoint(
                targetDB.ValidSpawnPoints,
                playerAirbase.Coordinates,
                new MinMaxD(
                    objectiveDistance * OBJECTIVE_DISTANCE_VARIATION_MIN,
                    objectiveDistance * OBJECTIVE_DISTANCE_VARIATION_MAX),
                lastCoordinates,
                new MinMaxD(
                    objectiveSeperation * OBJECTIVE_DISTANCE_VARIATION_MIN,
                    objectiveSeperation * OBJECTIVE_DISTANCE_VARIATION_MAX),
                GeneratorTools.GetSpawnPointCoalition(template, Side.Enemy));

            if (!spawnPoint.HasValue)
            {
                throw new BriefingRoomException($"Failed to spawn objective unit group. {String.Join(",", targetDB.ValidSpawnPoints.Select(x => x.ToString()).ToList())} Please try again (Consider Adusting Flight Plan)");
            }

            Coordinates objectiveCoordinates = spawnPoint.Value;

            return(objectiveCoordinates);
        }
예제 #24
0
        internal UnitMakerGroupInfo?AddUnitGroup(
            List <UnitFamily> families, int unitCount, Side side,
            string groupLua, string unitLua,
            Coordinates coordinates,
            UnitMakerGroupFlags unitMakerGroupFlags = 0,
            params KeyValuePair <string, object>[] extraSettings)
        {
            if (unitCount <= 0)
            {
                throw new BriefingRoomException("Asking for a zero units");
            }
            if (families.Count <= 0)
            {
                throw new BriefingRoomException("No Unit Families Provided");
            }
            DBEntryCoalition unitsCoalitionDB = CoalitionsDB[(int)((side == Side.Ally) ? PlayerCoalition : PlayerCoalition.GetEnemy())];

            var(country, units) = unitsCoalitionDB.GetRandomUnits(families, Template.ContextDecade, unitCount, Template.Mods);
            if (units.Count == 0)
            {
                throw new BriefingRoomException($"Found no units for {string.Join(", ", families)} {country}");
            }
            if (country != Country.ALL)
            {
                extraSettings = extraSettings.Append("Country".ToKeyValuePair(country)).ToArray();
            }


            if (unitMakerGroupFlags.HasFlag(UnitMakerGroupFlags.EmbeddedAirDefense) && (families.First().GetUnitCategory() == UnitCategory.Vehicle))
            {
                string[] airDefenseUnits = GeneratorTools.GetEmbeddedAirDefenseUnits(Template, side, country != Country.ALL ? country : null);
                units.AddRange(airDefenseUnits);
            }

            return(AddUnitGroup(Toolbox.ShuffleArray(units.ToArray()), side, families.First(), groupLua, unitLua, coordinates, unitMakerGroupFlags, extraSettings));
        }
예제 #25
0
        private void SetAirbase(T featureDB, UnitFamily unitFamily, ref string groupLua, ref string luaUnit, Side groupSide, ref Coordinates coordinates, Coordinates coordinates2, int unitCount, ref Dictionary <string, object> extraSettings)
        {
            if ((_template.MissionFeatures.Contains("ContextGroundStartAircraft") || featureDB.UnitGroupFlags.HasFlag(FeatureUnitGroupFlags.GroundStart)) && Toolbox.IsAircraft(unitFamily.GetUnitCategory()))
            {
                if (groupLua != "GroupAircraftParkedUncontrolled")
                {
                    groupLua += "Parked";
                }
                luaUnit += "Parked";
                var(airbase, parkingSpotIDsList, parkingSpotCoordinatesList) = _unitMaker.SpawnPointSelector.GetAirbaseAndParking(
                    _template, coordinates, unitCount,
                    GeneratorTools.GetSpawnPointCoalition(_template, groupSide, true).Value,
                    unitFamily);
                coordinates = airbase.Coordinates;
                extraSettings["ParkingID"]      = parkingSpotIDsList.ToArray();
                extraSettings["GroupAirbaseID"] = airbase.DCSID;
                extraSettings["UnitX"]          = (from Coordinates unitCoordinates in parkingSpotCoordinatesList select unitCoordinates.X).ToArray();
                extraSettings["UnitY"]          = (from Coordinates unitCoordinates in parkingSpotCoordinatesList select unitCoordinates.Y).ToArray();

                var midPoint = Coordinates.Lerp(coordinates, coordinates2, 0.4);
                extraSettings.AddIfKeyUnused("GroupMidX", midPoint.X);
                extraSettings.AddIfKeyUnused("GroupMidY", midPoint.Y);
            }
        }
예제 #26
0
        protected UnitMakerGroupInfo?AddMissionFeature(T featureDB, DCSMission mission, Coordinates coordinates, Coordinates?coordinates2, ref Dictionary <string, object> extraSettings, Side?objectiveTargetSide = null, bool hideEnemy = false)
        {
            // Add secondary coordinates (destination point) to the extra settings
            if (!coordinates2.HasValue)
            {
                coordinates2 = coordinates;                         // No destination point? Use initial point
            }
            extraSettings.AddIfKeyUnused("GroupX2", coordinates2.Value.X);
            extraSettings.AddIfKeyUnused("GroupY2", coordinates2.Value.Y);
            var TACANStr = GetExtraSettingsFromFeature(featureDB, ref extraSettings); // Add specific settings for this feature (TACAN frequencies, etc)

            // Feature unit group
            UnitMakerGroupInfo?groupInfo = null;

            if (FeatureHasUnitGroup(featureDB))
            {
                UnitMakerGroupFlags groupFlags = 0;

                if (featureDB.UnitGroupFlags.HasFlag(FeatureUnitGroupFlags.ImmediateAircraftActivation))
                {
                    groupFlags |= UnitMakerGroupFlags.ImmediateAircraftSpawn;
                }

                if (featureDB.UnitGroupFlags.HasFlag(FeatureUnitGroupFlags.RadioAircraftActivation))
                {
                    groupFlags |= UnitMakerGroupFlags.RadioAircraftSpawn;
                }

                Side groupSide = Side.Enemy;
                if (featureDB.UnitGroupFlags.HasFlag(FeatureUnitGroupFlags.Friendly))
                {
                    groupSide = Side.Ally;
                }
                else if (featureDB.UnitGroupFlags.HasFlag(FeatureUnitGroupFlags.SameSideAsTarget) && objectiveTargetSide.HasValue)
                {
                    groupSide = objectiveTargetSide.Value;
                }

                if (hideEnemy && groupSide == Side.Enemy)
                {
                    groupFlags |= UnitMakerGroupFlags.AlwaysHidden;
                }

                extraSettings.AddIfKeyUnused("Payload", featureDB.UnitGroupPayload);
                var groupLua   = featureDB.UnitGroupLuaGroup;
                var unitCount  = featureDB.UnitGroupSize.GetValue();
                var unitFamily = Toolbox.RandomFrom(featureDB.UnitGroupFamilies);
                var luaUnit    = featureDB.UnitGroupLuaUnit;
                SetAirbase(featureDB, unitFamily, ref groupLua, ref luaUnit, groupSide, ref coordinates, coordinates2.Value, unitCount, ref extraSettings);

                groupInfo = _unitMaker.AddUnitGroup(
                    unitFamily, unitCount,
                    groupSide,
                    groupLua, luaUnit,
                    coordinates, groupFlags,
                    extraSettings.ToArray());
                if (
                    groupSide == Side.Ally &&
                    groupInfo.HasValue &&
                    groupInfo.Value.UnitDB != null &&
                    groupInfo.Value.UnitDB.IsAircraft)
                {
                    mission.Briefing.AddItem(DCSMissionBriefingItemType.FlightGroup,
                                             $"{groupInfo.Value.Name}\t" +
                                             $"{unitCount}× {groupInfo.Value.UnitDB.UIDisplayName}\t" +
                                             $"{GeneratorTools.FormatRadioFrequency(groupInfo.Value.Frequency)}{TACANStr}\t" +
                                             $"{Toolbox.FormatPayload(featureDB.UnitGroupPayload)}"); // TODO: human-readable payload name
                }
                if (featureDB.ExtraGroups.Max > 1)
                {
                    SpawnExtraGroups(featureDB, mission, groupSide, groupFlags, coordinates, coordinates2.Value, extraSettings);
                }
            }

            // Feature Lua script
            string featureLua = "";

            // Adds the features' group ID to the briefingRoom.mission.missionFeatures.groupsID table
            if (this is MissionGeneratorFeaturesMission)
            {
                featureLua += $"briefingRoom.mission.missionFeatures.groupsID.{GeneratorTools.LowercaseFirstCharacter(featureDB.ID)} = {(groupInfo.HasValue ? groupInfo.Value.GroupID : 0)}\n";
                featureLua += $"briefingRoom.mission.missionFeatures.unitsID.{GeneratorTools.LowercaseFirstCharacter(featureDB.ID)} = {{{(groupInfo.HasValue ? string.Join(",", groupInfo.Value.UnitsID) : "")}}}\n";
            }

            if (!string.IsNullOrEmpty(featureDB.IncludeLuaSettings))
            {
                featureLua = featureDB.IncludeLuaSettings + "\n";
            }
            foreach (string luaFile in featureDB.IncludeLua)
            {
                featureLua += Toolbox.ReadAllTextIfFileExists($"{featureDB.SourceLuaDirectory}{luaFile}") + "\n";
            }
            foreach (KeyValuePair <string, object> extraSetting in extraSettings)
            {
                GeneratorTools.ReplaceKey(ref featureLua, extraSetting.Key, extraSetting.Value);
            }
            if (groupInfo.HasValue)
            {
                GeneratorTools.ReplaceKey(ref featureLua, "FeatureGroupID", groupInfo.Value.GroupID);
            }

            if (featureDB is DBEntryFeatureObjective)
            {
                mission.AppendValue("ScriptObjectivesFeatures", featureLua);
            }
            else
            {
                mission.AppendValue("ScriptMissionFeatures", featureLua);
            }

            // Add feature ogg files
            foreach (string oggFile in featureDB.IncludeOgg)
            {
                mission.AddMediaFile($"l10n/DEFAULT/{oggFile}", $"{BRPaths.INCLUDE_OGG}{oggFile}");
            }

            return(groupInfo);
        }
예제 #27
0
        private UnitMakerGroupInfo?AddStaticGroup(
            Country country,
            Coalition coalition,
            DCSSkillLevel?skill,
            UnitFamily unitFamily,
            Side side,
            string[] unitSets,
            string groupName,
            UnitCallsign?callsign,
            string groupTypeLua,
            Coordinates coordinates,
            UnitMakerGroupFlags unitMakerGroupFlags,
            params KeyValuePair <string, object>[] extraSettings
            )
        {
            List <int> unitsIDList   = new List <int>();
            var        initalGroupId = GroupID;

            foreach (var unitSet in unitSets)
            {
                DBEntryUnit unitDB = Database.Instance.GetEntry <DBEntryUnit>(unitSet);
                if (unitDB == null)
                {
                    BriefingRoom.PrintToLog($"Unit \"{unitSet}\" not found.", LogMessageErrorLevel.Warning);
                    continue;
                }
                int unitSetIndex = 0;
                foreach (var DCSID in unitDB.DCSIDs)
                {
                    var groupHeading = GetGroupHeading(coordinates, extraSettings);
                    SetUnitCoordinatesAndHeading(unitDB, unitSetIndex, coordinates, groupHeading, out Coordinates unitCoordinates, out double unitHeading);
                    var firstUnitID = UnitID;
                    var groupLua    = CreateGroup(
                        groupTypeLua,
                        unitCoordinates,
                        groupName,
                        extraSettings
                        );
                    var unitLua       = DCSID == "FARP" ? "UnitStaticFOB" : (unitDB.Category == UnitCategory.Cargo ? "UnitCargo" : "UnitStatic");
                    var unitsLuaTable = AddUnit(
                        DCSID,
                        groupName,
                        callsign,
                        1,
                        unitSetIndex,
                        unitDB,
                        unitLua,
                        coordinates,
                        unitMakerGroupFlags,
                        extraSettings
                        );

                    unitsIDList.Add(UnitID);
                    unitSetIndex++;
                    UnitID++;

                    GeneratorTools.ReplaceKey(ref groupLua, "Units", unitsLuaTable);


                    GeneratorTools.ReplaceKey(ref groupLua, "UnitID", firstUnitID);                                                                         // Must be after units are added
                    GeneratorTools.ReplaceKey(ref groupLua, "Skill", skill);                                                                                // Must be after units are added, because skill is set as a unit level
                    GeneratorTools.ReplaceKey(ref groupLua, "Hidden", GeneratorTools.GetHiddenStatus(Template.OptionsFogOfWar, side, unitMakerGroupFlags)); // If "hidden" was not set through custom values

                    AddUnitGroupToTable(country, UnitCategory.Static, groupLua);

                    BriefingRoom.PrintToLog($"Added group of {DCSID} {coalition} {unitFamily} at {coordinates}");

                    GroupID++;
                }
            }

            if (unitMakerGroupFlags.HasFlag(UnitMakerGroupFlags.EmbeddedAirDefense) && unitFamily != UnitFamily.StaticStructureOffshore)
            {
                var      firstUnitID     = UnitID;
                string[] airDefenseUnits = GeneratorTools.GetEmbeddedAirDefenseUnits(Template, side);
                var      groupLua        = CreateGroup(
                    "GroupVehicle",
                    coordinates,
                    groupName,
                    extraSettings
                    );
                var(unitsLuaTable, embeddedunitsIDList) = AddUnits(
                    airDefenseUnits,
                    groupName,
                    callsign,
                    "UnitVehicle",
                    coordinates,
                    unitMakerGroupFlags,
                    extraSettings
                    );
                GeneratorTools.ReplaceKey(ref groupLua, "Units", unitsLuaTable);
                GeneratorTools.ReplaceKey(ref groupLua, "UnitID", firstUnitID);                                                                         // Must be after units are added
                GeneratorTools.ReplaceKey(ref groupLua, "Skill", skill);                                                                                // Must be after units are added, because skill is set as a unit level
                GeneratorTools.ReplaceKey(ref groupLua, "Hidden", GeneratorTools.GetHiddenStatus(Template.OptionsFogOfWar, side, unitMakerGroupFlags)); // If "hidden" was not set through custom values
                GroupID++;
                unitsIDList.AddRange(embeddedunitsIDList);
                AddUnitGroupToTable(country, UnitCategory.Vehicle, groupLua);
                BriefingRoom.PrintToLog($"Added group of Embedded Air Defense for Static {coalition} {unitFamily} at {coordinates}");
            }

            DBEntryUnit firstUnitDB = Database.Instance.GetEntry <DBEntryUnit>(unitSets.First());

            if (firstUnitDB == null)
            {
                return(new UnitMakerGroupInfo(initalGroupId, coordinates, unitsIDList, groupName));
            }
            return(new UnitMakerGroupInfo(initalGroupId, coordinates, unitsIDList, groupName, firstUnitDB.AircraftData.RadioFrequency, firstUnitDB));
        }
예제 #28
0
        private string AddUnit(
            string DCSID,
            string groupName,
            UnitCallsign?callsign,
            int unitLuaIndex,
            int unitSetIndex,
            DBEntryUnit unitDB,
            string unitTypeLua,
            Coordinates coordinates,
            UnitMakerGroupFlags unitMakerGroupFlags,
            params KeyValuePair <string, object>[] extraSettings)
        {
            string unitLuaTemplate = File.ReadAllText($"{BRPaths.INCLUDE_LUA_UNITS}{Toolbox.AddMissingFileExtension(unitTypeLua, ".lua")}");
            var    groupHeading    = GetGroupHeading(coordinates, extraSettings);

            SetUnitCoordinatesAndHeading(unitDB, unitSetIndex, coordinates, groupHeading, out Coordinates unitCoordinates, out double unitHeading);

            string singleUnitLuaTable = new string(unitLuaTemplate);

            if (Toolbox.IsAircraft(unitDB.Category) && (unitLuaIndex == 1) && unitMakerGroupFlags.HasFlag(UnitMakerGroupFlags.FirstUnitIsClient))
            {
                GeneratorTools.ReplaceKey(ref singleUnitLuaTable, "Skill", SinglePlayerMission ? "Player" : "Client");
            }

            foreach (KeyValuePair <string, object> extraSetting in extraSettings) // Replace custom values first so they override other replacements
            {
                if (extraSetting.Value is Array)
                {
                    GeneratorTools.ReplaceKey(ref singleUnitLuaTable, extraSetting.Key, extraSetting.Value, unitLuaIndex - 1);
                }
                else
                {
                    GeneratorTools.ReplaceKey(ref singleUnitLuaTable, extraSetting.Key, extraSetting.Value);
                }
            }

            GeneratorTools.ReplaceKey(ref singleUnitLuaTable, "ExtraLua", unitDB.ExtraLua);
            GeneratorTools.ReplaceKey(ref singleUnitLuaTable, "Heading", unitHeading);
            GeneratorTools.ReplaceKey(ref singleUnitLuaTable, "DCSID", DCSID);
            GeneratorTools.ReplaceKey(ref singleUnitLuaTable, "UnitID", UnitID);
            GeneratorTools.ReplaceKey(ref singleUnitLuaTable, "UnitX", unitCoordinates.X);
            GeneratorTools.ReplaceKey(ref singleUnitLuaTable, "UnitY", unitCoordinates.Y);
            if (Toolbox.IsAircraft(unitDB.Category))
            {
                GeneratorTools.ReplaceKey(ref singleUnitLuaTable, "Callsign", callsign.Value.GetLua(unitLuaIndex));
                GeneratorTools.ReplaceKey(ref singleUnitLuaTable, "Name", callsign.Value.GetUnitName(unitLuaIndex));
                GeneratorTools.ReplaceKey(ref singleUnitLuaTable, "OnBoardNumber", Toolbox.RandomInt(1, 1000).ToString("000"));
                GeneratorTools.ReplaceKey(ref singleUnitLuaTable, "PropsLua", unitDB.AircraftData.PropsLua);
                GeneratorTools.ReplaceKey(ref singleUnitLuaTable, "RadioPresetsLua", string.Join("", unitDB.AircraftData.RadioPresets.Select((x, index) => $"[{index + 1}] = {x.ToLuaString()}")));
                GeneratorTools.ReplaceKey(ref singleUnitLuaTable, "Speed", unitDB.AircraftData.CruiseSpeed);
                GeneratorTools.ReplaceKey(ref singleUnitLuaTable, "PayloadCommon", unitDB.AircraftData.PayloadCommon);
                var payload = unitDB.AircraftData.GetPayloadLua(extraSettings.Any(x => x.Key == "Payload") ? extraSettings.First(x => x.Key == "Payload").Value.ToString() : "default");
                if (extraSettings.Any(x => x.Key == "Payload" && x.Value.ToString() == "EMPTY"))
                {
                    payload = "";
                }
                GeneratorTools.ReplaceKey(ref singleUnitLuaTable, "PayloadPylons", payload);
                GeneratorTools.ReplaceKey(ref singleUnitLuaTable, "Livery", extraSettings.Any(x => x.Key == "Livery") ? extraSettings.First(x => x.Key == "Livery").Value : "default");
            }
            else if (unitDB.Category == UnitCategory.Static || unitDB.Category == UnitCategory.Cargo)
            {
                if (unitDB.Shape.Length - 1 > unitSetIndex)
                {
                    GeneratorTools.ReplaceKey(ref singleUnitLuaTable, "Shape", unitDB.Shape[unitSetIndex]);
                }
                GeneratorTools.ReplaceKey(ref singleUnitLuaTable, "Name", $"{groupName} {unitLuaIndex}");
            }
            else
            {
                GeneratorTools.ReplaceKey(ref singleUnitLuaTable, "Name", $"{groupName} {unitLuaIndex}");
            }

            var unitString = $"[{unitLuaIndex}] =\n";

            unitString += "{\n";
            unitString += $"{singleUnitLuaTable}\n";
            unitString += $"}}, -- end of [{unitLuaIndex}]\n";

            return(unitString);
        }
예제 #29
0
        private static void CreateCAPGroups(
            UnitMaker unitMaker, MissionTemplateRecord template, Side side,
            Coalition coalition, AmountNR capAmount, Coordinates centerPoint,
            Coordinates opposingPoint, Coordinates destination, ref List <int> capAircraftGroupIDs)
        {
            var commonCAPDB             = Database.Instance.Common.CAP;
            DBCommonCAPLevel capLevelDB = commonCAPDB.CAPLevels[(int)capAmount];

            int unitsLeftToSpawn = capLevelDB.UnitCount.GetValue();

            if (unitsLeftToSpawn < 1)
            {
                return;                        // No groups to add, no need to go any further
            }
            do
            {
                int groupSize = Toolbox.RandomFrom(commonCAPDB.GroupSize);
                groupSize         = Math.Min(unitsLeftToSpawn, groupSize);
                unitsLeftToSpawn -= groupSize;

                // Find spawn point at the proper distance from the objective(s), but not to close from starting airbase
                Coordinates?spawnPoint =
                    unitMaker.SpawnPointSelector.GetRandomSpawnPoint(
                        new SpawnPointType[] { SpawnPointType.Air },
                        centerPoint,
                        commonCAPDB.DistanceFromCenter,
                        opposingPoint,
                        new MinMaxD(commonCAPDB.MinDistanceFromOpposingPoint, 99999),
                        GeneratorTools.GetSpawnPointCoalition(template, side));

                // No spawn point found, stop here.
                if (!spawnPoint.HasValue)
                {
                    BriefingRoom.PrintToLog($"No spawn point found for {coalition} combat air patrols.", LogMessageErrorLevel.Warning);
                    return;
                }

                Coordinates groupDestination = destination + Coordinates.CreateRandom(10, 20) * Toolbox.NM_TO_METERS;

                var extraSettings = new Dictionary <string, object> {
                    { "Payload", "Air-To-Air" },
                    { "GroupX2", groupDestination.X },
                    { "GroupY2", groupDestination.Y }
                };

                var luaUnit  = commonCAPDB.LuaUnit;
                var luaGroup = commonCAPDB.LuaGroup;
                var spawnpointCoordinates = spawnPoint.Value;
                var unitFamilies          = commonCAPDB.UnitFamilies.ToList();
                if (template.MissionFeatures.Contains("ContextGroundStartAircraft"))
                {
                    luaGroup += "Parked";
                    luaUnit  += "Parked";
                    var(airbase, parkingSpotIDsList, parkingSpotCoordinatesList) = unitMaker.SpawnPointSelector.GetAirbaseAndParking(template, spawnPoint.Value, groupSize, coalition, unitFamilies.First());
                    spawnpointCoordinates = airbase.Coordinates;
                    extraSettings.AddIfKeyUnused("ParkingID", parkingSpotIDsList.ToArray());
                    extraSettings.AddIfKeyUnused("GroupAirbaseID", airbase.DCSID);
                    extraSettings.AddIfKeyUnused("UnitX", (from Coordinates coordinates in parkingSpotCoordinatesList select coordinates.X).ToArray());
                    extraSettings.AddIfKeyUnused("UnitY", (from Coordinates coordinates in parkingSpotCoordinatesList select coordinates.Y).ToArray());
                }


                UnitMakerGroupInfo?groupInfo = unitMaker.AddUnitGroup(
                    unitFamilies, groupSize, side,
                    luaGroup, luaUnit,
                    spawnpointCoordinates,
                    0,
                    extraSettings.ToArray());

                if (!groupInfo.HasValue) // Failed to generate a group
                {
                    BriefingRoom.PrintToLog($"Failed to find units for {coalition} air defense unit group.", LogMessageErrorLevel.Warning);
                }

                capAircraftGroupIDs.Add(groupInfo.Value.GroupID);
            } while (unitsLeftToSpawn > 0);
        }
예제 #30
0
        internal static Dictionary <string, UnitMakerGroupInfo> GenerateCarrierGroup(
            UnitMaker unitMaker, ZoneMaker zoneMaker, DCSMission mission, MissionTemplateRecord template,
            Coordinates landbaseCoordinates, Coordinates objectivesCenter, double windSpeedAtSeaLevel,
            double windDirectionAtSeaLevel)
        {
            Dictionary <string, UnitMakerGroupInfo> carrierDictionary = new Dictionary <string, UnitMakerGroupInfo>(StringComparer.InvariantCultureIgnoreCase);

            DBEntryTheater theaterDB    = Database.Instance.GetEntry <DBEntryTheater>(template.ContextTheater);
            double         carrierSpeed = Math.Max(
                Database.Instance.Common.CarrierGroup.MinimumCarrierSpeed,
                Database.Instance.Common.CarrierGroup.IdealWindOfDeck - windSpeedAtSeaLevel);

            if (windSpeedAtSeaLevel == 0) // No wind? Pick a random direction so carriers don't always go to a 0 course when wind is calm.
            {
                windDirectionAtSeaLevel = Toolbox.RandomDouble(Toolbox.TWO_PI);
            }
            var carrierPathDeg  = ((windDirectionAtSeaLevel + Math.PI) % Toolbox.TWO_PI) * Toolbox.RADIANS_TO_DEGREES;
            var usedCoordinates = new List <Coordinates>();

            foreach (MissionTemplateFlightGroupRecord flightGroup in template.PlayerFlightGroups)
            {
                if (string.IsNullOrEmpty(flightGroup.Carrier))
                {
                    continue;                                            // No carrier for
                }
                if (carrierDictionary.ContainsKey(flightGroup.Carrier))
                {
                    continue;                                                     // Carrier type already added
                }
                if (flightGroup.Carrier.StartsWith("FOB"))
                {
                    //It Carries therefore carrier not because I can't think of a name to rename this lot
                    GenerateFOB(unitMaker, zoneMaker, flightGroup, carrierDictionary, mission, template, landbaseCoordinates, objectivesCenter);
                    continue;
                }
                DBEntryUnit unitDB = Database.Instance.GetEntry <DBEntryUnit>(flightGroup.Carrier);
                if ((unitDB == null) || !unitDB.Families.Any(x => x.IsCarrier()))
                {
                    continue;                                                               // Unit doesn't exist or is not a carrier
                }
                var(shipCoordinates, shipDestination) = GetSpawnAndDestination(unitMaker, template, theaterDB, usedCoordinates, landbaseCoordinates, objectivesCenter, carrierPathDeg);
                usedCoordinates.Add(shipCoordinates);
                string cvnID          = carrierDictionary.Count > 0 ? (carrierDictionary.Count + 1).ToString() : "";
                int    ilsChannel     = 11 + carrierDictionary.Count;
                double radioFrequency = 127.5 + carrierDictionary.Count;
                string tacanCallsign  = $"CVN{cvnID}";
                int    tacanChannel   = 74 + carrierDictionary.Count;

                UnitMakerGroupInfo?groupInfo =
                    unitMaker.AddUnitGroup(
                        new string[] { unitDB.ID }, Side.Ally, unitDB.Families[0],
                        "GroupShipCarrier", "UnitShip",
                        shipCoordinates, 0,
                        "GroupX2".ToKeyValuePair(shipDestination.X),
                        "GroupY2".ToKeyValuePair(shipDestination.Y),
                        "ILS".ToKeyValuePair(ilsChannel),
                        "RadioBand".ToKeyValuePair((int)RadioModulation.AM),
                        "RadioFrequency".ToKeyValuePair(GeneratorTools.GetRadioFrenquency(radioFrequency)),
                        "Speed".ToKeyValuePair(carrierSpeed),
                        "TACANCallsign".ToKeyValuePair(tacanCallsign),
                        "TACANChannel".ToKeyValuePair(tacanChannel),
                        "TACANFrequency".ToKeyValuePair(GeneratorTools.GetTACANFrequency(tacanChannel, 'X', false)),
                        "TACANMode".ToKeyValuePair("X"));

                if (!groupInfo.HasValue || (groupInfo.Value.UnitsID.Length == 0))
                {
                    continue;                                                               // Couldn't generate group
                }
                mission.Briefing.AddItem(
                    DCSMissionBriefingItemType.Airbase,
                    $"{unitDB.UIDisplayName}\t-\t{GeneratorTools.FormatRadioFrequency(radioFrequency)}\t{ilsChannel}\t{tacanCallsign}, {tacanChannel}X");

                carrierDictionary.Add(flightGroup.Carrier, groupInfo.Value);
            }

            return(carrierDictionary);
        }