Example #1
0
 /// <summary>
 /// Gets the orbit of this body around the sun.
 /// </summary>
 /// <returns>If the Sun, returns <c>null</c>. If a planet, returns its orbit. If a moon,
 /// returns its planet's orbit.</returns>
 /// <param name="body">The object whose motion around the Sun is desired.</param>
 private static Orbit getHeliocentricOrbit(CelestialBody body)
 {
     if (body.GetOrbitDriver() == null)
     {
         return(null);
     }
     else
     {
         Orbit orbit       = body.GetOrbit();
         Orbit parentOrbit = getHeliocentricOrbit(orbit.referenceBody);
         if (parentOrbit == null)
         {
             return(orbit);
         }
         else
         {
             return(parentOrbit);
         }
     }
 }
Example #2
0
        /// <summary>
        /// Returns the desired property of a known celestial body.
        /// </summary>
        ///
        /// <param name="planet">The exact, case-sensitive name of the celestial body. Assumes all
        /// loaded celestial bodies have unique names.</param>
        /// <param name="property">The short name of the property to recover. Must be one
        /// of ("rad", "soi", "sma", "per", "apo", "ecc", "inc", "ape", "lan", "mna0", "mnl0",
        /// "prot", "psun", "porb", "vesc", "vorb", "vmin", or "vmax").
        /// The only properties supported for Sun are "rad", "soi", "prot", and "vesc".</param>
        /// <returns>The value of <c>property</c> appropriate for <c>planet</c>. Distances are given
        /// in meters, angles are given in degrees.</returns>
        ///
        /// <exception cref="ArgumentException">Thrown if no planet named <c>name</c> exists, or if
        /// <c>property</c> does not have one of the allowed values. The program state shapp remain
        /// unchanged in the event of an exception.</exception>
        protected static double getPlanetProperty(string planet, string property)
        {
            CelestialBody body = AsteroidManager.getPlanetByName(planet);

            switch (property.ToLower())
            {
            case "rad":
                return(body.Radius);

            case "soi":
                return(body.sphereOfInfluence);

            case "prot":
                return(body.rotates ? body.rotationPeriod : double.PositiveInfinity);

            case "psol":
                if (body.solarRotationPeriod)
                {
                    return(body.solarDayLength);
                }
                else
                {
                    throw new ArgumentException(
                              Localizer.Format("#autoLOC_CustomAsteroids_ErrorPlanetNoDay", planet),
                              nameof(property));
                }

            case "vesc":
                return(Math.Sqrt(2 * body.gravParameter / body.Radius));

            default:
                if (body.GetOrbitDriver() == null)
                {
                    throw new ArgumentException(
                              Localizer.Format("#autoLOC_CustomAsteroids_ErrorPlanetNoOrbit", planet),
                              nameof(planet));
                }
                Orbit orbit = body.GetOrbit();

                switch (property.ToLower())
                {
                case "sma":
                    return(orbit.semiMajorAxis);

                case "per":
                    return(orbit.PeR);

                case "apo":
                    return(orbit.ApR);

                case "ecc":
                    return(orbit.eccentricity);

                case "inc":
                    return(orbit.inclination);

                case "ape":
                    return(orbit.argumentOfPeriapsis);

                case "lpe":
                    // Ignore inclination: http://en.wikipedia.org/wiki/Longitude_of_periapsis
                    return(orbit.LAN + orbit.argumentOfPeriapsis);

                case "lan":
                    return(orbit.LAN);

                case "mna0":
                    return(meanAnomalyAtUT(orbit, 0.0) * 180.0 / Math.PI);

                case "mnl0":
                    return(anomalyToLong(meanAnomalyAtUT(orbit, 0.0) * 180.0 / Math.PI,
                                         orbit.inclination, orbit.argumentOfPeriapsis, orbit.LAN));

                case "porb":
                    return(orbit.period);

                case "vorb":
                    // Need circumference of an ellipse; closed form does not exist
                    double sum        = orbit.semiMajorAxis + orbit.semiMinorAxis;
                    double diff       = orbit.semiMajorAxis - orbit.semiMinorAxis;
                    double h          = diff * diff / (sum * sum);
                    double correction = 1.0;
                    for (int n = 1; n < 10; n++)
                    {
                        double coeff = Util.DoubleFactorial(2 * n - 1)
                                       / (Math.Pow(2, n) * Util.Factorial(n))
                                       / (2 * n - 1);
                        correction += coeff * coeff * Math.Pow(h, n);
                    }
                    return(Math.PI * sum * correction / orbit.period);

                case "vmin":
                    return(orbit.getOrbitalSpeedAtDistance(orbit.ApR));

                case "vmax":
                    return(orbit.getOrbitalSpeedAtDistance(orbit.PeR));

                default:
                    throw new ArgumentException(
                              Localizer.Format("#autoLOC_CustomAsteroids_ErrorPlanetBadProperty", property),
                              nameof(property));
                }
            }
        }
        private IEnumerator<YieldInstruction> LoadCB(ConfigNode node, CelestialBody body)
        {
            bool updateMass = false;
            //OnGui();
            #region CBChanges
            print("Fixing CB " + node.name + " of radius " + body.Radius);
            guiMinor = "CelestialBody";
            //OnGui();
            double origRadius = body.Radius;
            double origAtmo = body.maxAtmosphereAltitude;

            #region CBMassRadius

            node.TryGetValue("bodyName", ref body.bodyName);
            node.TryGetValue("bodyDescription", ref body.bodyDescription);
            if (node.TryGetValue("Radius", ref body.Radius))
                updateMass = true;
            print("Radius ratio: " + body.Radius / origRadius);

            if (node.TryGetValue("Mass", ref body.Mass))
            {
                MassToOthers(body);

            }
            if (node.TryGetValue("GeeASL", ref body.GeeASL))
            {
                GeeASLToOthers(body);
                updateMass = false;
            }
            if (node.TryGetValue("gravParameter", ref body.gravParameter))
            {
                GravParamToOthers(body);
                updateMass = false;
            }
            #endregion

            #region CBAtmosphereTemperature
            node.TryGetValue("atmosphericAmbientColor", ref body.atmosphericAmbientColor);
            node.TryGetValue("atmosphere", ref body.atmosphere);
            node.TryGetValue("atmosphereScaleHeight", ref body.atmosphereScaleHeight);
            node.TryGetValue("atmosphereMultiplier", ref body.atmosphereMultiplier);
            node.TryGetValue("maxAtmosphereAltitude", ref body.maxAtmosphereAltitude);
            node.TryGetValue("staticPressureASL", ref body.staticPressureASL);
            node.TryGetValue("useLegacyAtmosphere", ref body.useLegacyAtmosphere);
            if (!body.useLegacyAtmosphere)
            {
                ConfigNode PCnode = node.GetNode("pressureCurve");
                if (PCnode != null)
                {
                    body.altitudeMultiplier = 1f;
                    body.pressureMultiplier = 1f;
                    AnimationCurve pressureCurve = Utils.LoadAnimationCurve(PCnode);
                    if (pressureCurve != null)
                        body.pressureCurve = pressureCurve;
                    else
                    {
                        body.useLegacyAtmosphere = true;
                        Debug.LogWarning("Unable to load pressureCurve data for " + body.name + ": Using legacy atmosphere");
                    }
                    print("*RSS* finished with " + body.GetName() + ".pressureCurve (" + body.pressureCurve.keys.Length.ToString() + " keys)");
                }
                else
                {
                    print("*RSS* useLegacyAtmosphere = False but pressureCurve not found!");
                }
            }
            if (node.HasNode("temperatureCurve"))
            {
                ConfigNode TCnode = node.GetNode("temperatureCurve");
                if (TCnode != null)
                {
                    AnimationCurve temperatureCurve = Utils.LoadAnimationCurve(TCnode);
                    if (temperatureCurve != null)
                    {
                        body.temperatureCurve = temperatureCurve;
                        // Following two lines corrects situations where planets without atmosphere's have these two fields zeroed out
                        // Maybe think about making these configurable in the planet's config node? yes? no? meh?
                        body.atmoshpereTemperatureMultiplier = 1f;
                        body.altitudeMultiplier = 1f;
                        print("*RSS* found and loaded temperatureCurve data for " + body.name);
                    }
                }
            }
            #endregion

            #region CBRotation
            node.TryGetValue("rotationPeriod", ref body.rotationPeriod);
            node.TryGetValue("tidallyLocked", ref body.tidallyLocked);
            node.TryGetValue("initialRotation", ref body.initialRotation);
            node.TryGetValue("inverseRotation", ref body.inverseRotation);
            #endregion

            if (updateMass)
                GeeASLToOthers(body);

            /*if (node.HasValue("axialTilt"))
            {
                if (!body.inverseRotation && double.TryParse(node.GetValue("axialTilt"), out dtmp))
                {
                    CBRotationFixer.CBRotations.Add(body.name, new CBRotation(body.name, dtmp, body.rotationPeriod, body.initialRotation));
                    body.rotationPeriod = 0;
                }
            }*/
            yield return null;

            #region CBOrbit
            ConfigNode onode = node.GetNode("Orbit");
            if (body.orbitDriver != null && body.orbit != null && onode != null)
            {
                if (loadInfo.useEpoch)
                    body.orbit.epoch = loadInfo.epoch;

                onode.TryGetValue("semiMajorAxis", ref body.orbit.semiMajorAxis);
                onode.TryGetValue("eccentricity", ref body.orbit.eccentricity);
                onode.TryGetValue("meanAnomalyAtEpoch", ref body.orbit.meanAnomalyAtEpoch);
                if (onode.TryGetValue("meanAnomalyAtEpochD", ref body.orbit.meanAnomalyAtEpoch))
                    body.orbit.meanAnomalyAtEpoch *= DEG2RAD;
                onode.TryGetValue("inclination", ref body.orbit.inclination);
                onode.TryGetValue("period", ref body.orbit.period);
                onode.TryGetValue("LAN", ref body.orbit.LAN);
                onode.TryGetValue("argumentOfPeriapsis", ref body.orbit.argumentOfPeriapsis);
                if (onode.HasValue("orbitColor"))
                {
                    try
                    {
                        Vector4 col = KSPUtil.ParseVector4(onode.GetValue("orbitColor"));
                        Color c = new Color(col.x, col.y, col.z, col.w);
                        body.GetOrbitDriver().orbitColor = c;
                    }
                    catch (Exception e)
                    {
                        print("*RSS* Error parsing as color4: original text: " + onode.GetValue("orbitColor") + " --- exception " + e.Message);
                    }
                }
                string bodyname = "";
                if (onode.TryGetValue("referenceBody", ref bodyname))
                {
                    if (body.orbit.referenceBody == null || !body.orbit.referenceBody.Equals(bodyname))
                    {
                        foreach (CelestialBody b in FlightGlobals.Bodies)
                        {
                            if (b.name.Equals(bodyname))
                            {
                                if (body.orbit.referenceBody)
                                {
                                    body.orbit.referenceBody.orbitingBodies.Remove(body);
                                }
                                b.orbitingBodies.Add(body);
                                body.orbit.referenceBody = b;
                                break;
                            }
                        }
                    }
                }
            }
            yield return null;
            // SOI and HillSphere done at end
            body.CBUpdate();
            #endregion
            #endregion

            #region SSPQSFade
            // Scaled space fader
            float SSFMult = 1.0f;
            float SSFStart = -1, SSFEnd = -1;
            node.TryGetValue("SSFStart", ref SSFStart);
            node.TryGetValue("SSFEnd", ref SSFEnd);
            node.TryGetValue("SSFMult", ref SSFMult);

            foreach (ScaledSpaceFader ssf in Resources.FindObjectsOfTypeAll(typeof(ScaledSpaceFader)))
            {
                if (ssf.celestialBody != null)
                {
                    if (ssf.celestialBody.name.Equals(node.name))
                    {
                        if (SSFStart >= 0)
                            ssf.fadeStart = SSFStart;
                        else
                            ssf.fadeStart *= SSFMult;

                        if (SSFEnd >= 0)
                            ssf.fadeEnd = SSFEnd;
                        else
                            ssf.fadeEnd *= SSFMult;
                    }
                }
            }
            // The CBT that fades out the PQS
            // Should probably do this as just another PQSMod, actually.
            foreach (PQSMod_CelestialBodyTransform c in Resources.FindObjectsOfTypeAll(typeof(PQSMod_CelestialBodyTransform)))
            {
                try
                {
                    if (c.body != null)
                    {
                        if (c.body.name.Equals(node.name))
                        {
                            print("Found CBT for " + node.name);
                            node.TryGetValue("PQSdeactivateAltitude", ref c.deactivateAltitude);
                            if (c.planetFade != null)
                            {
                                node.TryGetValue("PQSfadeStart", ref c.planetFade.fadeStart);
                                node.TryGetValue("PQSfadeEnd", ref c.planetFade.fadeEnd);
                                if (c.secondaryFades != null)
                                {
                                    foreach (PQSMod_CelestialBodyTransform.AltitudeFade af in c.secondaryFades)
                                    {
                                        node.TryGetValue("PQSSecfadeStart", ref af.fadeStart);
                                        node.TryGetValue("PQSSecfadeEnd", ref af.fadeEnd);
                                    }
                                }
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    print("CBT fix for " + node.name + " failed: " + e.Message);
                }
            }
            print("Did CBT for " + node.name);
            yield return null;
            #endregion

            #region Science
            // Science
            if (node.HasNode("CelestialBodyScienceParams"))
            {
                guiMinor = "Science";
                //OnGui();
                ConfigNode spNode = node.GetNode("CelestialBodyScienceParams");
                if (body.scienceValues != null)
                {
                    foreach (ConfigNode.Value val in spNode.values)
                    {
                        // meh, for now hard-code it. Saves worry of GIGO.
                        /*if(body.scienceValues.GetType().GetField(val.name) != null)
                            if(float.TryParse(val.value, out ftmp))
                                body.scienceValues.GetType().GetField(val.name).SetValue(*/
                        spNode.TryGetValue("LandedDataValue", ref body.scienceValues.LandedDataValue);
                        spNode.TryGetValue("SplashedDataValue", ref body.scienceValues.SplashedDataValue);
                        spNode.TryGetValue("FlyingLowDataValue", ref body.scienceValues.FlyingLowDataValue);
                        spNode.TryGetValue("FlyingHighDataValue", ref body.scienceValues.FlyingHighDataValue);
                        spNode.TryGetValue("InSpaceLowDataValue", ref body.scienceValues.InSpaceLowDataValue);
                        spNode.TryGetValue("InSpaceHighDataValue", ref body.scienceValues.InSpaceHighDataValue);
                        spNode.TryGetValue("RecoveryValue", ref body.scienceValues.RecoveryValue);
                        spNode.TryGetValue("flyingAltitudeThreshold", ref body.scienceValues.flyingAltitudeThreshold);
                        spNode.TryGetValue("spaceAltitudeThreshold", ref body.scienceValues.spaceAltitudeThreshold);
                    }
                }
                guiMinor = "";
                //OnGui();
            }
            yield return null;
            #endregion
        }