Ejemplo n.º 1
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
        }
Ejemplo n.º 2
0
 internal UnitMakerGroupInfo(int groupID, Coordinates coordinates, List <int> unitsID, string name, double frequency = 0.0, DBEntryUnit unitDB = null)
 {
     GroupID     = groupID;
     Coordinates = coordinates;
     Name        = name;
     UnitsID     = unitsID.ToArray();
     Frequency   = frequency;
     UnitDB      = unitDB;
 }
Ejemplo n.º 3
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);
 }
Ejemplo n.º 4
0
        private void SetUnitCoordinatesAndHeading(
            DBEntryUnit unitDB, int unitIndex, Coordinates groupCoordinates, double groupHeading,
            out Coordinates unitCoordinates, out double unitHeading)
        {
            unitCoordinates = groupCoordinates;
            unitHeading     = groupHeading;

            if (unitDB.IsAircraft)
            {
                unitCoordinates = groupCoordinates + new Coordinates(AIRCRAFT_UNIT_SPACING, AIRCRAFT_UNIT_SPACING) * unitIndex;
            }
            else
            {
                if (unitDB.OffsetCoordinates.Length > unitIndex) // Unit has a fixed set of coordinates (for SAM sites, etc.)
                {
                    Coordinates offsetCoordinates = unitDB.OffsetCoordinates[unitIndex];
                    unitCoordinates = TransformFromOffset(unitHeading, groupCoordinates, offsetCoordinates);
                }
                else // No fixed coordinates, generate random coordinates
                {
                    switch (unitDB.Category)
                    {
                    case UnitCategory.Ship:
                        if (unitIndex > 0)
                        {
                            unitCoordinates = groupCoordinates.CreateNearRandom(SHIP_UNIT_SPACING, SHIP_UNIT_SPACING * 10);
                        }
                        break;

                    case UnitCategory.Cargo:
                    case UnitCategory.Static:
                        // Static units are spawned exactly on the group location (and there's only a single unit per group)
                        break;

                    default:
                        unitCoordinates = groupCoordinates.CreateNearRandom(VEHICLE_UNIT_SPACING, VEHICLE_UNIT_SPACING * 10);
                        break;
                    }
                }

                if (unitDB.OffsetHeading.Length > unitIndex) // Unit has a fixed heading (for SAM sites, etc.)
                {
                    unitHeading = Toolbox.ClampAngle(unitHeading + unitDB.OffsetHeading[unitIndex]);
                }
                else if (unitDB.Category != UnitCategory.Ship)
                {
                    unitHeading = Toolbox.RandomDouble(Toolbox.TWO_PI);
                }
            }
        }
Ejemplo n.º 5
0
        private (string unitsLua, List <int> unitsIDList) AddUnits(
            string[] unitSets,
            string groupName,
            UnitCallsign?callsign,
            string unitTypeLua,
            Coordinates coordinates,
            UnitMakerGroupFlags unitMakerGroupFlags,
            params KeyValuePair <string, object>[] extraSettings
            )
        {
            string     unitsLuaTable = "";
            int        unitLuaIndex  = 1;
            List <int> unitsIDList   = new List <int>();

            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 (string DCSID in unitDB.DCSIDs)
                {
                    unitsLuaTable += AddUnit(
                        DCSID,
                        groupName,
                        callsign,
                        unitLuaIndex,
                        unitSetIndex,
                        unitDB,
                        unitTypeLua,
                        coordinates,
                        unitMakerGroupFlags,
                        extraSettings
                        );

                    unitsIDList.Add(UnitID);
                    unitSetIndex++;
                    unitLuaIndex++;
                    UnitID++;
                }
            }
            return(unitsLuaTable, unitsIDList);
        }
Ejemplo n.º 6
0
        private void CreatePlayerWaypoints(ref string groupLua, DCSMission mission, DBEntryUnit unitBP)
        {
            string waypointLua     = LuaTools.ReadIncludeLuaFile("Mission\\WaypointPlayer.lua");
            string allWaypointsLua = "";

            for (int i = 0; i < mission.Waypoints.Count; i++)
            {
                string waypoint = waypointLua;
                LuaTools.ReplaceKey(ref waypoint, "Index", i + 2);
                LuaTools.ReplaceKey(ref waypoint, "Name", mission.Waypoints[i].Name);
                LuaTools.ReplaceKey(ref waypoint, "X", mission.Waypoints[i].Coordinates.X);
                LuaTools.ReplaceKey(ref waypoint, "Y", mission.Waypoints[i].Coordinates.Y);

                double waypointAltitude, waypointSpeed;
                if (unitBP == null) // Unit not found in the database, use default values for the unit category
                {
                    waypointAltitude = GetAircraftCruiseAltitude(unitBP.Category, Amount.Average);
                    waypointSpeed    = GetAircraftCruiseSpeed(unitBP.Category, Amount.Average);
                }
                else
                {
                    waypointAltitude = GetAircraftCruiseAltitude(unitBP.Category, unitBP.AircraftData.CruiseAltitude);
                    waypointSpeed    = GetAircraftCruiseSpeed(unitBP.Category, unitBP.AircraftData.CruiseAltitude);
                }

                waypointAltitude *= mission.Waypoints[i].AltitudeMultiplier;
                waypointSpeed    *= mission.Waypoints[i].SpeedMultiplier;

                LuaTools.ReplaceKey(ref waypoint, "Altitude", waypointAltitude);
                LuaTools.ReplaceKey(ref waypoint, "Speed", waypointSpeed);

                allWaypointsLua += waypoint + "\n";
            }

            LuaTools.ReplaceKey(ref groupLua, "PlayerWaypoints", allWaypointsLua);
            LuaTools.ReplaceKey(ref groupLua, "LastPlayerWaypointIndex", mission.Waypoints.Count + 2);
        }
        private void CreatePlayerWaypoints(ref string groupLua, DCSMission mission, DBEntryUnit unitBP)
        {
            string waypointLua     = LuaTools.ReadIncludeLuaFile("Mission\\WaypointPlayer.lua");
            string allWaypointsLua = "";

            for (int i = 0; i < mission.Waypoints.Count; i++)
            {
                string waypoint = waypointLua;
                LuaTools.ReplaceKey(ref waypoint, "Index", i + 2);
                LuaTools.ReplaceKey(ref waypoint, "Name", mission.Waypoints[i].Name);
                LuaTools.ReplaceKey(ref waypoint, "X", mission.Waypoints[i].Coordinates.X);
                LuaTools.ReplaceKey(ref waypoint, "Y", mission.Waypoints[i].Coordinates.Y);

                double waypointAltitude, waypointSpeed;
                if (unitBP == null) // Unit not found in the database, use default values for the unit category
                {
                    waypointAltitude = ((unitBP.Category == UnitCategory.Helicopter) ? 1500 : 20000) * Toolbox.FEET_TO_METERS;
                    waypointSpeed    = ((unitBP.Category == UnitCategory.Helicopter) ? 90 : 300) * Toolbox.KNOTS_TO_METERS_PER_SECOND;
                }
                else
                {
                    waypointAltitude = unitBP.AircraftData.CruiseAltitude;
                    waypointSpeed    = unitBP.AircraftData.CruiseAltitude;
                }

                waypointAltitude *= mission.Waypoints[i].AltitudeMultiplier;
                waypointSpeed    *= mission.Waypoints[i].SpeedMultiplier;

                LuaTools.ReplaceKey(ref waypoint, "Altitude", waypointAltitude);
                LuaTools.ReplaceKey(ref waypoint, "Speed", waypointSpeed);

                allWaypointsLua += waypoint + "\n";
            }

            LuaTools.ReplaceKey(ref groupLua, "PlayerWaypoints", allWaypointsLua);
            LuaTools.ReplaceKey(ref groupLua, "LastPlayerWaypointIndex", mission.Waypoints.Count + 2);
        }
Ejemplo n.º 8
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);
        }
Ejemplo n.º 9
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);
        }
Ejemplo n.º 10
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));
        }
Ejemplo n.º 11
0
        internal static void GeneratePlayerFlightGroup(
            UnitMaker unitMaker,
            DCSMission mission,
            MissionTemplateRecord template,
            MissionTemplateFlightGroupRecord flightGroup,
            DBEntryAirbase playerAirbase,
            List <Waypoint> waypoints,
            Dictionary <string, UnitMakerGroupInfo> carrierDictionary,
            Coordinates averageInitialLocation,
            Coordinates objectivesCenter)
        {
            DBEntryAirbase  airbase             = playerAirbase;
            List <Waypoint> flightWaypoints     = new List <Waypoint>(waypoints);
            Coordinates     groupStartingCoords = playerAirbase.Coordinates;

            var package = template.AircraftPackages.FirstOrDefault(x => x.FlightGroupIndexes.Contains(template.PlayerFlightGroups.IndexOf(flightGroup)));

            if (package is not null)
            {
                var missionPackage = mission.MissionPackages.First(x => x.RecordIndex == template.AircraftPackages.IndexOf(package));
                flightWaypoints     = missionPackage.Waypoints;
                airbase             = missionPackage.Airbase;
                groupStartingCoords = missionPackage.Airbase.Coordinates;
            }
            DBEntryUnit unitDB = Database.Instance.GetEntry <DBEntryUnit>(flightGroup.Aircraft);

            // Not an unit, or not a player-controllable unit, abort.
            if ((unitDB == null) || !unitDB.AircraftData.PlayerControllable)
            {
                throw new BriefingRoomException($"Player flight group unit {flightGroup.Aircraft} does not exist or is not player-controllable.");
            }
            if (unitDB.AircraftData.MinimumRunwayLengthFt > 0 && airbase.RunwayLengthFt < unitDB.AircraftData.MinimumRunwayLengthFt)
            {
                BriefingRoom.PrintToLog($"Runway at {airbase.Name}({airbase.RunwayLengthFt}ft) is shorter than {unitDB.UIDisplayName}({unitDB.AircraftData.MinimumRunwayLengthFt}ft) required runway length.", LogMessageErrorLevel.Warning);
            }

            List <int>         parkingSpotIDsList         = new List <int>();
            List <Coordinates> parkingSpotCoordinatesList = new List <Coordinates>();
            var    groupLuaFile  = "GroupAircraftPlayer";
            var    carrierUnitID = 0;
            string carrierName   = null;
            var    side          = flightGroup.Hostile ? Side.Enemy : Side.Ally;
            var    country       = flightGroup.Country;
            var    payload       = flightGroup.Payload;
            var    extraSettings = new Dictionary <string, object>();
            UnitMakerGroupFlags unitMakerGroupFlags = flightGroup.AIWingmen ? UnitMakerGroupFlags.FirstUnitIsClient : 0;
            DCSSkillLevel       skillLevel          = flightGroup.AIWingmen ? Toolbox.RandomFrom(DCSSkillLevel.High, DCSSkillLevel.Excellent) : DCSSkillLevel.Client;

            if (!string.IsNullOrEmpty(flightGroup.Carrier) && carrierDictionary.ContainsKey(flightGroup.Carrier) && !flightGroup.Hostile) // Carrier take off
            {
                var carrier = carrierDictionary[flightGroup.Carrier];
                if (carrier.UnitDB.Families.Contains(UnitFamily.ShipCarrierSTOVL) && flightGroup.Carrier != "LHA_Tarawa")
                {
                    extraSettings.AddIfKeyUnused("Speed", 0);
                    unitMakerGroupFlags = 0;
                    skillLevel          = DCSSkillLevel.Client;
                    if (flightGroup.Aircraft == "AV8BNA")
                    {
                        payload = "EMPTY";
                    }
                }
                groupLuaFile  = "GroupAircraftPlayerCarrier";
                carrierUnitID = carrier.UnitsID[0];
                carrierName   = carrier.UnitDB.UIDisplayName;

                for (int i = 0; i < flightGroup.Count; i++)
                {
                    parkingSpotIDsList.Add(i + 1);
                    parkingSpotCoordinatesList.Add(carrier.Coordinates);
                }
                groupStartingCoords = carrier.Coordinates;
            }
            else if (flightGroup.Hostile)
            {
                var coalition = GeneratorTools.GetSpawnPointCoalition(template, side, true);
                var(hostileAirbase, hostileParkingSpotIDsList, hostileParkingSpotCoordinatesList) = unitMaker.SpawnPointSelector.GetAirbaseAndParking(template, objectivesCenter, flightGroup.Count, coalition.Value, unitDB.Families.First());
                parkingSpotIDsList         = hostileParkingSpotIDsList;
                parkingSpotCoordinatesList = hostileParkingSpotCoordinatesList;
                groupStartingCoords        = hostileParkingSpotCoordinatesList.First();
                airbase = hostileAirbase;

                if (country == Country.CJTFBlue || country == Country.CJTFRed)
                {
                    country = coalition == Coalition.Blue ? Country.CJTFBlue : Country.CJTFRed;
                }
            }
            else // Land airbase take off
            {
                var parkingSpots = unitMaker.SpawnPointSelector.GetFreeParkingSpots(airbase.DCSID, flightGroup.Count, unitDB.Families[0]);
                parkingSpotIDsList         = parkingSpots.Select(x => x.DCSID).ToList();
                parkingSpotCoordinatesList = parkingSpots.Select(x => x.Coordinates).ToList();
                groupStartingCoords        = parkingSpotCoordinatesList.First();
            }



            extraSettings.AddIfKeyUnused("Payload", payload);
            extraSettings.AddIfKeyUnused("Skill", skillLevel);
            extraSettings.AddIfKeyUnused("PlayerStartingAction", GeneratorTools.GetPlayerStartingAction(flightGroup.StartLocation));
            extraSettings.AddIfKeyUnused("PlayerStartingType", GeneratorTools.GetPlayerStartingType(flightGroup.StartLocation));
            extraSettings.AddIfKeyUnused("Country", country);
            extraSettings.AddIfKeyUnused("InitialWPName", Database.Instance.Common.Names.WPInitialName);
            extraSettings.AddIfKeyUnused("FinalWPName", Database.Instance.Common.Names.WPFinalName);
            extraSettings.AddIfKeyUnused("ParkingID", parkingSpotIDsList.ToArray());
            extraSettings.AddIfKeyUnused("PlayerWaypoints", GenerateFlightPlanLua(flightWaypoints));
            extraSettings.AddIfKeyUnused("LastPlayerWaypointIndex", flightWaypoints.Count + 2);
            extraSettings.AddIfKeyUnused("LinkUnit", carrierUnitID);
            extraSettings.AddIfKeyUnused("UnitX", (from Coordinates coordinates in parkingSpotCoordinatesList select coordinates.X).ToArray());
            extraSettings.AddIfKeyUnused("UnitY", (from Coordinates coordinates in parkingSpotCoordinatesList select coordinates.Y).ToArray());
            extraSettings.AddIfKeyUnused("MissionAirbaseX", groupStartingCoords.X);
            extraSettings.AddIfKeyUnused("MissionAirbaseY", groupStartingCoords.Y);
            extraSettings.AddIfKeyUnused("MissionAirbaseID", airbase.DCSID);
            extraSettings.AddIfKeyUnused("Livery", flightGroup.Livery);

            UnitMakerGroupInfo?groupInfo = unitMaker.AddUnitGroup(
                Enumerable.Repeat(flightGroup.Aircraft, flightGroup.Count).ToArray(), side, unitDB.Families[0],
                groupLuaFile, "UnitAircraftParked", groupStartingCoords,
                unitMakerGroupFlags,
                extraSettings.ToArray()
                );

            if (!groupInfo.HasValue)
            {
                BriefingRoom.PrintToLog("Failed to generate player flight group.", LogMessageErrorLevel.Warning);
                return;
            }

            SaveFlightGroup(mission, groupInfo, flightGroup, unitDB, carrierName ?? airbase.Name);
            SaveWaypointsToBriefing(
                mission,
                groupStartingCoords,
                flightWaypoints,
                template.OptionsMission.Contains("ImperialUnitsForBriefing"),
                groupInfo);
        }
Ejemplo n.º 12
0
        internal UnitMakerGroupInfo?AddUnitGroup(
            string[] units, Side side, UnitFamily unitFamily,
            string groupTypeLua, string unitTypeLua,
            Coordinates coordinates,
            UnitMakerGroupFlags unitMakerGroupFlags = 0,
            params KeyValuePair <string, object>[] extraSettings)
        {
            if (units.Length == 0)
            {
                return(null);
            }

            Coalition coalition = (side == Side.Ally) ? PlayerCoalition : PlayerCoalition.GetEnemy();
            Country   country   = (coalition == Coalition.Blue) ? Country.CJTFBlue : Country.CJTFRed;

            if (extraSettings.Any(x => x.Key == "Country"))
            {
                country = (Country)extraSettings.First(x => x.Key == "Country").Value;
            }

            var skill = GeneratorTools.GetDefaultSkillLevel(Template, side);

            if (extraSettings.Any(x => x.Key == "Skill"))
            {
                skill = (DCSSkillLevel)extraSettings.First(x => x.Key == "Skill").Value;
            }


            var          isUsingSkynet = Template.MissionFeatures.Contains("SkynetIADS");
            string       groupName;
            UnitCallsign?callsign = null;

            if (unitFamily.GetUnitCategory().IsAircraft())
            {
                callsign  = CallsignGenerator.GetCallsign(unitFamily, coalition, side, isUsingSkynet);
                groupName = callsign.Value.GroupName;
                if (extraSettings.Any(x => x.Key == "PlayerStartingType") && extraSettings.First(x => x.Key == "PlayerStartingType").Value.ToString() == "TakeOffParking")
                {
                    groupName += "(C)";
                }
            }
            else
            {
                groupName = GeneratorTools.GetGroupName(GroupID, unitFamily, side, isUsingSkynet);
            }

            if (unitFamily.GetUnitCategory() == UnitCategory.Static || unitFamily.GetUnitCategory() == UnitCategory.Cargo && unitFamily != UnitFamily.FOB)
            {
                return(AddStaticGroup(
                           country,
                           coalition,
                           skill,
                           unitFamily,
                           side,
                           units,
                           groupName,
                           callsign,
                           groupTypeLua,
                           coordinates,
                           unitMakerGroupFlags,
                           extraSettings
                           ));
            }

            var groupLua = CreateGroup(
                groupTypeLua,
                coordinates,
                groupName,
                extraSettings
                );


            int firstUnitID = UnitID;

            var(unitsLuaTable, unitsIDList) = AddUnits(
                units,
                groupName,
                callsign,
                unitTypeLua,
                coordinates,
                unitMakerGroupFlags,
                extraSettings
                );


            if (unitsIDList.Count == 0)
            {
                return(null);                        // No valid units added to this group
            }
            GeneratorTools.ReplaceKey(ref groupLua, "Units", unitsLuaTable);

            DBEntryUnit firstUnitDB        = units.Select(x => Database.Instance.GetEntry <DBEntryUnit>(x)).First(x => x != null);
            var         aircraftCategories = new UnitCategory[] { UnitCategory.Helicopter, UnitCategory.Plane };
            var         isAircraft         = firstUnitDB != null && aircraftCategories.Contains(firstUnitDB.Category);

            if (isAircraft)
            {
                groupLua = ApplyAircraftFields(groupLua, firstUnitDB, extraSettings);
                if (unitMakerGroupFlags.HasFlag(UnitMakerGroupFlags.ImmediateAircraftSpawn))
                {
                    Mission.AppendValue("AircraftActivatorCurrentQueue", $"{GroupID},");
                }
                else if (unitMakerGroupFlags.HasFlag(UnitMakerGroupFlags.RadioAircraftSpawn))
                {
                    Mission.AppendValue("AircraftRadioActivator", $"{{{GroupID}, \"{groupName}\"}},");
                }
                else if (groupTypeLua != "GroupAircraftParkedUncontrolled")
                {
                    Mission.AppendValue("AircraftActivatorReserveQueue", $"{GroupID},");
                }
            }

            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, unitFamily.GetUnitCategory(), groupLua);

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

            GroupID++;

            if (firstUnitDB == null)
            {
                return(new UnitMakerGroupInfo(GroupID - 1, coordinates, unitsIDList, groupName));
            }
            return(new UnitMakerGroupInfo(GroupID - 1, coordinates, unitsIDList, groupName, firstUnitDB.AircraftData.RadioFrequency, firstUnitDB));
        }
Ejemplo n.º 13
0
        private void SetUnitCoordinatesAndHeading(ref Coordinates unitCoordinates, ref double unitHeading, DBEntryUnit unitBP, int unitIndex)
        {
            if (unitBP.IsAircraft)
            {
                unitCoordinates += new Coordinates(AIRCRAFT_UNIT_SPACING, AIRCRAFT_UNIT_SPACING) * unitIndex;
            }
            else
            {
                if (unitBP.OffsetCoordinates.Length > unitIndex) // Unit has a fixed set of coordinates (for SAM sites, etc.)
                {
                    double      s = Math.Sin(unitHeading);
                    double      c = Math.Cos(unitHeading);
                    Coordinates offsetCoordinates = unitBP.OffsetCoordinates[unitIndex];
                    unitCoordinates += new Coordinates(offsetCoordinates.X * c - offsetCoordinates.Y * s, offsetCoordinates.X * s + offsetCoordinates.Y * c);
                }
                else // No fixed coordinates, generate random coordinates
                {
                    switch (unitBP.Category)
                    {
                    case UnitCategory.Ship:
                        unitCoordinates = unitCoordinates.CreateNearRandom(SHIP_UNIT_SPACING, SHIP_UNIT_SPACING * 10);
                        break;

                    case UnitCategory.Static:     // Static units are spawned exactly on the group location (and there's only a single unit per group)
                        break;

                    default:
                        unitCoordinates = unitCoordinates.CreateNearRandom(VEHICLE_UNIT_SPACING, VEHICLE_UNIT_SPACING * 10);
                        break;
                    }
                }

                if (unitBP.OffsetHeading.Length > unitIndex)                                         // Unit has a fixed heading (for SAM sites, etc.)
                {
                    unitHeading = Toolbox.ClampAngle(unitHeading + unitBP.OffsetHeading[unitIndex]); // editor looks odd but works fine if negative or over 2Pi
                }
                else if (unitBP.Category != UnitCategory.Ship)
                {
                    unitHeading = Toolbox.RandomDouble(Toolbox.TWO_PI);
                }
            }
        }
        /// <summary>
        /// Generates the mission briefing.
        /// </summary>
        /// <param name="mission">Mission</param>
        /// <param name="template">Template from which the mission should be built</param>
        /// <param name="airbaseDB">Airbase player will take off from and land back on</param>
        /// <param name="coalitionsDB">Database entries for the mission coalitions</param>
        public void GenerateMissionBriefing(DCSMission mission, MissionTemplate template, DBEntryObjective objectiveDB, DBEntryTheaterAirbase airbaseDB, DBEntryUnit carrierDB, List <UnitFlightGroupBriefingDescription> flightGroups, DBEntryCoalition[] coalitionsDB)
        {
            DebugLog.Instance.WriteLine("Generating mission briefing...", 1);

            // Get mission features
            DBEntryMissionFeature[] features = Database.Instance.GetEntries <DBEntryMissionFeature>(objectiveDB.MissionFeatures);

            string description = GeneratorTools.SanitizeString(template.BriefingDescription);

            if (string.IsNullOrEmpty(description)) // No custom mission description has been provided, generate one
            {
                description = objectiveDB.BriefingDescriptionByUnitFamily[(int)mission.Objectives[0].TargetFamily];
                if (string.IsNullOrEmpty(description)) // No custom briefing for this target family, use the default
                {
                    description = objectiveDB.BriefingDescription;
                }

                description =
                    GeneratorTools.MakeBriefingStringReplacements(GeneratorTools.ParseRandomString(description), mission, coalitionsDB);
            }
            description = GeneratorTools.SanitizeString(description);

            // Generate tasks
            string        baseName = carrierDB != null? carrierDB.ID : airbaseDB.Name;
            List <string> tasks    = new List <string> {
                $"Take off from {baseName}"
            };
            string objectiveTask = GeneratorTools.ParseRandomString(objectiveDB.BriefingTask);

            for (int i = 0; i < mission.Objectives.Length; i++)
            {
                string taskString = GeneratorTools.MakeBriefingStringReplacements(objectiveTask, mission, coalitionsDB, i);
                tasks.Add(taskString);
                mission.CoreLuaScript += $"briefingRoom.mission.objectives[{i + 1}].task = \"{taskString}\"\r\n";
            }
            tasks.Add($"Return to {baseName}");
            DebugLog.Instance.WriteLine($"{tasks.Count} task(s)", 2);

            // Generate mission remarks...
            List <string> remarks = new List <string>();

            remarks.AddRange( // ...from objective
                from string remark in objectiveDB.BriefingRemarks
                select GeneratorTools.MakeBriefingStringReplacements(GeneratorTools.ParseRandomString(remark), mission, coalitionsDB));
            foreach (DBEntryMissionFeature feature in features)
            {
                remarks.AddRange( // ...from features
                    from string remark in feature.BriefingRemarks
                    select GeneratorTools.MakeBriefingStringReplacements(GeneratorTools.ParseRandomString(remark), mission, coalitionsDB));
            }

            /*
             * // Opposition Remarks
             * string airDefenseNumbers = template.OppositionAirDefense == AmountN.Random? "Unknown":template.OppositionAirDefense.ToString();
             * string airDefenseSkill = template.OppositionSkillLevelGround == BRSkillLevel.Random? "Varied":template.OppositionSkillLevelGround.ToString();
             * string airForceNumbers = template.OppositionAirForce == AmountN.Random? "Unknown":template.OppositionAirForce.ToString();
             * string airForceSkill = template.OppositionSkillLevelAir == BRSkillLevel.Random? "Varied":template.OppositionSkillLevelAir.ToString();
             * string allyAirDefenseNumbers = template.PlayerFriendlyAirDefense == AmountN.Random? "Unknown":template.PlayerFriendlyAirDefense.ToString();
             * string allyAirDefenseSkill = template.PlayerAISkillLevel == BRSkillLevel.Random? "Varied":template.PlayerAISkillLevel.ToString();
             * remarks.AddRange(new List<string>{
             *  $"Enemy Air Defenses are {airDefenseNumbers} and they are {airDefenseSkill} troops",
             *  $"Expected Enemy Air Force response is {airForceNumbers} and they are {airForceSkill} pilots",
             *  $"Our Air Defenses are {allyAirDefenseNumbers} and they are {allyAirDefenseSkill} troops",});
             * remarks.Add("Use the \"F10/Other\" item in the comms for additional options");
             * DebugLog.Instance.WriteLine($"{remarks.Count} remark(s)", 2);
             */

            mission.BriefingHTML = CreateHTMLBriefing(mission, template, description, tasks, remarks, flightGroups, airbaseDB, carrierDB, coalitionsDB);
            mission.BriefingTXT  = CreateTXTBriefing(description, tasks, remarks, flightGroups, airbaseDB, carrierDB);
        }
        /// <summary>
        /// Creates the raw text briefing, to be used for the mission description inside DCS World.
        /// </summary>
        /// <param name="description"></param>
        /// <param name="tasks"></param>
        /// <param name="remarks"></param>
        /// <param name="flightGroups"></param>
        /// <param name="airbaseDB">Airbase player will take off from and land back on</param>
        /// <returns></returns>
        private string CreateTXTBriefing(
            string description, List <string> tasks, List <string> remarks,
            List <UnitFlightGroupBriefingDescription> flightGroups, DBEntryTheaterAirbase airbaseDB, DBEntryUnit carrier)
        {
            DebugLog.Instance.WriteLine("Generating raw text mission briefing...", 2);

            string briefing = description + "\n\n";

            briefing += "TASKS:\n";
            foreach (string t in tasks)
            {
                briefing += $"- {t}\n";
            }
            briefing += "\n";

            briefing += "REMARKS:\n";
            foreach (string r in remarks)
            {
                briefing += $"- {r}\n";
            }
            briefing += "\n";

            briefing += "MISSION PACKAGE:\n";
            foreach (UnitFlightGroupBriefingDescription fg in flightGroups)
            {
                briefing += $"- {fg.Callsign} ({fg.Count}×{fg.Type}, {fg.Task}) - {fg.Radio}{(string.IsNullOrEmpty(fg.Remarks) ? "" : $", {fg.Remarks}")}\n";
            }
        private string CreateHTMLBriefing(
            DCSMission mission, MissionTemplate template, string description,
            List <string> tasks, List <string> remarks,
            List <UnitFlightGroupBriefingDescription> flightGroups, DBEntryTheaterAirbase airbaseDB, DBEntryUnit carrierDB,
            DBEntryCoalition[] coalitionsDB)
        {
            DebugLog.Instance.WriteLine("Generating HTML mission briefing...", 2);

            if (!File.Exists(HTML_TEMPLATE_FILE)) // Briefing template not found
            {
                DebugLog.Instance.WriteLine("HTML template file not found.", 1, DebugLogMessageErrorLevel.Warning);
                return("HTML template file not found.");
            }

            string briefing = File.ReadAllText(HTML_TEMPLATE_FILE);

            // Title
            briefing = briefing.Replace("$MISSIONNAME$", mission.MissionName);
            briefing = briefing.Replace("$MISSIONTYPE$",
                                        GeneratorTools.RemoveAfterComma(template.ObjectiveType) + " mission " +
                                        ((template.GetMissionType() == MissionType.SinglePlayer) ?
                                         "(single-player)" : $"({template.GetPlayerCount()}-players multiplayer)"));

            // Situation summary
            briefing = briefing.Replace("$LONGDATE$", mission.DateTime.ToDateString(true));
            briefing = briefing.Replace("$LONGTIME$", mission.DateTime.ToTimeString());
            briefing = briefing.Replace("$SHORTDATE$", mission.DateTime.ToDateString(false));
            briefing = briefing.Replace("$SHORTTIME$", mission.DateTime.ToTimeString());
            briefing = briefing.Replace("$WEATHER$", GeneratorTools.GetEnumString(mission.Weather.WeatherLevel));
            briefing = briefing.Replace("$WIND$", GeneratorTools.GetEnumString(mission.Weather.WindLevel));
            briefing = briefing.Replace("$WINDSPEED$", mission.Weather.WindSpeedAverage.ToString("F0"));

            // Friends and enemies
            briefing = briefing.Replace("$PLAYERCOALITION$", GeneratorTools.RemoveAfterComma(template.GetCoalition(mission.CoalitionPlayer)));
            briefing = briefing.Replace("$ENEMYCOALITION$", GeneratorTools.RemoveAfterComma(template.GetCoalition(mission.CoalitionEnemy)));

            // Description
            briefing = briefing.Replace("$DESCRIPTION$", description.Replace("\n", "<br />"));

            // Tasks
            string tasksHTML = "";

            foreach (string task in tasks)
            {
                tasksHTML += $"<li>{task}</li>";
            }
            briefing = briefing.Replace("$TASKS$", tasksHTML);

            // Remarks
            string remarksHTML = "";

            foreach (string remark in remarks)
            {
                remarksHTML += $"<li>{remark}</li>";
            }
            briefing = briefing.Replace("$REMARKS$", remarksHTML);

            // Flight groups
            string flightGroupsHTML = "";

            foreach (UnitFlightGroupBriefingDescription fg in flightGroups)
            {
                flightGroupsHTML +=
                    "<tr>" +
                    $"<td>{fg.Callsign}</td>" +
                    $"<td>{fg.Count}×{fg.Type}</td>" +
                    $"<td>{fg.Task}</td><td>{fg.Radio}</td>" +
                    $"<td>{fg.Remarks}</td>" +
                    "</tr>";
            }
            briefing = briefing.Replace("$FLIGHTGROUPS$", flightGroupsHTML);

            // Airbases
            string airbasesHTML =
                "<tr>" +
                $"<td>{airbaseDB.Name}</td>" +
                $"<td>{airbaseDB.Runways}</td>" +
                $"<td>{airbaseDB.ATC}</td>" +
                $"<td>{airbaseDB.ILS}</td>" +
                $"<td>{airbaseDB.TACAN}</td>" +
                "</tr>";

            briefing = briefing.Replace("$AIRBASES$", airbasesHTML);

            string carrierHTML = "";

            if (carrierDB != null)
            {
                carrierHTML =
                    "<tr>" +
                    $"<td>{carrierDB.ID}</td>" +
                    $"<td>127.500AM</td>" +
                    $"<td>11</td>" +
                    $"<td>74X</td>" +
                    "</tr>";
            }
            briefing = briefing.Replace("$CARRIERS$", carrierHTML);


            // Waypoints
            string      waypointsHTML = "";
            double      distance;
            double      totalDistance   = 0.0;
            Coordinates currentPosition = mission.InitialPosition;

            waypointsHTML += $"<tr><td><strong>TAKEOFF</strong></td><td>-</td><td>-</td></tr>";
            foreach (DCSMissionWaypoint wp in mission.Waypoints)
            {
                distance        = currentPosition.GetDistanceFrom(wp.Coordinates);
                totalDistance  += distance;
                currentPosition = wp.Coordinates;

                waypointsHTML +=
                    $"<tr><td>{wp.Name}</td>" +
                    $"<td>{GeneratorTools.ConvertDistance(distance, template.BriefingUnitSystem)}</td>" +
                    $"<td>{GeneratorTools.ConvertDistance(totalDistance, template.BriefingUnitSystem)}</td></tr>";
            }
            distance       = currentPosition.GetDistanceFrom(mission.InitialPosition);
            totalDistance += distance;
            waypointsHTML += $"<tr><td><strong>LANDING</strong></td>" +
                             $"<td>{GeneratorTools.ConvertDistance(distance, template.BriefingUnitSystem)}</td>" +
                             $"<td>{GeneratorTools.ConvertDistance(totalDistance, template.BriefingUnitSystem)}</td></tr>";
            briefing = briefing.Replace("$WAYPOINTS$", waypointsHTML);

            return(briefing);
        }
        private void CreateUnitGroups(ref string lua, DCSMission mission, Coalition coalition, UnitCategory unitCategory)
        {
            int    i, j;
            int    groupIndex   = 1;
            string allGroupsLua = "";

            foreach (DCSMissionUnitGroup group in mission.UnitGroups)
            {
                if ((group.Coalition != coalition) ||   // Group does not belong to this coalition
                    (group.Category != unitCategory) || // Group does not belong to this unit category
                    (group.Units.Length == 0))          // Group doesn't contain any units
                {
                    continue;                           // Ignore it
                }
                string groupLua = LuaTools.ReadIncludeLuaFile($"Units\\{group.LuaGroup}");
                LuaTools.ReplaceKey(ref groupLua, "Index", groupIndex);
                LuaTools.ReplaceKey(ref groupLua, "X", group.Coordinates.X);
                LuaTools.ReplaceKey(ref groupLua, "Y", group.Coordinates.Y);
                LuaTools.ReplaceKey(ref groupLua, "X2", group.Coordinates2.X);
                LuaTools.ReplaceKey(ref groupLua, "Y2", group.Coordinates2.Y);
                LuaTools.ReplaceKey(ref groupLua, "Hidden", group.Flags.HasFlag(DCSMissionUnitGroupFlags.Hidden));
                LuaTools.ReplaceKey(ref groupLua, "ID", group.GroupID);
                LuaTools.ReplaceKey(ref groupLua, "FirstUnitID", group.Units[0].ID);
                LuaTools.ReplaceKey(ref groupLua, "Name", group.Name);
                LuaTools.ReplaceKey(ref groupLua, "ObjectiveAirbaseID", group.AirbaseID);

                if (group.CarrierId > 0)
                {
                    LuaTools.ReplaceKey(ref groupLua, "LinkUnit", group.CarrierId);
                }

                if (group.TACAN != null)
                {
                    LuaTools.ReplaceKey(ref groupLua, "TacanFrequency", group.TACAN.freqency);
                    LuaTools.ReplaceKey(ref groupLua, "TacanCallSign", group.TACAN.callsign);
                    LuaTools.ReplaceKey(ref groupLua, "TacanChannel", group.TACAN.channel);
                    LuaTools.ReplaceKey(ref groupLua, "UnitID", group.Units[0].ID);
                }
                if (group.ILS > 0)
                {
                    LuaTools.ReplaceKey(ref groupLua, "ILS", group.ILS);
                }


                DBEntryUnit unitBP = Database.Instance.GetEntry <DBEntryUnit>(group.UnitID);
                if (unitBP == null)
                {
                    continue;                 // TODO: error message?
                }
                // Group is a client group, requires player waypoints
                if (group.IsAPlayerGroup())
                {
                    CreatePlayerWaypoints(ref groupLua, mission, unitBP);
                }

                string allUnitsLua = "";
                for (i = 0; i < group.Units.Length; i++)
                {
                    string      unitLua         = LuaTools.ReadIncludeLuaFile($"Units\\{group.LuaUnit}");
                    Coordinates unitCoordinates = new Coordinates(group.Coordinates);
                    double      unitHeading     = 0;

                    if ((group.Category == UnitCategory.Static) || (group.Category == UnitCategory.Vehicle))
                    {
                        double randomSpreadAngle = Toolbox.RandomDouble(Math.PI * 2);
                        unitCoordinates += new Coordinates(Math.Cos(randomSpreadAngle) * 35, Math.Sin(randomSpreadAngle) * 35);
                        unitHeading      = Toolbox.RandomDouble(Math.PI * 2);
                    }
                    else
                    {
                        unitCoordinates += new Coordinates(50 * i, 50 * i);
                    }

                    if ((group.Category == UnitCategory.Helicopter) || (group.Category == UnitCategory.Plane)) // Unit is an aircraft
                    {
                        if (unitBP == null)
                        {
                            LuaTools.ReplaceKey(ref groupLua, "Altitude", ((group.Category == UnitCategory.Helicopter) ? 1500 : 4572) * Toolbox.RandomDouble(.8, 1.2));
                            LuaTools.ReplaceKey(ref unitLua, "Altitude", ((group.Category == UnitCategory.Helicopter) ? 1500 : 4572) * Toolbox.RandomDouble(.8, 1.2));
                            LuaTools.ReplaceKey(ref groupLua, "EPLRS", false);
                            LuaTools.ReplaceKey(ref unitLua, "PayloadCommon", "");
                            LuaTools.ReplaceKey(ref unitLua, "PayloadPylons", "");
                            LuaTools.ReplaceKey(ref unitLua, "RadioPresetsLua", "");
                            LuaTools.ReplaceKey(ref unitLua, "PropsLua", "");
                            LuaTools.ReplaceKey(ref groupLua, "RadioBand", 0);
                            LuaTools.ReplaceKey(ref groupLua, "RadioFrequency", 124.0f);
                            LuaTools.ReplaceKey(ref groupLua, "Speed", ((group.Category == UnitCategory.Helicopter) ? 51 : 125) * Toolbox.RandomDouble(.9, 1.1));
                        }
                        else
                        {
                            LuaTools.ReplaceKey(ref groupLua, "Altitude", unitBP.AircraftData.CruiseAltitude);
                            LuaTools.ReplaceKey(ref unitLua, "Altitude", unitBP.AircraftData.CruiseAltitude);
                            LuaTools.ReplaceKey(ref groupLua, "EPLRS", unitBP.Flags.HasFlag(DBEntryUnitFlags.EPLRS));
                            LuaTools.ReplaceKey(ref unitLua, "PayloadCommon", unitBP.AircraftData.PayloadCommon);
                            if (group.IsAPlayerGroup())
                            {
                                LuaTools.ReplaceKey(ref unitLua, "RadioPresetsLua", string.Join("", unitBP.AircraftData.RadioPresets.Select((x, index) => $"[{index + 1}] = {x.ToLuaString()}")));
                                LuaTools.ReplaceKey(ref unitLua, "PropsLua", unitBP.AircraftData.PropsLua);
                            }
                            else
                            {
                                LuaTools.ReplaceKey(ref unitLua, "RadioPresetsLua", "");
                                LuaTools.ReplaceKey(ref unitLua, "PropsLua", "");
                            }
                            LuaTools.ReplaceKey(ref groupLua, "RadioBand", (int)unitBP.AircraftData.RadioModulation);
                            LuaTools.ReplaceKey(ref groupLua, "RadioFrequency", unitBP.AircraftData.RadioFrequency);
                            LuaTools.ReplaceKey(ref groupLua, "Speed", unitBP.AircraftData.CruiseSpeed);

                            string   pylonLua = "";
                            string[] payload  = unitBP.AircraftData.GetPayload(group.Payload, mission.DateTime.Decade);
                            for (j = 0; j < DBEntryUnitAircraftData.MAX_PYLONS; j++)
                            {
                                string pylonCode = payload[j];
                                if (!string.IsNullOrEmpty(pylonCode))
                                {
                                    pylonLua += $"[{j + 1}] = {{[\"CLSID\"] = \"{pylonCode}\" }},\r\n";
                                }
                            }

                            LuaTools.ReplaceKey(ref unitLua, "PayloadPylons", pylonLua);
                        }
                    }
                    else if ((group.Category == UnitCategory.Ship))
                    {
                        if (group.RadioFrequency > 0)
                        {
                            LuaTools.ReplaceKey(ref unitLua, "RadioBand", (int)group.RadioModulation);
                            LuaTools.ReplaceKey(ref unitLua, "RadioFrequency", group.RadioFrequency * 1000000);
                        }
                        else
                        {
                            LuaTools.ReplaceKey(ref unitLua, "RadioBand", 0);
                            LuaTools.ReplaceKey(ref unitLua, "RadioFrequency", 127.0f * 1000000);
                        }
                        LuaTools.ReplaceKey(ref groupLua, "Speed", group.Speed);
                    }

                    if (unitBP == null)
                    {
                        LuaTools.ReplaceKey(ref unitLua, "ExtraLua", "");
                    }
                    else
                    {
                        LuaTools.ReplaceKey(ref unitLua, "ExtraLua", unitBP.ExtraLua);
                    }

                    LuaTools.ReplaceKey(ref unitLua, "Callsign", group.CallsignLua); // Must be before "index" replacement, as is it is integrated in the callsign
                    LuaTools.ReplaceKey(ref unitLua, "Index", i + 1);
                    LuaTools.ReplaceKey(ref unitLua, "ID", group.Units[i].ID);
                    LuaTools.ReplaceKey(ref unitLua, "Type", group.Units[i].Type);
                    LuaTools.ReplaceKey(ref unitLua, "Name", $"{group.Name} {i + 1}");
                    if (group.Flags.HasFlag(DCSMissionUnitGroupFlags.FirstUnitIsPlayer))
                    {
                        LuaTools.ReplaceKey(ref unitLua, "Skill", (i == 0) ? DCSSkillLevel.Player : group.Skill, false);
                    }
                    else
                    {
                        LuaTools.ReplaceKey(ref unitLua, "Skill", group.Skill, false);
                    }
                    LuaTools.ReplaceKey(ref unitLua, "X", group.Units[i].Coordinates.X);
                    LuaTools.ReplaceKey(ref unitLua, "Y", group.Units[i].Coordinates.Y);
                    LuaTools.ReplaceKey(ref unitLua, "Heading", group.Units[i].Heading);
                    LuaTools.ReplaceKey(ref unitLua, "OnboardNumber", Toolbox.RandomInt(1, 1000).ToString("000"));
                    LuaTools.ReplaceKey(ref unitLua, "ParkingID", group.Units[i].ParkingSpot);

                    allUnitsLua += unitLua + "\n";
                }
                LuaTools.ReplaceKey(ref groupLua, "units", allUnitsLua);

                allGroupsLua += groupLua + "\n";

                groupIndex++;
            }

            LuaTools.ReplaceKey(ref lua, $"Groups{unitCategory}{coalition}", allGroupsLua);
        }
Ejemplo n.º 18
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}\",");
     }
 }