void Start() { for (int i = 0; i < FlightGlobals.Bodies?.Count; i++) { body = FlightGlobals.Bodies[i]; Debug.Log("SigmaDimensions.Start", "> Planet: " + body.name + (body.name != body.displayName.Replace("^N", "") ? (", (A.K.A.: " + body.displayName.Replace("^N", "") + ")") : "") + (body.name != body.transform.name ? (", (A.K.A.: " + body.transform.name + ")") : "")); // Sigma Dimensions Settings resize = body.Has("resize") ? body.Get <double>("resize") : 1; landscape = body.Has("landscape") ? body.Get <double>("landscape") : 1; resizeBuildings = body.Has("resizeBuildings") ? body.Get <double>("resizeBuildings") : 1; // All PQSCity mods PQSCity[] cities = body.GetComponentsInChildren <PQSCity>(true); for (int j = 0; j < cities?.Length; j++) { CityFixer(cities[j]); cities[j].Orientate(); } // All PQSCity2 mods PQSCity2[] cities2 = body.GetComponentsInChildren <PQSCity2>(true); for (int j = 0; j < cities2?.Length; j++) { City2Fixer(cities2[j]); cities2[j].Orientate(); } } }
private static void ApplyOrbitVisibility(CelestialBody body) { if (HighLogic.LoadedScene != GameScenes.TRACKSTATION && (!HighLogic.LoadedSceneIsFlight || !MapView.MapIsEnabled)) { return; } // Loop // Check for Renderer if (!body.orbitDriver) { return; } if (!body.orbitDriver.Renderer) { return; } // Apply Orbit mode changes if (body.Has("drawMode")) { body.orbitDriver.Renderer.drawMode = body.Get <OrbitRenderer.DrawMode>("drawMode"); } // Apply Orbit icon changes if (body.Has("drawIcons")) { body.orbitDriver.Renderer.drawIcons = body.Get <OrbitRenderer.DrawIcons>("drawIcons"); } }
// Finalize an Orbit public static void FinalizeOrbit(CelestialBody body) { if (body.orbitDriver != null) { if (body.referenceBody != null) { // Only recalculate the SOI, if it's not forced if (!body.Has("hillSphere")) { body.hillSphere = body.orbit.semiMajorAxis * (1.0 - body.orbit.eccentricity) * Math.Pow(body.Mass / body.orbit.referenceBody.Mass, 1.0 / 3.0); } if (!body.Has("sphereOfInfluence")) { body.sphereOfInfluence = Math.Max( body.orbit.semiMajorAxis * Math.Pow(body.Mass / body.orbit.referenceBody.Mass, 0.4), Math.Max(body.Radius * Templates.SOIMinRadiusMult, body.Radius + Templates.SOIMinAltitude)); } // this is unlike stock KSP, where only the reference body's mass is used. body.orbit.period = 2 * Math.PI * Math.Sqrt(Math.Pow(body.orbit.semiMajorAxis, 2) / 6.674E-11 * body.orbit.semiMajorAxis / (body.referenceBody.Mass + body.Mass)); body.orbit.meanMotion = 2 * Math.PI / body.orbit.period; // in theory this should work but I haven't tested it if (body.orbit.eccentricity <= 1.0) { body.orbit.meanAnomaly = body.orbit.meanAnomalyAtEpoch; body.orbit.orbitPercent = body.orbit.meanAnomalyAtEpoch / (Math.PI * 2); body.orbit.ObTAtEpoch = body.orbit.orbitPercent * body.orbit.period; } else { // ignores this body's own mass for this one... body.orbit.meanAnomaly = body.orbit.meanAnomalyAtEpoch; body.orbit.ObT = Math.Pow(Math.Pow(Math.Abs(body.orbit.semiMajorAxis), 3.0) / body.orbit.referenceBody.gravParameter, 0.5) * body.orbit.meanAnomaly; body.orbit.ObTAtEpoch = body.orbit.ObT; } } else { body.sphereOfInfluence = Double.PositiveInfinity; body.hillSphere = Double.PositiveInfinity; } } try { body.CBUpdate(); } catch (Exception e) { UnityEngine.Debug.Log("CBUpdate for " + body.name + " failed: " + e.Message); } }
public static void CelestialBodyUpdate(CelestialBody body) { //Instead of a harmony patch, you can do it in the TimingManager.FixedUpdateAdd(TimingManager.TimingStage.Precalc) //That would involve running trough all the celestial bodies with a loop tough... if (!body.Has("tilt")) { return; } var tilt = new Vector3(body.Get("tilt", 0f), 0, 0); if (body.inverseRotation) { //Basically we do the same as body.bodyTransform.transform.Rotate but with the planetarium //as we are rotating WITH the planet and in the same reference plane Planetarium.Rotation = ApplySpaceRotation(Planetarium.Rotation, tilt); } else { body.rotation = ApplySpaceRotation(body.rotation, tilt); body.bodyTransform.transform.rotation = body.rotation; //We must fix the bodyFrame vectors as otherwise landed vessels will not take the axial tilt on track station body.rotation.swizzle.FrameVectors(out body.BodyFrame.X, out body.BodyFrame.Y, out body.BodyFrame.Z); } }
// Fix the Zooming-Out bug void FixZooming() { if (HighLogic.LoadedSceneHasPlanetarium && MapView.fetch != null && !isDone) { // Fix the bug via switching away from Home and back immideatly. // TODO: Check if this still happend PlanetariumCamera.fetch.SetTarget(PlanetariumCamera.fetch.targets[(PlanetariumCamera.fetch.targets.IndexOf(PlanetariumCamera.fetch.target) + 1) % PlanetariumCamera.fetch.targets.Count]); PlanetariumCamera.fetch.SetTarget(PlanetariumCamera.fetch.targets[(PlanetariumCamera.fetch.targets.IndexOf(PlanetariumCamera.fetch.target) - 1) + (((PlanetariumCamera.fetch.targets.IndexOf(PlanetariumCamera.fetch.target) - 1) >= 0) ? 0 : PlanetariumCamera.fetch.targets.Count)]); // Terminate for the moment. isDone = true; } // Set custom Zoom-In limits if (HighLogic.LoadedScene == GameScenes.TRACKSTATION || MapView.MapIsEnabled) { MapObject target = PlanetariumCamera.fetch.target; if (target?.celestialBody != null) { CelestialBody body = target.celestialBody; if (body.Has("maxZoom")) { PlanetariumCamera.fetch.minDistance = body.Get <float>("maxZoom"); } else { PlanetariumCamera.fetch.minDistance = 10; } } } }
/// <summary> /// Returns a value or a default one if the element doesn't exist /// </summary> public static T Get <T>(this CelestialBody body, String id, T defaultValue) { if (body.Has(id)) { return(body.Get <T>(id)); } return(defaultValue); }
internal static float maxTempAngleOffset(this CelestialBody body) { if (body?.Has("maxTempAngleOffset") == true) { return(body.Get <float>("maxTempAngleOffset")); } return(45f); }
public static void CelestialBodyAwake(CelestialBody body) { if (!body.Has("tilt")) { return; } body.bodyTransform.transform.Rotate(new Vector3(body.Get("tilt", 0f), 0, 0), Space.World); }
/// <summary> /// This method gets called when the vessel enters the SOI of a new body. Here we edit the FX controller, so /// it uses the effects defined for this body. /// </summary> void OnDominantBodyChange(GameEvents.FromToAction <CelestialBody, CelestialBody> data) { // The body the vessel switched to CelestialBody body = data.to; if (body.Has("reentryHeat")) { aeroFX.ReentryHeat = body.Get <AeroFXState>("reentryHeat"); } else { aeroFX.ReentryHeat = ReentryHeat; } if (body.Has("condensation")) { aeroFX.Condensation = body.Get <AeroFXState>("condensation"); } else { aeroFX.Condensation = Condensation; } }
// Fix the Zooming-Out bug private void FixZooming() { if (HighLogic.LoadedSceneHasPlanetarium && MapView.fetch && !_fixZoomingIsDone) { // Fix the bug via switching away from Home and back immediately. // TODO: Check if this still happens PlanetariumCamera.fetch.SetTarget(PlanetariumCamera.fetch.targets[ (PlanetariumCamera.fetch.targets.IndexOf(PlanetariumCamera.fetch.target) + 1) % PlanetariumCamera.fetch.targets.Count]); PlanetariumCamera.fetch.SetTarget(PlanetariumCamera.fetch.targets[ PlanetariumCamera.fetch.targets.IndexOf(PlanetariumCamera.fetch.target) - 1 + (PlanetariumCamera.fetch.targets.IndexOf(PlanetariumCamera.fetch.target) - 1 >= 0 ? 0 : PlanetariumCamera.fetch.targets.Count)]); // Terminate for the moment. _fixZoomingIsDone = true; } // Set custom Zoom-In limits if (HighLogic.LoadedScene != GameScenes.TRACKSTATION && !MapView.MapIsEnabled) { return; } MapObject target = PlanetariumCamera.fetch.target; if (!target || !target.celestialBody) { return; } CelestialBody body = target.celestialBody; if (body.Has("maxZoom")) { PlanetariumCamera.fetch.minDistance = body.Get <Single>("maxZoom"); } else { PlanetariumCamera.fetch.minDistance = 10; } }
// Contract Weight private static void PatchContractWeight(CelestialBody body) { if (ContractSystem.ContractWeights == null) { return; } if (!body.Has("contractWeight")) { return; } if (ContractSystem.ContractWeights.ContainsKey(body.name)) { ContractSystem.ContractWeights[body.name] = body.Get <Int32>("contractWeight"); } else { ContractSystem.ContractWeights.Add(body.name, body.Get <Int32>("contractWeight")); } }
void Start() { // FIX BODIES MOVED POSTSPAWN // Boolean postSpawnChanges = false; // Replaced 'foreach' with 'for' to improve performance CelestialBody[] postSpawnBodies = PSystemManager.Instance?.localBodies?.Where(b => b.Has("orbitPatches"))?.ToArray(); for (Int32 i = 0; i < postSpawnBodies?.Length; i++) { CelestialBody cb = postSpawnBodies[i]; // Fix position if the body gets moved PostSpawn ConfigNode patch = cb.Get <ConfigNode>("orbitPatches"); if (patch.GetValue("referenceBody") != null || patch.GetValue("semiMajorAxis") != null) { // Get the body PSystemBody body = PSystemManager.Instance?.systemPrefab?.GetComponentsInChildren <PSystemBody>(true)?.FirstOrDefault(b => b.name == cb.transform.name); if (body == null) { Debug.Log("[Kopernicus]: RnDFixer: Could not find PSystemBody => " + cb.transform.name); continue; } // Get the parent PSystemBody oldParent = PSystemManager.Instance?.systemPrefab?.GetComponentsInChildren <PSystemBody>(true)?.FirstOrDefault(b => b.children.Contains(body)); if (oldParent == null) { Debug.Log("[Kopernicus]: RnDFixer: Could not find referenceBody of CelestialBody => " + cb.transform.name); continue; } // Check if PostSpawnOrbit changes referenceBody PSystemBody newParent = oldParent; if (patch.GetValue("referenceBody") != null) { newParent = PSystemManager.Instance?.systemPrefab?.GetComponentsInChildren <PSystemBody>(true).FirstOrDefault(b => b.name == patch.GetValue("referenceBody")); } if (oldParent == null) { Debug.Log("[Kopernicus]: RnDFixer: Could not find PostSpawn referenceBody of CelestialBody => " + cb.transform.name); newParent = oldParent; } // Check if PostSpawnOrbit changes semiMajorAxis if (body?.orbitDriver?.orbit?.semiMajorAxis == null) { Debug.Log("[Kopernicus]: RnDFixer: Could not find PostSpawn semiMajorAxis of CelestialBody => " + cb.transform.name); continue; } NumericParser <Double> newSMA = body.orbitDriver.orbit.semiMajorAxis; if (patch.GetValue("semiMajorAxis") != null) { newSMA.SetFromString(patch.GetValue("semiMajorAxis")); } // Remove the body from oldParent.children oldParent.children.Remove(body); // Find the index of the body in newParent.children Int32 index = newParent.children.FindAll(c => c.orbitDriver.orbit.semiMajorAxis < newSMA.Value).Count; // Add the body to newParent.children if (index > newParent.children.Count) { newParent.children.Add(body); } else { newParent.children.Insert(index, body); } // Signal that the system has PostSpawn changes postSpawnChanges = true; } } // Rebuild Archives if (postSpawnChanges) { AddPlanets(); } // RDVisibility = HIDDEN // RDVisibility = SKIP // // Create a list with body to hide and their parent List <KeyValuePair <PSystemBody, KeyValuePair <PSystemBody, Int32> > > hideList = new List <KeyValuePair <PSystemBody, KeyValuePair <PSystemBody, Int32> > >(); // Create a list with body to skip and their parent List <KeyValuePair <PSystemBody, PSystemBody> > skipList = new List <KeyValuePair <PSystemBody, PSystemBody> >(); // Replaced 'foreach' with 'for' to improve performance PSystemBody[] bodies = PSystemManager.Instance.systemPrefab.GetComponentsInChildren <PSystemBody>(true); CelestialBody[] hideBodies = PSystemManager.Instance?.localBodies?.Where(cb => cb.Has("hiddenRnD"))?.ToArray(); for (Int32 i = 0; i < hideBodies?.Length; i++) { CelestialBody body = hideBodies[i]; PropertiesLoader.RDVisibility visibility = body.Get <PropertiesLoader.RDVisibility>("hiddenRnD"); if (visibility == PropertiesLoader.RDVisibility.HIDDEN || visibility == PropertiesLoader.RDVisibility.SKIP) { PSystemBody hidden = Utility.FindBody(PSystemManager.Instance.systemPrefab.rootBody, body.transform.name); PSystemBody parent = bodies.FirstOrDefault(b => b.children.Contains(hidden)); if (parent != null) { // Hide if (hidden.children.Count == 0 || visibility == PropertiesLoader.RDVisibility.HIDDEN) { body.Set("hiddenRnd", PropertiesLoader.RDVisibility.HIDDEN); hideList.Add(new KeyValuePair <PSystemBody, KeyValuePair <PSystemBody, Int32> >(hidden, new KeyValuePair <PSystemBody, Int32>(parent, 0))); } // Skip else { if (skipList.Any(b => b.Key == parent)) { Int32 index = skipList.IndexOf(skipList.FirstOrDefault(b => b.Key == parent)); skipList.Insert(index, new KeyValuePair <PSystemBody, PSystemBody>(hidden, parent)); } else { skipList.Add(new KeyValuePair <PSystemBody, PSystemBody>(hidden, parent)); } } } } } // Skip bodies for (Int32 i = 0; i < skipList.Count; i++) { KeyValuePair <PSystemBody, PSystemBody> pair = skipList[i]; // Get hidden body and parent PSystemBody hidden = pair.Key; PSystemBody parent = pair.Value; // Find where the hidden body is Int32 index = parent.children.IndexOf(hidden); // Remove the hidden body from its parent's children list so it won't show up when clicking the parent parent.children.Remove(hidden); // Put its children in its place parent.children.InsertRange(index, hidden.children); } // Hide bodies for (Int32 i = 0; i < hideList.Count; i++) { KeyValuePair <PSystemBody, KeyValuePair <PSystemBody, Int32> > pair = hideList[i]; // Get hidden body and parent PSystemBody hidden = pair.Key; PSystemBody parent = bodies.FirstOrDefault(b => b.children.Contains(hidden)); // Find where the hidden body is Int32 index = parent.children.IndexOf(hidden); // Remove the hidden body from its parent's children list so it won't show up when clicking the parent parent.children.Remove(hidden); // Save the position in the hideList hideList[i] = new KeyValuePair <PSystemBody, KeyValuePair <PSystemBody, Int32> >(hidden, new KeyValuePair <PSystemBody, Int32>(parent, index)); } // Apply changes and revert to the original PSystem if (hideList.Count > 0 || skipList?.Count > 0) { // Rebuild Archives AddPlanets(); // Undo the changes to the PSystem (hide) for (Int32 i = hideList.Count - 1; i > -1; i--) { PSystemBody hidden = hideList[i].Key; PSystemBody parent = hideList[i].Value.Key; Int32 oldIndex = hideList[i].Value.Value; parent.children.Insert(oldIndex, hidden); } // Undo the changes to the PSystem (skip) for (Int32 i = skipList.Count - 1; i > -1; i--) { PSystemBody hidden = skipList[i].Key; PSystemBody parent = skipList[i].Value; Int32 oldIndex = parent.children.IndexOf(hidden.children.FirstOrDefault()); parent.children.Insert(oldIndex, hidden); for (Int32 j = 0; j < hidden.children.Count; j++) { PSystemBody child = hidden.children[j]; if (parent.children.Contains(child)) { parent.children.Remove(child); } } } } // RDVisibility = NOICON // Kill Rotation // // Loop through the Containers RDPlanetListItemContainer[] containers = Resources.FindObjectsOfTypeAll <RDPlanetListItemContainer>().Where(i => i.label_planetName.text != "Planet name").ToArray(); for (Int32 i = 0; i < containers?.Count(); i++) { RDPlanetListItemContainer planetItem = containers[i]; // The label text is set from the CelestialBody's displayName CelestialBody body = PSystemManager.Instance?.localBodies?.FirstOrDefault(cb => cb.transform.name == planetItem.name); if (body == null) { Debug.Log("[Kopernicus]: RnDFixer: Could not find CelestialBody for the label => " + planetItem.name); continue; } // Barycenter if (body.Has("barycenter") || !body.Get("selectable", true)) { planetItem.planet.SetActive(false); planetItem.label_planetName.alignment = TextAlignmentOptions.MidlineLeft; } // RD Visibility if (body.Has("hiddenRnD")) { PropertiesLoader.RDVisibility visibility = body.Get <PropertiesLoader.RDVisibility>("hiddenRnD"); if (visibility == PropertiesLoader.RDVisibility.NOICON) { planetItem.planet.SetActive(false); planetItem.label_planetName.alignment = TextAlignmentOptions.MidlineLeft; } else { planetItem.planet.SetActive(true); planetItem.label_planetName.alignment = TextAlignmentOptions.MidlineRight; } } // Add planetItems to 'RnDRotationKill' if (planetItem?.planet?.transform?.rotation == null) { continue; } if (body.Has("RnDRotation") ? !body.Get <Boolean>("RnDRotation") : body?.scaledBody?.GetComponentInChildren <SunCoronas>(true) != null) { RnDRotationKill.Add(planetItem); } } }
// Stuff void LateUpdate() { FixZooming(); ApplyOrbitVisibility(); RDFixer(); // Remove buttons in map view for barycenters if (MapView.MapIsEnabled) { if (fields == null) { FieldInfo mode_f = typeof(OrbitTargeter).GetFields(BindingFlags.NonPublic | BindingFlags.Instance).FirstOrDefault(f => f.FieldType.IsEnum && f.FieldType.IsNested); FieldInfo context_f = typeof(OrbitTargeter).GetFields(BindingFlags.NonPublic | BindingFlags.Instance).FirstOrDefault(f => f.FieldType == typeof(MapContextMenu)); FieldInfo cast_f = typeof(OrbitTargeter).GetFields(BindingFlags.NonPublic | BindingFlags.Instance).FirstOrDefault(f => f.FieldType == typeof(OrbitRenderer.OrbitCastHit)); fields = new FieldInfo[] { mode_f, context_f, cast_f }; } if (FlightGlobals.ActiveVessel != null) { OrbitTargeter targeter = FlightGlobals.ActiveVessel.orbitTargeter; if (targeter == null) { return; } Int32 mode = (Int32)fields[0].GetValue(targeter); if (mode == 2) { OrbitRenderer.OrbitCastHit cast = (OrbitRenderer.OrbitCastHit)fields[2].GetValue(targeter); CelestialBody body = PSystemManager.Instance.localBodies.Find(b => b.name == cast.or?.discoveryInfo?.name?.Value); if (body == null) { return; } if (body.Has("barycenter") || body.Has("notSelectable")) { if (cast.driver?.Targetable == null) { return; } MapContextMenu context = MapContextMenu.Create(body.name, new Rect(0.5f, 0.5f, 300f, 50f), cast, () => { fields[0].SetValue(targeter, 0); fields[1].SetValue(targeter, null); }, new SetAsTarget(cast.driver.Targetable, () => FlightGlobals.fetch.VesselTarget)); fields[1].SetValue(targeter, context); } } } } foreach (CelestialBody body in PSystemManager.Instance.localBodies) { if (body.afg == null) { continue; } GameObject star_ = KopernicusStar.GetNearest(body).gameObject; Vector3 planet2cam = body.scaledBody.transform.position - body.afg.mainCamera.transform.position; body.afg.lightDot = Mathf.Clamp01(Vector3.Dot(planet2cam, body.afg.mainCamera.transform.position - star_.transform.position) * body.afg.dawnFactor); body.afg.GetComponent <Renderer>().material.SetFloat("_lightDot", body.afg.lightDot); } }
void ProcessBinaries(Loader ldr, ConfigNode cfgn) { if (ListOfBinaries?.Count > 0) { Debug.Log("SigmaBinary.ProcessBinaries", "Starting the set up of " + ListOfBinaries?.Count + " binary systems"); } while (ListOfBinaries?.Count > 0) { /// Loading the Bodies Body sbSecondary = ListOfBinaries.First().Value; Debug.Log("SigmaBinary.ProcessBinaries", "sbSecondary = " + sbSecondary?.Name); Body sbPrimary = OrbitPatcher(sbSecondary); Debug.Log("SigmaBinary.ProcessBinaries", "sbPrimary = " + sbPrimary?.Name); Body sbBarycenter = ListOfBodies.Find(b0 => b0.GeneratedBody.name == sigmabinarySBName[sbSecondary]); Debug.Log("SigmaBinary.ProcessBinaries", "sbBarycenter = " + sbBarycenter?.Name); Body sbReference = OrbitPatcher(sbPrimary); Debug.Log("SigmaBinary.ProcessBinaries", "sbReference = " + sbReference?.Name); Body sbOrbit = ListOfBodies.Find(ob => ob.GeneratedBody.name == sigmabinarySBName[sbSecondary] + "Orbit" && sigmabinaryRedrawOrbit.Contains(sbSecondary)); Debug.Log("SigmaBinary.ProcessBinaries", "sbOrbit = " + sbOrbit?.Name); Debug.Log("SigmaBinary.ProcessBinaries", "Loaded Bodies\nReferenceBody: " + sbReference?.GeneratedBody?.name + "\n Barycenter: " + sbBarycenter?.GeneratedBody?.name + "\n Primary: " + sbPrimary?.GeneratedBody?.name + "\n Secondary: " + sbSecondary?.GeneratedBody?.name + "\n Orbit: " + sbOrbit?.GeneratedBody?.name); Debug.Log("SigmaBinary.ProcessBinaries", "Loaded PSystemBodies\nReferenceBody: " + sbReference?.GeneratedBody?.name + "\n Barycenter: " + sbBarycenter?.GeneratedBody?.name + "\n Primary: " + sbPrimary?.GeneratedBody?.name + "\n Secondary: " + sbSecondary?.GeneratedBody?.name + "\n Orbit: " + sbOrbit?.GeneratedBody?.name); // Check that the bodies exist if (sbPrimary == null || sbBarycenter == null || sbReference == null) { break; } if (sbOrbit == null && sigmabinaryRedrawOrbit.Contains(sbSecondary)) { break; } // Load the CelestialBodies CelestialBody cbSecondary = sbSecondary?.GeneratedBody?.celestialBody; CelestialBody cbPrimary = sbPrimary?.GeneratedBody?.celestialBody; CelestialBody cbBarycenter = sbBarycenter?.GeneratedBody?.celestialBody; CelestialBody cbReference = sbReference?.GeneratedBody?.celestialBody; Debug.Log("SigmaBinary.ProcessBinaries", "Loaded CelestialBodies\nReferenceBody: " + cbReference + "\n Barycenter: " + cbBarycenter + "\n Primary: " + cbPrimary + "\n Secondary: " + cbSecondary + "\n Orbit: " + sbOrbit?.GeneratedBody?.celestialBody); /// Generating Binary System // Fix sphereOfInfluence where needed if (cbPrimary.Has("SBfixSOI")) { cbPrimary.sphereOfInfluence = sbPrimary.GeneratedBody.orbitDriver.orbit.semiMajorAxis * Math.Pow(cbPrimary.GetMass() / cbReference.GetMass(), 0.4); cbPrimary.Remove("SBfixSOI"); Debug.Log("SigmaBinary.ProcessBinaries", "Fixed 'sphereOfInfluence' of primary " + sbPrimary.GeneratedBody.name + ". sphereOfInfluence = " + cbPrimary.sphereOfInfluence); } if (cbSecondary.Has("SBfixSOI")) { cbSecondary.sphereOfInfluence = sbSecondary.GeneratedBody.orbitDriver.orbit.semiMajorAxis * Math.Pow(cbSecondary.GetMass() / cbPrimary.GetMass(), 0.4); cbSecondary.Remove("SBfixSOI"); Debug.Log("SigmaBinary.ProcessBinaries", "Fixed 'sphereOfInfluence' of secondary " + sbSecondary.GeneratedBody.name + ". sphereOfInfluence = " + cbSecondary.sphereOfInfluence); } // Remove Finalize Orbit if (cbSecondary.Has("finalizeBody") && cbSecondary.Get <bool>("finalizeBody")) { cbSecondary.Set("finalizeBody", false); Debug.Log("SigmaBinary.ProcessBinaries", "'finalizeBody' turned off for secondary body " + sbSecondary.GeneratedBody.name); // Fix sphereOfInfluence if (!cbSecondary.Has("sphereOfInfluence")) { cbSecondary.Set("sphereOfInfluence", Math.Max(sbSecondary.GeneratedBody.orbitDriver.orbit.semiMajorAxis * Math.Pow(cbSecondary.GetMass() / cbPrimary.GetMass(), 0.4), Math.Max(cbSecondary.Radius * Templates.SOI_MIN_RADIUS_MULTIPLIER, cbSecondary.Radius + Templates.SOI_MIN_ALTITUDE))); Debug.Log("SigmaBinary.ProcessBinaries", "recalculated 'sphereOfInfluence' for secondary body " + sbSecondary.GeneratedBody.name); } } if (cbPrimary.Has("finalizeBody") && cbPrimary.Get <bool>("finalizeBody")) { cbPrimary.Set("finalizeBody", false); Debug.Log("SigmaBinary.ProcessBinaries", "'finalizeBody' turned off for primary body " + sbPrimary.GeneratedBody.name); // Fix sphereOfInfluence if (!cbPrimary.Has("sphereOfInfluence")) { cbPrimary.Set("sphereOfInfluence", Math.Max(sbPrimary.GeneratedBody.orbitDriver.orbit.semiMajorAxis * Math.Pow(cbPrimary.GetMass() / cbReference.GetMass(), 0.4), Math.Max(cbPrimary.Radius * Templates.SOI_MIN_RADIUS_MULTIPLIER, cbPrimary.Radius + Templates.SOI_MIN_ALTITUDE))); Debug.Log("SigmaBinary.ProcessBinaries", "recalculated 'sphereOfInfluence' for primary body " + sbPrimary.GeneratedBody.name); } } /// Set Barycenter sbBarycenter.GeneratedBody.orbitDriver.orbit = new Orbit(sbPrimary.GeneratedBody.orbitDriver.orbit); sbBarycenter.Orbit.ReferenceBody = sbPrimary.Orbit.ReferenceBody; cbBarycenter.GeeASL = (cbPrimary.GetMass() + cbSecondary.GetMass()) / 1e5 * 6.674e-11d / Math.Pow(cbBarycenter.Radius, 2) / 9.80665d; cbBarycenter.rotationPeriod = 0; Debug.Log("SigmaBinary.SetBarycenter", "Printing orbital parameters of primary " + sbPrimary.GeneratedBody.name + " for reference."); Debug.Log("SigmaBinary.SetBarycenter", "referenceBody = " + sbPrimary.Orbit.ReferenceBody + ", semiMajorAxis = " + sbPrimary.GeneratedBody.orbitDriver.orbit.semiMajorAxis + ", period = " + sbPrimary.GetOrbitalPeriod(cbReference)); Debug.Log("SigmaBinary.SetBarycenter", "Calculated new orbital parameters for barycenter " + sbBarycenter.GeneratedBody.name); Debug.Log("SigmaBinary.SetBarycenter", "referenceBody = " + sbBarycenter.Orbit.ReferenceBody + ", semiMajorAxis = " + sbBarycenter.GeneratedBody.orbitDriver.orbit.semiMajorAxis); sbBarycenter.GeneratedBody.celestialBody.Set("customOrbitalPeriod", sbPrimary.GetOrbitalPeriod(cbReference)); Debug.Log("SigmaBinary.SetBarycenter", "Changed orbital period of barycenter " + sbBarycenter?.GeneratedBody?.name + ", new orbital period = " + sbBarycenter.GetOrbitalPeriod()); // Orbit Color if (sigmabinaryOrbitColor.ContainsKey(sbSecondary)) { sbBarycenter.GeneratedBody.orbitRenderer.SetColor(sigmabinaryOrbitColor[sbSecondary]); Debug.Log("SigmaBinary.SetBarycenter", "Barycenter " + sbBarycenter.GeneratedBody.name + " orbit line color set from list. color = " + sigmabinaryOrbitColor[sbSecondary]); } else { sbBarycenter.GeneratedBody.orbitRenderer.orbitColor = sbPrimary.GeneratedBody.orbitRenderer.orbitColor; Debug.Log("SigmaBinary.SetBarycenter", "Barycenter " + sbBarycenter.GeneratedBody.name + " orbit line color copied from primary " + sbPrimary.GeneratedBody.name + ". color = " + sbPrimary.GeneratedBody.orbitRenderer.orbitColor); } // Icon Color if (sigmabinaryIconColor.ContainsKey(sbSecondary)) { sbBarycenter.GeneratedBody.orbitRenderer.nodeColor = sigmabinaryIconColor[sbSecondary]; Debug.Log("SigmaBinary.SetBarycenter", "Barycenter " + sbBarycenter.GeneratedBody.name + " orbit icon color set from list. color = " + sigmabinaryIconColor[sbSecondary]); } else if (!sigmabinaryOrbitColor.ContainsKey(sbSecondary)) { sbBarycenter.GeneratedBody.orbitRenderer.nodeColor = sbPrimary.GeneratedBody.orbitRenderer.nodeColor; Debug.Log("SigmaBinary.SetBarycenter", "Barycenter " + sbBarycenter.GeneratedBody.name + " orbit icon color copied from primary " + sbPrimary.GeneratedBody.name + ". color = " + sbPrimary.GeneratedBody.orbitRenderer.nodeColor); } // Description if (sigmabinaryDescription.ContainsKey(sbSecondary)) { cbBarycenter.bodyDescription = sigmabinaryDescription[sbSecondary].Replace("<name>", nameof(sbBarycenter)).Replace("<primary>", nameof(sbPrimary)).Replace("<secondary>", nameof(sbSecondary)); Debug.Log("SigmaBinary.SetBarycenter", "Barycenter " + sbBarycenter.GeneratedBody.name + " description loaded."); } Debug.Log("SigmaBinary.SetBarycenter", "description = " + cbBarycenter.bodyDescription); // DrawMode and DrawIcons if (sigmabinaryMode.ContainsKey(sbSecondary)) { cbBarycenter.Set("drawMode", sigmabinaryMode[sbSecondary]); Debug.Log("SigmaBinary.SetBarycenter", "Barycenter " + sbBarycenter.GeneratedBody.name + " custom orbit 'drawMode' loaded. drawMode = " + sigmabinaryMode[sbSecondary].Value); } else if (cbPrimary.Has("drawMode")) { cbBarycenter.Set("drawMode", cbPrimary.Get <DrawMode>("drawMode")); Debug.Log("SigmaBinary.SetBarycenter", "Barycenter " + sbBarycenter.GeneratedBody.name + " orbit 'drawMode' copied from primary " + sbPrimary.GeneratedBody.name + ". drawMode = " + cbPrimary.Get <DrawMode>("drawMode")); cbPrimary.Set("drawMode", DrawMode.REDRAW_AND_RECALCULATE); Debug.Log("SigmaBinary.SetBarycenter", "Primary " + sbPrimary.GeneratedBody.name + " orbit 'drawMode' automatically set. drawMode = " + DrawMode.REDRAW_AND_RECALCULATE); } if (sigmabinaryIcon.ContainsKey(sbSecondary)) { cbPrimary.Set("drawIcons", sigmabinaryIcon[sbSecondary]); Debug.Log("SigmaBinary.SetBarycenter", "Primary " + sbPrimary.GeneratedBody.name + " custom orbit 'drawIcons' loaded. drawIcons = " + sigmabinaryIcon[sbSecondary].Value); } else if (cbPrimary.Has("drawIcons")) { cbBarycenter.Set("drawIcons", cbPrimary.Get <DrawIcons>("drawIcons")); Debug.Log("SigmaBinary.SetBarycenter", "Barycenter " + sbBarycenter.GeneratedBody.name + " orbit 'drawIcons' copied from primary " + sbPrimary.GeneratedBody.name + ". drawIcons = " + cbPrimary.Get <DrawIcons>("drawIcons")); cbPrimary.Set("drawIcons", DrawIcons.ALL); Debug.Log("SigmaBinary.SetBarycenter", "Primary " + sbPrimary.GeneratedBody.name + " orbit 'drawIcons' automatically set. drawIcons = " + DrawIcons.ALL); } /// Set Primary if (sbPrimary.Template.OriginalBody.celestialBody.name == "Kerbin") { Debug.Log("SigmaBinary.SetPrimary", "Primary " + sbPrimary.GeneratedBody.name + " uses Kerbin as Template."); if (!kerbinFixer.ContainsKey(sbPrimary.GeneratedBody.name)) { kerbinFixer.Add(sbPrimary.GeneratedBody.name, sbReference.GeneratedBody.name); Debug.Log("SigmaBinary.SetPrimary", "Stored patched 'referenceBody' " + cbReference + " of Primary " + sbPrimary.GeneratedBody.name + " in 'kerbinFixer'."); } if (!archivesFixerList.ContainsKey(sbPrimary.GeneratedBody)) { archivesFixerList.Add(sbPrimary.GeneratedBody, sbBarycenter.GeneratedBody); Debug.Log("SigmaBinary.SetPrimary", "Stored primary " + sbPrimary.GeneratedBody.name + " and barycenter " + sbBarycenter.GeneratedBody.name + " in 'archivesFixerList'."); } } sbPrimary.GeneratedBody.orbitDriver.orbit = new Orbit ( sbSecondary.GeneratedBody.orbitDriver.orbit.inclination, sbSecondary.GeneratedBody.orbitDriver.orbit.eccentricity, sbSecondary.GeneratedBody.orbitDriver.orbit.semiMajorAxis * cbSecondary.GetMass() / (cbSecondary.GetMass() + cbPrimary.GetMass()), sbSecondary.GeneratedBody.orbitDriver.orbit.LAN, sbSecondary.GeneratedBody.orbitDriver.orbit.argumentOfPeriapsis + 180d, sbSecondary.GeneratedBody.orbitDriver.orbit.meanAnomalyAtEpoch, sbSecondary.GeneratedBody.orbitDriver.orbit.epoch, cbBarycenter ); sbPrimary.Orbit.ReferenceBody = sbBarycenter.GeneratedBody.name; Debug.Log("SigmaBinary.SetPrimary", "Printing masses of bodies for reference. primary = " + cbPrimary.GetMass() + ", secondary = " + cbSecondary.GetMass() + ", ratio = " + (cbPrimary.GetMass() / cbSecondary.GetMass())); Debug.Log("SigmaBinary.SetPrimary", "Printing orbital parameters of secondary " + sbSecondary.GeneratedBody.name + " for reference."); Debug.Log("SigmaBinary.SetPrimary", "referenceBody = " + sbSecondary.Orbit.ReferenceBody + ", semiMajorAxis = " + sbSecondary.GeneratedBody.orbitDriver.orbit.semiMajorAxis); Debug.Log("SigmaBinary.SetPrimary", "Calculated new orbital parameters for primary " + sbPrimary.GeneratedBody.name); Debug.Log("SigmaBinary.SetPrimary", "referenceBody = " + sbPrimary.Orbit.ReferenceBody + ", semiMajorAxis = " + sbPrimary.GeneratedBody.orbitDriver.orbit.semiMajorAxis + ", ratio = " + (sbSecondary.GeneratedBody.orbitDriver.orbit.semiMajorAxis / sbPrimary.GeneratedBody.orbitDriver.orbit.semiMajorAxis)); sbPrimary.GeneratedBody.celestialBody.Set("customOrbitalPeriod", sbSecondary.GetOrbitalPeriod(cbPrimary)); Debug.Log("SigmaBinary.SetPrimary", "New Orbital Period for Primary " + sbPrimary.GeneratedBody.name + " = " + sbPrimary.GetOrbitalPeriod()); // Primary Locked if (cbPrimary.solarRotationPeriod) { cbPrimary.solarRotationPeriod = false; cbPrimary.rotationPeriod = (sbBarycenter.GetOrbitalPeriod() * cbPrimary.rotationPeriod) / (sbBarycenter.GetOrbitalPeriod() + cbPrimary.rotationPeriod); Debug.Log("SigmaBinary.SetPrimary", "Primary " + sbPrimary.GeneratedBody.name + " 'solarRotationPeriod' set to 'false'. recalculated rotation period = " + cbPrimary.rotationPeriod); } if (sigmabinaryPrimaryLocked.Contains(sbSecondary)) { cbPrimary.solarRotationPeriod = false; cbPrimary.rotationPeriod = sbPrimary.GetOrbitalPeriod(); Debug.Log("SigmaBinary.SetPrimary", "Primary " + sbPrimary.GeneratedBody.name + " is locked to reference " + sbReference.GeneratedBody.name + "."); Debug.Log("SigmaBinary.SetPrimary", "Primary " + sbPrimary.GeneratedBody.name + " 'solarRotationPeriod' set to 'false'. recalculated rotation period = " + cbPrimary.rotationPeriod); } /// Set Secondary Orbit if (sigmabinaryRedrawOrbit.Contains(sbSecondary)) { if (sbOrbit?.GeneratedBody?.celestialBody != null && !trackingStationFixer.Contains(sbOrbit.GeneratedBody.celestialBody)) { trackingStationFixer.Add(sbOrbit.GeneratedBody.celestialBody); } mapViewFixerList.Add(sbOrbit.GeneratedBody.celestialBody, cbSecondary); sbOrbit.GeneratedBody.orbitDriver.orbit = new Orbit ( sbSecondary.GeneratedBody.orbitDriver.orbit.inclination, sbSecondary.GeneratedBody.orbitDriver.orbit.eccentricity, sbSecondary.GeneratedBody.orbitDriver.orbit.semiMajorAxis - sbPrimary.GeneratedBody.orbitDriver.orbit.semiMajorAxis, sbSecondary.GeneratedBody.orbitDriver.orbit.LAN, sbSecondary.GeneratedBody.orbitDriver.orbit.argumentOfPeriapsis, sbSecondary.GeneratedBody.orbitDriver.orbit.meanAnomalyAtEpoch, sbSecondary.GeneratedBody.orbitDriver.orbit.epoch, cbBarycenter ); sbOrbit.Orbit.ReferenceBody = sbBarycenter.GeneratedBody.name; Debug.Log("SigmaBinary.SetMarker", "Printing orbital parameters of primary " + sbPrimary.GeneratedBody.name + " for reference."); Debug.Log("SigmaBinary.SetMarker", "referenceBody = " + sbPrimary.Orbit.ReferenceBody + ", semiMajorAxis = " + sbPrimary.GeneratedBody.orbitDriver.orbit.semiMajorAxis); Debug.Log("SigmaBinary.SetMarker", "Printing orbital parameters of secondary " + sbSecondary.GeneratedBody.name + " for reference."); Debug.Log("SigmaBinary.SetMarker", "referenceBody = " + sbSecondary.Orbit.ReferenceBody + ", semiMajorAxis = " + sbSecondary.GeneratedBody.orbitDriver.orbit.semiMajorAxis); Debug.Log("SigmaBinary.SetMarker", "Calculated new orbital parameters for orbit marker " + sbOrbit.GeneratedBody.name); Debug.Log("SigmaBinary.SetMarker", "referenceBody = " + sbOrbit.Orbit.ReferenceBody + ", semiMajorAxis = " + sbOrbit.GeneratedBody.orbitDriver.orbit.semiMajorAxis); sbOrbit.GeneratedBody.orbitRenderer.orbitColor = sbSecondary.GeneratedBody.orbitRenderer.orbitColor; Debug.Log("SigmaBinary.SetMarker", "Orbit marker " + sbOrbit.GeneratedBody.name + " orbit line color set from secondary " + sbSecondary.GeneratedBody.name + ". color = " + sbOrbit.GeneratedBody.orbitRenderer.orbitColor); sbOrbit.GeneratedBody.celestialBody.Set("customOrbitalPeriod", sbSecondary.GetOrbitalPeriod(cbPrimary)); Debug.Log("SigmaBinary.SetMarker", "Orbit marker " + sbOrbit.GeneratedBody.name + " orbital period = " + sbOrbit.GetOrbitalPeriod()); cbSecondary.Set("drawMode", DrawMode.OFF); Debug.Log("SigmaBinary.SetMarker", "Secondary " + sbSecondary.GeneratedBody.name + " orbit 'drawMode' automatically set. drawMode = " + DrawMode.OFF); } /// Set SphereOfInfluence for Barycenter and Primary if (!cbPrimary.Has("sphereOfInfluence")) { cbPrimary.Set("sphereOfInfluence", sbBarycenter.GeneratedBody.orbitDriver.orbit.semiMajorAxis * Math.Pow(cbPrimary.GetMass() / cbReference.GetMass(), 0.4)); Debug.Log("SigmaBinary.SetSoI", "Calculated 'sphereOfInfluence' for primary " + sbPrimary.GeneratedBody.name + ". sphereOfInfluence = " + cbPrimary.Get <double>("sphereOfInfluence")); } cbBarycenter.Set("sphereOfInfluence", cbPrimary.Get <double>("sphereOfInfluence")); Debug.Log("SigmaBinary.SetSoI", "Set barycenter " + sbBarycenter.GeneratedBody.name + " 'sphereOfInfluence' from primary " + sbPrimary.GeneratedBody.name + ". sphereOfInfluence = " + cbPrimary.Get <double>("sphereOfInfluence")); cbPrimary.Set("sphereOfInfluence", sbPrimary.GeneratedBody.orbitDriver.orbit.semiMajorAxis * (sbBarycenter.GeneratedBody.orbitDriver.orbit.eccentricity + 1) + cbBarycenter.Get <double>("sphereOfInfluence")); Debug.Log("SigmaBinary.SetSoI", "Recalculated 'sphereOfInfluence' for primary " + sbPrimary.GeneratedBody.name + ". sphereOfInfluence = " + cbPrimary.Get <double>("sphereOfInfluence")); /// Final Fixes for Bodies with a Kerbin Template // If the primary has a Kerbin Template, bypass PostSpawnOrbit if (kerbinFixer.ContainsKey(sbPrimary.GeneratedBody.name)) { Debug.Log("SigmaBinary.FixKerbinTemplate", "Primary " + sbPrimary.GeneratedBody.name + " uses Kerbin as Template."); // Revert the referenceBody to the original one sbPrimary.Orbit.ReferenceBody = kerbinFixer[sbPrimary.GeneratedBody.name]; Debug.Log("SigmaBinary.FixKerbinTemplate", "Primary " + sbPrimary.GeneratedBody.name + " 'referenceBody' reverted to the original. referenceBody = " + sbPrimary.Orbit.ReferenceBody); // Save the PostSpawn referenceBody for later kerbinFixer[sbPrimary.GeneratedBody.name] = sbBarycenter.GeneratedBody.name; Debug.Log("SigmaBinary.FixKerbinTemplate", "kerbinFixer[cbPrimary] set to barycenter " + sbBarycenter.GeneratedBody.name); // Clear PostSpawnOrbit if (sbPrimary.GeneratedBody.Has("orbitPatches")) { sbPrimary.GeneratedBody.Remove("orbitPatches"); Debug.Log("SigmaBinary.FixKerbinTemplate", "Primary " + sbPrimary.GeneratedBody.name + " 'PostSpawnOrbit' node removed, 'kerbinFixer' will handle this."); } } // If the secondary has a Kerbin Template, restore PostSpawnOrbit referenceBody if (kerbinFixer.ContainsKey(sbSecondary.GeneratedBody.name)) { Debug.Log("SigmaBinary.FixKerbinTemplate", "Secondary " + sbSecondary.GeneratedBody.name + " uses Kerbin as Template."); sbSecondary.Orbit.ReferenceBody = kerbinFixer[sbSecondary.GeneratedBody.name]; Debug.Log("SigmaBinary.FixKerbinTemplate", "Secondary " + sbSecondary.GeneratedBody.name + " 'referenceBody' reverted to the original. referenceBody = " + sbSecondary.Orbit.ReferenceBody); kerbinFixer.Remove(sbSecondary.GeneratedBody.name); Debug.Log("SigmaBinary.FixKerbinTemplate", "Secondary " + sbSecondary.GeneratedBody.name + " removed from 'kerbinFixer', 'PostSpawnOrbit' will handle this."); } /// Binary System Completed ListOfBinaries.Remove(ListOfBinaries.First().Key); Debug.Log("SigmaBinary.PostApply", "Binary system with secondary " + sbSecondary.GeneratedBody.name + " removed from 'ListOfBinaries'."); // Easter Eggs LateFixes.TextureFixer(sbPrimary, sbSecondary, ListOfBodies); // Log UnityEngine.Debug.Log("[SigmaLog]: Binary System Completed\nReferenceBody: " + sbReference.GeneratedBody.name + "\n Barycenter: " + sbBarycenter.GeneratedBody.name + "\n Primary: " + sbPrimary.GeneratedBody.name + "\n Secondary: " + sbSecondary.GeneratedBody.name + (Debug.debug ? "\n Orbit: " + sbOrbit?.GeneratedBody?.name : "")); } Debug.Log("SigmaBinary.ProcessBinaries", "Completed the set up of all binary systems."); }
private void ApplyMapTargetPatches() { if (!MapView.MapIsEnabled) { return; } // Grab the needed fields for reflection if (_fields == null) { FieldInfo modeField = typeof(OrbitTargeter).GetFields(BindingFlags.NonPublic | BindingFlags.Instance) .FirstOrDefault(f => f.FieldType.IsEnum && f.FieldType.IsNested); FieldInfo contextField = typeof(OrbitTargeter).GetFields(BindingFlags.NonPublic | BindingFlags.Instance) .FirstOrDefault(f => f.FieldType == typeof(MapContextMenu)); FieldInfo castField = typeof(OrbitTargeter).GetFields(BindingFlags.NonPublic | BindingFlags.Instance) .FirstOrDefault(f => f.FieldType == typeof(OrbitRenderer.OrbitCastHit)); _fields = new[] { modeField, contextField, castField }; } // Remove buttons in map view for barycenters if (!FlightGlobals.ActiveVessel) { return; } OrbitTargeter targeter = FlightGlobals.ActiveVessel.orbitTargeter; if (!targeter) { return; } Int32 mode = (Int32)_fields[0].GetValue(targeter); if (mode != 2) { return; } OrbitRenderer.OrbitCastHit cast = (OrbitRenderer.OrbitCastHit)_fields[2].GetValue(targeter); CelestialBody body = PSystemManager.Instance.localBodies.Find(b => cast.or != null && cast.or.discoveryInfo?.name != null && b.name == cast.or.discoveryInfo.name.Value); if (!body) { return; } if (!body.Has("barycenter") && body.Get("selectable", true)) { return; } if (!cast.driver || cast.driver.Targetable == null) { return; } MapContextMenu context = MapContextMenu.Create(body.name, new Rect(0.5f, 0.5f, 300f, 50f), cast, () => { _fields[0].SetValue(targeter, 0); _fields[1].SetValue(targeter, null); }, new SetAsTarget(cast.driver.Targetable, () => FlightGlobals.fetch.VesselTarget)); _fields[1].SetValue(targeter, context); }
// Apply PostSpawnOrbit patches private void ApplyOrbitPatches() { // Bodies Dictionary <String, KeyValuePair <CelestialBody, CelestialBody> > fixes = new Dictionary <String, KeyValuePair <CelestialBody, CelestialBody> >(); for (Int32 i = 0; i < PSystemManager.Instance.localBodies.Count; i++) { CelestialBody body = PSystemManager.Instance.localBodies[i]; // Post spawn patcher if (!body.Has("orbitPatches")) { continue; } ConfigNode orbitNode = body.Get <ConfigNode>("orbitPatches"); OrbitLoader loader = new OrbitLoader(body); CelestialBody oldRef = body.referenceBody; Parser.LoadObjectFromConfigurationNode(loader, orbitNode, "Kopernicus"); oldRef.orbitingBodies.Remove(body); if (body.referenceBody == null) { // 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(); Destroy(this); return; } 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) { continue; } Double rotationPeriod = body.rotationPeriod; Double orbitalPeriod = body.orbit.period; body.rotationPeriod = rotationPeriod * orbitalPeriod / (orbitalPeriod + rotationPeriod); } // 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 = trackingstation.Where(m => m != null).ToList(); // Undo stuff foreach (CelestialBody b in PSystemManager.Instance.localBodies.Where(b => b.Has("orbitPatches"))) { String transformName = b.transform.name; fixes[transformName].Value.orbitingBodies.Remove(b); fixes[transformName].Key.orbitingBodies.Add(b); fixes[transformName].Key.orbitingBodies = fixes[transformName].Key.orbitingBodies .OrderBy(cb => cb.orbit.semiMajorAxis).ToList(); } }
void Start() { foreach (CelestialBody cb in FlightGlobals.Bodies) { body = cb; resize = body.Has("resize") ? body.Get<double>("resize") : 1; landscape = body.Has("landscape") ? body.Get<double>("landscape") : 1; resizeBuildings = body.Has("resizeBuildings") ? body.Get<double>("resizeBuildings") : 1; foreach (PQSCity mod in body.GetComponentsInChildren<PQSCity>(true)) { CityFixer(mod); } foreach (PQSCity2 mod in body.GetComponentsInChildren<PQSCity2>(true)) { City2Fixer(mod); } } }
void FixAltitude() { CelestialBody body = FlightGlobals.currentMainBody; if (body == null) { return; } PQS pqs = body.pqsController; if (pqs == null) { return; } PQSCity city = GetComponent <PQSCity>(); if (city == null) { return; } // Location Vector3 planet = body.transform.position; Vector3 building = city.transform.position; // From body to city Vector3 location = (building - planet).normalized; // Sigma Dimensions Settings double resize = body.Has("resize") ? body.Get <double>("resize") : 1; double landscape = body.Has("landscape") ? body.Get <double>("landscape") : 1; double resizeBuildings = body.Has("resizeBuildings") ? body.Get <double>("resizeBuildings") : 1; // Max distance double maxDistance = Math.Abs(2 * pqs.mapMaxHeight); maxDistance *= resize * landscape > 1 ? resize * landscape : 1; maxDistance += body.Radius; RaycastHit[] hits = Physics.RaycastAll(planet + location * (float)maxDistance, -location, (float)maxDistance, LayerMask.GetMask("Local Scenery")); for (int i = 0; i < hits?.Length; i++) { if (hits[i].collider?.GetComponent <PQ>()) { // Update only once TimingManager.UpdateRemove(TimingManager.TimingStage.Normal, FixAltitude); Debug.Log("PQSCityFixer", "> Planet: " + body.transform.name); Debug.Log("PQSCityFixer", " > PQSCity: " + city); // PQSCity parameters double groundLevel = (hits[i].point - planet).magnitude - body.Radius; double error = pqs.GetSurfaceHeight(city.repositionRadial) - body.Radius - groundLevel; double oceanDepth = body.ocean && groundLevel < 0 ? -groundLevel : 0d; groundLevel = body.ocean && groundLevel < 0 ? 0d : groundLevel; Debug.Log("PQSCityFixer", " > Ground Level at Mod = " + groundLevel); Debug.Log("PQSCityFixer", " > Ocean Depth at Mod = " + groundLevel); Debug.Log("PQSCityFixer", " > Ground Level Error at Mod = " + groundLevel); // Fix Altitude if (city.repositionToSphere && !city.repositionToSphereSurface) { // Offset = Distance from the radius of the planet Debug.Log("PQSCityFixer", " > PQSCity Original Radius Offset = " + city.repositionRadiusOffset); double builtInOffset = city.repositionRadiusOffset - groundLevel / (resize * landscape); Debug.Log("PQSCityFixer", " > Builtuin Offset = " + builtInOffset); city.repositionRadiusOffset = groundLevel + error / (resize * landscape) - (groundLevel + error - city.repositionRadiusOffset) / resizeBuildings; Debug.Log("PQSCityFixer", " > PQSCity Fixed Radius Offset = " + city.repositionRadiusOffset); } else { // Offset = Distance from the surface of the planet if (!city.repositionToSphereSurface) { city.repositionToSphereSurface = true; city.repositionRadiusOffset = 0; } if (!city.repositionToSphereSurfaceAddHeight) { city.repositionToSphereSurfaceAddHeight = true; city.repositionRadiusOffset = 0; } Debug.Log("PQSCityFixer", " > PQSCity Original Surface Offset = " + city.repositionRadiusOffset); city.repositionRadiusOffset = oceanDepth + error / (resize * landscape) - (oceanDepth + error - city.repositionRadiusOffset) / resizeBuildings; Debug.Log("PQSCityFixer", " > PQSCity Fixed Surface Offset = " + city.repositionRadiusOffset); } city.Orientate(); DestroyImmediate(this); } } }
void Start() { // FIX BODIES MOVED POSTSPAWN // bool postSpawnChanges = false; foreach (CelestialBody cb in PSystemManager.Instance.localBodies.Where(b => b.Has("orbitPatches"))) { // Fix position if the body gets moved PostSpawn ConfigNode patch = cb.Get <ConfigNode>("orbitPatches"); if (patch.GetValue("referenceBody") != null || patch.GetValue("semiMajorAxis") != null) { // Get the body, the old parent and the new parent PSystemBody body = PSystemManager.Instance.systemPrefab.GetComponentsInChildren <PSystemBody>(true).First(b => b.name == name); PSystemBody oldParent = PSystemManager.Instance.systemPrefab.GetComponentsInChildren <PSystemBody>(true).First(b => b.children.Contains(body)); PSystemBody newParent = oldParent; if (patch.GetValue("referenceBody") != null) { newParent = PSystemManager.Instance.systemPrefab.GetComponentsInChildren <PSystemBody>(true).First(b => b.name == patch.GetValue("referenceBody")); } if (body != null && oldParent != null) { // If there is no new SMA it means only the parent changed NumericParser <double> newSMA = body.orbitDriver.orbit.semiMajorAxis; if (patch.GetValue("semiMajorAxis") != null) { newSMA.SetFromString(patch.GetValue("semiMajorAxis")); } // Count how many children comes before our body in the newParent.child list int index = 0; foreach (PSystemBody child in newParent.children) { if (child.orbitDriver.orbit.semiMajorAxis < newSMA.value) { index++; } } // Add the body as child for the new parent and remove it for the old parent if (index > newParent.children.Count) { newParent.children.Add(body); } else { newParent.children.Insert(index, body); } oldParent.children.Remove(body); postSpawnChanges = true; } } } // Rebuild Archives if (postSpawnChanges) { AddPlanets(); } // RDVisibility = SKIP // List <KeyValuePair <PSystemBody, PSystemBody> > skipList = new List <KeyValuePair <PSystemBody, PSystemBody> >(); // Create a list with body to hide and their parent PSystemBody[] bodies = PSystemManager.Instance.systemPrefab.GetComponentsInChildren <PSystemBody>(true); foreach (CelestialBody body in PSystemManager.Instance.localBodies.Where(b => b.Has("hiddenRnD"))) { if (body.Get <PropertiesLoader.RDVisibility>("hiddenRnD") == PropertiesLoader.RDVisibility.SKIP) { PSystemBody hidden = Utility.FindBody(PSystemManager.Instance.systemPrefab.rootBody, name); if (hidden.children.Count == 0) { body.Set("hiddenRnd", PropertiesLoader.RDVisibility.HIDDEN); } else { PSystemBody parent = bodies.First(b => b.children.Contains(hidden)); if (parent != null) { if (skipList.Any(b => b.Key == parent)) { int index = skipList.IndexOf(skipList.First(b => b.Key == parent)); skipList.Insert(index, new KeyValuePair <PSystemBody, PSystemBody>(hidden, parent)); } else { skipList.Add(new KeyValuePair <PSystemBody, PSystemBody>(hidden, parent)); } } } } } foreach (KeyValuePair <PSystemBody, PSystemBody> pair in skipList) { // Get hidden body and parent PSystemBody hidden = pair.Key; PSystemBody parent = pair.Value; // Find where the hidden body is int index = parent.children.IndexOf(hidden); // Put its children in its place parent.children.InsertRange(index, hidden.children); // Remove the hidden body from its parent's children list so it won't show up when clicking the parent parent.children.Remove(hidden); } if (skipList.Count > 0) { // Rebuild Archives AddPlanets(); // Undo the changes to the PSystem for (int i = skipList.Count; i > 0; i = i - 1) { PSystemBody hidden = skipList.ElementAt(i).Key; PSystemBody parent = skipList.ElementAt(i).Value; int oldIndex = parent.children.IndexOf(hidden.children.First()); parent.children.Insert(oldIndex, hidden); foreach (PSystemBody child in hidden.children) { if (parent.children.Contains(child)) { parent.children.Remove(child); } } } } // RDVisibility = HIDDEN // RDVisibility = NOICON // // Loop through the Container foreach (RDPlanetListItemContainer planetItem in Resources.FindObjectsOfTypeAll <RDPlanetListItemContainer>()) { // Barycenter CelestialBody body = PSystemManager.Instance.localBodies.Find(b => b.transform.name == planetItem.label_planetName.text); if (body.Has("barycenter") || body.Has("notSelectable")) { planetItem.planet.SetActive(false); planetItem.label_planetName.alignment = TextAlignmentOptions.MidlineLeft; } // RD Visibility if (body.Has("hiddenRnD")) { PropertiesLoader.RDVisibility visibility = body.Get <PropertiesLoader.RDVisibility>("hiddenRnD"); if (visibility == PropertiesLoader.RDVisibility.NOICON) { planetItem.planet.SetActive(false); planetItem.label_planetName.alignment = TextAlignmentOptions.MidlineLeft; } else if (visibility == PropertiesLoader.RDVisibility.HIDDEN) { planetItem.gameObject.SetActive(false); planetItem.Hide(); planetItem.HideChildren(); } else { planetItem.planet.SetActive(true); planetItem.label_planetName.alignment = TextAlignmentOptions.MidlineRight; } } // namechanges if (FindObjectsOfType <NameChanger>().Count(n => n.oldName == planetItem.label_planetName.text) != 0 && !planetItem.label_planetName.name.EndsWith("NAMECHANGER")) { NameChanger changer = FindObjectsOfType <NameChanger>().First(n => n.oldName == planetItem.label_planetName.text); planetItem.label_planetName.text = changer.newName; planetItem.label_planetName.name += "NAMECHANGER"; } } }
void Update() { CelestialBody body = FlightGlobals.currentMainBody; if (body == null) { return; } PQS pqs = body.pqsController; if (pqs == null) { return; } PQSCity2 city = GetComponent <PQSCity2>(); if (city == null) { return; } // Location Vector3 planet = body.transform.position; Vector3 building = city.transform.position; // From body to city Vector3 location = (building - planet).normalized; // Sigma Dimensions Settings double resize = body.Has("resize") ? body.Get <double>("resize") : 1; double landscape = body.Has("landscape") ? body.Get <double>("landscape") : 1; double resizeBuildings = body.Has("resizeBuildings") ? body.Get <double>("resizeBuildings") : 1; // Max distance double maxDistance = Math.Abs(2 * pqs.mapMaxHeight); maxDistance *= resize * landscape > 1 ? resize * landscape : 1; maxDistance += body.Radius; RaycastHit[] hits = Physics.RaycastAll(planet + location * (float)maxDistance, -location, (float)maxDistance, LayerMask.GetMask("Local Scenery")); for (int i = 0; i < hits?.Length; i++) { if (hits[i].collider?.GetComponent <PQ>()) { Debug.Log("PQSCity2Fixer", "> Planet: " + body.transform.name); Debug.Log("PQSCity2Fixer", " > PQSCity2: " + city); // PQSCity2 parameters double groundLevel = (hits[i].point - planet).magnitude - body.Radius; Debug.Log("PQSCity2Fixer", " > Ground Level at Mod (RAYCAST) = " + groundLevel); double error = pqs.GetSurfaceHeight(city.PlanetRelativePosition) - body.Radius - groundLevel; Debug.Log("PQSCity2Fixer", " > Ground Level Error at Mod = " + error); double oceanDepth = body.ocean && groundLevel < 0 ? -groundLevel : 0d; Debug.Log("PQSCity2Fixer", " > Ocean Depth at Mod = " + oceanDepth); groundLevel = body.ocean && groundLevel < 0 ? 0d : groundLevel; Debug.Log("PQSCity2Fixer", " > Ground Level at Mod (NEW) = " + groundLevel); // Because, SQUAD city.PositioningPoint.localPosition /= (float)(body.Radius + city.alt); // Fix Altitude if (!city.snapToSurface) { // Alt = Distance from the radius of the planet Debug.Log("PQSCity2Fixer", " > PQSCity2 Original Radius Offset = " + city.alt); double builtInOffset = city.alt - groundLevel / (resize * landscape); Debug.Log("PQSCity2Fixer", " > Builtuin Offset = " + builtInOffset); city.alt = groundLevel + error / (resize * landscape) - (groundLevel + error - city.alt) / resizeBuildings; Debug.Log("PQSCity2Fixer", " > PQSCity2 Fixed Radius Offset = " + city.alt); } else { // Offset = Distance from the surface of the planet Debug.Log("PQSCity2Fixer", " > PQSCity2 Original Surface Offset = " + city.snapHeightOffset); double newOffset = oceanDepth + error / (resize * landscape) - (oceanDepth + error - city.snapHeightOffset) / resizeBuildings; city.alt += newOffset - city.snapHeightOffset; city.snapHeightOffset = newOffset; Debug.Log("PQSCity2Fixer", " > PQSCity2 New Surface Offset = " + city.snapHeightOffset); } // Because, SQUAD city.PositioningPoint.localPosition *= (float)(body.Radius + city.alt); // Apply Changes and Destroy city.Orientate(); DestroyImmediate(this); } } }
void SaveGroups() { // LOAD SD GROUPS foreach (ConfigNode Group in GroupsList.Values) { string group = Group.GetValue("name"); CelestialBody body = FlightGlobals.Bodies.FirstOrDefault(b => b.transform.name == Group.GetValue("body")); if (string.IsNullOrEmpty(group) || body == null) { continue; } Debug.Log("PQSCityGroups.SaveGroups", ">>> Loading PQSCityGroups from config files <<<"); Debug.Log("PQSCityGroups.SaveGroups", "> Planet: " + body.name + (body.name != body.displayName.Replace("^N", "") ? (", (A.K.A.: " + body.displayName.Replace("^N", "") + ")") : "") + (body.name != body.transform.name ? (", (A.K.A.: " + body.transform.name + ")") : "")); Debug.Log("PQSCityGroups.SaveGroups", " > Group: " + group); bool.TryParse(Group.GetValue("exclude"), out bool exclude); // FIND GROUP CENTER Vector3Parser center = null; // Get Center position from the CENTER node if (Group.HasNode("CENTER")) { ConfigNode C = Group.GetNode("CENTER"); if (C.HasValue("CentralPQSCity")) { if (body == FlightGlobals.GetHomeBody() && C.GetValue("CentralPQSCity") == "KSC") { center = new Vector3(157000, -1000, -570000); } } if (center == null) { center = GetCenter(C, body); } } if (!body.Has("PQSCityGroups")) { body.Set("PQSCityGroups", new Dictionary <object, Vector3>()); } Dictionary <object, Vector3> PQSList = body.Get <Dictionary <object, Vector3> >("PQSCityGroups"); if (!body.Has("ExcludedPQSCityMods")) { body.Set("ExcludedPQSCityMods", new List <object>()); } List <object> ExcludeList = body.Get <List <object> >("ExcludedPQSCityMods"); // If the Center position has not been found get it from the MODS node if (Group.HasNode("MODS")) { ConfigNode M = Group.GetNode("MODS"); if (center == null) { center = GetCenter(M, body); } } // If the Center position has not been found get it from the external groups if ( center == null && ExternalGroups?.ContainsKey(body) == true && ExternalGroups[body].ContainsKey(group) ) { center = GetPosition(ExternalGroups[body][group].FirstOrDefault()); } // If the Center position has not been found stop here if (center == null) { continue; } Debug.Log("PQSCityGroups.SaveGroups", " > Center position = " + center.Value + ", (LAT: " + new SigmaDimensions.LatLon(center).lat + ", LON: " + new SigmaDimensions.LatLon(center).lon + ")"); // ADD PQS MODS TO THE GROUP if (Group.HasNode("MODS")) { ConfigNode M = Group.GetNode("MODS"); foreach (string city in M.GetValues("PQSCity")) { PQSCity mod = body.GetComponentsInChildren <PQSCity>(true).FirstOrDefault(m => m.name == city); if (mod != null) { // If the mod has already been added overwrite it // This way custom groups will overwrite external ones if (PQSList.ContainsKey(mod)) { PQSList.Remove(mod); } if (!exclude) { PQSList.Add(mod, center); Debug.Log("PQSCityGroups.SaveGroups", " > PQSCity: " + mod.name); } else { ExcludeList.Add(mod); Debug.Log("PQSCityGroups.SaveGroups", " > Excluded PQSCity: " + mod.name); } } } foreach (string city2 in M.GetValues("PQSCity2")) { PQSCity2 mod = body.GetComponentsInChildren <PQSCity2>(true).FirstOrDefault(m => m.name == city2); if (mod != null) { // If the mod has already been added overwrite it // This way custom groups will overwrite external ones if (PQSList.ContainsKey(mod)) { PQSList.Remove(mod); } if (!exclude) { PQSList.Add(mod, center); Debug.Log("PQSCityGroups.SaveGroups", " > PQSCity2: " + mod.name); } else { ExcludeList.Add(mod); Debug.Log("PQSCityGroups.SaveGroups", " > Excluded PQSCity2: " + mod.name); } } } } // ADD EXTERNAL MODS TO THIS GROUP if ( ExternalGroups?.ContainsKey(body) == true && ExternalGroups[body].ContainsKey(group) && ExternalGroups[body][group].Where(m => m != null)?.Count() > 0 ) { foreach (object mod in ExternalGroups[body][group].Where(m => m != null)) { // External groups should not overwrite custom ones if (PQSList.ContainsKey(mod)) { continue; } if (!exclude) { PQSList.Add(mod, center); Debug.Log("PQSCityGroups.SaveGroups", " > external: " + mod); } else { ExcludeList.Add(mod); Debug.Log("PQSCityGroups.SaveGroups", " > Excluded external: " + mod); } } ExternalGroups[body].Remove(group); } // REMOVE KSC FROM THE LIST PQSCity ksc = FlightGlobals.GetHomeBody().GetComponentsInChildren <PQSCity>(true).FirstOrDefault(m => m.name == "KSC"); if (PQSList.ContainsKey(ksc)) { PQSList.Remove(ksc); } if (ExcludeList.Contains(ksc)) { ExcludeList.Remove(ksc); } body.Set("PQSCityGroups", PQSList); body.Set("ExcludedPQSCityMods", ExcludeList); // ADD THIS GROUP TO THE MOVE LIST if (Group.HasNode("MOVE")) { ConfigNode C2 = Group.GetNode("MOVE"); Vector3? newCenter = GetCenter(C2, body); if (newCenter == null) { newCenter = center; } Debug.Log("PQSCityGroups.SaveGroups", "Move Group to position = " + newCenter.Value + ", (LAT: " + new SigmaDimensions.LatLon(newCenter.Value).lat + ", LON: " + new SigmaDimensions.LatLon(newCenter.Value).lon + ")"); var info = new KeyValuePair <Vector3, NumericParser <double>[]>((Vector3)newCenter, new[] { 0, 0, new NumericParser <double>() }); if (C2.HasValue("Rotate")) { info.Value[0].SetFromString(C2.GetValue("Rotate")); } Debug.Log("PQSCityGroups.SaveGroups", "Rotate group = " + info.Value[0].Value); if (C2.HasValue("fixAltitude")) { info.Value[1].SetFromString(C2.GetValue("fixAltitude")); } Debug.Log("PQSCityGroups.SaveGroups", "Fix group altitude = " + info.Value[1].Value); if (C2.HasValue("originalAltitude")) { info.Value[2].SetFromString(C2.GetValue("originalAltitude")); } else { info.Value[2].SetFromString("-Infinity"); } Debug.Log("PQSCityGroups.SaveGroups", "Original group altitude = " + (info.Value[2].Value == double.NegativeInfinity ? "[Not Specified]" : info.Value[2].Value.ToString())); if (!body.Has("PQSCityGroupsMove")) { body.Set("PQSCityGroupsMove", new Dictionary <Vector3, KeyValuePair <Vector3, NumericParser <double>[]> >()); } var MoveList = body.Get <Dictionary <Vector3, KeyValuePair <Vector3, NumericParser <double>[]> > >("PQSCityGroupsMove"); if (!MoveList.ContainsKey(center.Value)) { MoveList.Add(center.Value, info); } body.Set("PQSCityGroupsMove", MoveList); } } // Make sure External Groups are valid if (ExternalGroups == null) { ExternalGroups = new Dictionary <CelestialBody, Dictionary <string, List <object> > >(); } // LOAD REMAINING EXTERNAL GROUPS Debug.Log("PQSCityGroups.SaveGroups", ">>> Loading external PQSCityGroups <<<"); foreach (CelestialBody planet in ExternalGroups.Keys.Where(p => p != null && ExternalGroups[p] != null)) { Debug.Log("PQSCityGroups.SaveGroups", "> Planet: " + planet.name + (planet.name != planet.displayName.Replace("^N", "") ? (", (A.K.A.: " + planet.displayName.Replace("^N", "") + ")") : "") + (planet.name != planet.transform.name ? (", (A.K.A.: " + planet.transform.name + ")") : "")); foreach (string group in ExternalGroups[planet].Keys.Where(g => !string.IsNullOrEmpty(g) && ExternalGroups[planet][g] != null)) { if (ExternalGroups[planet][group].Count == 0) { continue; } Debug.Log("PQSCityGroups.SaveGroups", " > Group: " + group); // Since these groups are new they don't have a center // Define the center as the position of the first mod in the array Vector3?center = null; center = GetPosition(ExternalGroups[planet][group].FirstOrDefault()); if (center == null) { continue; } Debug.Log("PQSCityGroups.SaveGroups", " > Center position = " + center + ", (LAT: " + new SigmaDimensions.LatLon((Vector3)center).lat + ", LON: " + new SigmaDimensions.LatLon((Vector3)center).lon + ")"); if (!planet.Has("PQSCityGroups")) { planet.Set("PQSCityGroups", new Dictionary <object, Vector3>()); } Dictionary <object, Vector3> PQSList = planet.Get <Dictionary <object, Vector3> >("PQSCityGroups"); foreach (object mod in ExternalGroups[planet][group]) { if (!PQSList.ContainsKey(mod)) { PQSList.Add(mod, (Vector3)center); Debug.Log("PQSCityGroups.SaveGroups", " > external: " + mod); } } // REMOVE KSC FROM THE LIST PQSCity ksc = FlightGlobals.GetHomeBody().GetComponentsInChildren <PQSCity>(true).FirstOrDefault(m => m.name == "KSC"); if (PQSList.ContainsKey(ksc)) { PQSList.Remove(ksc); } planet.Set("PQSCityGroups", PQSList); } } // LOAD EXTERNAL EXCEPTIONS Debug.Log("PQSCityGroups.SaveGroups", ">>> Loading external PQSCityGroups exceptions <<<"); foreach (CelestialBody planet in ExternalExceptions.Keys.Where(p => p != null && ExternalExceptions[p] != null)) { Debug.Log("PQSCityGroups.SaveGroups", "> Planet: " + planet.name + (planet.name != planet.displayName.Replace("^N", "") ? (", (A.K.A.: " + planet.displayName.Replace("^N", "") + ")") : "") + (planet.name != planet.transform.name ? (", (A.K.A.: " + planet.transform.name + ")") : "")); foreach (string group in ExternalExceptions[planet].Keys.Where(g => !string.IsNullOrEmpty(g) && ExternalExceptions[planet][g] != null)) { if (ExternalExceptions[planet][group].Count == 0) { continue; } Debug.Log("PQSCityGroups.SaveGroups", " > Group: " + group); // Since these groups are exceptions they don't need a center if (!planet.Has("ExcludedPQSCityMods")) { planet.Set("ExcludedPQSCityMods", new Dictionary <object, Vector3>()); } List <object> ExcludeList = planet.Get <List <object> >("PQSCityGroups"); foreach (object mod in ExternalExceptions[planet][group]) { if (!ExcludeList.Contains(mod)) { ExcludeList.Add(mod); Debug.Log("PQSCityGroups.SaveGroups", " > excluded external: " + mod); } } // REMOVE KSC FROM THE LIST PQSCity ksc = FlightGlobals.GetHomeBody().GetComponentsInChildren <PQSCity>(true).FirstOrDefault(m => m.name == "KSC"); if (ExcludeList.Contains(ksc)) { ExcludeList.Remove(ksc); } planet.Set("ExcludedPQSCityMods", ExcludeList); } } }
/// <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")); } }); } }
void Update() { if (time < 0.2) { time += Time.deltaTime; } else { time = 0; CelestialBody body = FlightGlobals.currentMainBody; if (body == null) { return; } PQS pqs = body.pqsController; if (pqs == null) { return; } PQSCity city = GetComponent <PQSCity>(); if (city == null) { return; } // Location Vector3 planet = body.transform.position; Vector3 building = city.transform.position; // From body to city Vector3 location = (building - planet).normalized; // Sigma Dimensions Settings double resize = body.Has("resize") ? body.Get <double>("resize") : 1; double landscape = body.Has("landscape") ? body.Get <double>("landscape") : 1; double resizeBuildings = body.Has("resizeBuildings") ? body.Get <double>("resizeBuildings") : 1; // Max distance double maxDistance = Math.Abs(2 * pqs.mapMaxHeight); maxDistance *= resize * landscape > 1 ? resize * landscape : 1; maxDistance += body.Radius; RaycastHit[] hits = Physics.RaycastAll(planet + location * (float)maxDistance, -location, (float)maxDistance, LayerMask.GetMask("Local Scenery")); for (int i = 0; i < hits?.Length; i++) { if (hits[i].collider?.GetComponent <PQ>()) { Debug.Log("PQSCityFixer", "> Planet: " + body.transform.name); Debug.Log("PQSCityFixer", " > PQSCity: " + city); // PQSCity parameters double oldGroundLevel = pqs.GetSurfaceHeight(city.repositionRadial) - body.Radius; Debug.Log("PQSCityFixer", " > Old Ground Level at Mod (GETSURFACE) = " + oldGroundLevel); double oldOceanOffset = body.ocean && oldGroundLevel < 0 ? oldGroundLevel : 0d; Debug.Log("PQSCityFixer", " > Old Ocean Offset at Mod = " + oldOceanOffset); oldGroundLevel = body.ocean && oldGroundLevel < 0 ? 0d : oldGroundLevel; Debug.Log("PQSCityFixer", " > Old Ground Level at Mod (WITH OCEAN) = " + oldGroundLevel); double groundLevel = (hits[i].point - planet).magnitude - body.Radius; Debug.Log("PQSCityFixer", " > Ground Level at Mod (RAYCAST) = " + groundLevel); double oceanOffset = body.ocean && groundLevel < 0 ? groundLevel : 0d; Debug.Log("PQSCityFixer", " > Ocean Offset at Mod = " + oceanOffset); groundLevel = body.ocean && groundLevel < 0 ? 0d : groundLevel; Debug.Log("PQSCityFixer", " > Ground Level at Mod (WITH OCEAN) = " + groundLevel); // Fix Altitude if (!city.repositionToSphere && !city.repositionToSphereSurface) { // Offset = Distance from the center of the planet // THIS IS NOT POSSIBLE AS OF KSP 1.7.1 Debug.Log("PQSCityFixer", " > PQSCity Current Center Offset = " + city.repositionRadiusOffset); double builtInOffset = (city.repositionRadiusOffset - body.Radius - oldGroundLevel - oceanOffset) / resizeBuildings - (groundLevel + oceanOffset - oldGroundLevel - oldOceanOffset) / (resize * landscape); Debug.Log("PQSCityFixer", " > Builtin Offset = " + builtInOffset); city.repositionRadiusOffset = body.Radius + groundLevel + oceanOffset + builtInOffset * resizeBuildings; Debug.Log("PQSCityFixer", " > PQSCity Fixed Center Offset = " + city.repositionRadiusOffset); } else if (city.repositionToSphere && !city.repositionToSphereSurface) { // Offset = Distance from the radius of the planet Debug.Log("PQSCityFixer", " > PQSCity Current Radius Offset = " + city.repositionRadiusOffset); double builtInOffset = (city.repositionRadiusOffset - oldGroundLevel) / resizeBuildings - (groundLevel - oldGroundLevel) / (resize * landscape); Debug.Log("PQSCityFixer", " > Builtin Offset = " + builtInOffset); city.repositionRadiusOffset = groundLevel + builtInOffset * resizeBuildings; Debug.Log("PQSCityFixer", " > PQSCity Fixed Radius Offset = " + city.repositionRadiusOffset); } else { // Offset = Distance from the surface of the planet Debug.Log("PQSCityFixer", " > PQSCity Current Surface Offset = " + city.repositionRadiusOffset); double builtInOffset = city.repositionRadiusOffset / resizeBuildings - (groundLevel + oceanOffset - oldGroundLevel - oldOceanOffset) / (resize * landscape); Debug.Log("PQSCityFixer", " > Builtin Offset = " + builtInOffset); city.repositionRadiusOffset = builtInOffset * resizeBuildings + groundLevel + oceanOffset - oldGroundLevel - oldOceanOffset; Debug.Log("PQSCityFixer", " > PQSCity Fixed Surface Offset = " + city.repositionRadiusOffset); } // Apply Changes and Destroy city.Orientate(); DestroyImmediate(this); } } } }
// Stuff void LateUpdate() { FixZooming(); ApplyOrbitVisibility(); RDFixer(); ApplyOrbitIconCustomization(); // Prevent the orbit lines from flickering PlanetariumCamera.Camera.farClipPlane = 1e14f; // Remove buttons in map view for barycenters if (MapView.MapIsEnabled) { if (fields == null) { FieldInfo mode_f = typeof(OrbitTargeter).GetFields(BindingFlags.NonPublic | BindingFlags.Instance).FirstOrDefault(f => f.FieldType.IsEnum && f.FieldType.IsNested); FieldInfo context_f = typeof(OrbitTargeter).GetFields(BindingFlags.NonPublic | BindingFlags.Instance).FirstOrDefault(f => f.FieldType == typeof(MapContextMenu)); #if !KSP131 FieldInfo cast_f = typeof(OrbitTargeter).GetFields(BindingFlags.NonPublic | BindingFlags.Instance).FirstOrDefault(f => f.FieldType == typeof(OrbitRendererBase.OrbitCastHit)); #else FieldInfo cast_f = typeof(OrbitTargeter).GetFields(BindingFlags.NonPublic | BindingFlags.Instance).FirstOrDefault(f => f.FieldType == typeof(OrbitRenderer.OrbitCastHit)); #endif fields = new FieldInfo[] { mode_f, context_f, cast_f }; } if (FlightGlobals.ActiveVessel != null) { OrbitTargeter targeter = FlightGlobals.ActiveVessel.orbitTargeter; if (targeter == null) { return; } Int32 mode = (Int32)fields[0].GetValue(targeter); if (mode == 2) { #if !KSP131 OrbitRendererBase.OrbitCastHit cast = (OrbitRendererBase.OrbitCastHit)fields[2].GetValue(targeter); #else OrbitRenderer.OrbitCastHit cast = (OrbitRenderer.OrbitCastHit)fields[2].GetValue(targeter); #endif CelestialBody body = PSystemManager.Instance.localBodies.Find(b => b.name == cast.or?.discoveryInfo?.name?.Value); if (body == null) { return; } if (body.Has("barycenter") || !body.Get("selectable", true)) { if (cast.driver?.Targetable == null) { return; } MapContextMenu context = MapContextMenu.Create(body.name, new Rect(0.5f, 0.5f, 300f, 50f), cast, () => { fields[0].SetValue(targeter, 0); fields[1].SetValue(targeter, null); }, new SetAsTarget(cast.driver.Targetable, () => FlightGlobals.fetch.VesselTarget)); fields[1].SetValue(targeter, context); } } } } foreach (CelestialBody body in PSystemManager.Instance.localBodies) { if (body.afg == null) { continue; } GameObject star_ = KopernicusStar.GetNearest(body).gameObject; Vector3 planet2cam = body.scaledBody.transform.position - body.afg.mainCamera.transform.position; body.afg.lightDot = Mathf.Clamp01(Vector3.Dot(planet2cam, body.afg.mainCamera.transform.position - star_.transform.position) * body.afg.dawnFactor); body.afg.GetComponent <Renderer>().sharedMaterial.SetFloat("_lightDot", body.afg.lightDot); } // Update the names of the presets in the settings dialog if (HighLogic.LoadedScene == GameScenes.SETTINGS) { foreach (SettingsTerrainDetail detail in Resources.FindObjectsOfTypeAll <SettingsTerrainDetail>()) { detail.displayStringValue = true; detail.stringValues = _details ?? (_details = Templates.PresetDisplayNames.ToArray()); } } }