Пример #1
0
 public void UnHighlightAll()
 {
     highLight = false;
     for (int i = 0; i < stages.Count; i++)
     //foreach (EditorStatItem stage in stages)
     {
         EditorStatItem stage = stages[i];
         stage.UnHighlight();
     }
 }
Пример #2
0
 public void HighlightAll()
 {
     highLight = true;
     for (int i = 0; i < stages.Count; i++)
     //foreach (EditorStatItem stage in stages)
     {
         EditorStatItem stage = stages[i];
         stage.Highlight(tanksDry);
     }
 }
Пример #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!");
        }
Пример #4
0
        public void ConsolidateStages()
        {
            //finds identical (and adjacent) stages in the list and merges them into a single master stage
            //must find all identical stages first, then merge

            EditorStatItem compareItem = null;

            for (int i = 0; i < stages.Count; i++)
            {
                EditorStatItem stage = stages[i];
                //  if (compareItem == null)
                compareItem = stage;

                int j = i + 1;
                while (j < stages.Count)
                {
                    if (stages[j].parts.Count != compareItem.parts.Count || stages[j].mass != compareItem.mass || stages[j].chuteArea != compareItem.chuteArea)
                    {
                        //probably not the same stage setup
                        break;
                    }
                    j++;
                }

                if (j > i + 1)
                {
                    Log.Info("[SR] Found " + (j - i) + " identical stages");
                    //some stages are the same (up to j)
                    //merge the stages
                    for (int k = j - 1; k > i; k--)
                    {
                        //add the parts from k to i
                        stages[i].parts.AddRange(stages[k].parts);
                        stages.RemoveAt(k);
                    }
                    stages[i].ForceRecalculate();
                }
            }
        }
Пример #5
0
        public void DrawEditorGUI(int windowID)
        {
            GUILayout.BeginVertical();
            //provide toggles to turn highlighting on/off
            if (GUILayout.Button("Toggle Vessel Highlighting"))
            {
                highLight = !highLight;
                if (highLight)
                {
                    HighlightAll();
                }
                else
                {
                    UnHighlightAll();
                }
            }

            if (GUILayout.Button("Tanks: " + (tanksDry ? "Empty" : "Full")))
            {
                tanksDry = !tanksDry;
                if (highLight)
                {
                    HighlightAll();
                }
            }

            //list each stage, with info for each
            for (int i = 0; i < stages.Count; i++)
            //foreach (EditorStatItem stage in stages)
            {
                EditorStatItem stage = stages[i];

                GUILayout.BeginHorizontal();
                GUILayout.Label("Stage " + stage.stageNumber);
                double vel = tanksDry ? stage.EmptyVelocity : stage.FullVelocity;
                GUILayout.Label(vel.ToString("N1") + " m/s");
                GUILayout.Label(stage.GetRecoveryPercent(tanksDry) + "%");
                //    GUILayout.Label("("+stage.FullVelocity.ToString("N1") + ")");
                if (GUILayout.Button("Highlight"))
                {
                    //highlight this stage and unhighlight all others
                    bool status = stage.Highlighted;
                    if (highLight)
                    {
                        status = false;
                    }

                    UnHighlightAll();
                    stage.SetHighlight(!status, tanksDry);
                }
                GUILayout.EndHorizontal();
            }


            if (GUILayout.Button("Recalculate"))
            {
                Recalculate();
#if false
                BreakShipIntoStages();
                if (highLight)
                {
                    HighlightAll();
                }

                EditorGUIRect.height = 1; //reset the height so it is the smallest size it needs to be
#endif
            }
            GUILayout.EndVertical();

            /* if (GUI.Button(new Rect(EditorGUIRect.xMax-10, EditorGUIRect.yMin, 10, 10), "X"))
             * {
             *   UnHighlightAll();
             *   showEditorGUI = false;
             * }*/

            //Make it draggable
            if (!Input.GetMouseButtonDown(1) && !Input.GetMouseButtonDown(2))
            {
                GUI.DragWindow();
            }
        }
Пример #6
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!");
        }
Пример #7
0
        public void DrawEditorGUI(int windowID)
        {
            GUILayout.BeginVertical();
            //provide toggles to turn highlighting on/off
            if (GUILayout.Button(Localizer.Format("#StageRecovery_Highlight")))//"Toggle Vessel Highlighting"
            {
                highLight = !highLight;
                if (highLight)
                {
                    HighlightAll();
                }
                else
                {
                    UnHighlightAll();
                }
            }

            if (GUILayout.Button(Localizer.Format("#StageRecovery_TanksDry", (tanksDry ? Localizer.Format("#StageRecovery_TanksEmpty") :Localizer.Format("#StageRecovery_TanksFull")))))//"Tanks: " + "Empty" : "Full"
            {
                tanksDry = !tanksDry;
                if (highLight)
                {
                    HighlightAll();
                }
            }

            //list each stage, with info for each
            for (int i = 0; i < stages.Count; i++)
            //foreach (EditorStatItem stage in stages)
            {
                EditorStatItem stage = stages[i];

                GUILayout.BeginHorizontal();
                GUILayout.Label(Localizer.Format("", stage.stageNumber));//"Stage " +
                double vel = tanksDry ? stage.EmptyVelocity : stage.FullVelocity;
                GUILayout.Label(vel.ToString("N1") + " m/s");
                GUILayout.Label(stage.GetRecoveryPercent(tanksDry) + "%");
                //    GUILayout.Label("("+stage.FullVelocity.ToString("N1") + ")");
                if (GUILayout.Button(Localizer.Format("#StageRecovery_Highlight2")))//"Highlight"
                {
                    //highlight this stage and unhighlight all others
                    bool status = stage.Highlighted;
                    if (highLight)
                    {
                        status = false;
                    }

                    UnHighlightAll();
                    stage.SetHighlight(!status, tanksDry);
                }
                GUILayout.EndHorizontal();
            }


            if (GUILayout.Button(Localizer.Format("#StageRecovery_Recalculate")))//"Recalculate"
            {
                Recalculate();
            }

            GUILayout.EndVertical();

            /* if (GUI.Button(new Rect(EditorGUIRect.xMax-10, EditorGUIRect.yMin, 10, 10), "X"))
             * {
             *   UnHighlightAll();
             *   showEditorGUI = false;
             * }*/

            //Make it draggable
            if (!Input.GetMouseButtonDown(1) && !Input.GetMouseButtonDown(2))
            {
                GUI.DragWindow();
            }
        }
Пример #8
0
        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!");
        }
Пример #9
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!");
        }