Esempio n. 1
0
        public static double GetChuteArea(List <Part> parts)
        {
            double RCParameter    = 0;
            bool   realChuteInUse = false;

            try
            {
                foreach (Part p in parts)
                {
                    //Make a list of all the Module Names for easy checking later. This can be avoided, but is convenient.
                    List <string> ModuleNames = new List <string>();
                    foreach (PartModule pm in p.Modules)
                    {
                        ModuleNames.Add(pm.moduleName);
                    }

                    if (ModuleNames.Contains("RealChuteModule"))
                    {
                        if (!realChuteInUse)
                        {
                            RCParameter = 0;
                        }
                        //First off, get the PPMS since we'll need that
                        PartModule realChute = p.Modules["RealChuteModule"];
                        //Assuming that's not somehow null, then we continue
                        if (realChute != null) //Some of this was adopted from DebRefund, as Vendan's method of handling multiple parachutes is better than what I had.
                        {
                            //We make a list of ConfigNodes containing the parachutes (usually 1, but now there can be any number of them)
                            //We get that from the PPMS
                            ConfigNode rcNode = new ConfigNode();
                            realChute.Save(rcNode);

                            //It's existence means that RealChute is installed and in use on the craft (you could have it installed and use stock chutes, so we only check if it's on the craft)
                            realChuteInUse = true;

                            RCParameter += ProcessRealchute(rcNode);
                        }
                    }
                    else if (ModuleNames.Contains("RealChuteFAR")) //RealChute Lite for FAR
                    {
                        if (!realChuteInUse)
                        {
                            RCParameter = 0;
                        }

                        PartModule realChute = p.Modules["RealChuteFAR"];
                        float      diameter  = 0.0F; //realChute.moduleValues.GetValue("deployedDiameter")

                        if (realChute != null)
                        {
                            try
                            {
                                diameter = realChute.Fields.GetValue <float>("deployedDiameter");
                                Log.Info($"[SR] Diameter is {diameter}.");
                            }
                            catch (Exception e)
                            {
                                Debug.LogError("[SR] Exception while finding deployedDiameter for RealChuteFAR module on module.");
                                Debug.LogException(e);
                            }
                        }
                        else
                        {
                            Log.Info("[SR] moduleRef is null, attempting workaround to find diameter.");
                            object dDefault = p.partInfo.partPrefab.Modules["RealChuteFAR"]?.Fields?.GetValue("deployedDiameter"); //requires C# 6
                            if (dDefault != null)
                            {
                                diameter = Convert.ToSingle(dDefault);
                                Log.Info($"[SR] Workaround gave a diameter of {diameter}.");
                            }
                            else
                            {
                                Log.Info("[SR] Couldn't get default value, setting to 0 and calling it a day.");
                                diameter = 0.0F;
                            }
                        }
                        float dragC = 1.0f; //float.Parse(realChute.moduleValues.GetValue("staticCd"));
                        RCParameter += (dragC * Mathf.Pow(diameter, 2) * Math.PI / 4.0);

                        realChuteInUse = true;
                    }
                    else if (!realChuteInUse && ModuleNames.Contains("ModuleParachute"))
                    {
                        //Credit to m4v and RCSBuildAid: https://github.com/m4v/RCSBuildAid/blob/master/Plugin/CoDMarker.cs
                        Part         part      = p ?? p.partInfo.partPrefab; //the part, or the part prefab
                        DragCubeList dragCubes = part.DragCubes;
                        dragCubes.SetCubeWeight("DEPLOYED", 1);
                        dragCubes.SetCubeWeight("SEMIDEPLOYED", 0);
                        dragCubes.SetCubeWeight("PACKED", 0);
                        dragCubes.SetOcclusionMultiplier(0);
                        Quaternion rotation = Quaternion.LookRotation(Vector3d.up);
                        try
                        {
                            rotation = Quaternion.LookRotation(part.partTransform?.InverseTransformDirection(Vector3d.up) ?? Vector3d.up);
                        }
                        catch (Exception e)
                        {
                            Debug.LogException(e);
                        }
                        dragCubes.SetDragVectorRotation(rotation);
                    }
                    if (!realChuteInUse)
                    {
                        Part         part      = p ?? p.partInfo.partPrefab; //the part reference, or the part prefab
                        DragCubeList dragCubes = part.DragCubes;
                        dragCubes.ForceUpdate(false, true);
                        dragCubes.SetDragWeights();
                        dragCubes.SetPartOcclusion();

                        Vector3 dir = Vector3d.up;
                        try
                        {
                            dir = -part.partTransform?.InverseTransformDirection(Vector3d.down) ?? Vector3d.up;
                        }
                        catch (Exception e)
                        {
                            //Debug.LogException(e);
                            Log.Info("[SR] The expected excpetion is still present. " + e.Message);
                        }
                        dragCubes.SetDrag(dir, 0.03f); //mach 0.03, or about 10m/s

                        double dragCoeff = dragCubes.AreaDrag * PhysicsGlobals.DragCubeMultiplier;

                        RCParameter += (dragCoeff * PhysicsGlobals.DragMultiplier);
                    }
                }
            }
            catch (Exception e)
            {
                Debug.LogError("[SR] Error occured while trying to determine total chute area.");
                Debug.LogException(e);
            }
            return(RCParameter);
        }