/// <summary>
        /// Unloads all data used by this session component
        /// </summary>
        protected override void UnloadData()
        {
            PluginLog.Log("Unloading system generator data");

            UnloadNet();
            Objects?.Clear();
            PlanetDefinitions?.Clear();
            m_moonDefinitions?.Clear();
            MandatoryPlanets?.Clear();
            GasGiants?.Clear();
            m_settings = null;
            Static     = null;
        }
        /// <summary>
        /// Filters all planetary definitions based on settings set in the Plugin settings file and puts them in their respective lists.
        /// </summary>
        private void FilterDefinitions()
        {
            List <MyPlanetGeneratorDefinition> toRemovePlanets = new List <MyPlanetGeneratorDefinition>();

            foreach (var p in PlanetDefinitions)
            {
                if (p.Id.SubtypeId.String.Contains("Tutorial") || p.Id.SubtypeId.String.Contains("TestMap") || p.Id.SubtypeId.String.Contains("ModExample"))
                {
                    toRemovePlanets.Add(p);
                    continue;
                }
                if (!SettingsSession.Static.Settings.GeneratorSettings.UseVanillaPlanets && vanilla_planets.Contains(p.Id.SubtypeId.String))
                {
                    toRemovePlanets.Add(p);
                    continue;
                }
                if (SettingsSession.Static.Settings.GeneratorSettings.PlanetSettings.BlacklistedPlanets.Contains(p.Id.SubtypeId.String))
                {
                    toRemovePlanets.Add(p);
                }
                if (SettingsSession.Static.Settings.GeneratorSettings.PlanetSettings.Moons.Contains(p.Id.SubtypeId.String))
                {
                    toRemovePlanets.Add(p);
                    m_moonDefinitions.Add(p);
                    AvailableMoons.Add(p);
                }
                if (SettingsSession.Static.Settings.GeneratorSettings.PlanetSettings.MandatoryPlanets.Contains(p.Id.SubtypeId.String) || SettingsSession.Static.Settings.GeneratorSettings.SemiRandomizedGeneration)
                {
                    MandatoryPlanets.Add(p);
                }
                if (SettingsSession.Static.Settings.GeneratorSettings.PlanetSettings.GasGiants.Contains(p.Id.SubtypeId.String))
                {
                    GasGiants.Add(p);
                }
            }

            foreach (var r in toRemovePlanets)
            {
                PlanetDefinitions.Remove(r);
            }

            foreach (var p in PlanetDefinitions)
            {
                AvailablePlanets.Add(p);
            }

            ShuffleMandatoryPlanets();
        }
        /// <summary>
        /// Generates moon datas for a planet of the given size, gravity, name and distance from the world center.
        /// The moon has to have a size smaller than the planet
        /// </summary>
        /// <param name="planetSize">Size of the parent planet</param>
        /// <param name="surfaceGravity">Surface gravity of the parent planet</param>
        /// <param name="planetName">Name of the planet, used for naming the moon</param>
        /// <param name="distance">Distance</param>
        /// <returns>An array of all generated moons</returns>
        private MyPlanetMoonItem[] GenerateMoons(float planetSize, float surfaceGravity, string planetName, long distance)
        {
            if (MyRandom.Instance.NextFloat() > m_settings.PlanetSettings.MoonProbability)
            {
                return(new MyPlanetMoonItem[0]);
            }

            int maxMoons = GetMaxMoonCount(surfaceGravity);
            int numMoons = MyRandom.Instance.Next(maxMoons > 0 ? 1 : 0, maxMoons + 1);

            MyPlanetMoonItem[] moons = new MyPlanetMoonItem[numMoons];

            for (int i = 0; i < numMoons; i++)
            {
                var  dist       = planetSize * (i + 1) + planetSize * MyRandom.Instance.GetRandomFloat(0.5f, 1.5f);
                var  def        = GetPlanetMoonDefinition(planetSize * 0.8f);
                bool isGasGiant = GasGiants.Contains(def);

                if (dist + distance > m_settings.WorldSize && m_settings.WorldSize > 0)
                {
                    return(moons);
                }

                string name = SettingsSession.Static.Settings.GeneratorSettings.PlanetSettings.MoonNameFormat
                              .SetProperty("ObjectNumber", i + 1)
                              .SetProperty("ObjectNumberGreek", greek_letters[i % greek_letters.Length])
                              .SetProperty("ObjectNumberRoman", ConvertNumberToRoman(i + 1))
                              .SetProperty("ObjectLetterLower", (char)('a' + (i % 26)))
                              .SetProperty("ObjectLetterUpper", (char)('A' + (i % 26)))
                              .SetProperty("ObjectId", def.Id.SubtypeId.String)
                              .SetProperty("MoonPlanetName", planetName);

                MyPlanetMoonItem item = new MyPlanetMoonItem();
                item.Type        = SystemObjectType.MOON;
                item.DefName     = def.Id.SubtypeName.ToString();
                item.Distance    = dist;
                item.Size        = SizeByGravity(def.SurfaceGravity, isGasGiant);
                item.DisplayName = name;

                moons[i] = item;
            }

            return(moons);
        }
        /// <summary>
        /// Generates a planets data and possible moons or an asteroid ring for the planet
        /// </summary>
        /// <param name="index">Index of the planet in the system</param>
        /// <param name="distance">Distance from the world center</param>
        /// <param name="totalObjects">Total number of objects in the system</param>
        /// <param name="planetIndex">Index of the planet of the planets (n-th planet)</param>
        private void GeneratePlanet(int index, long distance, int totalObjects, ref int planetIndex)
        {
            MyPlanetItem planet = new MyPlanetItem();

            double mod = distance == 0 && m_settings.FirstPlanetCenter ? 1 : Math.Sin(index * Math.PI / totalObjects);

            var  def        = GetPlanetDefinition((int)(m_settings.PlanetSettings.PlanetSizeCap * mod));
            bool isGasGiant = GasGiants.Contains(def);
            var  size       = SizeByGravity(def.SurfaceGravity, isGasGiant);

            var      angle  = MyRandom.Instance.GetRandomFloat(0, (float)(2 * Math.PI));
            var      height = MyRandom.Instance.GetRandomFloat((float)Math.PI / 180 * -5, (float)Math.PI / 180 * 5);
            Vector3D pos    = new Vector3D(distance * Math.Sin(angle), distance * Math.Cos(angle), distance * Math.Sin(height));

            string name = SettingsSession.Static.Settings.GeneratorSettings.PlanetSettings.PlanetNameFormat
                          .SetProperty("ObjectNumber", planetIndex + 1)
                          .SetProperty("ObjectNumberGreek", greek_letters[planetIndex % greek_letters.Length])
                          .SetProperty("ObjectNumberRoman", ConvertNumberToRoman(planetIndex + 1))
                          .SetProperty("ObjectLetterLower", (char)('a' + (planetIndex % 26)))
                          .SetProperty("ObjectLetterUpper", (char)('A' + (planetIndex % 26)))
                          .SetProperty("ObjectId", def.Id.SubtypeId.String);

            ++planetIndex;

            planet.DisplayName    = name;
            planet.Type           = SystemObjectType.PLANET;
            planet.DefName        = def.Id.SubtypeId.String;
            planet.Size           = size;
            planet.PlanetRing     = GenerateRing(def.SurfaceGravity, planet.Size);
            planet.OffsetPosition = pos;
            planet.CenterPosition = pos;
            planet.PlanetMoons    = GenerateMoons(planet.Size, def.SurfaceGravity, planet.DisplayName, distance);
            planet.Generated      = false;

            Objects.Add(planet);
        }