public void Start() { if (HighLogic.LoadedSceneIsFlight && Statics.modifiedParts.ContainsKey(this.part.partInfo.partUrl)) { Log.Info("KSPPartVolumeModule.Start"); Statics.Check4DelModCargoPart(part); #if false ProtoPartSnapshot pps = part.protoPartSnapshot; foreach (var m in pps.modules) { if (m.moduleName == "ModuleCargoPart") { Log.Info("ModuleCargoPart found"); var currentCargoPart = m.moduleValues; Log.Info("ModuleCargoPart.configs: " + currentCargoPart); if (currentCargoPart.HasValue("packedVolume")) { var s = currentCargoPart.GetValue("packedVolume"); Log.Info("packedVolume found: " + s); currentCargoPart.SetValue("packedVolume", packedVolume.ToString("F0")); } else { Log.Error("packedVolume not found"); } } } #endif #if false var partConfig = part.partInfo.partConfig; if (partConfig != null) { Log.Info("partconfig found"); var moduleNodes = partConfig.GetNodes("MODULE"); Log.Info("partConfig: " + moduleNodes); Log.Info("moduleNodes.Count: " + moduleNodes.Length); for (int i = 0; i < moduleNodes.Length; i++) { Log.Info("name: " + moduleNodes[i].GetValue("name")); if (moduleNodes[i].GetValue("name") == "ModuleCargoPart") { Log.Info("ModuleCargoPart found"); var currentCargoPart = moduleNodes[i]; if (currentCargoPart.HasValue("packedVolume")) { var s = currentCargoPart.GetValue("packedVolume"); Log.Info("packedVolume found: " + s); currentCargoPart.SetValue("packedVolume", packedVolume.ToString("F0")); } else { Log.Error("packedVolume not found"); } } } } #endif } }
public void Start() { Settings.LoadConfig(); if (CheckForKIFA()) { return; } Start2(); Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); List <AvailablePart> loadedParts = PartLoader.LoadedPartsList; // PartLoader.Instance.loadedParts; StringBuilder stringBuilder; bool fileExists = File.Exists(VOL_CFG_FILE); Log.Info("Finding Parts Volume...."); using (List <AvailablePart> .Enumerator partEnumerator = loadedParts.GetEnumerator()) { while (partEnumerator.MoveNext()) { AvailablePart current = partEnumerator.Current; string[] urlParts = current.partUrl.Split('/'); string urlName = urlParts[urlParts.Length - 1]; // // urlName more precisely correspond to part name in the config than current.name, // but KerbalEVA and flag have empty urlname and need to be filtered, so: // string partName = urlParts[urlParts.Length - 1]; if (partName == "") { partName = current.name; } if (partBlacklist.Contains(partName) || Regex.IsMatch(partName, blacklistRegexPattern)) { Log.Info(String.Format("partName: {0, -40} found in the blacklist and ignored.", partName + ",")); continue; } bool contains_ModuleCargoPart = false; bool contains_ModuleInventoryPart = false; bool contains_KSPPartVolumeModule = false; bool containsCrew = false; bool isTank = false; bool isTankNotIgnoreable = false; bool sizeTooBig = false; bool isStock = false; bool isRcsPart = false; bool isEnginePart = false; ConfigNode currentCargoPart = null; if (!Settings.doStock) { if (urlParts[0] == "Squad" || urlParts[0] == "SquadExpansion") { if (!partWhitelist.Contains(partName)) { isStock = true; } } } var moduleNodes = current.partConfig.GetNodes("MODULE"); for (int i = 0; i < moduleNodes.Length; i++) { var name = moduleNodes[i].GetValue("name"); if (name == "ModuleCargoPart") { contains_ModuleCargoPart = true; currentCargoPart = moduleNodes[i]; } if (name == "ModuleInventoryPart") { contains_ModuleInventoryPart = true; } if (name == "KSPPartVolumeModule") { contains_KSPPartVolumeModule = true; } if (name == "ModuleRCS" || name == "ModuleRCSFX") { isRcsPart = true; } if (name == "ModuleEngines" || name == "ModuleEnginesFX") { isEnginePart = true; } // Check for manned if (!Settings.manned) { int CrewCapacity = 0; if (current.partConfig.TryGetValue("CrewCapacity", ref CrewCapacity)) { if (CrewCapacity > 0) { containsCrew = true; } } } } if (contains_KSPPartVolumeModule) { contains_ModuleCargoPart = false; } var resNodes = current.partConfig.GetNodes("RESOURCE"); float mass = 0; current.partConfig.TryGetValue("mass", ref mass); float totalResMass = 0; //if (!Settings.doTanks) { foreach (var resNode in resNodes) { var name = resNode.GetValue("name"); if (resourceBlackList.Contains(name)) { continue; } float maxAmount = 0; resNode.TryGetValue("maxAmount", ref maxAmount); var definition = PartResourceLibrary.Instance.GetDefinition(name); if (definition != null) { var density = definition.density; float resMass = maxAmount * density; totalResMass += resMass; } } if (totalResMass > mass) { isTankNotIgnoreable = true; isTank = !Settings.doTanks; } } stringBuilder = new StringBuilder(); Bounds bounds = default(Bounds); foreach (Bounds rendererBound in PartGeometryUtil.GetRendererBounds((Part)current.partPrefab)) { bounds.Encapsulate(rendererBound); } #if false Bounds colliderBounds = default(Bounds); foreach (Bounds rendererBound in PartGeometryUtil.GetPartColliderBounds((Part)current.partPrefab)) { colliderBounds.Encapsulate(rendererBound); } Bounds allBounds = default(Bounds); var a = PartGeometryUtil.GetPartColliderBounds(current.partPrefab); allBounds = PartGeometryUtil.MergeBounds(a, current.iconPrefab.transform.root); #endif float vol = (float)(bounds.size.x * bounds.size.y * bounds.size.z) * 1000f; if (vol > Settings.largestAllowablePart && Settings.limitSize) { sizeTooBig = true; } var maxLen = Math.Max(bounds.size.x, Math.Max(bounds.size.y, bounds.size.z)); var minLen = Math.Min(bounds.size.x, Math.Min(bounds.size.y, bounds.size.z)); var tankVol = Math.Pow(minLen * 0.5, 2) * maxLen * Math.PI * 1000; var adjVol = AdjustedVolume(current, vol, isEnginePart, isRcsPart, out float adj); int stackableQuantity = Math.Min((int)Settings.maxCommonStackVolume / (int)adjVol, Settings.maxPartsInStack); bool isManipulableOnly = false; bool isKSP_PartVolumeModule = false; string currentCargoPartPackedVolume = ""; if (currentCargoPart != null) { Log.Info("currentCargoPart: " + current.name); if (currentCargoPart.HasValue("packedVolume")) { currentCargoPartPackedVolume = currentCargoPart.GetValue("packedVolume"); currentCargoPart.SetValue("packedVolume", adjVol.ToString("F0")); Log.Info(String.Format("partName: {0, -40} packedVolume: {1,7}, calcPackedVolume: {2,7:F0}", partName + ",", currentCargoPartPackedVolume, adjVol)); var v = float.Parse(currentCargoPartPackedVolume); if (v <= 0) { isManipulableOnly = true; } isKSP_PartVolumeModule = currentCargoPart.HasValue("KSP_PartVolume"); } else { Log.Error(String.Format("partName: {0, -40} packedVolume not found", partName + ",")); } } if (contains_ModuleInventoryPart) { adjVol = -1; } StringBuilder tmp = new StringBuilder(); tmp.AppendLine("// " + current.partUrl); tmp.AppendLine("// Dimensions: x: " + bounds.size.x.ToString("F2") + ", y: " + bounds.size.y.ToString("F2") + ", z: " + bounds.size.z.ToString("F2")); tmp.AppendLine(string.Format("// Bounding Box Size: {0} liters", vol)); tmp.AppendLine("// Volume adjustment: " + (adj * 100).ToString("F0") + "%"); if (isRcsPart) { tmp.AppendLine("// RCS module detected"); } if (isEnginePart) { tmp.AppendLine("// Engine module detected"); } Part part = UnityEngine.Object.Instantiate(current.partPrefab); part.gameObject.SetActive(value: false); if (isTankNotIgnoreable) { var volume = DetermineVolume(part) * 1000; stringBuilder.AppendLine("// Calculated tank volume: " + volume.ToString("F1")); stringBuilder.AppendLine("// Calculated tankVol (max x min) volume: " + tankVol.ToString("F1")); } tmp.AppendLine("//"); if (!containsCrew && !isTank && !sizeTooBig && !isStock && !contains_ModuleInventoryPart && (!contains_ModuleCargoPart || (contains_ModuleCargoPart && Settings.processManipulableOnly && isManipulableOnly) || (!isKSP_PartVolumeModule && partWhitelist.Contains(partName)) )) { stringBuilder.Append(tmp); string adjName = partName.Replace(' ', '?').Replace('(', '?').Replace(')', '?'); if (contains_ModuleCargoPart) { stringBuilder.AppendLine("@PART[" + adjName + "]:HAS[@MODULE[ModuleCargoPart]]:Final"); stringBuilder.AppendLine("{"); stringBuilder.AppendLine(" @MODULE[ModuleCargoPart]"); stringBuilder.AppendLine(" {"); stringBuilder.AppendLine(" %packedVolume = " + adjVol.ToString("F0")); } else { stringBuilder.AppendLine("@PART[" + adjName + "]:HAS[!MODULE[ModuleCargoPart]]:Final"); stringBuilder.AppendLine("{"); stringBuilder.AppendLine(" MODULE"); stringBuilder.AppendLine(" {"); stringBuilder.AppendLine(" name = ModuleCargoPart"); stringBuilder.AppendLine(" packedVolume = " + adjVol.ToString("F0")); } if (Settings.stackParts && stackableQuantity > 1) { stringBuilder.AppendLine(" %stackableQuantity = " + stackableQuantity); } { stringBuilder.AppendLine(" %KSP_PartVolume = true"); stringBuilder.AppendLine(" }"); stringBuilder.AppendLine("}"); } RestartWindowVisible = true; newPartsDetected = true; part = UnityEngine.Object.Instantiate(current.partPrefab); part.gameObject.SetActive(value: false); foreach (PartModule m in part.Modules) { if (m.moduleName == "ModuleCargoPart") { var mcp = m as ModuleCargoPart; mcp.part = part; mcp.packedVolume = adjVol; if (stackableQuantity > 1) { mcp.stackableQuantity = stackableQuantity; } for (int i = current.moduleInfos.Count - 1; i >= 0; --i) { AvailablePart.ModuleInfo info = current.moduleInfos[i]; if (info.moduleName == Localizer.Format("#autoLOC_8002221")) // Cargo Part { try { info.info = mcp.GetInfo(); } catch (Exception ex) { Log.Error("PartInfo.Start, Part: " + current.partUrl + ", Exception caught in ModuleCargoPart.GetInfo, exception: " + ex.Message + "\n" + ex.StackTrace); info.info = "KSP_PartVolume error"; } break; } } } } } else { if (!fileExists) { stringBuilder.Append(tmp); stringBuilder.AppendLine("// Bypass reasons:"); if (containsCrew) { stringBuilder.AppendLine("// contains crew "); } if (isTank) { stringBuilder.AppendLine("// is tank"); } if (sizeTooBig) { stringBuilder.AppendLine("// size exceeds largestAllowablePart: " + Settings.largestAllowablePart); } if (isStock) { stringBuilder.AppendLine("// is stock"); } if (contains_ModuleCargoPart && !Settings.processManipulableOnly || contains_ModuleCargoPart && !isManipulableOnly) { stringBuilder.AppendLine("// contains ModuleCargoPart (packedVolume = " + currentCargoPartPackedVolume + ")"); } if (contains_ModuleInventoryPart) { stringBuilder.AppendLine("// contains ModuleInventoryPart"); } stringBuilder.AppendLine("//"); adjVol = -999; #if true current.partConfig.RemoveNode(currentCargoPart); //Part part = UnityEngine.Object.Instantiate(current.partPrefab); //part.gameObject.SetActive(value: false); Statics.Check4DelModCargoPart(part); //Destroy(part); #endif } } Destroy(part); if (!Statics.modifiedParts.ContainsKey(current.partUrl)) { Statics.modifiedParts.Add(current.partUrl, new PartModification(stringBuilder, adjVol, adjVol == -999)); } else { Log.Error("modifiedParts already contains: " + current.partUrl); } if (!fileExists) { stringBuilder.AppendLine("// ----------------------------------------------------------------------"); } } } stringBuilder = new StringBuilder(); if (Statics.modifiedParts.Count > 0) { foreach (var d in Statics.modifiedParts) { stringBuilder.Append(d.Value.cfg.ToString()); } File.AppendAllText(VOL_CFG_FILE, stringBuilder.ToString()); } stopwatch.Stop(); Log.Info("File written to " + VOL_CFG_FILE); Log.Info(string.Format("Run in {0}ms", (object)stopwatch.ElapsedMilliseconds)); //if (numCargoPartsAdded > 0) // ShowWarning(numCargoPartsAdded); }