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 void Start() { //Setup line renderers lrForVector = orbitingBody.GetComponentsInChildren <LineRenderer>()[0]; lrForVector.material = matForwardVector; lrForVector.positionCount = 2; lrForVector.startWidth = 0.3f; lrForVector.endWidth = 0.3f; lrNorVector = orbitingBody.GetComponentsInChildren <LineRenderer>()[1]; lrNorVector.material = matNormalVector; lrNorVector.positionCount = 2; lrNorVector.startWidth = 0.3f; lrNorVector.endWidth = 0.3f; }
internal static void SetTerrainRescales() { CelestialBody homeWorld = ConfigUtil.GetCelestialBody("HomeWorld"); if (homeWorld.bodyName == "Kerbin") { planetRescale = Math.Round(homeWorld.pqsController.radius, 0) / 600000; foreach (var pqs in homeWorld.GetComponentsInChildren <PQSCity>(true)) { if (pqs.SurfaceObjectName == "KSC") { var myheight = Math.Round(homeWorld.pqsController.GetSurfaceHeight(pqs.repositionRadial) - homeWorld.pqsController.radius, 1); Log.Normal("Found KSC at: " + Math.Round(myheight, 1) + "m above sealevel"); Log.Normal("body radius: " + Math.Round(homeWorld.pqsController.radius, 1) + "m"); terrainRescale = myheight / 64.8d; } } globalTerrainRescale = planetRescale * terrainRescale; } else { Log.Warning("our homeworld is " + homeWorld.name + ", nothing to do"); } }
private static Location KSCLocation() { CelestialBody home = FlightGlobals.Bodies.Where(cb => cb.isHomeWorld).First(); PQSCity ksc = home.GetComponentsInChildren <PQSCity>(true).Where(pqs => pqs.name == "KSC").First(); return(new Location(home, home.GetLatitude(ksc.transform.position), home.GetLongitude(ksc.transform.position))); }
private PQS GetOcean() { if (_ocean == null || mainBody != part.vessel.mainBody) { mainBody = part.vessel.mainBody; _ocean = mainBody.GetComponentsInChildren<PQS>(true).FirstOrDefault(p => p.name == mainBody.transform.name + "Ocean"); } return _ocean; }
private PQS GetOcean() { if (_ocean == null || mainBody != part.vessel.mainBody) { mainBody = part.vessel.mainBody; _ocean = mainBody.GetComponentsInChildren <PQS>(true).FirstOrDefault(p => p.name == mainBody.transform.name + "Ocean"); } return(_ocean); }
private static void LocationModeGUI() { int TOP_HEADER_WIDTH = 96; int TOP_EDIT_WIDTH = 160; int CITY_WIDTH = 124; int HEADING_WIDTH = 400; Vessel v = FlightGlobals.ActiveVessel; CelestialBody body = v.mainBody; GUILayout.BeginHorizontal(); GUILayout.Label("Latitude", headerLabel, GUILayout.Width(TOP_HEADER_WIDTH)); GUILayout.TextField(v.latitude.ToString(), GUILayout.Width(TOP_EDIT_WIDTH)); GUILayout.Label("Longitude", headerLabel, GUILayout.Width(TOP_HEADER_WIDTH)); GUILayout.TextField(v.longitude.ToString(), GUILayout.Width(TOP_EDIT_WIDTH)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Height", headerLabel, GUILayout.Width(TOP_HEADER_WIDTH)); double height = v.altitude - LocationUtil.TerrainHeight(v.latitude, v.longitude, body); GUILayout.TextField(height.ToString(), GUILayout.Width(TOP_EDIT_WIDTH)); GUILayout.Label("Altitude", headerLabel, GUILayout.Width(TOP_HEADER_WIDTH)); GUILayout.TextField(v.altitude.ToString(), GUILayout.Width(TOP_EDIT_WIDTH)); GUILayout.EndHorizontal(); GUILayout.Space(8); GUILayout.BeginHorizontal(); GUILayout.Label("PQS City", headerLabel, GUILayout.Width(CITY_WIDTH)); GUILayout.Label("PQS Offset", headerLabel, GUILayout.Width(HEADING_WIDTH)); GUILayout.EndHorizontal(); scrollPosition2 = GUILayout.BeginScrollView(scrollPosition2, GUILayout.Width(550), GUILayout.ExpandHeight(true)); foreach (PQSCity city in body.GetComponentsInChildren <PQSCity>(true)) { // Translate to a position in the PQSCity's coordinate system Vector3d vPos = FlightGlobals.ActiveVessel.transform.position - city.transform.position; Vector3d pos = new Vector3d(Vector3d.Dot(vPos, city.transform.right), Vector3d.Dot(vPos, city.transform.forward), Vector3d.Dot(vPos, city.transform.up)); GUILayout.BeginHorizontal(); GUILayout.Label(new GUIContent(city.name, city.name), clippedLabel, GUILayout.Width(CITY_WIDTH)); GUILayout.TextField(pos.x.ToString() + ", " + pos.y.ToString() + ", " + pos.z.ToString(), GUILayout.Width(HEADING_WIDTH)); GUILayout.EndHorizontal(); } GUILayout.EndScrollView(); if (Event.current.type == EventType.Repaint) { tooltip = GUI.tooltip; } }
private PQS GetOcean() { if (_ocean != null && _mainBody == Part.vessel.mainBody) { return(_ocean); } _mainBody = Part.vessel.mainBody; _ocean = _mainBody.GetComponentsInChildren <PQS>(true) .FirstOrDefault(p => p.name == _mainBody.transform.name + "Ocean"); return(_ocean); }
/// <summary> /// Uses the PQS System to query the color of the undergound /// </summary> /// <param name="body"></param> /// <param name="lat"></param> /// <param name="lon"></param> /// <returns></returns> public static Color GetSurfaceColorPQS(CelestialBody body, Double lat, Double lon) { // Tell the PQS that our actions are not supposed to end up in the terrain body.pqsController.isBuildingMaps = true; body.pqsController.isFakeBuild = true; // Create the vertex information PQS.VertexBuildData data = new PQS.VertexBuildData { directionFromCenter = body.GetRelSurfaceNVector(lat, lon).normalized, //vertHeight = body.pqsController.radius vertHeight = body.pqsController.GetSurfaceHeight(body.GetRelSurfaceNVector(lat, lon).normalized *body.Radius) }; // Fetch all enabled Mods //PQSMod[] mods = body.GetComponentsInChildren<PQSMod>(true).Where(m => m.modEnabled && m.sphere == body.pqsController).ToArray(); List <PQSMod> modsList = body.GetComponentsInChildren <PQSMod>(true).Where(m => m.modEnabled && m.sphere == body.pqsController).ToList(); modsList.Sort(delegate(PQSMod first, PQSMod second) { return(first.order.CompareTo(second.order)); }); PQSMod[] mods = modsList.ToArray(); // Iterate over them and build the height at this point // This is neccessary for mods that use the terrain height to // color the terrain (like HeightColorMap) foreach (PQSMod mod in mods) { mod.OnVertexBuildHeight(data); } // Iterate over the mods again, this time build the color component foreach (PQSMod mod in mods) { mod.OnVertexBuild(data); } // Reset the PQS body.pqsController.isBuildingMaps = false; body.pqsController.isFakeBuild = false; Color vertColor = data.vertColor; vertColor += new Color(0.01f, 0.01f, 0.02f); vertColor.a = 1; // The terrain color is now stored in data.vertColor. // For getting the height at this point you can use data.vertHeight return(vertColor); }
Vector3?GetCenter(ConfigNode node, CelestialBody body) { if (node.HasValue("CentralPQSCity")) { return(body.GetComponentsInChildren <PQSCity>(true).FirstOrDefault(p => p.name == node.GetValue("CentralPQSCity")).repositionRadial); } else if (node.HasValue("CentralPQSCity2")) { return(body.GetComponentsInChildren <PQSCity2>(true).First(p => p.name == node.GetValue("CentralPQSCity2")).PlanetRelativePosition); } else if (node.HasValue("CentralPosition")) { Vector3Parser v = new Vector3Parser(); v.SetFromString(node.GetValue("CentralPosition")); return(v); } else if (node.HasValue("CentralLAT") && node.HasValue("CentralLON")) { NumericParser <double> LAT = new NumericParser <double>(); NumericParser <double> LON = new NumericParser <double>(); LAT.SetFromString(node.GetValue("CentralLAT")); LON.SetFromString(node.GetValue("CentralLON")); return(Utility.LLAtoECEF(LAT, LON, 1, 1)); } else if (node.HasValue("PQSCity")) { return(body.GetComponentsInChildren <PQSCity>(true).FirstOrDefault(p => p.name == node.GetValue("PQSCity")).repositionRadial); } else if (node.HasValue("PQSCity2")) { return(body.GetComponentsInChildren <PQSCity2>(true).First(p => p.name == node.GetValue("PQSCity2")).PlanetRelativePosition); } else { return(null); } }
protected override void OnLoad(ConfigNode configNode) { base.OnLoad(configNode); foreach (ConfigNode child in configNode.GetNodes("WAYPOINT")) { // Read all the waypoint data WaypointData wpData = new WaypointData(); wpData.type = child.GetValue("type"); wpData.parameter = ConfigNodeUtil.ParseValue <List <string> >(child, "parameter", new List <string>()); wpData.names = ConfigNodeUtil.ParseValue <List <string> >(child, "names", new List <string>()); wpData.waypoint.celestialName = child.GetValue("celestialName"); wpData.waypoint.name = child.GetValue("name"); wpData.waypoint.id = child.GetValue("icon"); wpData.waypoint.latitude = Convert.ToDouble(child.GetValue("latitude")); wpData.waypoint.longitude = Convert.ToDouble(child.GetValue("longitude")); wpData.waypoint.altitude = Convert.ToDouble(child.GetValue("altitude")); wpData.waypoint.index = Convert.ToInt32(child.GetValue("index")); wpData.waypoint.visible = !(ConfigNodeUtil.ParseValue <bool?>(child, "hidden", (bool?)false).Value); wpData.waypoint.isClustered = ConfigNodeUtil.ParseValue <bool?>(child, "clustered", (bool?)false).Value; string pqsCityName = ConfigNodeUtil.ParseValue <string>(child, "pqsCity", null); if (pqsCityName != null) { CelestialBody body = FlightGlobals.Bodies.Where(b => b.name == wpData.waypoint.celestialName).First(); wpData.pqsCity = body.GetComponentsInChildren <PQSCity>(true).Where(pqs => pqs.name == pqsCityName).First(); wpData.pqsOffset = ConfigNodeUtil.ParseValue <Vector3d>(child, "pqsOffset"); } wpData.randomAltitude = ConfigNodeUtil.ParseValue <bool?>(child, "randomAltitude", (bool?)false).Value; wpData.underwater = ConfigNodeUtil.ParseValue <bool?>(child, "underwater", (bool?)false).Value; // Set contract data wpData.SetContract(contract); // Create additional waypoint details string paramID = wpData.parameter.FirstOrDefault(); if (wpData.waypoint.visible && (!wpData.parameter.Any() || contract.AllParameters. Where(p => p.ID == paramID && p.State == ParameterState.Complete).Any())) { AddWayPoint(wpData); } // Add to the global list waypoints.Add(wpData); } }
// Patch various references to point to the nearest star private static void PatchStarReferences(CelestialBody body) { GameObject star = KopernicusStar.GetNearest(body).gameObject; if (body.afg != null) { body.afg.sunLight = star; } if (body.scaledBody.GetComponent <MaterialSetDirection>() != null) { body.scaledBody.GetComponent <MaterialSetDirection>().target = star.transform; } foreach (PQSMod_MaterialSetDirection msd in body.GetComponentsInChildren <PQSMod_MaterialSetDirection>(true)) { msd.target = star.transform; } }
public SCANanomaly[] getAnomalies() { if (anomalies == null) { PQSCity[] sites = body.GetComponentsInChildren <PQSCity>(true); anomalies = new SCANanomaly[sites.Length]; for (int i = 0; i < sites.Length; ++i) { anomalies[i] = new SCANanomaly(sites[i].name, body.GetLongitude(sites[i].transform.position), body.GetLatitude(sites[i].transform.position), sites[i]); } } for (int i = 0; i < anomalies.Length; ++i) { anomalies[i].known = isCovered(anomalies[i].longitude, anomalies[i].latitude, SCANtype.Anomaly); anomalies[i].detail = isCovered(anomalies[i].longitude, anomalies[i].latitude, SCANtype.AnomalyDetail); } return(anomalies); }
public override bool Load(ConfigNode configNode) { // Before loading, verify the SCANsat version if (!SCANsatUtil.VerifySCANsatVersion()) { return(false); } // Load base class bool valid = base.Load(configNode); // Do not check the requirement on active contracts. Otherwise when they scan the // contract is invalidated, which is usually not what's meant. checkOnActiveContract = false; valid &= ConfigNodeUtil.ParseValue <string>(configNode, "scanType", x => scanType = x, this, "Anomaly", SCANsatUtil.ValidateSCANname); valid &= ConfigNodeUtil.ParseValue <double>(configNode, "latitude", x => latitude = x, this, 0.0); valid &= ConfigNodeUtil.ParseValue <double>(configNode, "longitude", x => longitude = x, this, 0.0); valid &= ConfigNodeUtil.MutuallyExclusive(configNode, new string[] { "latitude", "longitude" }, new string[] { "pqsCity" }, this); valid &= ValidateTargetBody(configNode); string pqsName = null; valid &= ConfigNodeUtil.ParseValue <string>(configNode, "pqsCity", x => pqsName = x, this, (string)null); if (pqsName != null) { try { CelestialBody body = FlightGlobals.Bodies.Where(b => b == targetBody).First(); pqsCity = body.GetComponentsInChildren <PQSCity>(true).Where(pqs => pqs.name == pqsName).First(); } catch (Exception e) { LoggingUtil.LogError(this, "Couldn't load PQSCity with name '" + pqsCity + "'"); LoggingUtil.LogException(e); valid = false; } } return(valid); }
void ActivateAndReleaseBody() { if (_capturedBody) { _capturedBody.HideOrbit(); if (Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl)) { _capturedBody.Attractor = null; _capturedBody.Velocity = Vector2.zero; } _capturedBody.enabled = true; _capturedBody.IsDrawOrbit = ShowOrbits; var coll = _capturedBody.GetComponentsInChildren <Collider2D>(); foreach (var c in coll) { c.enabled = true; } _capturedBody = null; } }
/// <summary> /// Changes the parameters of the body /// </summary> public override Boolean Tweak(CelestialBody body) { // Is the body a GasPlanet or a Star? if (!body.hasSolidSurface || body.scaledBody.GetComponentsInChildren <SunShaderController>().Length != 0) { return(false); } // Is the body our homeworld? if (body.isHomeWorld) { return(false); } // Does the body have an ocean? This could end badly if (body.ocean) { return(false); } // Process previous states if (toRestore.Contains(body)) { // Enable the Atmosphere from Ground AtmosphereFromGround[] afgs = body.GetComponentsInChildren <AtmosphereFromGround>(); foreach (AtmosphereFromGround afg in afgs) { afg.gameObject.SetActive(true); } // Enable the Light controller MaterialSetDirection[] msds = body.GetComponentsInChildren <MaterialSetDirection>(); foreach (MaterialSetDirection msd in msds) { msd.gameObject.SetActive(true); } // Atmosphere \o/ body.atmosphere = true; // Restore the old material GameObject backupGameObject = body.scaledBody.GetChild("Backup"); backupGameObject.SetActive(false); body.scaledBody.GetComponent <Renderer>().sharedMaterial = backupGameObject.GetComponent <MeshRenderer>().material; UnityEngine.Object.Destroy(backupGameObject); // Update state toRestore.Remove(body); } else if (toDelete.Contains(body)) { // Remove the Atmosphere from Ground AtmosphereFromGround[] afgs = body.GetComponentsInChildren <AtmosphereFromGround>(); foreach (AtmosphereFromGround afg in afgs) { UnityEngine.Object.Destroy(afg.gameObject); } // Disable the Light controller MaterialSetDirection[] msds = body.GetComponentsInChildren <MaterialSetDirection>(); foreach (MaterialSetDirection msd in msds) { UnityEngine.Object.Destroy(msd.gameObject); } // No Atmosphere :( body.atmosphere = false; // Restore the old material GameObject backupGameObject = body.scaledBody.GetChild("Backup"); backupGameObject.SetActive(false); body.scaledBody.GetComponent <Renderer>().sharedMaterial = backupGameObject.GetComponent <MeshRenderer>().material; UnityEngine.Object.Destroy(backupGameObject); // Update state toDelete.Remove(body); } // For all other bodies, there is a small chance (5%) that their existing // atmosphere is toggled, or a new one gets added if (GetRandom(HighLogic.CurrentGame.Seed, 0, 100) < 5) { //Report::Report.fetch.SetPrefix("PlanetaryBody: " + body.bodyDisplayName); //Report::Report.fetch.ReportLine("Atmosphere toggled"); ToggleAtmosphere(body); //Report::Report.fetch.ReportSection(); return(true); } //Report::Report.fetch.ReportSection(); // Did we tweak something? return(false); }
/// <summary> /// Gets called when the users switches from one game scene to another one. /// </summary> void OnGameSceneSwitchRequested(GameEvents.FromToAction <GameScenes, GameScenes> action) { // Are we loading a game? if (action.from == GameScenes.MAINMENU && action.to == GameScenes.SPACECENTER) { // Get a sorted list of bodies List <CelestialBody> bodies = Utility.GetSortedBodies(); // Tweak it! for (Int32 j = 0; j < bodies.Count; j++) { // Get the Body CelestialBody body = bodies[j]; // Is this body blacklisted? if (bodyBlacklist != null) { if (bodyBlacklist.GetValues("blacklist").Any(b => body.bodyName == b)) { continue; } } // Was the body edited? Boolean edited = false; // Tweak the PQS itself for (Int32 i = 0; i < PQSTweakers.Count; i++) { // Tweaker IPQSTweaker tweaker = PQSTweakers[i]; // Check the config ConfigNode config = ConfigCache[tweaker.GetConfig()]; // Is the tweak group enabled? if (!config.HasValue("enabled")) { continue; } if (!Boolean.TryParse(config.GetValue("enabled"), out Boolean isEnabled) || !isEnabled) { continue; } // Is the tweak itself enabled? String setting = tweaker.GetSetting(); if (setting != null) { if (!config.HasValue(setting)) { continue; } if (!Boolean.TryParse(config.GetValue(setting), out isEnabled) || !isEnabled) { continue; } } // Tweak it if (tweaker.Tweak(body, body.pqsController)) { edited = true; } } // Get the PQSMods PQSMod[] mods = body.GetComponentsInChildren <PQSMod>(true); for (Int32 i = 0; i < PQSModTweakers.Count; i++) { // Tweaker IPQSModTweaker tweaker = PQSModTweakers[i]; // Check the config ConfigNode config = ConfigCache[tweaker.GetConfig()]; // Is the tweak group enabled? if (!config.HasValue("enabled")) { continue; } if (!Boolean.TryParse(config.GetValue("enabled"), out Boolean isEnabled) || !isEnabled) { continue; } // Is the tweak itself enabled? String setting = tweaker.GetSetting(); if (setting != null) { if (!config.HasValue(setting)) { continue; } if (!Boolean.TryParse(config.GetValue(setting), out isEnabled) || !isEnabled) { continue; } } // Tweak them foreach (PQSMod mod in mods) { if (tweaker.Tweak(body, mod)) { edited = true; mod.OnSetup(); } } } // The body was edited, we should update it's scaled space if (edited && scaledSpaceUpdate.All(b => b.name != body.name)) { scaledSpaceUpdate.Add(body); } } // Tweak Celestial Bodies for (Int32 i = 0; i < CBTweakers.Count; i++) { // Tweaker ICelestialBodyTweaker tweaker = CBTweakers[i]; // Check the config ConfigNode config = ConfigCache[tweaker.GetConfig()]; // Is the tweak group enabled? if (!config.HasValue("enabled")) { continue; } if (!Boolean.TryParse(config.GetValue("enabled"), out Boolean isEnabled) || !isEnabled) { continue; } // Is the tweak itself enabled? String setting = tweaker.GetSetting(); if (setting != null) { if (!config.HasValue(setting)) { continue; } if (!Boolean.TryParse(config.GetValue(setting), out isEnabled) || !isEnabled) { continue; } } // Tweak it! for (Int32 j = 0; j < bodies.Count; j++) { // Get the Body CelestialBody body = bodies[j]; // Tweak it tweaker.Tweak(body); } } } // Are we leaving the game? if (action.to == GameScenes.MAINMENU) { if (PSystemManager.Instance?.localBodies == null) { return; } // Reset the random RandomProvider.Reset(); // Kill the PQS so it definitly rebuilds when we load a game for (Int32 i = 0; i < PSystemManager.Instance.localBodies.Count; i++) { CelestialBody body = PSystemManager.Instance.localBodies[i]; body.pqsController?.ResetSphere(); } } }
/// <summary> /// Disables an existing atmosphere, or adds a new one if there is none /// </summary> private void ToggleAtmosphere(CelestialBody body) { // Disable an existing atmosphere if (body.atmosphere) { // Disable the Atmosphere from Ground AtmosphereFromGround[] afgs = body.GetComponentsInChildren <AtmosphereFromGround>(); foreach (AtmosphereFromGround afg in afgs) { afg.gameObject.SetActive(false); } // Disable the Light controller MaterialSetDirection[] msds = body.GetComponentsInChildren <MaterialSetDirection>(); foreach (MaterialSetDirection msd in msds) { msd.gameObject.SetActive(false); } // No Atmosphere :( body.atmosphere = false; // Get the material Renderer renderer = body.scaledBody.GetComponent <Renderer>(); Material material = renderer.sharedMaterial; Texture2D diffuseMap = (Texture2D)material.GetTexture("_MainTex"); Texture2D bumpMap = (Texture2D)material.GetTexture("_BumpMap"); // Create a new scaled material Material newMaterial = new Material(Shader.Find("Terrain/Scaled Planet (Simple)")); newMaterial.SetTexture("_MainTex", diffuseMap); newMaterial.SetTexture("_BumpMap", bumpMap); newMaterial.SetFloat("_Shininess", material.GetFloat("_Shininess")); // TODO: Investigate newMaterial.SetColor("_SpecColor", material.GetColor("_SpecColor")); // TODO: Investigate // Apply the material renderer.sharedMaterial = newMaterial; // Backup the old material GameObject backupGameObject = new GameObject("Backup"); backupGameObject.SetActive(false); backupGameObject.AddComponent <MeshRenderer>().material = material; backupGameObject.transform.parent = body.scaledBody.transform; // Update state toRestore.Add(body); } else { // Add a new atmosphere, this could get funny // We will just copy Laythe for the most parts body.atmosphere = true; body.atmosphereContainsOxygen = GetRandom(HighLogic.CurrentGame.Seed, 0, 99) < 10; // Oxygen is rare body.atmosphereDepth = (body.pqsController.radiusMax / 10) * GetRandomDouble(HighLogic.CurrentGame.Seed, 0.8, 1.2); body.atmosphereAdiabaticIndex = 1.39999997615814 * GetRandomDouble(HighLogic.CurrentGame.Seed, 0.8, 1.2); body.atmosphereGasMassLapseRate = 4.84741125702493 * GetRandomDouble(HighLogic.CurrentGame.Seed, 0.8, 1.2); body.atmosphereMolarMass = 0.0289644002914429 * GetRandomDouble(HighLogic.CurrentGame.Seed, 0.8, 1.2); Double multiplier = GetRandomDouble(HighLogic.CurrentGame.Seed, 0, 1); body.atmospherePressureSeaLevel = (595 * multiplier) + 5; body.atmosphereTemperatureSeaLevel = (270 * multiplier) + 240; body.atmDensityASL = (6.9 * multiplier) + 0.1; body.atmosphereTemperatureLapseRate = GetRandomDouble(HighLogic.CurrentGame.Seed, 0.004, 0.005); body.atmospherePressureCurveIsNormalized = true; body.atmosphereTemperatureCurveIsNormalized = true; body.atmosphereUsePressureCurve = true; body.atmosphereUseTemperatureCurve = true; // Select a curve template KeyValuePair <FloatCurve, FloatCurve> template = GetRandomElement(HighLogic.CurrentGame.Seed, CurveTemplates.Atmospheres); body.atmospherePressureCurve = template.Key; body.atmosphereTemperatureCurve = template.Value; // Now add the visuals GameObject scaledVersion = body.scaledBody; // Add the material light direction behavior MaterialSetDirection materialLightDirection = scaledVersion.AddComponent <MaterialSetDirection>(); materialLightDirection.valueName = "_localLightDirection"; // Create the atmosphere shell game object GameObject scaledAtmosphere = new GameObject("Atmosphere"); scaledAtmosphere.transform.parent = scaledVersion.transform; scaledAtmosphere.transform.position = scaledVersion.transform.position; scaledAtmosphere.transform.localPosition = Vector3.zero; scaledAtmosphere.layer = 9; MeshRenderer mrenderer = scaledAtmosphere.AddComponent <MeshRenderer>(); mrenderer.sharedMaterial = new Material(Shader.Find("AtmosphereFromGround")); MeshFilter meshFilter = scaledAtmosphere.AddComponent <MeshFilter>(); meshFilter.sharedMesh = Templates.ReferenceGeosphere; AtmosphereFromGround atmosphereFromGround = scaledAtmosphere.AddComponent <AtmosphereFromGround>(); // Get the average color of the current texture Renderer renderer = body.scaledBody.GetComponent <Renderer>(); Material material = renderer.sharedMaterial; Texture2D diffuseMap = Utility.CreateReadable((Texture2D)material.GetTexture("_MainTex")); Texture2D bumpMap = (Texture2D)material.GetTexture("_BumpMap"); Color average = Utility.GetAverageColor(diffuseMap); Color altered = AlterColor(average); Color darkAltered = Utility.Dark(altered); body.afg = atmosphereFromGround; atmosphereFromGround.planet = body; atmosphereFromGround.sunLight = Planetarium.fetch.Sun.gameObject; atmosphereFromGround.mainCamera = PlanetariumCamera.fetch.transform; atmosphereFromGround.waveLength = new Color(1 - darkAltered.r, 1 - darkAltered.g, 1 - darkAltered.b, 0.5f); // Ambient Light body.atmosphericAmbientColor = altered; // Scaled Material Material newMaterial = new Material(Shader.Find("Terrain/Scaled Planet (RimAerial)")); newMaterial.SetTexture("_MainTex", diffuseMap); newMaterial.SetTexture("_BumpMap", bumpMap); newMaterial.SetFloat("_Shininess", material.GetFloat("_Shininess")); // TODO: Investigate newMaterial.SetColor("_SpecColor", material.GetColor("_SpecColor")); // TODO: Investigate newMaterial.SetFloat("_rimPower", (Single)GetRandomDouble(HighLogic.CurrentGame.Seed, 3.8, 5)); newMaterial.SetFloat("_rimBlend", 1f); // Generate the atmosphere rim texture Gradient gradient = new Gradient(); gradient.Add(0f, altered); gradient.Add(0.2f, new Color(0.0549f, 0.0784f, 0.141f, 1f)); gradient.Add(1f, new Color(0.0196f, 0.0196f, 0.0196f, 1f)); // Generate the ramp from a gradient Texture2D ramp = new Texture2D(512, 1); Color[] colors = ramp.GetPixels(0); for (Int32 i = 0; i < colors.Length; i++) { // Compute the position in the gradient Single k = (Single)i / colors.Length; colors[i] = gradient.ColorAt(k); } ramp.SetPixels(colors, 0); ramp.Apply(true, false); ramp.wrapMode = TextureWrapMode.Clamp; ramp.mipMapBias = 0.0f; // Set the color ramp newMaterial.SetTexture("_rimColorRamp", ramp); // Apply the material renderer.sharedMaterial = newMaterial; // Backup the old material GameObject backupGameObject = new GameObject("Backup"); backupGameObject.SetActive(false); backupGameObject.AddComponent <MeshRenderer>().material = material; backupGameObject.transform.parent = scaledVersion.transform; // Update state toDelete.Add(body); } }
public static WaypointGenerator Create(ConfigNode configNode, WaypointGeneratorFactory factory) { WaypointGenerator wpGenerator = new WaypointGenerator(); // Waypoint Manager integration EventData <string> onWaypointIconAdded = GameEvents.FindEvent <EventData <string> >("OnWaypointIconAdded"); bool valid = true; int index = 0; foreach (ConfigNode child in ConfigNodeUtil.GetChildNodes(configNode)) { DataNode dataNode = new DataNode("WAYPOINT_" + index, factory.dataNode, factory); try { ConfigNodeUtil.SetCurrentDataNode(dataNode); dataNode["type"] = child.name; double? altitude = null; WaypointData wpData = new WaypointData(child.name); // Use an expression to default - then it'll work for dynamic contracts if (!child.HasValue("targetBody")) { child.AddValue("targetBody", "@/targetBody"); } valid &= ConfigNodeUtil.ParseValue <CelestialBody>(child, "targetBody", x => wpData.waypoint.celestialName = x != null ? x.name : "", factory); valid &= ConfigNodeUtil.ParseValue <List <string> >(child, "name", x => wpData.names = x, factory, new List <string>()); valid &= ConfigNodeUtil.ParseValue <double?>(child, "altitude", x => altitude = x, factory, (double?)null); valid &= ConfigNodeUtil.ParseValue <List <string> >(child, "parameter", x => wpData.parameter = x, factory, new List <string>()); valid &= ConfigNodeUtil.ParseValue <bool>(child, "hidden", x => wpData.waypoint.visible = !x, factory, false); Action <string> assignWaypoint = (x) => { wpData.waypoint.id = x; if (onWaypointIconAdded != null) { onWaypointIconAdded.Fire(x); } }; if (!wpData.waypoint.visible) { valid &= ConfigNodeUtil.ParseValue <string>(child, "icon", assignWaypoint, factory, ""); } else { valid &= ConfigNodeUtil.ParseValue <string>(child, "icon", assignWaypoint, factory); } valid &= ConfigNodeUtil.ParseValue <bool>(child, "underwater", x => wpData.underwater = x, factory, false); valid &= ConfigNodeUtil.ParseValue <bool>(child, "clustered", x => wpData.waypoint.isClustered = x, factory, false); // Track the index wpData.waypoint.index = index++; // Get altitude if (altitude == null) { wpData.waypoint.altitude = 0.0; wpData.randomAltitude = true; } else { wpData.waypoint.altitude = altitude.Value; } // Get settings that differ by type if (child.name == "WAYPOINT") { valid &= ConfigNodeUtil.ParseValue <double>(child, "latitude", x => wpData.waypoint.latitude = x, factory); valid &= ConfigNodeUtil.ParseValue <double>(child, "longitude", x => wpData.waypoint.longitude = x, factory); } else if (child.name == "RANDOM_WAYPOINT") { // Get settings for randomization valid &= ConfigNodeUtil.ParseValue <bool>(child, "waterAllowed", x => wpData.waterAllowed = x, factory, true); valid &= ConfigNodeUtil.ParseValue <bool>(child, "forceEquatorial", x => wpData.forceEquatorial = x, factory, false); valid &= ConfigNodeUtil.ParseValue <int>(child, "count", x => wpData.count = x, factory, 1, x => Validation.GE(x, 1)); } else if (child.name == "RANDOM_WAYPOINT_NEAR") { // Get settings for randomization valid &= ConfigNodeUtil.ParseValue <bool>(child, "waterAllowed", x => wpData.waterAllowed = x, factory, true); // Get near waypoint details valid &= ConfigNodeUtil.ParseValue <int>(child, "nearIndex", x => wpData.nearIndex = x, factory, x => Validation.GE(x, 0) && Validation.LT(x, wpGenerator.waypoints.Count)); valid &= ConfigNodeUtil.ParseValue <bool>(child, "chained", x => wpData.chained = x, factory, false); valid &= ConfigNodeUtil.ParseValue <int>(child, "count", x => wpData.count = x, factory, 1, x => Validation.GE(x, 1)); // Get distances valid &= ConfigNodeUtil.ParseValue <double>(child, "minDistance", x => wpData.minDistance = x, factory, 0.0, x => Validation.GE(x, 0.0)); valid &= ConfigNodeUtil.ParseValue <double>(child, "maxDistance", x => wpData.maxDistance = x, factory, x => Validation.GT(x, 0.0)); } else if (child.name == "PQS_CITY") { wpData.randomAltitude = false; string dummy = null; valid &= ConfigNodeUtil.ParseValue <string>(child, "pqsCity", x => dummy = x, factory, x => { bool v = true; if (!string.IsNullOrEmpty(wpData.waypoint.celestialName)) { try { CelestialBody body = FlightGlobals.Bodies.Where(b => b.name == wpData.waypoint.celestialName).First(); wpData.pqsCity = body.GetComponentsInChildren <PQSCity>(true).Where(pqs => pqs.name == x).First(); } catch (Exception e) { LoggingUtil.LogError(typeof(WaypointGenerator), "Couldn't load PQSCity with name '{0}'", x); LoggingUtil.LogException(e); v = false; } } else { // Force this to get re-run when the targetBody is loaded throw new DataNode.ValueNotInitialized("/targetBody"); } return(v); }); valid &= ConfigNodeUtil.ParseValue <Vector3d>(child, "pqsOffset", x => wpData.pqsOffset = x, factory, new Vector3d()); } else if (child.name == "LAUNCH_SITE") { wpData.randomAltitude = false; string dummy = null; valid &= ConfigNodeUtil.ParseValue <string>(child, "launchSite", x => dummy = x, factory, x => { bool v = true; if (!string.IsNullOrEmpty(wpData.waypoint.celestialName)) { try { wpData.launchSite = ConfigNodeUtil.ParseLaunchSiteValue(x); } catch (Exception e) { LoggingUtil.LogError(typeof(WaypointGenerator), "Couldn't load Launch Site with name '{0}'", x); LoggingUtil.LogException(e); v = false; } } else { // Force this to get re-run when the targetBody is loaded throw new DataNode.ValueNotInitialized("/targetBody"); } return(v); }); valid &= ConfigNodeUtil.ParseValue <Vector3d>(child, "pqsOffset", x => wpData.pqsOffset = x, factory, new Vector3d()); } else { LoggingUtil.LogError(factory, "Unrecognized waypoint node: '{0}'", child.name); valid = false; } // Check for unexpected values valid &= ConfigNodeUtil.ValidateUnexpectedValues(child, factory); // Copy waypoint data WaypointData old = wpData; wpData = new WaypointData(old, null); wpGenerator.waypoints.Add(wpData); } finally { ConfigNodeUtil.SetCurrentDataNode(factory.dataNode); } } return(valid ? wpGenerator : null); }
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); } } }
public static void AtmosphereToggler() { // Only run in TrackingStation or MapView if (!HighLogic.LoadedSceneHasPlanetarium && !MapView.MapIsEnabled) { return; } // Only work when the player is focused on a planet if (PlanetariumCamera.fetch.target.celestialBody == null) { return; } // When the user presses Ctrl+A in the Tracking Station, toggle the atmosphere of the currently selected body // Get the body CelestialBody body = PSystemManager.Instance.localBodies.Find(b => b.transform.name == PlanetariumCamera.fetch.target.celestialBody.transform.name); // Yes this is silly, but it shows how to find a body by its name // Toggle Atmosphere if (atmosphericBodies.Contains(body.transform.name)) { // Disable the Atmosphere from Ground AtmosphereFromGround[] afgs = body.GetComponentsInChildren <AtmosphereFromGround>(); foreach (AtmosphereFromGround afg in afgs) { afg.gameObject.SetActive(false); } // Disable the Light controller MaterialSetDirection[] msds = body.GetComponentsInChildren <MaterialSetDirection>(); foreach (MaterialSetDirection msd in msds) { msd.gameObject.SetActive(false); } // No Atmosphere :( body.atmosphere = false; // Message ScreenMessages.PostScreenMessage("Atmosphere Disabled " + body.displayName.Replace("^N", ""), 2f, ScreenMessageStyle.UPPER_RIGHT); } else { // Enable the Atmosphere from Ground AtmosphereFromGround[] AtmoFromGround = body.GetComponentsInChildren <AtmosphereFromGround>(); foreach (AtmosphereFromGround afg in AtmoFromGround) { afg.gameObject.SetActive(true); } // Enable the Light controller MaterialSetDirection[] materialSetDir = body.GetComponentsInChildren <MaterialSetDirection>(); foreach (MaterialSetDirection msd in materialSetDir) { msd.gameObject.SetActive(true); } // Atmosphere \o/ body.atmosphere = true; // Message ScreenMessages.PostScreenMessage("Atmosphere Enabled " + body.displayName.Replace("^N", ""), 2f, ScreenMessageStyle.UPPER_RIGHT); } }
public static WaypointGenerator Create(ConfigNode configNode, WaypointGeneratorFactory factory) { WaypointGenerator wpGenerator = new WaypointGenerator(); bool valid = true; int index = 0; foreach (ConfigNode child in ConfigNodeUtil.GetChildNodes(configNode)) { DataNode dataNode = new DataNode("WAYPOINT_" + index, factory.dataNode, factory); try { ConfigNodeUtil.SetCurrentDataNode(dataNode); dataNode["type"] = child.name; double? altitude = null; WaypointData wpData = new WaypointData(child.name); // Use an expression to default - then it'll work for dynamic contracts if (!child.HasValue("targetBody")) { child.AddValue("targetBody", "@/targetBody"); } valid &= ConfigNodeUtil.ParseValue <CelestialBody>(child, "targetBody", x => wpData.waypoint.celestialName = x != null ? x.name : "", factory); valid &= ConfigNodeUtil.ParseValue <List <string> >(child, "name", x => wpData.names = x, factory, new List <string>()); valid &= ConfigNodeUtil.ParseValue <double?>(child, "altitude", x => altitude = x, factory, (double?)null); valid &= ConfigNodeUtil.ParseValue <List <string> >(child, "parameter", x => wpData.parameter = x, factory, new List <string>()); valid &= ConfigNodeUtil.ParseValue <bool>(child, "hidden", x => wpData.waypoint.visible = !x, factory, false); if (!wpData.waypoint.visible) { valid &= ConfigNodeUtil.ParseValue <string>(child, "icon", x => wpData.waypoint.id = x, factory, ""); } else { valid &= ConfigNodeUtil.ParseValue <string>(child, "icon", x => wpData.waypoint.id = x, factory); } // The FinePrint logic is such that it will only look in Squad/Contracts/Icons for icons. // Cheat this by hacking the path in the game database. if (wpData.waypoint.id.Contains("/")) { GameDatabase.TextureInfo texInfo = GameDatabase.Instance.databaseTexture.Where(t => t.name == wpData.waypoint.id).FirstOrDefault(); if (texInfo != null) { texInfo.name = "Squad/Contracts/Icons/" + wpData.waypoint.id; } } valid &= ConfigNodeUtil.ParseValue <bool>(child, "underwater", x => wpData.underwater = x, factory, false); valid &= ConfigNodeUtil.ParseValue <bool>(child, "clustered", x => wpData.waypoint.isClustered = x, factory, false); // Track the index wpData.waypoint.index = index++; // Get altitude if (altitude == null) { wpData.waypoint.altitude = 0.0; wpData.randomAltitude = true; } else { wpData.waypoint.altitude = altitude.Value; } // Get settings that differ by type if (child.name == "WAYPOINT") { valid &= ConfigNodeUtil.ParseValue <double>(child, "latitude", x => wpData.waypoint.latitude = x, factory); valid &= ConfigNodeUtil.ParseValue <double>(child, "longitude", x => wpData.waypoint.longitude = x, factory); } else if (child.name == "RANDOM_WAYPOINT") { // Get settings for randomization valid &= ConfigNodeUtil.ParseValue <bool>(child, "waterAllowed", x => wpData.waterAllowed = x, factory, true); valid &= ConfigNodeUtil.ParseValue <bool>(child, "forceEquatorial", x => wpData.forceEquatorial = x, factory, false); valid &= ConfigNodeUtil.ParseValue <int>(child, "count", x => wpData.count = x, factory, 1, x => Validation.GE(x, 1)); } else if (child.name == "RANDOM_WAYPOINT_NEAR") { // Get settings for randomization valid &= ConfigNodeUtil.ParseValue <bool>(child, "waterAllowed", x => wpData.waterAllowed = x, factory, true); // Get near waypoint details valid &= ConfigNodeUtil.ParseValue <int>(child, "nearIndex", x => wpData.nearIndex = x, factory, x => Validation.GE(x, 0) && Validation.LT(x, wpGenerator.waypoints.Count)); valid &= ConfigNodeUtil.ParseValue <bool>(child, "chained", x => wpData.chained = x, factory, false); valid &= ConfigNodeUtil.ParseValue <int>(child, "count", x => wpData.count = x, factory, 1, x => Validation.GE(x, 1)); // Get distances valid &= ConfigNodeUtil.ParseValue <double>(child, "minDistance", x => wpData.minDistance = x, factory, 0.0, x => Validation.GE(x, 0.0)); valid &= ConfigNodeUtil.ParseValue <double>(child, "maxDistance", x => wpData.maxDistance = x, factory, x => Validation.GT(x, 0.0)); } else if (child.name == "PQS_CITY") { wpData.randomAltitude = false; string dummy = null; valid &= ConfigNodeUtil.ParseValue <string>(child, "pqsCity", x => dummy = x, factory, x => { bool v = true; if (!string.IsNullOrEmpty(wpData.waypoint.celestialName)) { try { CelestialBody body = FlightGlobals.Bodies.Where(b => b.name == wpData.waypoint.celestialName).First(); wpData.pqsCity = body.GetComponentsInChildren <PQSCity>(true).Where(pqs => pqs.name == x).First(); } catch (Exception e) { LoggingUtil.LogError(typeof(WaypointGenerator), "Couldn't load PQSCity with name '" + x + "'"); LoggingUtil.LogException(e); v = false; } } else { // Force this to get re-run when the targetBody is loaded throw new DataNode.ValueNotInitialized("/targetBody"); } return(v); }); valid &= ConfigNodeUtil.ParseValue <Vector3d>(child, "pqsOffset", x => wpData.pqsOffset = x, factory, new Vector3d()); } else { LoggingUtil.LogError(factory, "Unrecognized waypoint node: '" + child.name + "'"); valid = false; } // Check for unexpected values valid &= ConfigNodeUtil.ValidateUnexpectedValues(child, factory); // Copy waypoint data WaypointData old = wpData; for (int i = 0; i < old.count; i++) { wpData = new WaypointData(old, null); wpGenerator.waypoints.Add(wpData); if (old.parameter.Any()) { wpData.parameter = new List <string>(); wpData.parameter.Add(old.parameter.Count() == 1 ? old.parameter.First() : old.parameter.ElementAtOrDefault(i)); } // Set the name if (old.names.Any()) { wpData.waypoint.name = (old.names.Count() == 1 ? old.names.First() : old.names.ElementAtOrDefault(i)); } if (string.IsNullOrEmpty(wpData.waypoint.name) || wpData.waypoint.name.ToLower() == "site") { wpData.waypoint.name = StringUtilities.GenerateSiteName(random.Next(), wpData.waypoint.celestialBody, !wpData.waterAllowed); } // Handle waypoint chaining if (wpData.chained && i != 0) { wpData.nearIndex = wpGenerator.waypoints.Count - 2; } } } finally { ConfigNodeUtil.SetCurrentDataNode(factory.dataNode); } } return(valid ? wpGenerator : null); }
private static IEnumerable <Transform> FindInterestingThings(CelestialBody body) { return(body.GetComponentsInChildren <Transform>().Where(child => !InterestingThingIgnores.Any(i => child.name.StartsWith(i)) && !child.name.StartsWith(body.name))); }
public static WaypointGenerator Create(ConfigNode configNode, CelestialBody defaultBody, WaypointGeneratorFactory factory) { WaypointGenerator wpGenerator = new WaypointGenerator(); bool valid = true; int index = 0; foreach (ConfigNode child in ConfigNodeUtil.GetChildNodes(configNode)) { double? altitude = null; WaypointData wpData = new WaypointData(child.name); valid &= ConfigNodeUtil.ParseValue <string>(child, "targetBody", x => wpData.waypoint.celestialName = x, factory, defaultBody != null ? defaultBody.name : null, Validation.NotNull); valid &= ConfigNodeUtil.ParseValue <string>(child, "name", x => wpData.waypoint.name = x, factory, (string)null); valid &= ConfigNodeUtil.ParseValue <double?>(child, "altitude", x => altitude = x, factory, (double?)null); valid &= ConfigNodeUtil.ParseValue <string>(child, "parameter", x => wpData.parameter = x, factory, ""); valid &= ConfigNodeUtil.ParseValue <bool>(child, "hidden", x => wpData.hidden = x, factory, false); if (wpData.hidden) { valid &= ConfigNodeUtil.ParseValue <string>(child, "icon", x => wpData.waypoint.id = x, factory, ""); } else { valid &= ConfigNodeUtil.ParseValue <string>(child, "icon", x => wpData.waypoint.id = x, factory); } // The FinePrint logic is such that it will only look in Squad/Contracts/Icons for icons. // Cheat this by hacking the path in the game database. if (wpData.waypoint.id.Contains("/")) { GameDatabase.TextureInfo texInfo = GameDatabase.Instance.databaseTexture.Where(t => t.name == wpData.waypoint.id).FirstOrDefault(); if (texInfo != null) { texInfo.name = "Squad/Contracts/Icons/" + wpData.waypoint.id; } } // Track the index wpData.waypoint.index = index++; // Get altitude if (altitude == null) { wpData.waypoint.altitude = 0.0; wpData.randomAltitude = true; } else { wpData.waypoint.altitude = altitude.Value; } DataNode dataNode = new DataNode("WAYPOINT_" + (index - 1), factory.dataNode, factory); try { ConfigNodeUtil.SetCurrentDataNode(dataNode); // Get settings that differ by type if (child.name == "WAYPOINT") { valid &= ConfigNodeUtil.ParseValue <double>(child, "latitude", x => wpData.waypoint.latitude = x, factory); valid &= ConfigNodeUtil.ParseValue <double>(child, "longitude", x => wpData.waypoint.longitude = x, factory); } else if (child.name == "RANDOM_WAYPOINT") { // Get settings for randomization valid &= ConfigNodeUtil.ParseValue <bool>(child, "waterAllowed", x => wpData.waterAllowed = x, factory, true); valid &= ConfigNodeUtil.ParseValue <bool>(child, "forceEquatorial", x => wpData.forceEquatorial = x, factory, false); valid &= ConfigNodeUtil.ParseValue <int>(child, "count", x => wpData.count = x, factory, 1, x => Validation.GE(x, 1)); } else if (child.name == "RANDOM_WAYPOINT_NEAR") { // Get settings for randomization valid &= ConfigNodeUtil.ParseValue <bool>(child, "waterAllowed", x => wpData.waterAllowed = x, factory, true); // Get near waypoint details valid &= ConfigNodeUtil.ParseValue <int>(child, "nearIndex", x => wpData.nearIndex = x, factory, x => Validation.GE(x, 0)); valid &= ConfigNodeUtil.ParseValue <int>(child, "count", x => wpData.count = x, factory, 1, x => Validation.GE(x, 1)); // Get distances valid &= ConfigNodeUtil.ParseValue <double>(child, "minDistance", x => wpData.minDistance = x, factory, 0.0, x => Validation.GE(x, 0.0)); // To be deprecated if (child.HasValue("nearDistance")) { valid &= ConfigNodeUtil.ParseValue <double>(child, "nearDistance", x => wpData.maxDistance = x, factory, x => Validation.GT(x, 0.0)); LoggingUtil.LogWarning(factory, "The 'nearDistance' attribute is obsolete as of Contract Configurator 0.7.4. It will be removed in 1.0.0 in favour of minDistance/maxDistance."); } else { valid &= ConfigNodeUtil.ParseValue <double>(child, "maxDistance", x => wpData.maxDistance = x, factory, x => Validation.GT(x, wpData.minDistance)); } } else if (child.name == "PQS_CITY") { wpData.randomAltitude = false; string pqsCity = null; valid &= ConfigNodeUtil.ParseValue <string>(child, "pqsCity", x => pqsCity = x, factory); if (pqsCity != null) { try { CelestialBody body = FlightGlobals.Bodies.Where(b => b.name == wpData.waypoint.celestialName).First(); wpData.pqsCity = body.GetComponentsInChildren <PQSCity>(true).Where(pqs => pqs.name == pqsCity).First(); } catch (Exception e) { LoggingUtil.LogError(typeof(WaypointGenerator), "Couldn't load PQSCity with name '" + pqsCity + "'"); LoggingUtil.LogException(e); valid = false; } } valid &= ConfigNodeUtil.ParseValue <Vector3d>(child, "pqsOffset", x => wpData.pqsOffset = x, factory, new Vector3d()); } else { LoggingUtil.LogError(factory, "Unrecognized waypoint node: '" + child.name + "'"); valid = false; } } finally { ConfigNodeUtil.SetCurrentDataNode(factory.dataNode); } // Add to the list wpGenerator.waypoints.Add(wpData); } return(valid ? wpGenerator : null); }
private static IEnumerable<Transform> FindInterestingThings(CelestialBody body) { return body.GetComponentsInChildren<Transform>().Where(child => !InterestingThingIgnores.Any(i => child.name.StartsWith(i)) && !child.name.StartsWith(body.name)); }
/// <summary> /// [HACK] Spawn a new body from the PSystem-Prefab /// </summary> public static void Instantiate(PSystemBody template, string name) { // Fix Templates if (template == null) { ScreenMessages.PostScreenMessage("You need a valid Template!", 3f, ScreenMessageStyle.UPPER_CENTER); return; } // Spawn Message ScreenMessages.PostScreenMessage("Created new Planet " + name + ", based on " + template.name + "!", 5f, ScreenMessageStyle.UPPER_CENTER); ScreenMessages.PostScreenMessage("This tool is meant to be used by modders, it can break mods!", 5f, ScreenMessageStyle.UPPER_CENTER); // Clone the Template GameObject bodyObject = UnityEngine.Object.Instantiate(template.gameObject); PSystemBody body = bodyObject.GetComponent <PSystemBody>(); // Alter it's name and flight-Number body.name = name; body.celestialBody.bodyName = name; body.celestialBody.transform.name = name; body.celestialBody.bodyTransform.name = name; body.scaledVersion.name = name; if (body.pqsVersion != null) { body.pqsVersion.name = name; body.pqsVersion.gameObject.name = name; body.pqsVersion.transform.name = name; foreach (PQS p in body.pqsVersion.GetComponentsInChildren(typeof(PQS), true)) { p.name = p.name.Replace(template.celestialBody.bodyName, name); } } body.flightGlobalsIndex = PSystemManager.Instance.localBodies.Last().flightGlobalsIndex + 1; // Change it's Orbit body.orbitDriver.orbit = Orbit.CreateRandomOrbitAround(PSystemManager.Instance.localBodies.First(), 4000000000, 60000000000); body.orbitDriver.referenceBody = PSystemManager.Instance.localBodies.First(); body.orbitDriver.orbit.referenceBody = body.orbitDriver.referenceBody; body.orbitRenderer.lowerCamVsSmaRatio = template.orbitRenderer.lowerCamVsSmaRatio; body.orbitRenderer.upperCamVsSmaRatio = template.orbitRenderer.upperCamVsSmaRatio; // Clear it's childs body.children = new List <PSystemBody>(); // Add it to the System-Prefab body.transform.parent = PSystemManager.Instance.systemPrefab.transform; PSystemManager.Instance.systemPrefab.rootBody.children.Add(body); // Hack^6 - Hack the PSystemManager to spawn this thing MethodInfo spawnBody = typeof(PSystemManager).GetMethod("SpawnBody", BindingFlags.NonPublic | BindingFlags.Instance); spawnBody.Invoke(PSystemManager.Instance, new object[] { PSystemManager.Instance.localBodies.First(), body }); CelestialBody cBody = PSystemManager.Instance.localBodies.Last(); // Add the body to FlightGlobals.Bodies FlightGlobals.fetch.bodies.Add(cBody); // Start the CelestialBody typeof(CelestialBody).GetMethod("Start", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(cBody, null); // Start the OrbitDriver if (cBody.orbitDriver != null) { typeof(OrbitDriver).GetMethod("Start", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(cBody.orbitDriver, null); } // Fix and start the OrbitRenderer if (Resources.FindObjectsOfTypeAll <OrbitRenderer>().Count(r => r.name == cBody.name) == 1) { OrbitRenderer renderer = Resources.FindObjectsOfTypeAll <OrbitRenderer>().First(r => r.name == cBody.name); renderer.driver = cBody.orbitDriver; renderer.celestialBody = cBody; typeof(OrbitRenderer).GetMethod("Start", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(renderer, null); } // Force the start of the PQS-Spheres foreach (PQS p in cBody.GetComponentsInChildren <PQS>(true)) { p.ForceStart(); } // Fix the ScaledVersion if (cBody.scaledBody.GetComponents <ScaledSpaceFader>().Length == 1) { cBody.scaledBody.GetComponent <ScaledSpaceFader>().celestialBody = cBody; } if (cBody.scaledBody.GetComponents <AtmosphereFromGround>().Length == 1) { cBody.scaledBody.GetComponent <AtmosphereFromGround>().planet = cBody; } }
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); } } }