// Transforms body references in the save games private static void TransformBodyReferencesOnSave(GameEvents.FromToAction <ProtoVessel, ConfigNode> data) { // Save the reference to the real body if (data.to == null) { return; } ConfigNode orbit = data.to.GetNode("ORBIT"); CelestialBody body = PSystemManager.Instance.localBodies.FirstOrDefault(b => b.flightGlobalsIndex == data.from.orbitSnapShot.ReferenceBodyIndex); if (body == null) { return; } orbit.AddValue("IDENT", UBI.GetUBI(body)); }
/// <summary> /// Gets invoked when all bodies were successfully loaded /// </summary> public static void OnLoaderLoadedAllBodies(Loader loader, ConfigNode node) { // Grab home star and home planet CelestialBody[] cbs = Bodies.Select(b => b.celestialBody).ToArray(); CelestialBody star = UBI.GetBody(InterstellarSettings.Instance.HomeStar, cbs); if (!star.Has("IC:HomePlanet")) { throw new Exception("The home star must have a home planet defined."); } CelestialBody planet = UBI.GetBody(InterstellarSettings.Instance.HomePlanet ?? star.Get("IC:HomePlanet", ""), cbs); // Grab the position of the home star Vector3d position = star.Get("IC:Position", Vector3d.zero); // Fix the naming of home star and home planet Body starBody = Bodies.Find(b => b.celestialBody == star); Body planetBody = Bodies.Find(b => b.celestialBody == planet); RenameBody(starBody, "Sun"); RenameBody(planetBody, "Kerbin"); planet.isHomeWorld = true; // Since this body is the center of the universe, remove its orbit UnityEngine.Object.DestroyImmediate(starBody.generatedBody.celestialBody.GetComponent <OrbitRendererUpdater>()); UnityEngine.Object.DestroyImmediate(starBody.generatedBody.orbitDriver); UnityEngine.Object.DestroyImmediate(starBody.generatedBody.orbitRenderer); starBody.orbit = null; // Trigger the KSC mover WithBody(planetBody, () => { planetBody.pqs = new PQSLoader(); }); // Go through each body, and calculate the orbits of the stars foreach (Body body in Bodies) { // Don't work with non-IC bodies if (!body.celestialBody.Has("IC:Position")) { continue; } // We already edited the home star if (body.celestialBody == star) { continue; } // Apply the SOI if (body.celestialBody.Has("IC:SOI")) { body.properties.sphereOfInfluence = body.celestialBody.Get("IC:SOI", 0d) * InterstellarSettings.Instance.KI; } // Calculate the real position of the star Vector3d realPosition = body.celestialBody.Get("IC:Position", Vector3d.zero) - position; // Apply the orbital parameters WithBody(body, () => { body.orbit = new OrbitLoader(); body.orbit.semiMajorAxis = Math.Pow( Math.Pow(realPosition.x, 2) + Math.Pow(realPosition.y, 2) + Math.Pow(realPosition.z, 2), 0.5) * InterstellarSettings.Instance.KI; body.orbit.eccentricity = 0; body.orbit.argumentOfPeriapsis = 90; body.orbit.meanAnomalyAtEpoch = 0; body.orbit.inclination = Math.Atan(realPosition.z / Math.Pow(Math.Pow(realPosition.x, 2) + Math.Pow(realPosition.y, 2), 0.5)) / Math.PI * 180; body.orbit.longitudeOfAscendingNode = CalculateLAN(realPosition.x, realPosition.y); body.orbit.period = Double.MaxValue; body.orbit.referenceBody = UBI.GetUBI(star); // This is a bit of a hack, because 1.3.1 and 1.4.5+ use different enums for // that value, and i want IC to be compatible with all versions try { PropertyInfo orbitMode = typeof(OrbitLoader).GetProperty("mode"); Type parserType = orbitMode.PropertyType; MethodInfo setFromString = parserType.GetMethod("SetFromString"); Object parser = orbitMode.GetValue(body.orbit, null); setFromString.Invoke(parser, new[] { "OFF" }); orbitMode.SetValue(body.orbit, parser, null); } catch { // ignored } // Load additional patches if (body.celestialBody.Has("IC:OrbitPatches")) { Parser.LoadObjectFromConfigurationNode(body.orbit, body.celestialBody.Get <ConfigNode>("IC:OrbitPatches")); } }); } }