void City2Fixer(PQSCity2 city) { Debug.Log("SigmaDimensions.City2Fixer", " > PQSCity2: " + city.name); // Resize the Building city.transform.localScale *= (float)resizeBuildings; // Fix PQSCity Groups if (body.Has("PQSCityGroups")) { Dictionary <object, Vector3> PQSList = body.Get <Dictionary <object, Vector3> >("PQSCityGroups"); if (PQSList.ContainsKey(city)) { GroupFixer(city, PQSList[city]); } } // Add PQSCity2Fixer Component PQSCity2Fixer fixer = city.GetComponent <PQSCity2Fixer>() ?? city.gameObject.AddComponent <PQSCity2Fixer>(); // Terrain double groundLevel = body.pqsController.GetSurfaceHeight(city.PlanetRelativePosition) - body.Radius; double oceanDepth = body.ocean && groundLevel < 0 ? -groundLevel : 0d; groundLevel = body.ocean && groundLevel < 0 ? 0d : groundLevel; // Fix Altitude if (!city.snapToSurface) { double builtInOffset = city.alt - groundLevel / (resize * landscape); Debug.Log("SigmaDimensions.City2Fixer", " > Builtuin Offset = " + builtInOffset); // Offset = Distance from the radius of the planet Debug.Log("SigmaDimensions.City2Fixer", " > PQSCity Original Radius Offset = " + city.alt); city.alt = groundLevel + builtInOffset * resizeBuildings; Debug.Log("SigmaDimensions.City2Fixer", " > PQSCity Fixed Radius Offset = " + city.alt); } else { double builtInOffset = city.snapHeightOffset - oceanDepth / (resize * landscape); Debug.Log("SigmaDimensions.CityFixer", " > Builtuin Offset = " + builtInOffset); // Offset = Distance from the surface of the planet Debug.Log("SigmaDimensions.CityFixer", " > PQSCity Original Surface Offset = " + city.snapHeightOffset); city.snapHeightOffset = oceanDepth + builtInOffset * resizeBuildings; Debug.Log("SigmaDimensions.CityFixer", " > PQSCity Fixed Surface Offset = " + city.snapHeightOffset); } }
private static void ApplyLaunchSitePatches() { #if !KSP131 if (!ExpansionsLoader.IsExpansionInstalled("MakingHistory")) { return; } PQSCity2[] cities = FindObjectsOfType <PQSCity2>(); for (Int32 i = 0; i < Templates.RemoveLaunchSites.Count; i++) { String site = Templates.RemoveLaunchSites[i]; // Remove the launch site from the list if it exists if (PSystemSetup.Instance.LaunchSites.Any(s => s.name == site)) { PSystemSetup.Instance.RemoveLaunchSite(site); } PQSCity2 city = cities.FirstOrDefault(c => { GameObject o; return((o = c.gameObject).name == site || o.name == site + "(Clone)"); }); // Kill the PQSCity if it exists if (city != null) { Destroy(city.gameObject); } } // PSystemSetup.RemoveLaunchSite does not remove launch sites from PSystemSetup.StockLaunchSites // Currently an ArgumentOutOfRangeException can result when they are different lists because of a bug in stock code try { FieldInfo stockLaunchSitesField = typeof(PSystemSetup).GetField("stocklaunchsites", BindingFlags.NonPublic | BindingFlags.Instance); if (stockLaunchSitesField == null) { return; } LaunchSite[] stockLaunchSites = (LaunchSite[])stockLaunchSitesField.GetValue(PSystemSetup.Instance); LaunchSite[] updateStockLaunchSites = stockLaunchSites.Where(site => !Templates.RemoveLaunchSites.Contains(site.name)).ToArray(); if (stockLaunchSites.Length != updateStockLaunchSites.Length) { stockLaunchSitesField.SetValue(PSystemSetup.Instance, updateStockLaunchSites); } } catch (Exception ex) { Logger.Default.Log("Failed to remove launch sites from 'stockLaunchSites' field. Exception information follows."); Logger.Default.LogException(ex); } #endif }
void FixAltitude(object mod, double terrainShift, double fixAltitude) { Debug.Log("SigmaDimensions.FixAltitude", " > Terrain Shift = " + terrainShift); string type = mod.GetType().ToString(); if (type == "PQSCity") { PQSCity pqs = (PQSCity)mod; if (!pqs.repositionToSphere && !pqs.repositionToSphereSurface) { pqs.repositionToSphereSurface = true; pqs.repositionRadiusOffset = 0; } if (pqs.repositionToSphereSurface && !pqs.repositionToSphereSurfaceAddHeight) { pqs.repositionToSphereSurfaceAddHeight = true; pqs.repositionRadiusOffset = 0; } if (!pqs.repositionToSphereSurface) { pqs.repositionRadiusOffset += terrainShift; } Debug.Log("SigmaDimensions.FixAltitude", " > Mod original repositionRadiusOffset = " + pqs.repositionRadiusOffset); pqs.repositionRadiusOffset += fixAltitude; Debug.Log("SigmaDimensions.FixAltitude", " > Fixed repositionRadiusOffset = " + pqs.repositionRadiusOffset); } else if (type == "PQSCity2") { PQSCity2 pqs = (PQSCity2)mod; if (pqs.snapToSurface) { pqs.snapHeightOffset += fixAltitude; Debug.Log("SigmaDimensions.FixAltitude", " > Fixed snapHeightOffset = " + pqs.snapHeightOffset); } else { pqs.alt += terrainShift + fixAltitude; Debug.Log("SigmaDimensions.FixAltitude", " > Fixed PQSCity2.alt = " + pqs.alt); } } }
/// <summary> /// Removes the wreck model from an KSC Object. /// </summary> internal static void MangleSquadStatic(GameObject gameObject) { gameObject.transform.parent = null; var transforms = gameObject.transform.GetComponentsInChildren <Transform>(true); foreach (var transform in transforms) { if (transform.name.Equals("wreck", StringComparison.InvariantCultureIgnoreCase)) { transform.parent = null; GameObject.Destroy(transform.gameObject); } if (transform.name.Equals("commnetnode", StringComparison.InvariantCultureIgnoreCase)) { transform.parent = null; GameObject.Destroy(transform.gameObject); } } PQSCity2 pqs2 = gameObject.GetComponent <PQSCity2>(); if (pqs2 != null) { GameObject.Destroy(pqs2); } CommNet.CommNetHome cnhome = gameObject.GetComponent <CommNet.CommNetHome>(); if (cnhome != null) { GameObject.Destroy(cnhome); } DestructibleBuilding destBuilding = gameObject.GetComponentInChildren <DestructibleBuilding>(); if (destBuilding != null) { GameObject.Destroy(destBuilding); } }
void City2Fixer(PQSCity2 pqs) { // Resize the Building pqs.transform.localScale *= (float)resizeBuildings; // Fix PQSCity Groups if (body.Has("PQSCityGroups")) { Dictionary<object, Vector3> PQSList = body.Get<Dictionary<object, Vector3>>("PQSCityGroups"); if (PQSList.ContainsKey(pqs)) { GroupFixer(pqs, PQSList[pqs].normalized); } } // Fix Altitude if (!pqs.snapToSurface) { // Offset = Distance from the center of the planet double groundLevel = body.pqsController.GetSurfaceHeight(pqs.PlanetRelativePosition) - body.Radius; double fromRadius = pqs.alt - (body.Radius / resize); double builtInOffset = fromRadius - groundLevel / (resize * landscape); pqs.alt = body.Radius + groundLevel + builtInOffset * resizeBuildings; } else { // Offset = Distance from the surface of the planet pqs.snapHeightOffset *= resizeBuildings; } }
internal static void AddPQSCenter2(string tgtName) { CelestialBody body = ConfigUtil.GetCelestialBody("HomeWorld"); var mods = body.pqsController.GetComponentsInChildren <PQSCity2>(true); PQSCity2 tgtPQS = null; foreach (var m in mods) { //Log.Normal("PQS2Name: " + m.name); if (m.name == tgtName) { tgtPQS = m; continue; } } if (tgtPQS == null) { Log.Normal("No BasePQS found: " + tgtName); return; } GroupCenter newGroup = new GroupCenter(); newGroup.isBuiltIn = true; newGroup.Group = tgtName + "_Builtin"; newGroup.CelestialBody = body; newGroup.RotationAngle = (float)tgtPQS.rotation; newGroup.RadialPosition = KKMath.GetRadiadFromLatLng(body, tgtPQS.lat, tgtPQS.lon); //newGroup.RadiusOffset = (float)0; newGroup.RadiusOffset = (float)tgtPQS.alt; newGroup.SeaLevelAsReference = true; //newGroup.repositionToSphere = tgtPQS.repositionToSphere; newGroup.Spawn(); }
// Post apply event void IParserEventSubscriber.PostApply(ConfigNode node) { // Should we remove the atmosphere if (body.celestialBody.atmosphere && removeAtmosphere.Value) { // Find atmosphere from ground and destroy the game object AtmosphereFromGround atmosphere = body.scaledVersion.GetComponentsInChildren <AtmosphereFromGround>(true)[0]; atmosphere.transform.parent = null; UnityEngine.Object.Destroy(atmosphere.gameObject); // Destroy the light controller MaterialSetDirection light = body.scaledVersion.GetComponentsInChildren <MaterialSetDirection>(true)[0]; UnityEngine.Object.Destroy(light); // No more atmosphere :( body.celestialBody.atmosphere = false; } // If we have a PQS if (body.pqsVersion != null) { Logger.Active.Log("[Kopernicus]: Configuration.Template: Using Template \"" + body.celestialBody.bodyName + "\""); // Should we remove the ocean? if (body.celestialBody.ocean && removeOcean.Value) { // Find atmosphere the ocean PQS PQS ocean = body.pqsVersion.GetComponentsInChildren <PQS>(true).Where(pqs => pqs != body.pqsVersion).First(); PQSMod_CelestialBodyTransform cbt = body.pqsVersion.GetComponentsInChildren <PQSMod_CelestialBodyTransform>(true).First(); // Destroy the ocean PQS (this could be bad - destroying the secondary fades...) cbt.planetFade.secondaryRenderers.Remove(ocean.gameObject); cbt.secondaryFades = null; ocean.transform.parent = null; UnityEngine.Object.Destroy(ocean); // No more ocean :( body.celestialBody.ocean = false; body.pqsVersion.mapOcean = false; } // Selectively remove PQS Mods if (removePQSMods != null && removePQSMods.Value.LongCount() > 0) { // We need a List with Types to remove List <Type> mods = new List <Type>(); Dictionary <String, Type> modsPerName = new Dictionary <String, Type>(); foreach (String mod in removePQSMods.Value) { // If the definition has a name specified, grab that String mType = mod; String name = ""; if (mType.EndsWith("]")) { String[] split = mType.Split('['); mType = split[0]; name = split[1].Remove(split[1].Length - 1); } // Get the mods matching the String String modName = mType; if (!mod.Contains("PQS")) { modName = "PQSMod_" + mod; } if (name == "") { //mods.Add(Type.GetType(modName + ", Assembly-CSharp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")); Type t = Parser.ModTypes.Find(m => m.Name == modName); if (t != null) { mods.Add(t); } } else { //modsPerName.Add(name, Type.GetType(modName + ", Assembly-CSharp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")); Type t = Parser.ModTypes.Find(m => m.Name == modName); if (t != null) { modsPerName.Add(name, t); } } } Utility.RemoveModsOfType(mods, body.pqsVersion); foreach (KeyValuePair <String, Type> kvP in modsPerName) { Int32 index = 0; String name = kvP.Key; if (name.Contains(';')) { String[] split = name.Split(';'); name = split[0]; Int32.TryParse(split[1], out index); } PQSMod[] allMods = body.pqsVersion.GetComponentsInChildren(kvP.Value, true).Select(m => m as PQSMod).Where(m => m.name == name).ToArray(); if (allMods.Length > 0) { if (allMods[index] is PQSCity) { PQSCity city = allMods[index] as PQSCity; if (city.lod != null) { foreach (PQSCity.LODRange range in city.lod) { if (range.objects != null) { foreach (GameObject o in range.objects) { UnityEngine.Object.DestroyImmediate(o); } } if (range.renderers != null) { foreach (GameObject o in range.renderers) { UnityEngine.Object.DestroyImmediate(o); } } } } } if (allMods[index] is PQSCity2) { PQSCity2 city = allMods[index] as PQSCity2; if (city.objects != null) { foreach (PQSCity2.LodObject range in city.objects) { if (range.objects != null) { foreach (GameObject o in range.objects) { UnityEngine.Object.DestroyImmediate(o); } } } } } // If no mod is left, delete the game object too GameObject gameObject = allMods[index].gameObject; UnityEngine.Object.DestroyImmediate(allMods[index]); PQSMod[] allRemainingMods = gameObject.GetComponentsInChildren <PQSMod>(true); if (allRemainingMods.Length == 0) { UnityEngine.Object.DestroyImmediate(gameObject); } } } } if (removeAllMods != null && removeAllMods.Value) { // Remove all mods Utility.RemoveModsOfType(null, body.pqsVersion); } } // Should we remove the progress tree if (removeProgressTree.Value) { body.celestialBody.progressTree = null; } // Figure out what kind of body we are if (body.scaledVersion.GetComponentsInChildren <SunShaderController>(true).Length > 0) { type = BodyType.Star; } else if (body.celestialBody.atmosphere) { type = BodyType.Atmospheric; } else { type = BodyType.Vacuum; } // remove coronas if (type == BodyType.Star && removeCoronas) { foreach (SunCoronas corona in body.scaledVersion.GetComponentsInChildren <SunCoronas>(true)) { corona.GetComponent <Renderer>().enabled = false; // RnD hard refs Coronas, so we need to disable them } } // Event Events.OnTemplateLoaderPostApply.Fire(this, node); }
// Post apply event void IParserEventSubscriber.PostApply(ConfigNode node) { // Should we remove the atmosphere if (Body.celestialBody.atmosphere && RemoveAtmosphere.Value) { // Find atmosphere from ground and destroy the game object AtmosphereFromGround atmosphere = Body.scaledVersion.GetComponentsInChildren <AtmosphereFromGround>(true)[0]; atmosphere.transform.parent = null; Object.Destroy(atmosphere.gameObject); // Destroy the light controller MaterialSetDirection light = Body.scaledVersion.GetComponentsInChildren <MaterialSetDirection>(true)[0]; Object.Destroy(light); // No more atmosphere :( Body.celestialBody.atmosphere = false; } Logger.Active.Log("Using Template \"" + Body.celestialBody.bodyName + "\""); // If we have a PQS if (Body.pqsVersion != null) { #if (!KSP_VERSION_1_8) // We only support one surface material per body, so use the one with the highest quality available if (GameSettings.TERRAIN_SHADER_QUALITY == 3) { Material surfaceMaterial = Body.pqsVersion.ultraQualitySurfaceMaterial; if (!surfaceMaterial) { surfaceMaterial = Body.pqsVersion.highQualitySurfaceMaterial; } if (!surfaceMaterial) { surfaceMaterial = Body.pqsVersion.mediumQualitySurfaceMaterial; } if (!surfaceMaterial) { surfaceMaterial = Body.pqsVersion.lowQualitySurfaceMaterial; } if (!surfaceMaterial) { surfaceMaterial = Body.pqsVersion.surfaceMaterial; } Body.pqsVersion.ultraQualitySurfaceMaterial = surfaceMaterial; Body.pqsVersion.highQualitySurfaceMaterial = surfaceMaterial; Body.pqsVersion.mediumQualitySurfaceMaterial = surfaceMaterial; Body.pqsVersion.lowQualitySurfaceMaterial = surfaceMaterial; Body.pqsVersion.surfaceMaterial = surfaceMaterial; } #endif if (GameSettings.TERRAIN_SHADER_QUALITY == 2) { Material surfaceMaterial = Body.pqsVersion.highQualitySurfaceMaterial; if (!surfaceMaterial) { surfaceMaterial = Body.pqsVersion.mediumQualitySurfaceMaterial; } if (!surfaceMaterial) { surfaceMaterial = Body.pqsVersion.lowQualitySurfaceMaterial; } if (!surfaceMaterial) { surfaceMaterial = Body.pqsVersion.surfaceMaterial; } #if (!KSP_VERSION_1_8) Body.pqsVersion.ultraQualitySurfaceMaterial = surfaceMaterial; #endif Body.pqsVersion.highQualitySurfaceMaterial = surfaceMaterial; Body.pqsVersion.mediumQualitySurfaceMaterial = surfaceMaterial; Body.pqsVersion.lowQualitySurfaceMaterial = surfaceMaterial; Body.pqsVersion.surfaceMaterial = surfaceMaterial; } else if (GameSettings.TERRAIN_SHADER_QUALITY == 1) { Material surfaceMaterial = Body.pqsVersion.mediumQualitySurfaceMaterial; if (!surfaceMaterial) { surfaceMaterial = Body.pqsVersion.lowQualitySurfaceMaterial; } if (!surfaceMaterial) { surfaceMaterial = Body.pqsVersion.surfaceMaterial; } #if (!KSP_VERSION_1_8) Body.pqsVersion.ultraQualitySurfaceMaterial = surfaceMaterial; #endif Body.pqsVersion.highQualitySurfaceMaterial = surfaceMaterial; Body.pqsVersion.mediumQualitySurfaceMaterial = surfaceMaterial; Body.pqsVersion.lowQualitySurfaceMaterial = surfaceMaterial; Body.pqsVersion.surfaceMaterial = surfaceMaterial; } else if (GameSettings.TERRAIN_SHADER_QUALITY == 0) { Material surfaceMaterial = Body.pqsVersion.lowQualitySurfaceMaterial; if (!surfaceMaterial) { surfaceMaterial = Body.pqsVersion.lowQualitySurfaceMaterial; } if (!surfaceMaterial) { surfaceMaterial = Body.pqsVersion.surfaceMaterial; } #if (!KSP_VERSION_1_8) Body.pqsVersion.ultraQualitySurfaceMaterial = surfaceMaterial; #endif Body.pqsVersion.highQualitySurfaceMaterial = surfaceMaterial; Body.pqsVersion.mediumQualitySurfaceMaterial = surfaceMaterial; Body.pqsVersion.lowQualitySurfaceMaterial = surfaceMaterial; Body.pqsVersion.surfaceMaterial = surfaceMaterial; } // Should we remove the ocean? if (Body.celestialBody.ocean) { // Find atmosphere the ocean PQS PQS ocean = Body.pqsVersion.GetComponentsInChildren <PQS>(true) .First(pqs => pqs != Body.pqsVersion); PQSMod_CelestialBodyTransform cbt = Body.pqsVersion .GetComponentsInChildren <PQSMod_CelestialBodyTransform>(true).First(); #if (!KSP_VERSION_1_8) if (GameSettings.TERRAIN_SHADER_QUALITY == 3) { Material surfaceMaterial = ocean.ultraQualitySurfaceMaterial; if (!surfaceMaterial) { surfaceMaterial = ocean.highQualitySurfaceMaterial; } if (!surfaceMaterial) { surfaceMaterial = ocean.mediumQualitySurfaceMaterial; } if (!surfaceMaterial) { surfaceMaterial = ocean.lowQualitySurfaceMaterial; } if (!surfaceMaterial) { surfaceMaterial = ocean.surfaceMaterial; } ocean.ultraQualitySurfaceMaterial = surfaceMaterial; ocean.highQualitySurfaceMaterial = surfaceMaterial; ocean.mediumQualitySurfaceMaterial = surfaceMaterial; ocean.lowQualitySurfaceMaterial = surfaceMaterial; ocean.surfaceMaterial = surfaceMaterial; } #endif if (GameSettings.TERRAIN_SHADER_QUALITY == 2) { Material surfaceMaterial = ocean.highQualitySurfaceMaterial; if (!surfaceMaterial) { surfaceMaterial = ocean.mediumQualitySurfaceMaterial; } if (!surfaceMaterial) { surfaceMaterial = ocean.lowQualitySurfaceMaterial; } if (!surfaceMaterial) { surfaceMaterial = ocean.surfaceMaterial; } #if (!KSP_VERSION_1_8) ocean.ultraQualitySurfaceMaterial = surfaceMaterial; #endif ocean.highQualitySurfaceMaterial = surfaceMaterial; ocean.mediumQualitySurfaceMaterial = surfaceMaterial; ocean.lowQualitySurfaceMaterial = surfaceMaterial; ocean.surfaceMaterial = surfaceMaterial; } else if (GameSettings.TERRAIN_SHADER_QUALITY == 1) { Material surfaceMaterial = ocean.mediumQualitySurfaceMaterial; if (!surfaceMaterial) { surfaceMaterial = ocean.lowQualitySurfaceMaterial; } if (!surfaceMaterial) { surfaceMaterial = ocean.surfaceMaterial; } #if (!KSP_VERSION_1_8) ocean.ultraQualitySurfaceMaterial = surfaceMaterial; #endif ocean.highQualitySurfaceMaterial = surfaceMaterial; ocean.mediumQualitySurfaceMaterial = surfaceMaterial; ocean.lowQualitySurfaceMaterial = surfaceMaterial; ocean.surfaceMaterial = surfaceMaterial; } else if (GameSettings.TERRAIN_SHADER_QUALITY == 0) { Material surfaceMaterial = ocean.lowQualitySurfaceMaterial; if (!surfaceMaterial) { surfaceMaterial = ocean.lowQualitySurfaceMaterial; } if (!surfaceMaterial) { surfaceMaterial = ocean.surfaceMaterial; } #if (!KSP_VERSION_1_8) ocean.ultraQualitySurfaceMaterial = surfaceMaterial; #endif ocean.highQualitySurfaceMaterial = surfaceMaterial; ocean.mediumQualitySurfaceMaterial = surfaceMaterial; ocean.lowQualitySurfaceMaterial = surfaceMaterial; ocean.surfaceMaterial = surfaceMaterial; } if (RemoveOcean.Value) { // Destroy the ocean PQS (this could be bad - destroying the secondary fades...) cbt.planetFade.secondaryRenderers.Remove(ocean.gameObject); cbt.secondaryFades = null; ocean.transform.parent = null; Object.Destroy(ocean); // No more ocean :( Body.celestialBody.ocean = false; Body.pqsVersion.mapOcean = false; } } // Selectively remove PQS Mods if (RemovePqsMods != null && RemovePqsMods.Value.LongCount() > 0) { // We need a List with Types to remove List <Type> mods = new List <Type>(); Dictionary <String, Type> modsPerName = new Dictionary <String, Type>(); foreach (String mod in RemovePqsMods.Value) { // If the definition has a name specified, grab that String mType = mod; String mName = ""; if (mType.EndsWith("]")) { String[] split = mType.Split('['); mType = split[0]; mName = split[1].Remove(split[1].Length - 1); } // Get the mods matching the String String modName = mType; if (!mod.Contains("PQS")) { modName = "PQSMod_" + mod; } if (mName == "") { //mods.Add(Type.GetType(modName + ", Assembly-CSharp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")); Type t = Parser.ModTypes.Find(m => m.Name == modName); if (t != null) { mods.Add(t); } } else { //modsPerName.Add(name, Type.GetType(modName + ", Assembly-CSharp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")); Type t = Parser.ModTypes.Find(m => m.Name == modName); if (t != null) { modsPerName.Add(mName, t); } } } Utility.RemoveModsOfType(mods, Body.pqsVersion); foreach (KeyValuePair <String, Type> kvP in modsPerName) { Int32 index = 0; String modName = kvP.Key; if (modName.Contains(';')) { String[] split = modName.Split(';'); modName = split[0]; Int32.TryParse(split[1], out index); } PQSMod[] allMods = Body.pqsVersion.GetComponentsInChildren(kvP.Value, true) .OfType <PQSMod>().Where(m => m.name == modName).ToArray(); if (allMods.Length <= 0) { continue; } if (allMods[index] is PQSCity) { PQSCity city = (PQSCity)allMods[index]; if (city.lod != null) { foreach (PQSCity.LODRange range in city.lod) { if (range.objects != null) { foreach (GameObject o in range.objects) { Object.DestroyImmediate(o); } } if (range.renderers == null) { continue; } { foreach (GameObject o in range.renderers) { Object.DestroyImmediate(o); } } } } } if (allMods[index] is PQSCity2) { PQSCity2 city = (PQSCity2)allMods[index]; if (city.objects != null) { foreach (PQSCity2.LodObject range in city.objects) { if (range.objects == null) { continue; } foreach (GameObject o in range.objects) { Object.DestroyImmediate(o); } } } } // If no mod is left, delete the game object too GameObject gameObject = allMods[index].gameObject; Object.DestroyImmediate(allMods[index]); PQSMod[] allRemainingMods = gameObject.GetComponentsInChildren <PQSMod>(true); if (allRemainingMods.Length == 0) { Object.DestroyImmediate(gameObject); } } } if (RemoveAllMods != null && RemoveAllMods.Value) { // Remove all mods Utility.RemoveModsOfType(null, Body.pqsVersion); } } // Should we remove the progress tree if (RemoveProgressTree.Value) { Body.celestialBody.progressTree = null; } // Figure out what kind of body we are Boolean isStar = Body.scaledVersion.GetComponentsInChildren <SunShaderController>(true).Length > 0; // remove coronas if (isStar && RemoveCoronas) { foreach (SunCoronas corona in Body.scaledVersion.GetComponentsInChildren <SunCoronas>(true)) { // RnD hard refs Coronas, so we need to disable them corona.GetComponent <Renderer>().enabled = false; } } // Event Events.OnTemplateLoaderPostApply.Fire(this, node); }
/// <summary> /// Will remove all mods of given types (or all, if types null) /// </summary> /// <param name="types">If null, will remove all mods except blacklisted mods</param> /// <param name="p">PQS to remove from</param> /// <param name="blacklist">list of mod types to not remove (optional)</param> public static void RemoveModsOfType(List <Type> types, PQS p, List <Type> blacklist = null) { Logger.Active.Log("Removing mods from pqs " + p.name); List <PQSMod> cpMods = p.GetComponentsInChildren <PQSMod>(true).ToList(); Boolean addTypes = types == null; if (addTypes) { types = new List <Type>(); } if (blacklist == null) { Logger.Active.Log("Creating blacklist"); blacklist = new List <Type>(); if (!types.Contains(typeof(PQSMod_CelestialBodyTransform))) { blacklist.Add(typeof(PQSMod_CelestialBodyTransform)); } if (!types.Contains(typeof(PQSMod_MaterialSetDirection))) { blacklist.Add(typeof(PQSMod_MaterialSetDirection)); } if (!types.Contains(typeof(PQSMod_UVPlanetRelativePosition))) { blacklist.Add(typeof(PQSMod_UVPlanetRelativePosition)); } if (!types.Contains(typeof(PQSMod_QuadMeshColliders))) { blacklist.Add(typeof(PQSMod_QuadMeshColliders)); } Logger.Active.Log("Blacklist count = " + blacklist.Count); } if (addTypes) { Logger.Active.Log("Adding all found PQSMods in pqs " + p.name); foreach (PQSMod m in cpMods) { Type mType = m.GetType(); if (types.Contains(mType) || blacklist.Contains(mType)) { continue; } Logger.Active.Log("Adding to remove list: " + mType); types.Add(mType); } } List <GameObject> toCheck = new List <GameObject>(); foreach (Type mType in types) { List <PQSMod> mods = cpMods.Where(m => m.GetType() == mType).ToList(); foreach (PQSMod delMod in mods) { if (delMod == null) { continue; } Logger.Active.Log("Removed mod " + mType); if (!toCheck.Contains(delMod.gameObject)) { toCheck.Add(delMod.gameObject); } delMod.sphere = null; switch (delMod) { case PQSCity mod: { PQSCity city = mod; if (city.lod != null) { foreach (PQSCity.LODRange range in city.lod) { if (range.objects != null) { foreach (GameObject o in range.objects) { UnityEngine.Object.DestroyImmediate(o); } } if (range.renderers == null) { continue; } foreach (GameObject o in range.renderers) { UnityEngine.Object.DestroyImmediate(o); } } } break; } case PQSCity2 mod: { PQSCity2 city = mod; if (city.objects != null) { foreach (PQSCity2.LodObject range in city.objects) { if (range.objects == null) { continue; } foreach (GameObject o in range.objects) { UnityEngine.Object.DestroyImmediate(o); } } } break; } } cpMods.Remove(delMod); // If no mod is left, delete the game object too GameObject gameObject = delMod.gameObject; UnityEngine.Object.DestroyImmediate(delMod); PQSMod[] allRemainingMods = gameObject.GetComponentsInChildren <PQSMod>(true); if (allRemainingMods.Length == 0) { UnityEngine.Object.DestroyImmediate(gameObject); } } } }
void FixAltitude() { 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>()) { // Update only once TimingManager.UpdateRemove(TimingManager.TimingStage.Normal, FixAltitude); Debug.Log("PQSCity2Fixer", "> Planet: " + body.transform.name); Debug.Log("PQSCity2Fixer", " > PQSCity2: " + city); // PQSCity2 parameters double groundLevel = (hits[i].point - planet).magnitude - body.Radius; double error = pqs.GetSurfaceHeight(city.PlanetRelativePosition) - body.Radius - groundLevel; double oceanDepth = body.ocean && groundLevel < 0 ? -groundLevel : 0d; groundLevel = body.ocean && groundLevel < 0 ? 0d : groundLevel; Debug.Log("PQSCity2Fixer", " > Ground Level at Mod = " + groundLevel); Debug.Log("PQSCity2Fixer", " > Ocean Depth at Mod = " + groundLevel); Debug.Log("PQSCity2Fixer", " > Ground Level Error at Mod = " + groundLevel); // Fix Altitude if (!city.snapToSurface) { // Offset = 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 { Debug.Log("PQSCity2Fixer", " > PQSCity2 Original Surface Offset = " + city.snapHeightOffset); city.snapHeightOffset = oceanDepth + error / (resize * landscape) - (oceanDepth + error - city.snapHeightOffset) / resizeBuildings; Debug.Log("PQSCity2Fixer", " > PQSCity2 Fixed Surface Offset = " + city.snapHeightOffset); } city.Orientate(); DestroyImmediate(this); } } }
// Execute MainMenu functions void Start() { previous = PlanetariumCamera.fetch.initialTarget; PlanetariumCamera.fetch.targets .Where(m => m.celestialBody != null && (m.celestialBody.Has("barycenter") || !m.celestialBody.Get("selectable", true))) .ToList() .ForEach(map => PlanetariumCamera.fetch.targets.Remove(map)); // Stars GameObject gob = Sun.Instance.gameObject; KopernicusStar star = gob.AddComponent <KopernicusStar>(); Utility.CopyObjectFields(Sun.Instance, star, false); DestroyImmediate(Sun.Instance); Sun.Instance = star; // LensFlares gob = SunFlare.Instance.gameObject; KopernicusSunFlare flare = gob.AddComponent <KopernicusSunFlare>(); gob.name = star.sun.name; Utility.CopyObjectFields(SunFlare.Instance, flare, false); DestroyImmediate(SunFlare.Instance); SunFlare.Instance = star.lensFlare = flare; // Bodies Dictionary <String, KeyValuePair <CelestialBody, CelestialBody> > fixes = new Dictionary <String, KeyValuePair <CelestialBody, CelestialBody> >(); foreach (CelestialBody body in PSystemManager.Instance.localBodies) { // More stars if (body.flightGlobalsIndex != 0 && body.scaledBody.GetComponentsInChildren <SunShaderController>(true).Length > 0) { GameObject starObj = Instantiate(Sun.Instance.gameObject); star = starObj.GetComponent <KopernicusStar>(); star.sun = body; starObj.transform.parent = Sun.Instance.transform.parent; starObj.name = body.name; starObj.transform.localPosition = Vector3.zero; starObj.transform.localRotation = Quaternion.identity; starObj.transform.localScale = Vector3.one; starObj.transform.position = body.position; starObj.transform.rotation = body.rotation; GameObject flareObj = Instantiate(SunFlare.Instance.gameObject); flare = flareObj.GetComponent <KopernicusSunFlare>(); star.lensFlare = flare; flareObj.transform.parent = SunFlare.Instance.transform.parent; flareObj.name = body.name; flareObj.transform.localPosition = Vector3.zero; flareObj.transform.localRotation = Quaternion.identity; flareObj.transform.localScale = Vector3.one; flareObj.transform.position = body.position; flareObj.transform.rotation = body.rotation; } // Post spawn patcher if (body.Has("orbitPatches")) { ConfigNode orbitNode = body.Get <ConfigNode>("orbitPatches"); OrbitLoader loader = new OrbitLoader(body); Parser.LoadObjectFromConfigurationNode(loader, orbitNode, "Kopernicus"); CelestialBody oldRef = body.referenceBody; body.referenceBody.orbitingBodies.Remove(body); CelestialBody newRef = UBI.GetBody(loader.referenceBody); if (newRef != null) { body.orbit.referenceBody = body.orbitDriver.referenceBody = newRef; } else { // Log the exception Debug.Log("Exception: PostSpawnOrbit reference body for \"" + body.name + "\" could not be found. Missing body name is \"" + loader.referenceBody + "\"."); // Open the Warning popup Injector.DisplayWarning(); } fixes.Add(body.transform.name, new KeyValuePair <CelestialBody, CelestialBody>(oldRef, body.referenceBody)); body.referenceBody.orbitingBodies.Add(body); body.referenceBody.orbitingBodies = body.referenceBody.orbitingBodies.OrderBy(cb => cb.orbit.semiMajorAxis).ToList(); body.orbit.Init(); body.orbitDriver.UpdateOrbit(); // Calculations if (!body.Has("sphereOfInfluence")) { body.sphereOfInfluence = body.orbit.semiMajorAxis * Math.Pow(body.Mass / body.orbit.referenceBody.Mass, 0.4); } if (!body.Has("hillSphere")) { body.hillSphere = body.orbit.semiMajorAxis * (1 - body.orbit.eccentricity) * Math.Pow(body.Mass / body.orbit.referenceBody.Mass, 0.333333333333333); } if (body.solarRotationPeriod) { Double rotPeriod = Utility.FindBody(PSystemManager.Instance.systemPrefab.rootBody, body.transform.name).celestialBody.rotationPeriod; Double num1 = Math.PI * 2 * Math.Sqrt(Math.Pow(Math.Abs(body.orbit.semiMajorAxis), 3) / body.orbit.referenceBody.gravParameter); body.rotationPeriod = rotPeriod * num1 / (num1 + rotPeriod);; } } } // Update the order in the tracking station List <MapObject> trackingstation = new List <MapObject>(); Utility.DoRecursive(PSystemManager.Instance.localBodies[0], cb => cb.orbitingBodies, cb => { trackingstation.Add(PlanetariumCamera.fetch.targets.Find(t => t.celestialBody == cb)); }); PlanetariumCamera.fetch.targets.Clear(); PlanetariumCamera.fetch.targets.AddRange(trackingstation); // Update the initialTarget of the tracking station Resources.FindObjectsOfTypeAll <PlanetariumCamera>().FirstOrDefault().initialTarget = Resources.FindObjectsOfTypeAll <ScaledMovement>().FirstOrDefault(o => o.celestialBody.isHomeWorld); // Undo stuff foreach (CelestialBody b in PSystemManager.Instance.localBodies.Where(b_ => b_.Has("orbitPatches"))) { fixes[b.transform.name].Value.orbitingBodies.Remove(b); fixes[b.transform.name].Key.orbitingBodies.Add(b); fixes[b.transform.name].Key.orbitingBodies = fixes[b.transform.name].Key.orbitingBodies.OrderBy(cb => cb.orbit.semiMajorAxis).ToList(); } #if !KSP131 if (ExpansionsLoader.IsExpansionInstalled("MakingHistory")) { PQSCity2[] cities = FindObjectsOfType <PQSCity2>(); foreach (String site in Templates.RemoveLaunchSites) { // Remove the launch site from the list if it exists if (PSystemSetup.Instance.LaunchSites.Any(s => s.name == site)) { PSystemSetup.Instance.RemoveLaunchSite(site); } PQSCity2 city = cities.FirstOrDefault(c => c.gameObject.name == site || c.gameObject.name == site + "(Clone)"); // Kill the PQSCity if it exists if (city != null) { Destroy(city.gameObject); } } // PSystemSetup.RemoveLaunchSite does not remove launch sites from PSystemSetup.StockLaunchSites // Currently an ArgumentOutOfRangeException can result when they are different lists because of a bug in stock code try { FieldInfo stockLaunchSitesField = typeof(PSystemSetup).GetField("stocklaunchsites", BindingFlags.NonPublic | BindingFlags.Instance); LaunchSite[] stockLaunchSites = (LaunchSite[])stockLaunchSitesField.GetValue(PSystemSetup.Instance); LaunchSite[] updateStockLaunchSites = stockLaunchSites.Where(site => !Templates.RemoveLaunchSites.Contains(site.name)).ToArray(); if (stockLaunchSites.Length != updateStockLaunchSites.Length) { stockLaunchSitesField.SetValue(PSystemSetup.Instance, updateStockLaunchSites); } } catch (Exception ex) { Logger.Default.Log("Failed to remove launch sites from 'stockLaunchSites' field. Exception information follows."); Logger.Default.LogException(ex); } } #endif #if FALSE // AFG-Ception foreach (CelestialBody body in PSystemManager.Instance.localBodies) { if (body.afg == null) { continue; } foreach (KopernicusStar s in KopernicusStar.Stars) { AtmosphereFromGround afg; if (s != Sun.Instance) { afg = Instantiate(body.afg.gameObject) .GetComponent <AtmosphereFromGround>(); Utility.CopyObjectFields(body.afg, afg, false); afg.transform.parent = body.afg.transform.parent; afg.transform.localPosition = body.afg.transform.localPosition; afg.transform.localScale = body.afg.transform.localScale; afg.transform.localRotation = body.afg.transform.localRotation; afg.gameObject.layer = body.afg.gameObject.layer; } else { afg = body.afg; } afg.gameObject.AddComponent <KopernicusStarAFG>().Star = s; } } #endif }
void Awake() { foreach (ConfigNode city in GameDatabase.Instance.GetConfigNodes("CITY")) { // check for a name, we need one if (!city.HasValue("name")) { continue; } // create the new city GameObject cityObject = new GameObject(); cityObject.name = city.GetValue("name"); PQSCity2 pqsCity = cityObject.AddComponent <PQSCity2>(); pqsCity.objectName = cityObject.name; // read and set values, using defaults when none are defined if (city.HasValue("verticalOffset")) { pqsCity.alt = double.Parse(city.GetValue("verticalOffset")); pqsCity.snapHeightOffset = double.Parse(city.GetValue("verticalOffset")); } CelestialBody body = FlightGlobals.GetHomeBody(); if (city.HasValue("body")) { body = FlightGlobals.GetBodyByName(city.GetValue("body")); } pqsCity.sphere = body.pqsController; if (city.HasValue("lat")) { pqsCity.lat = double.Parse(city.GetValue("lat")); } if (city.HasValue("lon")) { pqsCity.lon = double.Parse(city.GetValue("lon")); } if (city.HasValue("rotation")) { pqsCity.rotation = double.Parse(city.GetValue("rotation")); } if (city.HasValue("snapToSurface")) { pqsCity.snapToSurface = city.GetValue("snapToSurface").Equals("true", StringComparison.OrdinalIgnoreCase); } if (city.HasValue("displayName")) { pqsCity.displayobjectName = city.GetValue("displayName"); } else { pqsCity.displayobjectName = cityObject.name; } // all the subnodes ConfigNode[] lods = city.GetNodes("LOD"); String[] flagTransforms = city.GetValues("flagTransform"); ConfigNode[] launchSites = city.GetNodes("LAUNCHSITE"); // load the LODs and models List <PQSCity2.LodObject> lodObjects = new List <PQSCity2.LodObject>(); foreach (ConfigNode lod in lods) { // create a new LodObject PQSCity2.LodObject lodObject = new PQSCity2.LodObject(); // define the distance to stop rendering if (lod.HasValue("visibleRange")) { lodObject.visibleRange = float.Parse(lod.GetValue("visibleRange")); } else { lodObject.visibleRange = 25000; } // read the models attached to this LOD ConfigNode[] models = lod.GetNodes("MODEL"); List <GameObject> objects = new List <GameObject>(); foreach (ConfigNode model in models) { // make sure the model exists if (!model.HasValue("model") | !GameDatabase.Instance.ExistsModel(model.GetValue("model"))) { continue; } // get an instance of the model GameObject modelInstance = GameDatabase.Instance.GetModel(model.GetValue("model")); // attach it to the city modelInstance.transform.parent = cityObject.transform; // set the transform values if defined if (model.HasValue("position")) { modelInstance.transform.localPosition = ConfigNode.ParseVector3(model.GetValue("position")); } if (model.HasValue("rotation")) { modelInstance.transform.localEulerAngles = ConfigNode.ParseVector3(model.GetValue("rotation")); } if (model.HasValue("scale")) { modelInstance.transform.localScale = ConfigNode.ParseVector3(model.GetValue("scale")); } // move to the local scenery layer modelInstance.SetLayerRecursive(15); // add the model to the list //objects.Add(modelInstance); modelInstance.SetActive(true); // force all colliders to be concave MeshCollider[] mColliders = modelInstance.GetComponentsInChildren <MeshCollider>(true); foreach (MeshCollider collider in mColliders) { collider.convex = false; } } // add the object list to the lodObject lodObject.objects = objects.ToArray(); // add the lodObject to the lodObject list lodObjects.Add(lodObject); } // add the LODs to the PQSCity pqsCity.objects = lodObjects.ToArray(); // set the flag transforms if (flagTransforms.Length != 0) { // add the flag handler component CityFlag cityFlag = cityObject.AddComponent <CityFlag>(); // add each transform to the handler foreach (string flagTransform in flagTransforms) { cityFlag.flagObjects.Add(CityUtils.FindChild(flagTransform, cityObject)); } } // finalize the PQSCity cityObject.transform.parent = body.pqsController.transform; pqsCity.Orientate(); // add a CommNet antenna if defined if (city.HasNode("COMMNET")) { // reference the confignode for future reference ConfigNode commNet = city.GetNode("COMMNET"); // create the CommNetHome CommNet.CommNetHome cNetHome = cityObject.AddComponent <CommNet.CommNetHome>(); // set the internal name cNetHome.nodeName = cityObject.name; // get the values from the config if (commNet.HasValue("nodeName")) { cNetHome.displaynodeName = commNet.GetValue("nodeName"); } else { cNetHome.displaynodeName = pqsCity.displayobjectName; } if (commNet.HasValue("antennaPower")) { cNetHome.antennaPower = double.Parse(commNet.GetValue("antennaPower")); } if (commNet.HasValue("isKSC")) { cNetHome.isKSC = commNet.GetValue("isKSC").Equals("true", StringComparison.OrdinalIgnoreCase); } if (commNet.HasValue("isPermanent")) { cNetHome.isPermanent = commNet.GetValue("isPermanent").Equals("true", StringComparison.OrdinalIgnoreCase); } if (city.HasValue("commNetTransform")) { cNetHome.nodeTransform = CityUtils.FindChild(city.GetValue("commNetTransform"), cityObject).transform; } else { cNetHome.nodeTransform = cityObject.transform; } } // setup the launch sites (Making History required) foreach (ConfigNode site in launchSites) { // we need a name if (!site.HasValue("name")) { continue; } // create the spawnpoint LaunchSite.SpawnPoint spawnPoint = new LaunchSite.SpawnPoint(); spawnPoint.name = site.GetValue("name"); // select the facility EditorFacility facility = EditorFacility.VAB; if (site.HasValue("facility") && site.GetValue("facility") == "SPH") { facility = EditorFacility.SPH; } // find and reparent the spawnTransform // reparenting is done to ensure that it works Transform spawnTransform = CityUtils.FindChild(site.GetValue("transform"), cityObject).transform; spawnTransform.SetParent(cityObject.transform); // create the launchsite LaunchSite launchSite = new LaunchSite(site.GetValue("name"), body.pqsController.name, site.GetValue("title"), new LaunchSite.SpawnPoint[] { spawnPoint }, cityObject.name + "/" + spawnTransform.name, facility); // change the mapIcon // todo: remove mapIcon if (facility == EditorFacility.VAB) { launchSite.nodeType = KSP.UI.Screens.Mapview.MapNode.SiteType.LaunchSite; } else { launchSite.nodeType = KSP.UI.Screens.Mapview.MapNode.SiteType.Runway; } // finalize the LaunchSite launchSite.Setup(pqsCity, new PQS[] { body.pqsController }); PSystemSetup.Instance.AddLaunchSite(launchSite); } } }
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); } } }
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; } 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 oldGroundLevel = pqs.GetSurfaceHeight(city.PlanetRelativePosition) - body.Radius; Debug.Log("PQSCity2Fixer", " > Old Ground Level at Mod (GETSURFACE) = " + oldGroundLevel); double oldOceanOffset = body.ocean && oldGroundLevel < 0 ? oldGroundLevel : 0d; Debug.Log("PQSCity2Fixer", " > Old Ocean Offset at Mod = " + oldOceanOffset); oldGroundLevel = body.ocean && oldGroundLevel < 0 ? 0d : oldGroundLevel; Debug.Log("PQSCity2Fixer", " > Old Ground Level at Mod (WITH OCEAN) = " + oldGroundLevel); double groundLevel = (hits[i].point - planet).magnitude - body.Radius; Debug.Log("PQSCity2Fixer", " > Ground Level at Mod (RAYCAST) = " + groundLevel); double oceanOffset = body.ocean && groundLevel < 0 ? groundLevel : 0d; Debug.Log("PQSCity2Fixer", " > Ocean Offset at Mod = " + oceanOffset); 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 - oldGroundLevel) / resizeBuildings - (groundLevel - oldGroundLevel) / (resize * landscape); Debug.Log("PQSCity2Fixer", " > Builtin Offset = " + builtInOffset); city.alt = groundLevel + builtInOffset * 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 builtInOffset = city.snapHeightOffset / resizeBuildings - (groundLevel + oceanOffset - oldGroundLevel - oldOceanOffset) / (resize * landscape); Debug.Log("PQSCity2Fixer", " > Builtin Offset = " + builtInOffset); double newOffset = builtInOffset * resizeBuildings + groundLevel + oceanOffset - oldGroundLevel - oldOceanOffset; Debug.Log("PQSCity2Fixer", " > PQSCity2 Fixed Surface Offset = " + newOffset); city.alt += newOffset - city.snapHeightOffset; city.snapHeightOffset = newOffset; } // Because, SQUAD city.PositioningPoint.localPosition *= (float)(body.Radius + city.alt); // Apply Changes and Destroy city.Orientate(); DestroyImmediate(this); } } } }
void LinkToKSC(PQSCity2 pqs) { PQSCity KSC = body.GetComponentsInChildren<PQSCity>().First(m => m.name == "KSC"); LatLon movedKSC = new LatLon(KSC.repositionRadial.normalized); Vector3 reference = body.Get<Dictionary<object, Vector3>>("PQSCityGroups")[pqs].normalized; if (reference == movedKSC.vector) { // Fix Rotation float angle = KSC.reorientFinalAngle - (-15); pqs.rotation += angle; // Stock Vectors (KSC, North, East) LatLon stockKSC = new LatLon(new Vector3(157000, -1000, -570000).normalized); Vector3 north = Vector3.ProjectOnPlane(Vector3.up, stockKSC.vector); Vector3 east = QuaternionD.AngleAxis(90, stockKSC.vector) * north; // PQS Vectors (PQS, North, East) Vector3 oldPQS = Vector3.ProjectOnPlane(pqs.PlanetRelativePosition.normalized, stockKSC.vector); Vector3 pqsNorth = Vector3.Project(oldPQS, north); Vector3 pqsEast = Vector3.Project(oldPQS, east); // Distance from KSC (Northward, Eastward) float northward = pqsNorth.magnitude * (1 - (Vector3.Angle(north.normalized, pqsNorth.normalized) / 90)); float eastward = pqsEast.magnitude * (1 - (Vector3.Angle(east.normalized, pqsEast.normalized) / 90)); // New KSC Vectors (North, East) Vector3 newNorth = Vector3.ProjectOnPlane(Vector3.up, movedKSC.vector).normalized; Vector3 newEast = (QuaternionD.AngleAxis(90, movedKSC.vector) * newNorth); // Account for PQSCity rotation: // PQSCity rotate when their Longitude changes angle -= (float)(stockKSC.lon - movedKSC.lon); QuaternionD rotation = QuaternionD.AngleAxis(angle, movedKSC.vector); // Calculate final position by adding the north and east distances to the movedKSC position // then rotate the new vector by as many degrees as it is necessary to account for the PQS model rotation LatLon newPQS = new LatLon(rotation * (movedKSC.vector + newNorth * northward + newEast * eastward)); pqs.lat = newPQS.lat; pqs.lon = newPQS.lon; // Fix Altitude if (!pqs.snapToSurface) { pqs.alt += (body.pqsController.GetSurfaceHeight(movedKSC.vector) - body.Radius) / (resize * landscape) - 64.7846885412; } } }
void GroupFixer(PQSCity2 pqs, Vector3 REFvector) { if (body == FlightGlobals.GetHomeBody()) LinkToKSC(pqs); Vector3 PQSvector = pqs.PlanetRelativePosition.normalized; Vector3 NEWvector = Vector3.LerpUnclamped(REFvector, PQSvector, (float)(resizeBuildings / resize)); LatLon NEWlatlon = new LatLon(NEWvector); pqs.lat = NEWlatlon.lat; pqs.lon = NEWlatlon.lon; }