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
            }
        }
Exemple #2
0
        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);
        }