Exemplo n.º 1
0
        /// <summary>
        /// Generates Data for a star based on it's spectral type and populates it with the data.
        /// </summary>
        /// <remarks>
        /// This function randomly generates the Radius, Temperature, Luminosity, Mass and Age of a star and then returns a star populated with those generated values.
        /// What follows is a brief description of how that is done for each data point:
        /// <list type="Bullet">
        /// <item>
        /// <b>Temperature:</b> The Temp. of the star is obtained by using the Randon.Next(min, max) function to get a random Temp. in the range a star of the given
        /// spectral type.
        /// </item>
        /// <item>
        /// <b>Luminosity:</b> The Luminosity of a star is calculated by using the RNG_NextDoubleRange() function to get a random Luminosity in the range a star of the
        /// given spectral type.
        /// </item>
        /// <item>
        /// <b>Age:</b> The possible ages for a star depend largely on its mass. The bigger and heaver the star the more pressure is put on its core where fusion occur
        /// which increases the rate that it burns Hydrogen which reduces the life of the star. The Big O class stars only last a few million years before either
        /// going Hyper Nova or devolving into a class B star. on the other hand a class G star (like Sol) has a life expectancy of about 10 billion years while a
        /// little class M star could last 100 billion years or more (hard to tell given that the Milky way is 13.2 billion years old and the universe is only
        /// about a billion years older then that). Given this we first use the mass of the star to produce a number between 0 and 1 that we can use to pick a
        /// possible age from the range (just like all the above). To get the number between 0 and 1 we use the following formula:
        /// <c>1 - Mass / MaxMassOfStarOfThisType</c>
        /// </item>
        /// </list>
        /// </remarks>
        /// <param name="starMVDB">The SystemBodyDB of the star.</param>
        /// <param name="spectralType">The Spectral Type of the star.</param>
        /// <param name="randomSelection">Random selection to generate consistent values.</param>
        /// <returns>A StarInfoDB Populated with data generated based on Spectral Type and SystemBodyDB information provided.</returns>
        private StarInfoDB GenerateStarInfo(MassVolumeDB starMVDB, SpectralType spectralType, double randomSelection)
        {
            double maxStarAge = _galaxyGen.Settings.StarAgeBySpectralType[spectralType].Max;

            StarInfoDB starData = new StarInfoDB {// for star age we will make it proportional to the inverse of the stars mass ratio (for that type of star).
                // while this will produce the same age for the same mass/type of star the chances of getting the same
                // mass/type are tiny. Tho there will still be the obvious inverse relationship here.
                Age          = (1 - starMVDB.Mass / _galaxyGen.Settings.StarMassBySpectralType[spectralType].Max) * maxStarAge,
                SpectralType = spectralType,
                Temperature  = (uint)Math.Round(GMath.SelectFromRange(_galaxyGen.Settings.StarTemperatureBySpectralType[spectralType], randomSelection)),
                Luminosity   = (float)GMath.SelectFromRange(_galaxyGen.Settings.StarLuminosityBySpectralType[spectralType], randomSelection)
            };

            // Generate a string specifying the full spectral class form a star.
            // start by getting the sub-division, which is based on temp.
            double sub = starData.Temperature / _galaxyGen.Settings.StarTemperatureBySpectralType[starData.SpectralType].Max; // temp range from 0 to 1.

            starData.SpectralSubDivision = (ushort)Math.Round((1 - sub) * 10);                                                // invert temp range as 0 is hottest, 9 is coolest.

            // now get the luminosity class
            //< @todo For right now everthing is just main sequence. see http://en.wikipedia.org/wiki/Stellar_classification
            // on how this should be done. For right now tho class V is fine (its just flavor text).
            starData.LuminosityClass = LuminosityClass.V;

            // finally add them all up to get the class string:
            starData.Class = starData.SpectralType + starData.SpectralSubDivision.ToString() + "-" + starData.LuminosityClass;

            return(starData);
        }
Exemplo n.º 2
0
        public static Entity CreateJumpPoint(StarSystemFactory ssf, StarSystem system)
        {
            var primaryStarInfoDB = system.GetFirstEntityWithDataBlob <StarInfoDB>().GetDataBlob <OrbitDB>().Root.GetDataBlob <StarInfoDB>();

            NameDB        jpNameDB        = new NameDB("Jump Point");
            PositionDB    jpPositionDB    = new PositionDB(0, 0, 0, system.Guid);
            TransitableDB jpTransitableDB = new TransitableDB();

            jpTransitableDB.IsStabilized = system.Game.Settings.AllJumpPointsStabilized ?? false;

            if (!jpTransitableDB.IsStabilized)
            {
                // TODO: Introduce a random chance to stablize jumppoints.
            }

            var jpPositionLimits = new MinMaxStruct(ssf.GalaxyGen.Settings.OrbitalDistanceByStarSpectralType[primaryStarInfoDB.SpectralType].Min, ssf.GalaxyGen.Settings.OrbitalDistanceByStarSpectralType[primaryStarInfoDB.SpectralType].Max);

            jpPositionDB.X_AU = GMath.SelectFromRange(jpPositionLimits, system.RNG.NextDouble());
            jpPositionDB.Y_AU = GMath.SelectFromRange(jpPositionLimits, system.RNG.NextDouble());

            // Randomly flip the position sign to allow negative values.
            if (system.RNG.Next(0, 100) < 50)
            {
                jpPositionDB.X_AU = 0 - jpPositionDB.X_AU;
            }
            if (system.RNG.Next(0, 100) < 50)
            {
                jpPositionDB.Y_AU = 0 - jpPositionDB.Y_AU;
            }

            var dataBlobs = new List <BaseDataBlob> {
                jpNameDB, jpTransitableDB, jpPositionDB
            };

            Entity jumpPoint = Entity.Create(system, Guid.Empty, dataBlobs);

            return(jumpPoint);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Generates an entire group of stars for a starSystem.
        /// </summary>
        /// <remarks>
        /// Stars created with this method are sorted by mass.
        /// Stars created with this method are added to the newSystem's EntityManager.
        /// </remarks>
        /// <param name="system">The Star System the new stars belongs to.</param>
        /// <param name="numStars">The number of stars to create.</param>
        /// <returns>A mass-sorted list of entity ID's for the generated stars.</returns>
        public List <Entity> CreateStarsForSystem(StarSystem system, int numStars, DateTime currentDateTime)
        {
            // Argument Validation.
            if (system == null)
            {
                throw new ArgumentNullException("system");
            }

            if (numStars <= 0)
            {
                throw new ArgumentOutOfRangeException("numStars", "numStars must be greater than 0.");
            }

            // List of stars we'll be creating.
            var stars = new List <Entity>();

            while (stars.Count < numStars)
            {
                // Generate a SpectralType for the star.
                SpectralType starType;
                if (_galaxyGen.Settings.RealStarSystems)
                {
                    starType = _galaxyGen.Settings.StarTypeDistributionForRealStars.Select(system.RNG.NextDouble());
                }
                else
                {
                    starType = _galaxyGen.Settings.StarTypeDistributionForFakeStars.Select(system.RNG.NextDouble());
                }

                // We will use the one random number to select from all the spectral type ranges. Should give us saner numbers for stars.
                double randomSelection = system.RNG.NextDouble();

                // Generate the star's datablobs.
                MassVolumeDB starMVDB = MassVolumeDB.NewFromMassAndRadius(
                    GMath.SelectFromRange(_galaxyGen.Settings.StarMassBySpectralType[starType], randomSelection),
                    GMath.SelectFromRange(_galaxyGen.Settings.StarRadiusBySpectralType[starType], randomSelection));

                StarInfoDB starData = GenerateStarInfo(starMVDB, starType, randomSelection);

                // Initialize Position as 0,0,0. It will be updated when the star's orbit is calculated.
                PositionDB positionData = new PositionDB(0, 0, 0, system.Guid);

                var baseDataBlobs = new List <BaseDataBlob> {
                    starMVDB, starData, positionData
                };

                stars.Add(Entity.Create(system, Guid.Empty, baseDataBlobs));
            }

            // The root star must be the most massive. Find it.
            Entity rootStar = stars[0];

            double rootStarMass = rootStar.GetDataBlob <MassVolumeDB>().Mass;

            foreach (Entity currentStar in stars)
            {
                double currentStarMass = currentStar.GetDataBlob <MassVolumeDB>().Mass;

                if (rootStarMass < currentStarMass)
                {
                    rootStar     = currentStar;
                    rootStarMass = rootStar.GetDataBlob <MassVolumeDB>().Mass;
                }
            }

            // Swap the root star to index 0.
            int    rootIndex     = stars.IndexOf(rootStar);
            Entity displacedStar = stars[0];

            stars[rootIndex] = displacedStar;
            stars[0]         = rootStar;

            // Generate orbits.
            Entity       anchorStar   = stars[0];
            MassVolumeDB anchorMVDB   = anchorStar.GetDataBlob <MassVolumeDB>();
            Entity       previousStar = stars[0];

            previousStar.SetDataBlob(new OrbitDB());

            int starIndex = 0;

            foreach (Entity currentStar in stars)
            {
                StarInfoDB currentStarInfo   = currentStar.GetDataBlob <StarInfoDB>();
                NameDB     currentStarNameDB = new NameDB(system.NameDB.DefaultName + " " + (char)('A' + starIndex) + " " + currentStarInfo.SpectralType + currentStarInfo.SpectralSubDivision + currentStarInfo.LuminosityClass);
                currentStar.SetDataBlob(currentStarNameDB);

                if (previousStar == currentStar)
                {
                    // This is the "Anchor Star"
                    continue;
                }

                OrbitDB    previousOrbit    = previousStar.GetDataBlob <OrbitDB>();
                StarInfoDB previousStarInfo = previousStar.GetDataBlob <StarInfoDB>();

                double minDistance = _galaxyGen.Settings.OrbitalDistanceByStarSpectralType[previousStarInfo.SpectralType].Max + _galaxyGen.Settings.OrbitalDistanceByStarSpectralType[currentStarInfo.SpectralType].Max + previousOrbit.SemiMajorAxis;

                double sma          = minDistance * Math.Pow(system.RNG.NextDouble(), 3);
                double eccentricity = Math.Pow(system.RNG.NextDouble() * 0.8, 3);

                OrbitDB currentOrbit = OrbitDB.FromAsteroidFormat(anchorStar, anchorMVDB.Mass, currentStar.GetDataBlob <MassVolumeDB>().Mass, sma, eccentricity, _galaxyGen.Settings.MaxBodyInclination * system.RNG.NextDouble(), system.RNG.NextDouble() * 360, system.RNG.NextDouble() * 360, system.RNG.NextDouble() * 360, currentDateTime);
                currentStar.SetDataBlob(currentOrbit);
                currentStar.GetDataBlob <PositionDB>().SetParent(currentOrbit.Parent);
                previousStar = currentStar;
                starIndex++;
            }
            return(stars);
        }