Example #1
0
        StageParts DetermineStage(Part parent)
        {
            StageParts  stage   = new StageParts();
            List <Part> toCheck = new List <Part>()
            {
                parent
            };

            while (toCheck.Count > 0) //should instead search through the children, stopping when finding a decoupler, then switch to it's children
            {
                Part checking = toCheck[0];
                toCheck.RemoveAt(0);
                stage.parts.Add(checking);

                foreach (Part part in checking.children)
                {
                    //search for decouplers
                    if (part.FindModulesImplementing <IStageSeparator>().Count() >= 1)
                    {
                        stage.decouplers.Add(part);
                    }
                    else
                    {
                        toCheck.Add(part);
                    }
                }
            }
            return(stage);
        }
Example #2
0
        StageParts DetermineStage(Part parent)
        {
            StageParts  stage   = new StageParts();
            List <Part> toCheck = new List <Part>()
            {
                parent
            };

            while (toCheck.Count > 0) //should instead search through the children, stopping when finding a decoupler, then switch to it's children
            {
                Part checking = toCheck[0];
                toCheck.RemoveAt(0);
                stage.parts.Add(checking);

                foreach (Part part in checking.children)
                {
                    //search for decouplers
                    if (part.Modules.Contains("ModuleDecouple") || part.Modules.Contains("ModuleAnchoredDecoupler"))
                    {
                        stage.decouplers.Add(part);
                    }
                    else
                    {
                        toCheck.Add(part);
                    }
                }
            }
            return(stage);
        }
Example #3
0
        public void BreakShipIntoStages()
        {
            stages.Clear();
            //loop through the part tree and try to break it into stages
            List <Part>    parts    = EditorLogic.fetch.ship.parts;
            EditorStatItem current  = new EditorStatItem();
            int            stageNum = 0;

            StageParts  stage = new StageParts();
            List <Part> RemainingDecouplers = null; // = new List<Part>() { parts[0] };

            foreach (var p in parts)
            {
                if (p.parent == null)
                {
                    RemainingDecouplers = new List <Part>()
                    {
                        p
                    };
                    break;
                }
            }
            if (RemainingDecouplers == null)
            {
                Log.Error("No parent part found");
                return;
            }
            while (RemainingDecouplers.Count > 0)
            {
                //determine stages from the decouplers
                Part parent = RemainingDecouplers[0];
                RemainingDecouplers.RemoveAt(0);
                stage   = DetermineStage(parent);
                current = new EditorStatItem
                {
                    stageNumber = stageNum++,
                    parts       = stage.parts
                };
                RemainingDecouplers.AddRange(stage.decouplers);

                //compute properties
                double dryMass = 0;
                double wetMass = 0;

                stage.parts.ForEach(p => { dryMass += p.mass; wetMass += p.mass + p.GetResourceMass(); });
                current.dryMass   = dryMass;
                current.mass      = wetMass;
                current.chuteArea = StageRecovery.GetChuteArea(stage.parts);

                stages.Add(current);
            }

            ConsolidateStages();
            Log.Info("[SR] Found " + stages.Count + " stages!");
        }
Example #4
0
        StageParts DetermineStage(Part parent)
        {
            Log.Info("DetermineStage 1 parent: " + parent.partInfo.title);
            StageParts  stage   = new StageParts();
            List <Part> toCheck = new List <Part>()
            {
                parent
            };

            while (toCheck.Count > 0) //should instead search through the children, stopping when finding a decoupler, then switch to it's children
            {
                Part checking = toCheck[0];
                toCheck.RemoveAt(0);
                bool isEnginePlate = false;
                if (Versioning.version_major == 1 && Versioning.version_minor >= 7)
                {
                    isEnginePlate = CheckForEnginePlate(parent, checking);
                }

                stage.parts.Add(checking);

                for (int i = 0; i < checking.children.Count; i++)
                //foreach (Part part in checking.children)
                {
                    Part part = checking.children[i];

                    //search for decouplers
                    //if (part.Modules.Contains("ModuleDecouple") || part.Modules.Contains("ModuleAnchoredDecoupler"))

                    if (Versioning.version_major == 1 && Versioning.version_minor >= 7 && isEnginePlate)
                    {
                        if (CheckForParentEnginePlate(part))
                        {
                            stage.decouplers.Add(part);
                            continue;
                        }
                    }

                    // If this part is a decoupler, add it to the list
                    if (part.FindModulesImplementing <IStageSeparator>().Count > 0)
                    {
                        stage.decouplers.Add(part);
                    }
                    else
                    {
                        toCheck.Add(part);
                    }
                }
            }
            return(stage);
        }
Example #5
0
        public void BreakShipIntoStages()
        {
            stages.Clear();
            //loop through the part tree and try to break it into stages
            List <Part>    parts          = EditorLogic.fetch.ship.parts;
            EditorStatItem current        = new EditorStatItem();
            int            stageNum       = 0;
            bool           realChuteInUse = false;

            StageParts  stage = new StageParts();
            List <Part> RemainingDecouplers = new List <Part>()
            {
                parts[0]
            };

            while (RemainingDecouplers.Count > 0)
            {
                //determine stages from the decouplers
                Part parent = RemainingDecouplers[0];
                RemainingDecouplers.RemoveAt(0);
                stage               = DetermineStage(parent);
                current             = new EditorStatItem();
                current.stageNumber = stageNum++;
                current.parts       = stage.parts;
                RemainingDecouplers.AddRange(stage.decouplers);

                //compute properties
                foreach (Part part in stage.parts)
                {
                    current.dryMass += part.mass;
                    current.mass    += part.mass + part.GetResourceMass();

                    double pChutes = 0;
                    if (part.Modules.Contains("RealChuteModule"))
                    {
                        PartModule realChute = part.Modules["RealChuteModule"];
                        ConfigNode rcNode    = new ConfigNode();
                        realChute.Save(rcNode);

                        //This is where the Reflection starts. We need to access the material library that RealChute has, so we first grab it's Type
                        Type matLibraryType = AssemblyLoader.loadedAssemblies
                                              .SelectMany(a => a.assembly.GetExportedTypes())
                                              .SingleOrDefault(t => t.FullName == "RealChute.Libraries.MaterialsLibrary.MaterialsLibrary");


                        //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[] parachutes = rcNode.GetNodes("PARACHUTE");
                        //We then act on each individual parachute in the module
                        foreach (ConfigNode chute in parachutes)
                        {
                            //First off, the diameter of the parachute. From that we can (later) determine the Vt, assuming a circular chute
                            float diameter = float.Parse(chute.GetValue("deployedDiameter"));
                            //The name of the material the chute is made of. We need this to get the actual material object and then the drag coefficient
                            string mat = chute.GetValue("material");
                            //This grabs the method that RealChute uses to get the material. We will invoke that with the name of the material from before.
                            System.Reflection.MethodInfo matMethod = matLibraryType.GetMethod("GetMaterial", new Type[] { mat.GetType() });
                            //In order to invoke the method, we need to grab the active instance of the material library
                            object MatLibraryInstance = matLibraryType.GetProperty("Instance").GetValue(null, null);
                            //With the library instance we can invoke the GetMaterial method (passing the name of the material as a parameter) to receive an object that is the material
                            object materialObject = matMethod.Invoke(MatLibraryInstance, new object[] { mat });
                            //With that material object we can extract the dragCoefficient using the helper function above.
                            float dragC = (float)StageRecovery.GetMemberInfoValue(materialObject.GetType().GetMember("DragCoefficient")[0], materialObject);
                            //Now we calculate the RCParameter. Simple addition of this doesn't result in perfect results for Vt with parachutes with different diameter or drag coefficients
                            //But it works perfectly for mutiple identical parachutes (the normal case)
                            pChutes += dragC * (float)Math.Pow(diameter, 2);
                        }
                        realChuteInUse = true;
                    }
                    else if (part.Modules.Contains("RealChuteFAR")) //RealChute Lite for FAR
                    {
                        PartModule realChute = part.Modules["RealChuteFAR"];
                        float      diameter  = (float)realChute.Fields.GetValue("deployedDiameter");
                        // = float.Parse(realChute.moduleValues.GetValue("deployedDiameter"));
                        float dragC = 1.0f; //float.Parse(realChute.moduleValues.GetValue("staticCd"));
                        pChutes += dragC * (float)Math.Pow(diameter, 2);

                        realChuteInUse = true;
                    }
                    else if (!realChuteInUse && part.Modules.Contains("ModuleParachute"))
                    {
                        double scale = 1.0;
                        //check for Tweakscale and modify the area appropriately
                        if (part.Modules.Contains("TweakScale"))
                        {
                            PartModule tweakScale = part.Modules["TweakScale"];
                            double     currentScale = 100, defaultScale = 100;
                            double.TryParse(tweakScale.Fields.GetValue("currentScale").ToString(), out currentScale);
                            double.TryParse(tweakScale.Fields.GetValue("defaultScale").ToString(), out defaultScale);
                            scale = currentScale / defaultScale;
                        }

                        ModuleParachute mp = (ModuleParachute)part.Modules["ModuleParachute"];
                        //dragCoeff += part.mass * mp.fullyDeployedDrag;
                        pChutes += mp.areaDeployed * Math.Pow(scale, 2);
                    }

                    current.chuteArea += pChutes;
                }

                stages.Add(current);
            }

            ConsolidateStages();
            Debug.Log("[SR] Found " + stages.Count + " stages!");
        }
        public void BreakShipIntoStages()
        {
            //loop through the part tree and try to break it into stages
            List <Part>    parts    = EditorLogic.fetch.ship.parts;
            EditorStatItem current  = new EditorStatItem();
            int            stageNum = 0;

            StageParts  stage = new StageParts();
            List <Part> RemainingDecouplers = null; // = new List<Part>() { parts[0] };

            for (int i = 0; i < parts.Count; i++)
            {
                Part p = parts[i];
                if (p.parent == null)
                {
                    RemainingDecouplers = new List <Part>()
                    {
                        p
                    };
                    break;
                }
            }
            if (RemainingDecouplers == null)
            {
                stages.Clear();
                Log.Error("No parent part found");
                return;
            }

            var stageList = new List <EditorStatItem>();

            while (RemainingDecouplers.Count > 0)
            {
                //determine stages from the decouplers
                Part parent = RemainingDecouplers[0];
                RemainingDecouplers.RemoveAt(0);
                stage   = DetermineStage(parent);
                current = new EditorStatItem
                {
                    stageNumber = stageNum++,
                    parts       = stage.parts
                };
#if DEBUG
                Log.Info("Parent part: " + parent.partInfo.title);
                foreach (var d in stage.decouplers)
                {
                    Log.Info("Child decouplers: " + d.partInfo.title);
                }
#endif

                RemainingDecouplers.AddRange(stage.decouplers);

                //compute properties
                double dryMass = 0;
                double wetMass = 0;

                stage.parts.ForEach(p => { dryMass += p.mass; wetMass += p.mass + p.GetResourceMass(); });


                current.dryMass   = dryMass;
                current.mass      = wetMass;
                current.chuteArea = StageRecovery.GetChuteArea(stage.parts);

                stageList.Add(current);
            }

            ConsolidateStages(ref stageList);
            stages.Clear(); // wait until we have a full stages collection before we clear it
            stages.AddRange(stageList);
            Log.Info("[SR] Found " + stages.Count + " stages!");
        }
        StageParts DetermineStage(Part parent)
        {
            StageParts stage = new StageParts();
            List<Part> toCheck = new List<Part>() { parent };
            while (toCheck.Count > 0) //should instead search through the children, stopping when finding a decoupler, then switch to it's children
            {
                Part checking = toCheck[0];
                toCheck.RemoveAt(0);
                stage.parts.Add(checking);

                foreach (Part part in checking.children)
                {
                    //search for decouplers
                    if (part.Modules.Contains("ModuleDecouple") || part.Modules.Contains("ModuleAnchoredDecoupler"))
                    {
                        stage.decouplers.Add(part);
                    }
                    else
                    {
                        toCheck.Add(part);
                    }
                }
            }
            return stage;
        }
        public void BreakShipIntoStages()
        {
            stages.Clear();
            //loop through the part tree and try to break it into stages
            List<Part> parts = EditorLogic.fetch.ship.parts;
            EditorStatItem current = new EditorStatItem();
            int stageNum = 0;
            bool realChuteInUse = false;

            StageParts stage = new StageParts();
            List<Part> RemainingDecouplers = new List<Part>() { parts[0] };
            while (RemainingDecouplers.Count > 0)
            {
                //determine stages from the decouplers
                Part parent = RemainingDecouplers[0];
                RemainingDecouplers.RemoveAt(0);
                stage = DetermineStage(parent);
                current = new EditorStatItem();
                current.stageNumber = stageNum++;
                current.parts = stage.parts;
                RemainingDecouplers.AddRange(stage.decouplers);

                //compute properties
                foreach (Part part in stage.parts)
                {
                    current.dryMass += part.mass;
                    current.mass += part.mass + part.GetResourceMass();

                    double pChutes = 0;
                    if (part.Modules.Contains("RealChuteModule"))
                    {
                        PartModule realChute = part.Modules["RealChuteModule"];
                        ConfigNode rcNode = new ConfigNode();
                        realChute.Save(rcNode);

                        //This is where the Reflection starts. We need to access the material library that RealChute has, so we first grab it's Type
                        Type matLibraryType = AssemblyLoader.loadedAssemblies
                            .SelectMany(a => a.assembly.GetExportedTypes())
                            .SingleOrDefault(t => t.FullName == "RealChute.Libraries.MaterialsLibrary.MaterialsLibrary");

                        //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[] parachutes = rcNode.GetNodes("PARACHUTE");
                        //We then act on each individual parachute in the module
                        foreach (ConfigNode chute in parachutes)
                        {
                            //First off, the diameter of the parachute. From that we can (later) determine the Vt, assuming a circular chute
                            float diameter = float.Parse(chute.GetValue("deployedDiameter"));
                            //The name of the material the chute is made of. We need this to get the actual material object and then the drag coefficient
                            string mat = chute.GetValue("material");
                            //This grabs the method that RealChute uses to get the material. We will invoke that with the name of the material from before.
                            System.Reflection.MethodInfo matMethod = matLibraryType.GetMethod("GetMaterial", new Type[] { mat.GetType() });
                            //In order to invoke the method, we need to grab the active instance of the material library
                            object MatLibraryInstance = matLibraryType.GetProperty("Instance").GetValue(null, null);
                            //With the library instance we can invoke the GetMaterial method (passing the name of the material as a parameter) to receive an object that is the material
                            object materialObject = matMethod.Invoke(MatLibraryInstance, new object[] { mat });
                            //With that material object we can extract the dragCoefficient using the helper function above.
                            float dragC = (float)StageRecovery.GetMemberInfoValue(materialObject.GetType().GetMember("DragCoefficient")[0], materialObject);
                            //Now we calculate the RCParameter. Simple addition of this doesn't result in perfect results for Vt with parachutes with different diameter or drag coefficients
                            //But it works perfectly for mutiple identical parachutes (the normal case)
                            pChutes += dragC * (float)Math.Pow(diameter, 2);
                        }
                        realChuteInUse = true;
                    }
                    else if (part.Modules.Contains("RealChuteFAR")) //RealChute Lite for FAR
                    {
                        PartModule realChute = part.Modules["RealChuteFAR"];
                        float diameter = (float)realChute.Fields.GetValue("deployedDiameter");
                        // = float.Parse(realChute.moduleValues.GetValue("deployedDiameter"));
                        float dragC = 1.0f; //float.Parse(realChute.moduleValues.GetValue("staticCd"));
                        pChutes += dragC * (float)Math.Pow(diameter, 2);

                        realChuteInUse = true;
                    }
                    else if (!realChuteInUse && part.Modules.Contains("ModuleParachute"))
                    {
                        double scale = 1.0;
                        //check for Tweakscale and modify the area appropriately
                        if (part.Modules.Contains("TweakScale"))
                        {
                            PartModule tweakScale = part.Modules["TweakScale"];
                            double currentScale = 100, defaultScale = 100;
                            double.TryParse(tweakScale.Fields.GetValue("currentScale").ToString(), out currentScale);
                            double.TryParse(tweakScale.Fields.GetValue("defaultScale").ToString(), out defaultScale);
                            scale = currentScale / defaultScale;
                        }

                        ModuleParachute mp = (ModuleParachute)part.Modules["ModuleParachute"];
                        //dragCoeff += part.mass * mp.fullyDeployedDrag;
                        pChutes += mp.areaDeployed * Math.Pow(scale, 2);
                    }

                    current.chuteArea += pChutes;
                }

                stages.Add(current);
            }

            ConsolidateStages();
            Debug.Log("[SR] Found " + stages.Count + " stages!");
        }