/// <summary> /// Updates the target position and emits the particles /// </summary> private void Update() { // Update the values emitter.material.mainTexture = mainTexture; var sh = emitter.ps.shape; sh.mesh = mesh; // We have a target if (target != "None") { if (!TargetTransform) { TargetTransform = UBI.GetBody(target).scaledBody.transform; } Vector3 speed = TargetTransform.position; speed -= transform.parent.position; speed *= speedScale; emitter.minEnergy = minEnergy / TimeWarp.CurrentRate; emitter.maxEnergy = maxEnergy / TimeWarp.CurrentRate; emitter.maxEmission = Convert.ToInt32(maxEmission * TimeWarp.CurrentRate); emitter.minEmission = Convert.ToInt32(minEmission * TimeWarp.CurrentRate); emitter.rndVelocity = randomVelocity * TimeWarp.CurrentRate; speed *= TimeWarp.CurrentRate; emitter.worldVelocity = speed; } transform.localScale = scale; }
/// <summary> /// Updates the target position and emits the particles /// </summary> private void Update() { // Update the values emitter.minSize = minSize; emitter.maxSize = maxSize; animator.sizeGrow = sizeGrow; animator.colorAnimation = colorAnimation; renderer.sharedMaterial.mainTexture = mainTexture; filter.mesh = filter.sharedMesh = mesh ? mesh : transform.parent.GetComponent <MeshFilter>().sharedMesh; animator.force = force; // We have a target if (target != "None") { if (!TargetTransform) { TargetTransform = UBI.GetBody(target).scaledBody.transform; } Vector3 speed = TargetTransform.position; speed -= transform.parent.position; speed *= speedScale; emitter.minEnergy = minEnergy / TimeWarp.CurrentRate; emitter.maxEnergy = maxEnergy / TimeWarp.CurrentRate; emitter.maxEmission = maxEmission * TimeWarp.CurrentRate; emitter.minEmission = minEmission * TimeWarp.CurrentRate; emitter.rndVelocity = randomVelocity * TimeWarp.CurrentRate; speed *= TimeWarp.CurrentRate; emitter.worldVelocity = speed; } transform.localScale = scale; }
// Transforms body references in the save games private static void TransformBodyReferencesOnLoad(GameEvents.FromToAction <ProtoVessel, ConfigNode> data) { // Check if the config node is null if (data.to == null) { return; } ConfigNode orbit = data.to.GetNode("ORBIT"); String bodyIdent = orbit.GetValue("IDENT"); CelestialBody body = UBI.GetBody(bodyIdent); if (body == null) { return; } orbit.SetValue("REF", body.flightGlobalsIndex); }
public void SpawnAsteroid(Asteroid asteroid, UInt32 seed) { // Create Default Orbit Orbit orbit = null; CelestialBody body = null; // Select Orbit Type Int32 type = Random.Range(0, 3); if (type == 0 && asteroid.Location.Around.Count != 0) { // Around Location.AroundLoader[] around = GetProbabilityList(asteroid.Location.Around, asteroid.Location.Around.Select(a => a.Probability.Value).ToList()).ToArray(); Location.AroundLoader loader = around[Random.Range(0, around.Length)]; body = UBI.GetBody(loader.Body); if (!body) { return; } if (loader.Reached && !ReachedBody(body)) { return; } orbit = new Orbit { referenceBody = body, eccentricity = loader.Eccentricity, semiMajorAxis = loader.SemiMajorAxis, inclination = loader.Inclination, LAN = loader.LongitudeOfAscendingNode, argumentOfPeriapsis = loader.ArgumentOfPeriapsis, meanAnomalyAtEpoch = loader.MeanAnomalyAtEpoch, epoch = loader.Epoch }; orbit.Init(); } else if (type == 1 && asteroid.Location.Nearby.Count != 0) { // Nearby Location.NearbyLoader[] nearby = GetProbabilityList(asteroid.Location.Nearby, asteroid.Location.Nearby.Select(a => a.Probability.Value).ToList()).ToArray(); Location.NearbyLoader loader = nearby[Random.Range(0, nearby.Length)]; body = UBI.GetBody(loader.Body); if (!body) { return; } if (loader.Reached && !ReachedBody(body)) { return; } orbit = new Orbit { eccentricity = body.orbit.eccentricity + loader.Eccentricity, semiMajorAxis = body.orbit.semiMajorAxis * loader.SemiMajorAxis, inclination = body.orbit.inclination + loader.Inclination, LAN = body.orbit.LAN * loader.LongitudeOfAscendingNode, argumentOfPeriapsis = body.orbit.argumentOfPeriapsis * loader.ArgumentOfPeriapsis, meanAnomalyAtEpoch = body.orbit.meanAnomalyAtEpoch * loader.MeanAnomalyAtEpoch, epoch = body.orbit.epoch, referenceBody = body.orbit.referenceBody }; orbit.Init(); } else if (type == 2 && asteroid.Location.Flyby.Count != 0) { // Flyby Location.FlybyLoader[] flyby = GetProbabilityList(asteroid.Location.Flyby, asteroid.Location.Flyby.Select(a => a.Probability.Value).ToList()).ToArray(); Location.FlybyLoader loader = flyby[Random.Range(0, flyby.Length)]; body = UBI.GetBody(loader.Body); if (!body) { return; } if (loader.Reached && !ReachedBody(body)) { return; } orbit = Orbit.CreateRandomOrbitFlyBy(body, Random.Range(loader.MinDuration, loader.MaxDuration)); } // Check if (orbit == null) { Debug.Log("[Kopernicus] No new objects this time. (Probability is " + asteroid.Probability.Value + "%)"); return; } // Name String asteroidName = DiscoverableObjectsUtil.GenerateAsteroidName(); // Lifetime Double lifetime = Random.Range(asteroid.MinUntrackedLifetime, asteroid.MaxUntrackedLifetime) * 24d * 60d * 60d; Double maxLifetime = asteroid.MaxUntrackedLifetime * 24d * 60d * 60d; // Size UntrackedObjectClass size = (UntrackedObjectClass)(Int32)(asteroid.Size.Evaluate(Random.Range(0f, 1f)) * Enum.GetNames(typeof(UntrackedObjectClass)).Length); // Spawn ConfigNode vessel = null; vessel = ProtoVessel.CreateVesselNode( asteroidName, VesselType.SpaceObject, orbit, 0, new[] { ProtoVessel.CreatePartNode( "PotatoRoid", seed ) }, new ConfigNode("ACTIONGROUPS"), ProtoVessel.CreateDiscoveryNode( DiscoveryLevels.Presence, size, lifetime, maxLifetime ) ); OverrideNode(ref vessel, asteroid.Vessel); ProtoVessel protoVessel = new ProtoVessel(vessel, HighLogic.CurrentGame); if (asteroid.UniqueName && FlightGlobals.Vessels.Count(v => v.vesselName == protoVessel.vesselName) != 0) { return; } Kopernicus.Events.OnRuntimeUtilitySpawnAsteroid.Fire(asteroid, protoVessel); protoVessel.Load(HighLogic.CurrentGame.flightState); GameEvents.onNewVesselCreated.Fire(protoVessel.vesselRef); GameEvents.onAsteroidSpawned.Fire(protoVessel.vesselRef); Debug.Log("[Kopernicus] New object found near " + body.name + ": " + protoVessel.vesselName + "!"); }
// Execute MainMenu functions void Start() { previous = PlanetariumCamera.fetch.initialTarget; PlanetariumCamera.fetch.targets .Where(m => m.celestialBody != null && (m.celestialBody.Has("barycenter") || !m.celestialBody.Get("selectable", true))) .ToList() .ForEach(map => PlanetariumCamera.fetch.targets.Remove(map)); // Stars GameObject gob = Sun.Instance.gameObject; KopernicusStar star = gob.AddComponent <KopernicusStar>(); Utility.CopyObjectFields(Sun.Instance, star, false); DestroyImmediate(Sun.Instance); Sun.Instance = star; // LensFlares gob = SunFlare.Instance.gameObject; KopernicusSunFlare flare = gob.AddComponent <KopernicusSunFlare>(); gob.name = star.sun.name; Utility.CopyObjectFields(SunFlare.Instance, flare, false); DestroyImmediate(SunFlare.Instance); SunFlare.Instance = star.lensFlare = flare; // Bodies Dictionary <String, KeyValuePair <CelestialBody, CelestialBody> > fixes = new Dictionary <String, KeyValuePair <CelestialBody, CelestialBody> >(); foreach (CelestialBody body in PSystemManager.Instance.localBodies) { // More stars if (body.flightGlobalsIndex != 0 && body.scaledBody.GetComponentsInChildren <SunShaderController>(true).Length > 0) { GameObject starObj = Instantiate(Sun.Instance.gameObject); star = starObj.GetComponent <KopernicusStar>(); star.sun = body; starObj.transform.parent = Sun.Instance.transform.parent; starObj.name = body.name; starObj.transform.localPosition = Vector3.zero; starObj.transform.localRotation = Quaternion.identity; starObj.transform.localScale = Vector3.one; starObj.transform.position = body.position; starObj.transform.rotation = body.rotation; GameObject flareObj = Instantiate(SunFlare.Instance.gameObject); flare = flareObj.GetComponent <KopernicusSunFlare>(); star.lensFlare = flare; flareObj.transform.parent = SunFlare.Instance.transform.parent; flareObj.name = body.name; flareObj.transform.localPosition = Vector3.zero; flareObj.transform.localRotation = Quaternion.identity; flareObj.transform.localScale = Vector3.one; flareObj.transform.position = body.position; flareObj.transform.rotation = body.rotation; } // Post spawn patcher if (body.Has("orbitPatches")) { ConfigNode orbitNode = body.Get <ConfigNode>("orbitPatches"); OrbitLoader loader = new OrbitLoader(body); Parser.LoadObjectFromConfigurationNode(loader, orbitNode, "Kopernicus"); CelestialBody oldRef = body.referenceBody; body.referenceBody.orbitingBodies.Remove(body); CelestialBody newRef = UBI.GetBody(loader.referenceBody); if (newRef != null) { body.orbit.referenceBody = body.orbitDriver.referenceBody = newRef; } else { // Log the exception Debug.Log("Exception: PostSpawnOrbit reference body for \"" + body.name + "\" could not be found. Missing body name is \"" + loader.referenceBody + "\"."); // Open the Warning popup Injector.DisplayWarning(); } fixes.Add(body.transform.name, new KeyValuePair <CelestialBody, CelestialBody>(oldRef, body.referenceBody)); body.referenceBody.orbitingBodies.Add(body); body.referenceBody.orbitingBodies = body.referenceBody.orbitingBodies.OrderBy(cb => cb.orbit.semiMajorAxis).ToList(); body.orbit.Init(); body.orbitDriver.UpdateOrbit(); // Calculations if (!body.Has("sphereOfInfluence")) { body.sphereOfInfluence = body.orbit.semiMajorAxis * Math.Pow(body.Mass / body.orbit.referenceBody.Mass, 0.4); } if (!body.Has("hillSphere")) { body.hillSphere = body.orbit.semiMajorAxis * (1 - body.orbit.eccentricity) * Math.Pow(body.Mass / body.orbit.referenceBody.Mass, 0.333333333333333); } if (body.solarRotationPeriod) { Double rotPeriod = Utility.FindBody(PSystemManager.Instance.systemPrefab.rootBody, body.transform.name).celestialBody.rotationPeriod; Double num1 = Math.PI * 2 * Math.Sqrt(Math.Pow(Math.Abs(body.orbit.semiMajorAxis), 3) / body.orbit.referenceBody.gravParameter); body.rotationPeriod = rotPeriod * num1 / (num1 + rotPeriod);; } } } // Update the order in the tracking station List <MapObject> trackingstation = new List <MapObject>(); Utility.DoRecursive(PSystemManager.Instance.localBodies[0], cb => cb.orbitingBodies, cb => { trackingstation.Add(PlanetariumCamera.fetch.targets.Find(t => t.celestialBody == cb)); }); PlanetariumCamera.fetch.targets.Clear(); PlanetariumCamera.fetch.targets.AddRange(trackingstation); // Update the initialTarget of the tracking station Resources.FindObjectsOfTypeAll <PlanetariumCamera>().FirstOrDefault().initialTarget = Resources.FindObjectsOfTypeAll <ScaledMovement>().FirstOrDefault(o => o.celestialBody.isHomeWorld); // Undo stuff foreach (CelestialBody b in PSystemManager.Instance.localBodies.Where(b_ => b_.Has("orbitPatches"))) { fixes[b.transform.name].Value.orbitingBodies.Remove(b); fixes[b.transform.name].Key.orbitingBodies.Add(b); fixes[b.transform.name].Key.orbitingBodies = fixes[b.transform.name].Key.orbitingBodies.OrderBy(cb => cb.orbit.semiMajorAxis).ToList(); } #if !KSP131 if (ExpansionsLoader.IsExpansionInstalled("MakingHistory")) { PQSCity2[] cities = FindObjectsOfType <PQSCity2>(); foreach (String site in Templates.RemoveLaunchSites) { // Remove the launch site from the list if it exists if (PSystemSetup.Instance.LaunchSites.Any(s => s.name == site)) { PSystemSetup.Instance.RemoveLaunchSite(site); } PQSCity2 city = cities.FirstOrDefault(c => c.gameObject.name == site || c.gameObject.name == site + "(Clone)"); // Kill the PQSCity if it exists if (city != null) { Destroy(city.gameObject); } } // PSystemSetup.RemoveLaunchSite does not remove launch sites from PSystemSetup.StockLaunchSites // Currently an ArgumentOutOfRangeException can result when they are different lists because of a bug in stock code try { FieldInfo stockLaunchSitesField = typeof(PSystemSetup).GetField("stocklaunchsites", BindingFlags.NonPublic | BindingFlags.Instance); LaunchSite[] stockLaunchSites = (LaunchSite[])stockLaunchSitesField.GetValue(PSystemSetup.Instance); LaunchSite[] updateStockLaunchSites = stockLaunchSites.Where(site => !Templates.RemoveLaunchSites.Contains(site.name)).ToArray(); if (stockLaunchSites.Length != updateStockLaunchSites.Length) { stockLaunchSitesField.SetValue(PSystemSetup.Instance, updateStockLaunchSites); } } catch (Exception ex) { Logger.Default.Log("Failed to remove launch sites from 'stockLaunchSites' field. Exception information follows."); Logger.Default.LogException(ex); } } #endif #if FALSE // AFG-Ception foreach (CelestialBody body in PSystemManager.Instance.localBodies) { if (body.afg == null) { continue; } foreach (KopernicusStar s in KopernicusStar.Stars) { AtmosphereFromGround afg; if (s != Sun.Instance) { afg = Instantiate(body.afg.gameObject) .GetComponent <AtmosphereFromGround>(); Utility.CopyObjectFields(body.afg, afg, false); afg.transform.parent = body.afg.transform.parent; afg.transform.localPosition = body.afg.transform.localPosition; afg.transform.localScale = body.afg.transform.localScale; afg.transform.localRotation = body.afg.transform.localRotation; afg.gameObject.layer = body.afg.gameObject.layer; } else { afg = body.afg; } afg.gameObject.AddComponent <KopernicusStarAFG>().Star = s; } } #endif }
public void SpawnAsteroid(Asteroid asteroid, UInt32 seed) { // Create Default Orbit Orbit orbit = null; CelestialBody body = null; // Select Orbit Type Int32 type = Random.Range(0, 3); if (type == 0 && asteroid.Location.Around.Count != 0) { // Around Location.AroundLoader[] around = GetProbabilityList(asteroid.Location.Around, asteroid.Location.Around.Select(a => a.Probability.Value).ToList()).ToArray(); Location.AroundLoader loader = around[Random.Range(0, around.Length)]; body = UBI.GetBody(loader.Body); if (!body) { return; } if (loader.Reached && !ReachedBody(body)) { return; } orbit = new Orbit { referenceBody = body, eccentricity = loader.Eccentricity, semiMajorAxis = loader.SemiMajorAxis, inclination = loader.Inclination, LAN = loader.LongitudeOfAscendingNode, argumentOfPeriapsis = loader.ArgumentOfPeriapsis, meanAnomalyAtEpoch = loader.MeanAnomalyAtEpoch, epoch = loader.Epoch }; orbit.Init(); } else if (type == 1 && asteroid.Location.Nearby.Count != 0) { // Nearby Location.NearbyLoader[] nearby = GetProbabilityList(asteroid.Location.Nearby, asteroid.Location.Nearby.Select(a => a.Probability.Value).ToList()).ToArray(); Location.NearbyLoader loader = nearby[Random.Range(0, nearby.Length)]; body = UBI.GetBody(loader.Body); if (!body) { return; } if (loader.Reached && !ReachedBody(body)) { return; } orbit = new Orbit { eccentricity = body.orbit.eccentricity + loader.Eccentricity, semiMajorAxis = body.orbit.semiMajorAxis * loader.SemiMajorAxis, inclination = body.orbit.inclination + loader.Inclination, LAN = body.orbit.LAN * loader.LongitudeOfAscendingNode, argumentOfPeriapsis = body.orbit.argumentOfPeriapsis * loader.ArgumentOfPeriapsis, meanAnomalyAtEpoch = body.orbit.meanAnomalyAtEpoch * loader.MeanAnomalyAtEpoch, epoch = body.orbit.epoch, referenceBody = body.orbit.referenceBody }; orbit.Init(); } else if (type == 2 && asteroid.Location.Flyby.Count != 0) { // Flyby Location.FlybyLoader[] flyby = GetProbabilityList(asteroid.Location.Flyby, asteroid.Location.Flyby.Select(a => a.Probability.Value).ToList()).ToArray(); Location.FlybyLoader loader = flyby[Random.Range(0, flyby.Length)]; body = UBI.GetBody(loader.Body); if (!body) { return; } if (loader.Reached && !ReachedBody(body)) { return; } orbit = Orbit.CreateRandomOrbitFlyBy(body, Random.Range(loader.MinDuration, loader.MaxDuration)); } // Check if (orbit == null) { Debug.Log("[Kopernicus] No new objects this time. (Probability is " + asteroid.Probability.Value + "%)"); return; } // Name String asteroidName = DiscoverableObjectsUtil.GenerateAsteroidName(); // Lifetime Double lifetime = Random.Range(asteroid.MinUntrackedLifetime, asteroid.MaxUntrackedLifetime) * 24d * 60d * 60d; Double maxLifetime = asteroid.MaxUntrackedLifetime * 24d * 60d * 60d; // Size UntrackedObjectClass size = (UntrackedObjectClass)(Int32)(asteroid.Size.Evaluate(Random.Range(0f, 1f)) * Enum.GetNames(typeof(UntrackedObjectClass)).Length); // Spawn ConfigNode vessel = null; #if (KSP_VERSION_1_10_1 || KSP_VERSION_1_11_1) if (Random.Range(0, 100) > RuntimeUtility.KopernicusConfig.CometPercentage) { #endif vessel = ProtoVessel.CreateVesselNode( asteroidName, VesselType.SpaceObject, orbit, 0, new[] { ProtoVessel.CreatePartNode( "PotatoRoid", seed ) }, new ConfigNode("ACTIONGROUPS"), ProtoVessel.CreateDiscoveryNode( DiscoveryLevels.Presence, size, lifetime, maxLifetime ) ); OverrideNode(ref vessel, asteroid.Vessel); ProtoVessel protoVessel = new ProtoVessel(vessel, HighLogic.CurrentGame); if (asteroid.UniqueName && FlightGlobals.Vessels.Count(v => v.vesselName == protoVessel.vesselName) != 0) { return; } Kopernicus.Events.OnRuntimeUtilitySpawnAsteroid.Fire(asteroid, protoVessel); protoVessel.Load(HighLogic.CurrentGame.flightState); GameEvents.onNewVesselCreated.Fire(protoVessel.vesselRef); GameEvents.onAsteroidSpawned.Fire(protoVessel.vesselRef); Debug.Log("[Kopernicus] New object found near " + body.name + ": " + protoVessel.vesselName + "!"); #if (KSP_VERSION_1_10_1 || KSP_VERSION_1_11_1) } else { float fragmentDynamicPressureModifier = 0f; bool optimizedCollider = false; CometOrbitType cometType = CometManager.GenerateWeightedCometType(); Orbit cometOrbit = cometType.CalculateHomeOrbit(); UntrackedObjectClass randomObjClass = cometType.GetRandomObjClass(); CometDefinition cometDef = CometManager.GenerateDefinition(cometType, randomObjClass, (int)seed); ConfigNode configNode = cometDef.CreateVesselNode(optimizedCollider, fragmentDynamicPressureModifier, hasName: false); ConfigNode configNode2 = ProtoVessel.CreatePartNode("PotatoComet", seed); uint value = 0u; configNode2.TryGetValue("persistentId", ref value); configNode.AddValue("cometPartId", value); ConfigNode configNode3 = new ConfigNode("VESSELMODULES"); configNode3.AddNode(configNode); vessel = ProtoVessel.CreateVesselNode(DiscoverableObjectsUtil.GenerateCometName(), VesselType.SpaceObject, cometOrbit, 0, new ConfigNode[1] { configNode2 }, new ConfigNode("ACTIONGROUPS"), ProtoVessel.CreateDiscoveryNode(DiscoveryLevels.Presence, randomObjClass, lifetime, maxLifetime), configNode3); OverrideNode(ref vessel, asteroid.Vessel); ProtoVessel protoVessel = new ProtoVessel(vessel, HighLogic.CurrentGame); Kopernicus.Events.OnRuntimeUtilitySpawnAsteroid.Fire(asteroid, protoVessel); protoVessel.Load(HighLogic.CurrentGame.flightState); GameEvents.onNewVesselCreated.Fire(protoVessel.vesselRef); GameEvents.onAsteroidSpawned.Fire(protoVessel.vesselRef); Debug.Log("[Kopernicus] New object found near " + body.name + ": " + protoVessel.vesselName + "!"); } #endif }
// Update the menu body private void Start() { if (!Templates.KopernicusMainMenu) { return; } // Select a random body? if (Templates.RandomMainMenuBodies.Any()) { Templates.MenuBody = Templates.RandomMainMenuBodies[new Random().Next(0, Templates.RandomMainMenuBodies.Count)]; } // Grab the main body CelestialBody planetCb = UBI.GetBody(Templates.MenuBody); if (planetCb == null) { planetCb = PSystemManager.Instance.localBodies.Find(b => b.isHomeWorld); } if (planetCb == null) { Debug.LogError("[Kopernicus] Could not find home world!"); return; } // Load Textures OnDemandStorage.EnableBody(Templates.MenuBody); // Get the MainMenu-Logic MainMenu main = FindObjectOfType <MainMenu>(); if (main == null) { Debug.LogError("[Kopernicus] No main menu object!"); return; } MainMenuEnvLogic logic = main.envLogic; // Set it to Space, because the Mun-Area won't work with sth else than Mun if (logic.areas.Length < 2) { Debug.LogError("[Kopernicus] Not enough bodies"); return; } // Get our active Space GameObject space = logic.areas[1]; // Deactivate Kerbins Transform Transform kerbin = space.transform.Find("Kerbin"); if (kerbin == null) { Debug.LogError("[Kopernicus] No Kerbin transform!"); return; } kerbin.gameObject.SetActive(false); // Deactivate Muns Transform Transform munPivot = space.transform.Find("MunPivot"); if (munPivot == null) { Debug.LogError("[Kopernicus] No MunPivot transform!"); return; } munPivot.gameObject.SetActive(false); // Activate the textures ScaledSpaceOnDemand od = planetCb.scaledBody.GetComponentInChildren <ScaledSpaceOnDemand>(); if (od != null) { od.Start(); od.LoadTextures(); } // Clone the scaledVersion and attach it to the Scene GameObject menuPlanet = Utility.Instantiate(Utility .FindBody(PSystemManager.Instance.systemPrefab.rootBody, planetCb.transform.name).scaledVersion, space.transform, true); menuPlanet.name = planetCb.transform.name; // Destroy stuff DestroyImmediate(menuPlanet.GetComponent <ScaledSpaceFader>()); DestroyImmediate(menuPlanet.GetComponent <SphereCollider>()); DestroyImmediate(menuPlanet.GetComponentInChildren <AtmosphereFromGround>()); DestroyImmediate(menuPlanet.GetComponent <MaterialSetDirection>()); // That sounds funny Rotato planetRotato = menuPlanet.AddComponent <Rotato>(); Rotato planetRefRotato = kerbin.GetComponent <Rotato>(); planetRotato.speed = planetRefRotato.speed * ((Single)planetCb.rotationPeriod / KERBIN_ROTATION_PERIOD); menuPlanet.transform.Rotate(0f, (Single)planetCb.initialRotation, 0f); // Scale the body menuPlanet.transform.localScale = kerbin.localScale; menuPlanet.transform.localPosition = kerbin.localPosition; menuPlanet.transform.position = kerbin.position; // And set it to layer 0 menuPlanet.layer = 0; Events.OnRuntimeUtilityUpdateMenu.Fire(); }
/// <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")); } }); } }
/// <summary> /// Applies the PostSpawnOrbit and then returns the referenceBody /// </summary> Body OrbitPatcher(Body body) { Debug.Log("SigmaBinary.OrbitPatcher", "celestialBody = " + body?.GeneratedBody?.celestialBody); if (body?.GeneratedBody?.celestialBody?.Has("sbPatched") == false) { if (body?.GeneratedBody?.orbitDriver?.orbit == null) { Debug.Log("OrbitPatcher", "Body " + body.GeneratedBody.name + " does not have an orbit."); return(null); } // This 'if' is here to make sure stars don't give us trouble if (body?.GeneratedBody?.orbitDriver?.orbit?.referenceBody == null) { body.GeneratedBody.orbitDriver.orbit.referenceBody = ListOfBodies.Find(rb => rb.GeneratedBody.name == body.Orbit.ReferenceBody).GeneratedBody.celestialBody; Debug.Log("SigmaBinary.OrbitPatcher", "Body " + body.GeneratedBody.name + " 'referenceBody' set to " + body.GeneratedBody.orbitDriver.orbit.referenceBody); } // If the body has a Kerbin Template, save the original referenceBody for later if (body?.Template?.OriginalBody?.celestialBody?.name == "Kerbin") { Debug.Log("SigmaBinary.OrbitPatcher", "Body " + body.GeneratedBody.name + " uses Kerbin as Template."); kerbinFixer.Add(body.GeneratedBody.name, body.Orbit.ReferenceBody); Debug.Log("SigmaBinary.OrbitPatcher", "Store original 'referenceBody' " + body.Orbit.ReferenceBody + " of body " + body.GeneratedBody.name + " in 'kerbinFixer'."); } if (body?.GeneratedBody?.Has("orbitPatches") == true) { ConfigNode patch = body.GeneratedBody.Get <ConfigNode>("orbitPatches"); Debug.Log("SigmaBinary.OrbitPatcher", "Body " + body.GeneratedBody.name + " has a 'PostSpawnOrbit' node."); // Fix sphereOfInfluence if (patch.HasValue("referenceBody") || patch.HasValue("semiMajorAxis")) { if (!body.GeneratedBody.celestialBody.Has("sphereOfInfluence")) { body.GeneratedBody.celestialBody.Set("SBfixSOI", true); Debug.Log("SigmaBinary.OrbitPatcher", "'sphereOfInfluence' of body " + body.GeneratedBody.name + " needs to be recalculated."); } } // Patch orbit using the original 'PostSpawnOrbit' node if (patch?.values?.Count > 0) { // Create a new loader OrbitLoader loader = new SigmaOrbitLoader(body.GeneratedBody); // Apply the patch to the loader Parser.LoadObjectFromConfigurationNode(loader, patch, "Kopernicus"); Debug.Log("SigmaBinary.OrbitPatcher", "Patched orbit of body " + body.GeneratedBody.name + " using 'PostSpawnOrbit' node"); // Remove 'PostSpawnOrbit' node body.GeneratedBody.Remove("orbitPatches"); Debug.Log("SigmaBinary.OrbitPatcher", "Body " + body.GeneratedBody.name + " 'PostSpawnOrbit' node removed."); // If the patch is used to reparent the body if (patch.HasValue("referenceBody")) { body.Orbit.ReferenceBody = patch.GetValue("referenceBody"); body.GeneratedBody.orbitDriver.orbit.referenceBody = ListOfBodies.Find(rb => rb.GeneratedBody.name == body.Orbit.ReferenceBody).GeneratedBody.celestialBody; Debug.Log("SigmaBinary.OrbitPatcher", "Body " + body.GeneratedBody.name + " 'referenceBody' set from 'PostSpawnOrbit'. referenceBody = " + body.Orbit.ReferenceBody + " (" + body.GeneratedBody.orbitDriver.orbit.referenceBody + ")"); // Keep the ConfigNode for all bodies with a Kerbin Template if (body?.Template?.OriginalBody?.celestialBody?.name == "Kerbin") { Debug.Log("SigmaBinary.OrbitPatcher", "Body " + body.GeneratedBody.name + " uses Kerbin as Template."); ConfigNode temp = new ConfigNode(); temp.AddValue("referenceBody", patch.GetValue("referenceBody")); body.GeneratedBody.Set("orbitPatches", temp); Debug.Log("SigmaBinary.OrbitPatcher", "Body " + body.GeneratedBody.name + " original 'PostSpawnOrbit' node restored."); } } } } body.GeneratedBody.celestialBody.Set("sbPatched", true); } CelestialBody referenceBody = UBI.GetBody(body.Orbit.ReferenceBody, ListOfBodies.Select(b => b.CelestialBody).ToArray()); return(ListOfBodies?.FirstOrDefault(b => b?.CelestialBody == referenceBody)); }