/// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="coordinates">X,Y coordinates of the objective (NOT the waypoint for this objective).</param>
 /// <param name="name">Name of this objective.</param>
 /// <param name="altitude">Altitude multiplier for this objective.</param>
 /// <param name="airdromeID">ID of the airdrome linked to this objective, if any.</param>
 public DCSMissionObjectiveLocation(Coordinates coordinates, string name = "", double altitude = 1f, int airdromeID = 0)
 {
     Coordinates = coordinates;
     Name        = name.ToUpperInvariant();
     Altitude    = HQTools.Clamp(altitude, 0f, 2f);
     AirdromeID  = airdromeID;
 }
예제 #2
0
        /// <summary>
        /// Generates wind settings for the mission. Must be called once mission weather level has been set, as weather is used for auto wind.
        /// </summary>
        /// <param name="mission">The mission.</param>
        /// <param name="wind">The preferred wind speed.</param>
        /// <param name="theater">Theater definition from which to get wind info for this part of the world.</param>
        public void GenerateWind(DCSMission mission, Wind wind, DefinitionTheater theater)
        {
            DebugLog.Instance.Log("Generating wind...");

            DebugLog.Instance.Log($"  Wind speed should be {wind.ToString().ToUpperInvariant()}");

            // If auto, speed depends on weather, so we never end up with no wind in a storm
            mission.WindLevel = (wind == Wind.Auto) ?
                                (Wind)(HQTools.Clamp((int)mission.WeatherLevel + HQTools.RandomMinMax(-1, 1), 0, (int)Wind.StrongGale))
                : wind;

            DebugLog.Instance.Log($"    Wind speed level set to {mission.WindLevel}");

            for (int i = 0; i < 3; i++)
            {
                mission.WeatherWindSpeed[i]     = Math.Max(0, theater.Wind[(int)mission.WindLevel].Wind.GetValue());
                mission.WeatherWindDirection[i] = (mission.WeatherWindSpeed[i] > 0) ? HQTools.RandomInt(0, 360) : 0;
                DebugLog.Instance.Log($"    Wind speed at {WIND_ALTITUDE[i]} meters set to {mission.WeatherWindSpeed[i]} m/s, direction of {mission.WeatherWindDirection[i]}");
            }

            // Turbulence = max(weatherTurbulence, windTurbulence)
            mission.WeatherTurbulence = Math.Max(mission.WeatherTurbulence, theater.Wind[(int)mission.WindLevel].Turbulence.GetValue());
            DebugLog.Instance.Log($"    Turbulence updated to {mission.WeatherTurbulence} m/s");

            DebugLog.Instance.Log();
        }
예제 #3
0
        /// <summary>
        /// Constructor. Loads data from a .ini file.
        /// </summary>
        /// <param name="ini">The .ini file to load from.</param>
        /// <param name="section">The .ini section to load from.</param>
        /// <param name="key">The top level .ini key to load from.</param>
        public LibraryCommonSettingsEnemyAirDefense(INIFile ini, string section, string key)
        {
            EmbeddedChance   = HQTools.Clamp(ini.GetValue <int>(section, $"{key}.Embedded.Chance") / 100.0, 0.0, 1.0);
            EmbeddedCount    = ini.GetValue <MinMaxI>(section, $"{key}.Embedded.Count");
            EmbeddedFamilies = ini.GetValueArray <UnitFamily>(section, $"{key}.Embedded.Families");
            EmbeddedFamilies = (from f in EmbeddedFamilies where VALID_EMBEDDED_FAMILIES.Contains(f) select f).ToArray();
            if (EmbeddedFamilies.Length == 0)
            {
                EmbeddedFamilies = new UnitFamily[] { UnitFamily.VehicleAAA }
            }
            ;

            InAreaGroupCount = new MinMaxI[AIR_DEFENSE_RANGE_COUNT];
            InAreaGroupSize  = new MinMaxI[AIR_DEFENSE_RANGE_COUNT];
            InAreaFamilies   = new UnitFamily[AIR_DEFENSE_RANGE_COUNT][];

            for (int i = 0; i < AIR_DEFENSE_RANGE_COUNT; i++)
            {
                string subKey = $"{key}.InArea.{((AirDefenseRange)i).ToString()}";

                InAreaGroupCount[i] = ini.GetValue <MinMaxI>(section, $"{subKey}.GroupCount");
                InAreaGroupSize[i]  = ini.GetValue <MinMaxI>(section, $"{subKey}.GroupSize");
                InAreaFamilies[i]   = ini.GetValueArray <UnitFamily>(section, $"{subKey}.Families");
                InAreaFamilies[i]   = (from f in InAreaFamilies[i] where VALID_INAREA_FAMILIES.Contains(f) select f).ToArray();
                if (InAreaFamilies[i].Length == 0)
                {
                    InAreaFamilies[i] = new UnitFamily[] { UnitFamily.VehicleAAA }
                }
                ;
            }
        }
    }
}
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="aircraftType">ID of the aircraft type.</param>
 /// <param name="count">Number of aircraft in the flight group.</param>
 /// <param name="task">Task assigned to the flight group.</param>
 /// <param name="aiWingmen">If true, all aircraft but the first will be AI-controlled. If false, all aircraft will be client-controlled.</param>
 /// <param name="startLocation">Where should the flight group start from?</param>
 public MissionTemplatePlayerFlightGroup(string aircraftType, int count, PlayerFlightGroupTask task, bool aiWingmen, PlayerFlightGroupStartLocation startLocation)
 {
     AircraftType  = aircraftType;
     Count         = HQTools.Clamp(count, 1, MAX_AIRCRAFT_COUNT);
     Task          = task;
     WingmenAI     = aiWingmen;
     StartLocation = startLocation;
 }
예제 #5
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="coordinates">X,Y coordinates of the waypoint.</param>
 /// <param name="name">Name of the waypoint.</param>
 /// <param name="altitudeMultiplier">Altitude multiplier (1.0 = default altitude for aircraft, 0.0 = ground)</param>
 /// <param name="speedMultiplier">Speed multiplier (1.0 = default speed for aircraft, 0.0 = no speed)</param>
 /// <param name="wpAction">Waypoint action (as written in Mission.lua file)</param>
 /// <param name="wpType">Waypoint action type (as written in Mission.lua file)</param>
 /// <param name="airdromeID">ID of the airdrome to use for this waypoint, if any.</param>
 public DCSMissionWaypoint(
     Coordinates coordinates,
     string name = "WP$INDEX$",
     double altitudeMultiplier = 1.0,
     double speedMultiplier    = 1.0,
     string wpAction           = DEFAULT_WP_ACTION,
     string wpType             = DEFAULT_WP_ACTION_TYPE,
     int airdromeID            = 0)
 {
     Coordinates        = coordinates;
     Name               = name;
     AltitudeMultiplier = HQTools.Clamp(altitudeMultiplier, MIN_ALTITUDE_MULTIPLIER, MAX_ALTITUDE_MULTIPLIER);
     SpeedMultiplier    = HQTools.Clamp(speedMultiplier, MIN_SPEED_MULTIPLIER, MAX_SPEED_MULTIPLIER);
     WPAction           = wpAction;
     WPType             = wpType;
     AirdromeID         = airdromeID;
 }
예제 #6
0
        /// <summary>
        /// Picks a starting time for the mission.
        /// Must be called after mission date has been set because sunrise/sunset time changes every month.
        /// </summary>
        /// <param name="mission">The mission.</param>
        /// <param name="timeOfDay">The preferred time of day (noon, dawn, twilight, night, random...)</param>
        /// <param name="theater">Theater definition from which to get sunrise/sunset time.</param>
        public void GenerateMissionTime(DCSMission mission, TimeOfDay timeOfDay, DefinitionTheater theater)
        {
            DebugLog.Instance.Log("Generating mission starting time...");

            double fullTime;

            DebugLog.Instance.Log($"  Mission should start at {timeOfDay.ToString().ToUpperInvariant()}");

            switch (timeOfDay)
            {
            default:     // aka TimeOfDay.Random;
                mission.TimeHour   = HQTools.RandomInt(0, 24);
                mission.TimeMinute = HQTools.RandomInt(0, 4) * 15;
                return;

            case TimeOfDay.RandomDaytime:
                fullTime = HQTools.RandomInt(theater.DayTime[(int)mission.DateMonth].Min, theater.DayTime[(int)mission.DateMonth].Max - 60);
                break;

            case TimeOfDay.Dawn:
                fullTime = HQTools.RandomInt(theater.DayTime[(int)mission.DateMonth].Min, theater.DayTime[(int)mission.DateMonth].Min + 120);
                break;

            case TimeOfDay.Noon:
                fullTime = HQTools.RandomInt(
                    (theater.DayTime[(int)mission.DateMonth].Min + theater.DayTime[(int)mission.DateMonth].Max) / 2 - 90,
                    (theater.DayTime[(int)mission.DateMonth].Min + theater.DayTime[(int)mission.DateMonth].Max) / 2 + 90);
                break;

            case TimeOfDay.Twilight:
                fullTime = HQTools.RandomInt(theater.DayTime[(int)mission.DateMonth].Max - 120, theater.DayTime[(int)mission.DateMonth].Max + 30);
                break;

            case TimeOfDay.Night:
                fullTime = HQTools.RandomInt(0, theater.DayTime[(int)mission.DateMonth].Min - 120);
                break;
            }

            mission.TimeHour   = HQTools.Clamp((int)Math.Floor(fullTime / 60), 0, 23);
            mission.TimeMinute = HQTools.Clamp((int)Math.Floor((fullTime - mission.TimeHour * 60) / 15) * 15, 0, 45);

            DebugLog.Instance.Log($"    Starting time set to {mission.TimeHour.ToString("00")}:{mission.TimeMinute.ToString("00")}");
            DebugLog.Instance.Log();
        }
        // NEXTVERSION
        // public Country[][] LiveriesPriority { get; private set; } = new Country[2][];
        // public string[][] Liveries { get; private set; } = new string[HQTools.EnumCount<Country>()][];

        /// <summary>
        /// Loads data required by this definition.
        /// </summary>
        /// <param name="ini">The ini file to load from.</param>
        /// <returns>True is successful, false if an error happened.</returns>
        protected override bool OnLoad(INIFile ini)
        {
            // --------------
            // [Unit] section
            // --------------
            ID = ini.GetValue <string>("Unit", "ID");
            if (string.IsNullOrEmpty(ID))
            {
                return(false);
            }

            DCSID = ini.GetValue <string>("Unit", "DCSID");
            if (string.IsNullOrEmpty(DCSID))
            {
                DCSID = ID;
            }

            DisplayName = ini.GetValue <string>("Unit", "DisplayName");

            Families = ini.GetValueArray <UnitFamily>("Unit", "Families"); if (Families.Length == 0)
            {
                return(false);
            }

            Category = HQTools.GetUnitCategoryFromUnitFamily(Families[0]);
            // All families must belong to the same category. If that's not the case, remove all "wrong" families.
            Families = (from UnitFamily f in Families where f.ToString().StartsWith(Category.ToString()) select f).ToArray();
            if (Families.Length == 0)
            {
                return(false);
            }

            InService = HQTools.ParseEnumString <TimePeriod>(ini.GetValue <string>("Unit", "InService"), '-', "Decade");
            if (InService.Length < 2)
            {
                return(false);
            }
            InService = InService.Take(2).OrderBy(x => x).ToArray();

            ExtraLua = ini.GetValue <string>("Unit", "ExtraLua");

            // ---------------
            // [Comms] section
            // ---------------
            CommsRadioFrequency = ini.GetValue <float>("Comms", "RadioFrequency");
            CommsRadioFrequency = (CommsRadioFrequency <= 0) ? DEFAULT_RADIO_FREQUENCY : CommsRadioFrequency;

            CommsTACANChannel     = HQTools.Clamp(ini.GetValue <int>("Comms", "TACAN.Channel"), 0, 99);
            CommsTACANChannelMode = ini.GetValue <string>("Comms", "TACAN.ChannelMode").ToUpperInvariant();
            CommsTACANChannelMode = (CommsTACANChannelMode == "Y") ? "Y" : "X";
            CommsTACANCallsign    = ini.GetValue <string>("Comms", "TACAN.Callsign").ToUpperInvariant();

            CommsILSChannel = HQTools.Clamp(ini.GetValue <int>("Comms", "ILS.Channel"), 0, 99);

            // ----------------------------------------------------
            // [Aircraft] section (only for planes and helicopters)
            // ----------------------------------------------------
            if ((Category == UnitCategory.Helicopter) || (Category == UnitCategory.Plane))
            {
                AircraftDefaultTask       = ini.GetValue <DCSFlightGroupTask>("Aircraft", "DefaultTask");
                AircraftAirToAirRating[0] = ini.GetValue <int>("Aircraft", "AirToAirRating.A2APayload");
                AircraftAirToAirRating[1] = ini.GetValue <int>("Aircraft", "AirToAirRating.A2GPayload");
                AircraftCruiseAltitude    = ini.GetValue <int>("Aircraft", "CruiseAltitude") * HQTools.FEET_TO_METERS;
                if (AircraftCruiseAltitude <= 0)
                {
                    AircraftCruiseAltitude = Category == UnitCategory.Helicopter ? 350 : 6000;
                }
                AircraftCruiseSpeed = ini.GetValue <int>("Aircraft", "CruiseSpeed") * HQTools.KNOTS_TO_METERSPERSECOND;
                if (AircraftCruiseSpeed <= 0)
                {
                    AircraftCruiseSpeed = Category == UnitCategory.Helicopter ? 50 : 130;
                }
                AircraftPlayerControllable = ini.GetValue <bool>("Aircraft", "PlayerControllable");
                AircraftCarrierShipType    = ini.GetValueArray <CarrierGroupShipType>("Aircraft", "CarrierShipType");

                // -----------------------------------------------------------
                // [AircraftPayload] section (only for planes and helicopters)
                // -----------------------------------------------------------
                int i, j;

                AircraftPayloadCommon = ini.GetValue <string>("AircraftPayload", "Common");

                List <PlayerFlightGroupPayloadType> payloadsList = new List <PlayerFlightGroupPayloadType>();

                for (i = 0; i < AircraftPayloadPylons.GetLength(0); i++)
                {
                    for (j = 0; j < AircraftPayloadPylons.GetLength(1); j++)
                    {
                        AircraftPayloadPylons[i, j] = ini.GetValue <string>("AircraftPayload",
                                                                            $"Pylons.{((PlayerFlightGroupPayloadType)i).ToString()}.Pylon{HQTools.ValToString(j + 1, "00")}");

                        // Each payload with at least one pylon not empty is a valid payload
                        if (!payloadsList.Contains((PlayerFlightGroupPayloadType)i) && !string.IsNullOrEmpty(AircraftPayloadPylons[i, j]))
                        {
                            payloadsList.Add((PlayerFlightGroupPayloadType)i);
                        }
                    }
                }

                AircraftAvailablePayloads = payloadsList.ToArray();
            }

            // ------------------
            // [Liveries] section
            // ------------------
            // NEXT VERSION
            //LiveriesPriority[0] = ini.GetValueArray<Country>("Liveries", "Priority.Real");
            //LiveriesPriority[1] = ini.GetValueArray<Country>("Liveries", "Priority.Fictional");

            //Liveries = new string[HQTools.EnumCount<Country>()][];
            //for (int i = 0; i < Liveries.Length; i++)
            //    Liveries[i] = ini.GetValueArray<string>("Liveries", $"Country.{(Country)i}", '|');

            return(true);
        }