/// <summary>
        /// Loads data required by this definition.
        /// </summary>
        /// <param name="ini">INI file to load definition from.</param>
        /// <returns>True is successful, false if an error happened.</returns>
        protected override bool OnLoad(INIFile ini)
        {
            int i;

            // [Theater] section
            DCSID               = ini.GetValue <string>("Theater", "DCSID");
            DefaultMapCenter    = ini.GetValue <Coordinates>("Theater", "DefaultMapCenter");
            RequiredModules     = ini.GetValueArray <string>("Theater", "RequiredModules");
            MagneticDeclination = ini.GetValue <float>("Theater", "MagneticDeclination");

            // [Daytime] section
            DayTime = new MinMaxI[12];
            for (i = 0; i < 12; i++)
            {
                DayTime[i] = ini.GetValue <MinMaxI>("Daytime", ((Month)i).ToString());
            }

            // [Temperature] section
            Temperature = new MinMaxI[12];
            for (i = 0; i < 12; i++)
            {
                Temperature[i] = ini.GetValue <MinMaxI>("Temperature", ((Month)i).ToString());
            }

            // [Weather] section
            Weather = new DefinitionTheaterWeather[HQTools.EnumCount <Weather>() - 1]; // -1 because we don't want "Random"
            for (i = 0; i < Weather.Length; i++)
            {
                Weather[i] = new DefinitionTheaterWeather(ini, ((Weather)i).ToString());
            }

            // [Wind] section
            Wind = new DefinitionTheaterWind[HQTools.EnumCount <Wind>() - 1]; // -1 because we don't want "Auto"
            for (i = 0; i < Wind.Length; i++)
            {
                Wind[i] = new DefinitionTheaterWind(ini, ((Wind)i).ToString());
            }

            // [Airbases] section
            Airbases = new DefinitionTheaterAirbase[ini.GetTopLevelKeysInSection("Airbases").Length];
            i        = 0;
            foreach (string k in ini.GetTopLevelKeysInSection("Airbases"))
            {
                Airbases[i] = new DefinitionTheaterAirbase(ini, k); i++;
            }

            // [SpawnPoints] section
            SpawnPoints = new DefinitionTheaterSpawnPoint[ini.GetKeysInSection("SpawnPoints").Length];
            i           = 0;
            foreach (string k in ini.GetKeysInSection("SpawnPoints"))
            {
                SpawnPoints[i] = new DefinitionTheaterSpawnPoint(ini, k); i++;
            }

            ResetUsedSpawnPoints();

            return(true);
        }
        public DefinitionTheaterSpawnPoint?GetRandomSpawnPoint(
            TheaterLocationSpawnPointType[] validTypes = null, DCSCountry[] validCountries = null,
            MinMaxD?distanceFrom  = null, Coordinates?distanceOrigin  = null,
            MinMaxD?distanceFrom2 = null, Coordinates?distanceOrigin2 = null)
        {
            IEnumerable <DefinitionTheaterSpawnPoint> validSP = (from DefinitionTheaterSpawnPoint s in SpawnPoints where !UsedSpawnPointsID.Contains(s.UniqueID) select s);

            if (validTypes != null)
            {
                validSP = (from DefinitionTheaterSpawnPoint s in validSP where validTypes.Contains(s.PointType) select s);
            }

            if (validCountries != null)
            {
                validSP = (from DefinitionTheaterSpawnPoint s in validSP where validCountries.Contains(s.Country) select s);
            }

            if (distanceFrom.HasValue && distanceOrigin.HasValue)
            {
                if (validSP.Count() == 0)
                {
                    return(null);
                }

                MinMaxD searchRange = distanceFrom.Value;

                IEnumerable <DefinitionTheaterSpawnPoint> validSPInRange = (from DefinitionTheaterSpawnPoint s in validSP select s);

                do
                {
                    validSPInRange = (from DefinitionTheaterSpawnPoint s in validSP where searchRange.Contains(distanceOrigin.Value.GetDistanceFrom(s.Coordinates)) select s);
                    searchRange    = new MinMaxD(searchRange.Min * 0.9, Math.Max(100, searchRange.Max * 1.1));
                } while (validSPInRange.Count() == 0);

                validSP = (from DefinitionTheaterSpawnPoint s in validSPInRange select s);
            }

            if (distanceFrom2.HasValue && distanceOrigin2.HasValue)
            {
                if (validSP.Count() == 0)
                {
                    return(null);
                }

                MinMaxD searchRange = distanceFrom2.Value;

                IEnumerable <DefinitionTheaterSpawnPoint> validSPInRange = (from DefinitionTheaterSpawnPoint s in validSP select s);

                do
                {
                    validSPInRange = (from DefinitionTheaterSpawnPoint s in validSP where searchRange.Contains(distanceOrigin2.Value.GetDistanceFrom(s.Coordinates)) select s);
                    searchRange    = new MinMaxD(searchRange.Min * 0.9, Math.Max(100, searchRange.Max * 1.1));
                } while (validSPInRange.Count() == 0);

                validSP = (from DefinitionTheaterSpawnPoint s in validSPInRange select s);
            }

            if (validSP.Count() == 0)
            {
                return(null);
            }

            DefinitionTheaterSpawnPoint selectedSpawnPoint = HQTools.RandomFrom(validSP.ToArray());

            UsedSpawnPointsID.Add(selectedSpawnPoint.UniqueID);
            return(selectedSpawnPoint);
        }