Example #1
0
        //Lists the errors of a given type
        private List <string> GetErrors(string type)
        {
            if (type == "general")
            {
                List <string> general = new List <string>();

                if (!RCUtils.CanParseTime(timer) || !RCUtils.CheckRange(RCUtils.ParseTime(timer), 0, 3600))
                {
                    general.Add("Deployment timer");
                }
                if (!RCUtils.CanParseWithEmpty(spares) || !RCUtils.CheckRange(RCUtils.ParseWithEmpty(spares), -1, 10) || !RCUtils.IsWholeNumber(RCUtils.ParseWithEmpty(spares)))
                {
                    general.Add("Spare chutes");
                }
                if (!RCUtils.CanParse(cutSpeed) || !RCUtils.CheckRange(float.Parse(cutSpeed), 0.01f, 100))
                {
                    general.Add("Autocut speed");
                }
                return(general);
            }
            else if (type == "main")
            {
                return(main.errors);
            }
            else if (type == "secondary")
            {
                return(secondary.errors);
            }
            return(new List <string>());
        }
Example #2
0
        public override void OnStart(PartModule.StartState state)
        {
            if ((!HighLogic.LoadedSceneIsEditor && !HighLogic.LoadedSceneIsFlight) || !CompatibilityChecker.IsAllCompatible())
            {
                return;
            }

            //Identification of the RealChuteModule
            if (this.part.Modules.Contains("RealChuteModule"))
            {
                rcModule = this.part.Modules["RealChuteModule"] as RealChuteModule;
            }
            else
            {
                return;
            }
            secondaryChute = rcModule.secondaryChute;
            if (textureLibrary != "none")
            {
                textureLib.TryGetConfig(textureLibrary, ref textures);
            }
            bodies = AtmoPlanets.fetch;

            //Initializes ChuteTemplates
            LoadChutes();
            if (this.part.name.Contains("(Clone)(Clone)"))
            {
                if (this.part.symmetryCounterparts.Count > 0)
                {
                    CopyFromOriginal(this.part.symmetryCounterparts.Find(p => !p.name.Contains("(Clone)(Clone)")));
                }
                RCUtils.RemoveClone(this.part);
            }
            chutes.ForEach(c => c.Initialize());
            if (sizes.Count <= 0)
            {
                sizes = sizeLib.GetSizes(this.part.partInfo.name);
            }

            //Creates an instance of the texture library
            editorGUI = new EditorGUI(this);
            if (textureLibrary != "none")
            {
                editorGUI.cases    = textures.caseNames;
                editorGUI.canopies = textures.canopyNames;
                editorGUI.models   = textures.modelNames;
                textures.TryGetCase(caseID, type, ref parachuteCase);
                lastCaseID = caseID;
            }

            if (HighLogic.LoadedSceneIsEditor)
            {
                //Windows initiation
                this.editorGUI.window = new Rect(5, 370, 420, Screen.height - 375);
                this.chutes.ForEach(c => c.materialsWindow = new Rect(editorGUI.matX, editorGUI.matY, 375, 275));
                this.editorGUI.failedWindow         = new Rect(Screen.width / 2 - 150, Screen.height / 2 - 150, 300, 300);
                this.editorGUI.successfulWindow     = new Rect(Screen.width / 2 - 150, Screen.height / 2 - 25, 300, 50);
                this.editorGUI.presetsWindow        = new Rect(Screen.width / 2 - 200, Screen.height / 2 - 250, 400, 500);
                this.editorGUI.presetsSaveWindow    = new Rect(Screen.width / 2 - 175, Screen.height / 2 - 110, 350, 220);
                this.editorGUI.presetsWarningWindow = new Rect(Screen.width / 2 - 100, Screen.height / 2 - 50, 200, 100);

                if (!initiated)
                {
                    planets = bodies.GetPlanetIndex("Kerbin");
                    //Gets the original part state
                    if (textureLibrary != "none")
                    {
                        if (textures.TryGetCase(currentCase, ref parachuteCase))
                        {
                            caseID = textures.GetCaseIndex(parachuteCase);
                        }
                        lastCaseID = caseID;
                    }

                    //Identification of the values from the RealChuteModule
                    mustGoDown     = rcModule.mustGoDown;
                    deployOnGround = rcModule.deployOnGround;
                    timer          = rcModule.timer + "s";
                    cutSpeed       = rcModule.cutSpeed.ToString();
                    if (rcModule.spareChutes != -1)
                    {
                        spares = rcModule.spareChutes.ToString();
                    }
                    originalSize = this.part.transform.GetChild(0).localScale;
                    initiated    = true;
                }
            }

            if (parent == null)
            {
                parent = this.part.FindModelTransform(rcModule.parachutes[0].parachuteName).parent;
            }

            //Updates the part
            if (textureLibrary != "none")
            {
                UpdateCaseTexture(this.part, rcModule);
            }
            UpdateScale(this.part, rcModule);
        }
Example #3
0
 //Lists the errors of a given type
 internal List <string> GetErrors(bool general)
 {
     if (general)
     {
         List <string> errors = new List <string>();
         float         f      = 0;
         if (!GUIUtils.TryParseTime(this.timer, out f) || !GUIUtils.CheckRange(f, 0, 3600))
         {
             errors.Add("Deployment timer");
         }
         if (!GUIUtils.TryParseWithEmpty(this.spares, out f) || !GUIUtils.CheckRange(f, -1, 10) || !RCUtils.IsWholeNumber(f))
         {
             errors.Add("Spare chutes");
         }
         if (!float.TryParse(this.cutSpeed, out f) || !GUIUtils.CheckRange(f, 0.01f, 100))
         {
             errors.Add("Autocut speed");
         }
         if (!float.TryParse(this.landingAlt, out f) || !GUIUtils.CheckRange(f, 0, (float)this.body.GetMaxAtmosphereAltitude()))
         {
             errors.Add("Landing altitude");
         }
         return(errors);
     }
     else
     {
         return(new List <string>(this.chutes.SelectMany(c => c.templateGUI.errors)));
     }
 }
Example #4
0
        //Info window
        private void Window(int id)
        {
            GUI.DragWindow(new Rect(0, 0, window.width, 30));
            GUILayout.BeginVertical();
            StringBuilder builder = new StringBuilder("Part name: ").AppendLine(this.part.partInfo.title);

            builder.Append("Symmetry counterparts: ").AppendLine(this.part.symmetryCounterparts.Count.ToString());
            builder.Append("Part mass: ").Append(this.part.TotalMass().ToString("0.###")).Append("t");
            GUILayout.Label(builder.ToString(), skins.label);
            scroll = GUILayout.BeginScrollView(scroll, false, false, skins.horizontalScrollbar, skins.verticalScrollbar, skins.box);
            GUILayout.Space(5);
            GUILayout.Label("General:", RCUtils.boldLabel, GUILayout.Width(120));
            builder = new StringBuilder("Autocut speed: ").Append(cutSpeed).AppendLine("m/s");
            if (timer >= 60)
            {
                builder.Append("Deployment timer: ").AppendLine(RCUtils.ToMinutesSeconds(timer));
            }
            else if (timer > 0)
            {
                builder.Append("Deployment timer: ").Append(timer.ToString("0.#")).AppendLine("s");
            }
            if (this.mustGoDown)
            {
                builder.AppendLine("Must go downwards to deploy");
            }
            if (this.deployOnGround)
            {
                builder.AppendLine("Automatically deploys on ground contact");
            }
            if (this.spareChutes >= 0)
            {
                builder.Append("Spare chutes: ").Append(chuteCount);
            }
            else
            {
                builder.Append("Spare chutes: inf");
            }
            GUILayout.Label(builder.ToString(), skins.label);
            for (int i = 0; i < parachutes.Count; i++)
            {
                GUILayout.Label("___________________________________________", RCUtils.boldLabel);
                GUILayout.Space(3);
                GUILayout.Label(RCUtils.ParachuteNumber(i), RCUtils.boldLabel, GUILayout.Width(120));
                parachutes[i].UpdateGUI();
            }

            GUILayout.EndScrollView();
            if (HighLogic.LoadedSceneIsFlight && this.part.symmetryCounterparts.Count > 0)
            {
                GUILayout.BeginHorizontal();
                GUILayout.FlexibleSpace();
                if (GUILayout.Button("Copy to counterparts", skins.button, GUILayout.Width(150)))
                {
                    CopyToCouterparts();
                }
                GUILayout.FlexibleSpace();
                GUILayout.EndHorizontal();
            }
            GUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();
            if (GUILayout.Button("Close", skins.button, GUILayout.Width(150)))
            {
                this.visible = false;
            }
            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();
            GUILayout.EndVertical();
        }
Example #5
0
        //Lists the errors of a given type
        internal List <string> GetErrors(string type)
        {
            if (type == "general")
            {
                List <string> general = new List <string>();

                if (!RCUtils.CanParseTime(timer) || !RCUtils.CheckRange(RCUtils.ParseTime(timer), 0, 3600))
                {
                    general.Add("Deployment timer");
                }
                if (!RCUtils.CanParseWithEmpty(spares) || !RCUtils.CheckRange(RCUtils.ParseWithEmpty(spares), -1, 10) || !RCUtils.IsWholeNumber(RCUtils.ParseWithEmpty(spares)))
                {
                    general.Add("Spare chutes");
                }
                if (!RCUtils.CanParse(cutSpeed) || !RCUtils.CheckRange(float.Parse(cutSpeed), 0.01f, 100))
                {
                    general.Add("Autocut speed");
                }
                if (!RCUtils.CanParse(landingAlt) || !RCUtils.CheckRange(float.Parse(landingAlt), 0, (float)body.GetMaxAtmosphereAltitude()))
                {
                    general.Add("Landing altitude");
                }
                return(general);
            }
            else if (type == "main" || type == "secondary")
            {
                return(chutes.SelectMany(c => c.errors).ToList());
            }
            return(new List <string>());
        }
Example #6
0
        //Applies changes to the parachute
        internal void ApplyChanges(bool toSymmetryCounterparts)
        {
            parachute.material = material.name;
            parachute.mat      = material;

            if (calcSelect)
            {
                float m = 0;
                if (getMass)
                {
                    m = this.pChute.GetCraftMass(useDry);
                }
                else
                {
                    m = float.Parse(mass);
                }

                double alt     = typeID == 1 ? double.Parse(refDepAlt) : double.Parse(pChute.landingAlt);
                float  density = (float)body.GetDensityAtAlt(alt);

                float speed  = float.Parse(landingSpeed);
                float speed2 = speed * speed;

                float acc = typeID == 2 ? float.Parse(deceleration) : (float)(body.GeeASL * RCUtils.geeToAcc);

                Debug.Log(String.Concat("[RealChute]: ", this.part.partInfo.title, " ", RCUtils.ParachuteNumber(this.id), " - m: ", m, "t, alt: ", alt, "m, rho: ", density, "kg/m³, v²: ", speed2, "m²/s², acceleration: ", acc, "m/s²"));

                parachute.deployedDiameter = RCUtils.Round(Mathf.Sqrt((8000f * m * acc) / (Mathf.PI * speed2 * material.dragCoefficient * density * float.Parse(chuteCount))));
                if ((this.pChute.textureLibrary != "none" || this.textures.modelNames.Length > 0) && parachute.deployedDiameter > model.maxDiam)
                {
                    parachute.deployedDiameter = model.maxDiam;
                    this.editorGUI.warning     = true;
                }
                else if ((this.pChute.textureLibrary == "none" || this.textures.modelNames.Length <= 0) && parachute.deployedDiameter > 70f)
                {
                    parachute.deployedDiameter = 70f;
                    this.editorGUI.warning     = true;
                }
                else
                {
                    this.editorGUI.warning = false;
                }
                parachute.preDeployedDiameter = RCUtils.Round(typeID == 0 ? (parachute.deployedDiameter / 20) : (parachute.deployedDiameter / 2));
                Debug.Log(String.Concat("[RealChute]: ", this.part.partInfo.title, " ", RCUtils.ParachuteNumber(this.id), " - depDiam: ", parachute.deployedDiameter, "m, preDepDiam: ", parachute.preDeployedDiameter, "m"));
            }

            else
            {
                parachute.preDeployedDiameter = RCUtils.Round(float.Parse(preDepDiam));
                parachute.deployedDiameter    = RCUtils.Round(float.Parse(depDiam));
            }

            parachute.minIsPressure = isPressure;
            if (isPressure)
            {
                parachute.minPressure = float.Parse(predepClause);
            }
            else
            {
                parachute.minDeployment = float.Parse(predepClause);
            }
            parachute.deploymentAlt      = float.Parse(deploymentAlt);
            parachute.cutAlt             = RCUtils.ParseWithEmpty(cutAlt);
            parachute.preDeploymentSpeed = float.Parse(preDepSpeed);
            parachute.deploymentSpeed    = float.Parse(depSpeed);

            if (toSymmetryCounterparts)
            {
                foreach (Part part in this.part.symmetryCounterparts)
                {
                    Parachute sym = ((RealChuteModule)part.Modules["RealChuteModule"]).parachutes[id];
                    sym.material            = material.name;
                    sym.mat                 = material;
                    sym.deployedDiameter    = parachute.deployedDiameter;
                    sym.preDeployedDiameter = parachute.preDeployedDiameter;

                    sym.minIsPressure = isPressure;
                    if (isPressure)
                    {
                        sym.minPressure = parachute.minPressure;
                    }
                    else
                    {
                        sym.minDeployment = parachute.minDeployment;
                    }
                    sym.deploymentAlt      = parachute.deploymentAlt;
                    sym.cutAlt             = parachute.cutAlt;
                    sym.preDeploymentSpeed = parachute.preDeploymentSpeed;
                    sym.deploymentSpeed    = parachute.deploymentSpeed;

                    ChuteTemplate template = ((ProceduralChute)part.Modules["ProceduralChute"]).chutes[id];
                    template.chuteID       = this.chuteID;
                    template.typeID        = this.typeID;
                    template.modelID       = this.modelID;
                    template.materialsID   = this.materialsID;
                    template.isPressure    = this.isPressure;
                    template.calcSelect    = this.calcSelect;
                    template.getMass       = this.getMass;
                    template.useDry        = this.useDry;
                    template.preDepDiam    = this.preDepDiam;
                    template.depDiam       = this.depDiam;
                    template.predepClause  = this.predepClause;
                    template.mass          = this.mass;
                    template.landingSpeed  = this.landingSpeed;
                    template.deceleration  = this.deceleration;
                    template.refDepAlt     = this.refDepAlt;
                    template.chuteCount    = this.chuteCount;
                    template.deploymentAlt = this.deploymentAlt;
                    template.cutAlt        = this.cutAlt;
                    template.preDepSpeed   = this.preDepSpeed;
                    template.depSpeed      = this.depSpeed;
                }
            }
        }
Example #7
0
 //Gives the cost for this parachute
 public float GetModuleCost()
 {
     return(RCUtils.Round(this.parachutes.Sum(p => p.deployedArea * p.mat.areaCost)));
 }
Example #8
0
        //Main GUI window
        private void Window(int id)
        {
            GUILayout.BeginVertical();

            #region Info labels
            //Header labels
            StringBuilder builder = new StringBuilder();
            builder.Append("Selected part: ").AppendLine(this.Part.partInfo.title);
            builder.Append("Symmetry counterparts: ").AppendLine(this.Part.symmetryCounterparts.Count.ToString());
            builder.Append("Case mass: ").Append(this.RCModule.caseMass.ToString("0.000")).Append("t");
            if (this.Sizes.Count > 0)
            {
                builder.Append("\t\tCase cost: ").Append(this.Sizes[this.pChute.size].Cost.ToString("0.#")).Append("F");
            }
            builder.Append("\nTotal part mass: ").Append(this.Part.TotalMass().ToString("0.000")).Append("t");
            builder.Append("\tTotal part cost: ").Append(this.Part.TotalCost().ToString("0.#")).Append("F");
            GUILayout.Label(builder.ToString());
            #endregion

            #region Presets
            //Presets buttons
            GUILayout.BeginHorizontal();
            if (GUILayout.Button("Select a preset"))
            {
                this.presetVisible = !this.presetVisible;
            }

            if (GUILayout.Button("Save as preset..."))
            {
                this.presetSaveVisible = !this.presetSaveVisible;
            }
            GUILayout.EndHorizontal();
            #endregion

            //Scroll being
            this.mainScroll = GUILayout.BeginScrollView(this.mainScroll);

            #region Planet selector
            //Target planet selection
            GUILayout.Space(10);
            GUILayout.BeginHorizontal(GUILayout.Height(30));
            GUILayout.BeginVertical();
            GUILayout.FlexibleSpace();
            GUILayout.Label("Target planet:");
            GUILayout.FlexibleSpace();
            GUILayout.EndVertical();
            this.pChute.planets = GUILayout.SelectionGrid(this.pChute.planets, AtmoPlanets.Instance.BodyNames, 4, GUILayout.Width(250));
            GUILayout.EndHorizontal();
            this.pChute.body = AtmoPlanets.Instance.GetBody(this.pChute.planets);
            #endregion

            #region Size cyclers
            //Size selection
            if (this.Sizes.Count > 0)
            {
                GUILayout.BeginHorizontal(GUILayout.Height(20));
                GUILayout.BeginVertical();
                GUILayout.FlexibleSpace();
                GUILayout.Label("Cycle part size");
                GUILayout.EndVertical();
                GUILayout.FlexibleSpace();
                if (GUILayout.Button("Previous size", GUILayout.Width(125)))
                {
                    this.pChute.size--;
                    if (this.pChute.size < 0)
                    {
                        this.pChute.size = this.Sizes.Count - 1;
                    }
                }
                if (GUILayout.Button("Next size", GUILayout.Width(125)))
                {
                    this.pChute.size++;
                    if (this.pChute.size > this.Sizes.Count - 1)
                    {
                        this.pChute.size = 0;
                    }
                }
                GUILayout.EndHorizontal();
            }
            #endregion

            GUILayout.Space(5);
            GUILayout.BeginHorizontal();
            GUILayout.BeginVertical();

            //Main chute texture selector
            GUILayout.Space(5);
            this.Chutes[0].templateGUI.TextureSelector();

            #region General
            //Materials editor
            GUILayout.Space(5);
            this.Chutes[0].templateGUI.MaterialsSelector();

            //MustGoDown
            GuiUtils.CreateTwinToggle("Must go down to deploy:", ref this.pChute.mustGoDown, this.window.width);

            //DeployOnGround
            GuiUtils.CreateTwinToggle("Deploy on ground contact:", ref this.pChute.deployOnGround, this.window.width);

            //Timer
            GuiUtils.CreateTimeEntryArea("Deployment timer:", ref this.pChute.timer, 0, 3600);

            //Spares
            GuiUtils.CreateEmptyEntryArea("Spare chutes:", ref this.pChute.spares, -1, 10);

            //CutSpeed
            GuiUtils.CreateEntryArea("Autocut speed (m/s):", ref this.pChute.cutSpeed, 0.01f, 100);

            //LandingAlt
            GuiUtils.CreateEntryArea("Landing alt (m):", ref this.pChute.landingAlt, 0, (float)this.pChute.body.GetMaxAtmosphereAltitude());
            #endregion

            #region Main
            //Indicator label
            GUILayout.Space(10);
            GUILayout.Label("________________________________________________", GuiUtils.BoldLabel);
            GUILayout.Label("Main chute:", GuiUtils.BoldLabel, GUILayout.Width(150));
            GUILayout.Label("‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾", GuiUtils.BoldLabel);

            this.Chutes[0].templateGUI.Calculations();
            #endregion

            #region Secondary
            if (this.pChute.secondaryChute)
            {
                for (int i = 1; i < this.Chutes.Count; i++)
                {
                    ChuteTemplate chute = this.Chutes[i];

                    //Indicator label
                    GUILayout.Space(10);
                    GUILayout.Label("________________________________________________", GuiUtils.BoldLabel);
                    GUILayout.Label(RCUtils.ParachuteNumber(i) + ":", GuiUtils.BoldLabel, GUILayout.Width(150));
                    GUILayout.Label("‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾", GuiUtils.BoldLabel);

                    //Texture selector
                    GUILayout.Space(5);
                    chute.templateGUI.TextureSelector();

                    //Materials editor
                    GUILayout.Space(5);
                    chute.templateGUI.MaterialsSelector();

                    chute.templateGUI.Calculations();
                }
            }
            #endregion

            GUILayout.EndVertical();
            GUILayout.BeginVertical();
            GUILayout.EndVertical();
            GUILayout.EndHorizontal();
            GUILayout.EndScrollView();
            //Scroll end

            #region Application
            GUILayout.Space(5);
            if (GUILayout.Button("Apply settings"))
            {
                this.pChute.Apply(false);
            }

            if (this.Part.symmetryCounterparts.Count > 0)
            {
                if (GUILayout.Button("Apply to all symmetry counterparts"))
                {
                    this.pChute.Apply(true);
                }
            }
            #endregion

            GUILayout.EndVertical();
        }
Example #9
0
        //Applies changes to the parachute
        internal void ApplyChanges(bool toSymmetryCounterparts)
        {
            this.parachute.material = this.material.name;
            this.parachute.mat      = this.material;

            if (this.templateGUI.calcSelect)
            {
                double m = this.templateGUI.getMass ? this.pChute.GetCraftMass(this.templateGUI.useDry) : double.Parse(this.templateGUI.mass);
                double alt = 0, acc = 0;
                switch (this.templateGUI.type)
                {
                case ParachuteType.Main:
                {
                    alt = double.Parse(this.pChute.landingAlt);
                    acc = (this.body.GeeASL * RCUtils.geeToAcc);
                    break;
                }

                case ParachuteType.Drogue:
                {
                    alt = double.Parse(this.templateGUI.refDepAlt);
                    acc = (this.body.GeeASL * RCUtils.geeToAcc);
                    break;
                }

                case ParachuteType.Drag:
                {
                    alt = double.Parse(this.pChute.landingAlt);
                    acc = double.Parse(this.templateGUI.deceleration);
                    break;
                }

                default:
                    break;
                }
                double density = this.body.GetDensityAtAlt(alt);
                double speed   = double.Parse(this.templateGUI.landingSpeed);
                speed = speed * speed;

                Debug.Log(String.Format("[RealChute]: {0} {1} - m: {2}t, alt: {3}m, ρ: {4}kg/m³, v²: {5}m²/s², a: {6}m/s²", this.part.partInfo.title, RCUtils.ParachuteNumber(this.id), m, alt, density, speed, acc));

                this.parachute.deployedDiameter = RCUtils.Round(Math.Sqrt((8000 * m * acc) / (Math.PI * speed * material.dragCoefficient * density * double.Parse(this.templateGUI.chuteCount))));
                float maxDiam = (this.textures != null || this.textures.models.Count > 0) ? this.model.maxDiam : 70;
                if (this.parachute.deployedDiameter > this.model.maxDiam)
                {
                    this.parachute.deployedDiameter = maxDiam;
                    this.editorGUI.warning          = true;
                }
                else
                {
                    this.editorGUI.warning = false;
                }
                this.parachute.preDeployedDiameter = RCUtils.Round(this.templateGUI.type == ParachuteType.Main ? (this.parachute.deployedDiameter / 20) : (this.parachute.deployedDiameter / 2));
                Debug.Log(String.Format("[RealChute]: {0} {1} - depDiam: {2}m, preDepDiam: {3}m", this.part.partInfo.title, RCUtils.ParachuteNumber(this.id), this.parachute.deployedDiameter, this.parachute.preDeployedDiameter));
            }

            else
            {
                this.parachute.preDeployedDiameter = RCUtils.Round(float.Parse(this.templateGUI.preDepDiam));
                this.parachute.deployedDiameter    = RCUtils.Round(float.Parse(this.templateGUI.depDiam));
                Debug.Log(String.Format("[RealChute]: {0} {1} - depDiam: {2}m, preDepDiam: {3}m", this.part.partInfo.title, RCUtils.ParachuteNumber(this.id), this.parachute.deployedDiameter, this.parachute.preDeployedDiameter));
            }

            this.parachute.minIsPressure = this.templateGUI.isPressure;
            if (this.templateGUI.isPressure)
            {
                this.parachute.minPressure = float.Parse(this.templateGUI.predepClause);
            }
            else
            {
                this.parachute.minDeployment = float.Parse(this.templateGUI.predepClause);
            }
            this.parachute.deploymentAlt      = float.Parse(this.templateGUI.deploymentAlt);
            this.parachute.cutAlt             = GUIUtils.ParseEmpty(this.templateGUI.cutAlt);
            this.parachute.preDeploymentSpeed = float.Parse(this.templateGUI.preDepSpeed);
            this.parachute.deploymentSpeed    = float.Parse(this.templateGUI.depSpeed);

            if (toSymmetryCounterparts)
            {
                foreach (Part part in this.part.symmetryCounterparts)
                {
                    Parachute sym = ((RealChuteModule)part.Modules["RealChuteModule"]).parachutes[id];
                    sym.material            = this.material.name;
                    sym.mat                 = this.material;
                    sym.deployedDiameter    = this.parachute.deployedDiameter;
                    sym.preDeployedDiameter = this.parachute.preDeployedDiameter;
                    sym.minIsPressure       = this.templateGUI.isPressure;
                    sym.minPressure         = this.parachute.minPressure;
                    sym.minDeployment       = this.parachute.minDeployment;
                    sym.deploymentAlt       = this.parachute.deploymentAlt;
                    sym.cutAlt              = this.parachute.cutAlt;
                    sym.preDeploymentSpeed  = this.parachute.preDeploymentSpeed;
                    sym.deploymentSpeed     = this.parachute.deploymentSpeed;

                    TemplateGUI template = ((ProceduralChute)part.Modules["ProceduralChute"]).chutes[id].templateGUI;
                    template.chuteID       = this.templateGUI.chuteID;
                    template.typeID        = this.templateGUI.typeID;
                    template.modelID       = this.templateGUI.modelID;
                    template.materialsID   = this.templateGUI.materialsID;
                    template.isPressure    = this.templateGUI.isPressure;
                    template.calcSelect    = this.templateGUI.calcSelect;
                    template.getMass       = this.templateGUI.getMass;
                    template.useDry        = this.templateGUI.useDry;
                    template.preDepDiam    = this.templateGUI.preDepDiam;
                    template.depDiam       = this.templateGUI.depDiam;
                    template.predepClause  = this.templateGUI.predepClause;
                    template.mass          = this.templateGUI.mass;
                    template.landingSpeed  = this.templateGUI.landingSpeed;
                    template.deceleration  = this.templateGUI.deceleration;
                    template.refDepAlt     = this.templateGUI.refDepAlt;
                    template.chuteCount    = this.templateGUI.chuteCount;
                    template.deploymentAlt = this.templateGUI.deploymentAlt;
                    template.cutAlt        = this.templateGUI.cutAlt;
                    template.preDepSpeed   = this.templateGUI.preDepSpeed;
                    template.depSpeed      = this.templateGUI.depSpeed;
                }
            }
        }
Example #10
0
 //Gives the cost for this parachute
 public float GetModuleCost(float defaultCost, ModifierStagingSituation sit) => RCUtils.Round(this.parachutes.Sum(p => p.DeployedArea * p.mat.AreaCost));
Example #11
0
        //Info window
        private void Window(int id)
        {
            //Header
            GUI.DragWindow(this.drag);
            GUILayout.BeginVertical();

            //Top info labels
            StringBuilder builder = new StringBuilder("Part name: ").AppendLine(this.part.partInfo.title);

            builder.Append("Symmetry counterparts: ").AppendLine(this.part.symmetryCounterparts.Count.ToString());
            builder.Append("Part mass: ").Append(this.part.TotalMass().ToString("0.###")).Append("t");
            GUILayout.Label(builder.ToString());

            //Beginning scroll
            this.scroll = GUILayout.BeginScrollView(this.scroll, false, false, GUI.skin.horizontalScrollbar, GUI.skin.verticalScrollbar, GUI.skin.box);
            GUILayout.Space(5);
            GUILayout.Label("General:", GuiUtils.BoldLabel, GUILayout.Width(120));

            //General labels
            builder = new StringBuilder("Autocut speed: ").Append(this.cutSpeed).AppendLine("m/s");
            if (this.timer >= 60)
            {
                builder.Append("Deployment timer: ").AppendLine(RCUtils.ToMinutesSeconds(this.timer));
            }
            else if (this.timer > 0)
            {
                builder.Append("Deployment timer: ").Append(this.timer.ToString("0.#")).AppendLine("s");
            }
            if (this.mustGoDown)
            {
                builder.AppendLine("Must go downwards to deploy");
            }
            if (this.deployOnGround)
            {
                builder.AppendLine("Automatically deploys on ground contact");
            }
            if (this.spareChutes >= 0)
            {
                builder.Append("Spare chutes: ").Append(this.chuteCount);
            }
            else
            {
                builder.Append("Spare chutes: inf");
            }
            GUILayout.Label(builder.ToString());

            //Specific labels
            for (int i = 0; i < this.parachutes.Count; i++)
            {
                GUILayout.Label("___________________________________________", GuiUtils.BoldLabel);
                GUILayout.Space(3);
                GUILayout.Label(RCUtils.ParachuteNumber(i) + ":", GuiUtils.BoldLabel, GUILayout.Width(120));
                this.parachutes[i].RenderGUI();
            }

            //End scroll
            GUILayout.EndScrollView();

            //Copy button if in flight
            if (HighLogic.LoadedSceneIsFlight && this.part.symmetryCounterparts.Count > 0)
            {
                GuiUtils.CenteredButton("Copy to others chutes", CopyToCounterparts);
            }

            //Close button
            GuiUtils.CenteredButton("Close", () => this.visible = false);

            //Closer
            GUILayout.EndVertical();
        }
Example #12
0
        //Checks if there is a timer and/or a mustGoDown clause active
        public void CheckForWait()
        {
            bool timerSpent = true, goesDown = true;

            this.screenMessage = string.Empty;
            //Timer
            if (this.timer > 0 && this.deploymentTimer.Elapsed.TotalSeconds < this.timer)
            {
                timerSpent = false;
                if (!this.deploymentTimer.IsRunning)
                {
                    this.deploymentTimer.Start();
                }
                if (this.vessel.isActiveVessel)
                {
                    float time = this.timer - (float)this.deploymentTimer.Elapsed.TotalSeconds;
                    this.screenMessage = time < 60 ? $"Deployment in {time:0.0}s" : $"Deployment in {RCUtils.ToMinutesSeconds(time)}";
                }
            }
            else if (this.deploymentTimer.IsRunning)
            {
                this.deploymentTimer.Stop();
            }

            //Goes down
            if (this.mustGoDown && this.vessel.verticalSpeed > 0)
            {
                if (!timerSpent)
                {
                    this.screenMessage += "\n";
                }
                goesDown = false;
                if (this.vessel.isActiveVessel)
                {
                    this.screenMessage += $"Deployment awaiting negative vertical velocity\nCurrent vertical velocity: {this.vessel.verticalSpeed:0.0}/s";
                }
            }

            //Can deploy or not
            if (timerSpent && goesDown)
            {
                this.wait       = false;
                this.showDisarm = false;
                this.deploymentTimer.Reset();
            }
            else
            {
                this.part.stackIcon.SetIconColor(XKCDColors.LightCyan);
                this.wait       = true;
                this.showDisarm = true;
            }
        }
Example #13
0
        //Applies changes to the parachute
        internal void ApplyChanges(bool toSymmetryCounterparts)
        {
            this.parachute.material = this.material.Name;
            this.parachute.mat      = this.material;

            if (this.templateGUI.calcSelect)
            {
                double m = this.templateGUI.getMass ? this.pChute.GetCraftMass(this.templateGUI.useDry) : double.Parse(this.templateGUI.mass);
                double alt = 0, acc = 0;
                switch (this.templateGUI.Type)
                {
                case ParachuteType.MAIN:
                {
                    alt = double.Parse(this.pChute.landingAlt);
                    acc = this.Body.GeeASL * RCUtils.GeeToAcc;
                    break;
                }

                case ParachuteType.DROGUE:
                {
                    alt = double.Parse(this.templateGUI.refDepAlt);
                    acc = this.Body.GeeASL * RCUtils.GeeToAcc;
                    break;
                }

                case ParachuteType.DRAG:
                {
                    alt = double.Parse(this.pChute.landingAlt);
                    acc = double.Parse(this.templateGUI.deceleration);
                    break;
                }
                }

                double density = this.Body.GetDensityAtAlt(alt, this.Body.GetMaxTemperatureAtAlt(alt));
                double speed   = double.Parse(this.templateGUI.landingSpeed);
                speed *= speed;

                Debug.Log($"[RealChute]: {this.Part.partInfo.title} {RCUtils.ParachuteNumber(this.id)} - m: {m}t, alt: {alt}m, ρ: {density}kg/m³, v²: {speed}m²/s², a: {acc}m/s²");

                this.parachute.deployedDiameter = RCUtils.Round(Math.Sqrt((8000 * m * acc) / (Math.PI * speed * this.material.DragCoefficient * density * double.Parse(this.templateGUI.chuteCount))));
                float maxDiam = (this.Textures != null) && (this.Textures.Models.Count > 0) ? this.model.MaxDiam : 70f;
                if (this.parachute.deployedDiameter > this.model.MaxDiam)
                {
                    this.parachute.deployedDiameter = maxDiam;
                    this.EditorGUI.warning          = true;
                }
                else
                {
                    this.EditorGUI.warning = false;
                }
                this.parachute.preDeployedDiameter = RCUtils.Round(this.templateGUI.Type == ParachuteType.MAIN ? this.parachute.deployedDiameter / 20 : this.parachute.deployedDiameter / 2);
                Debug.Log($"[RealChute]: {this.Part.partInfo.title} {RCUtils.ParachuteNumber(this.id)} - depDiam: {this.parachute.deployedDiameter}m, preDepDiam: {this.parachute.preDeployedDiameter}m");
            }

            else
            {
                this.parachute.preDeployedDiameter = RCUtils.Round(float.Parse(this.templateGUI.preDepDiam));
                this.parachute.deployedDiameter    = RCUtils.Round(float.Parse(this.templateGUI.depDiam));
                Debug.Log($"[RealChute]: {this.Part.partInfo.title} {RCUtils.ParachuteNumber(this.id)} - depDiam: {this.parachute.deployedDiameter}m, preDepDiam: {this.parachute.preDeployedDiameter}m");
            }

            this.parachute.minIsPressure = this.templateGUI.isPressure;
            if (this.templateGUI.isPressure)
            {
                this.parachute.minPressure = float.Parse(this.templateGUI.predepClause);
            }
            else
            {
                this.parachute.minDeployment = float.Parse(this.templateGUI.predepClause);
            }
            this.parachute.deploymentAlt      = float.Parse(this.templateGUI.deploymentAlt);
            this.parachute.cutAlt             = GuiUtils.ParseEmpty(this.templateGUI.cutAlt);
            this.parachute.preDeploymentSpeed = float.Parse(this.templateGUI.preDepSpeed);
            this.parachute.deploymentSpeed    = float.Parse(this.templateGUI.depSpeed);

            if (toSymmetryCounterparts)
            {
                foreach (Part part in this.Part.symmetryCounterparts)
                {
                    Parachute sym = ((RealChuteModule)part.Modules["RealChuteModule"]).parachutes[this.id];
                    sym.material            = this.material.Name;
                    sym.mat                 = this.material;
                    sym.deployedDiameter    = this.parachute.deployedDiameter;
                    sym.preDeployedDiameter = this.parachute.preDeployedDiameter;
                    sym.minIsPressure       = this.templateGUI.isPressure;
                    sym.minPressure         = this.parachute.minPressure;
                    sym.minDeployment       = this.parachute.minDeployment;
                    sym.deploymentAlt       = this.parachute.deploymentAlt;
                    sym.cutAlt              = this.parachute.cutAlt;
                    sym.preDeploymentSpeed  = this.parachute.preDeploymentSpeed;
                    sym.deploymentSpeed     = this.parachute.deploymentSpeed;

                    TemplateGUI template = ((ProceduralChute)part.Modules["ProceduralChute"]).chutes[this.id].templateGUI;
                    template.chuteId       = this.templateGUI.chuteId;
                    template.TypeId        = this.templateGUI.TypeId;
                    template.modelId       = this.templateGUI.modelId;
                    template.materialsId   = this.templateGUI.materialsId;
                    template.isPressure    = this.templateGUI.isPressure;
                    template.calcSelect    = this.templateGUI.calcSelect;
                    template.getMass       = this.templateGUI.getMass;
                    template.useDry        = this.templateGUI.useDry;
                    template.preDepDiam    = this.templateGUI.preDepDiam;
                    template.depDiam       = this.templateGUI.depDiam;
                    template.predepClause  = this.templateGUI.predepClause;
                    template.mass          = this.templateGUI.mass;
                    template.landingSpeed  = this.templateGUI.landingSpeed;
                    template.deceleration  = this.templateGUI.deceleration;
                    template.refDepAlt     = this.templateGUI.refDepAlt;
                    template.chuteCount    = this.templateGUI.chuteCount;
                    template.deploymentAlt = this.templateGUI.deploymentAlt;
                    template.cutAlt        = this.templateGUI.cutAlt;
                    template.preDepSpeed   = this.templateGUI.preDepSpeed;
                    template.depSpeed      = this.templateGUI.depSpeed;
                }
            }
        }
Example #14
0
        //Calculations GUI core
        internal void Calculations()
        {
            #region Calculations
            //Selection mode
            GUILayout.Space(5);
            GUILayout.BeginHorizontal();
            GUILayout.Label("Calculations mode:", skins.label);
            if (GUILayout.Toggle(calcSelect, "Automatic", skins.toggle))
            {
                calcSelect = true;
            }
            GUILayout.FlexibleSpace();
            if (GUILayout.Toggle(!calcSelect, "Manual", skins.toggle))
            {
                calcSelect = false;
            }
            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();
            GUILayout.Space(5);

            //Calculations
            parachuteScroll = GUILayout.BeginScrollView(parachuteScroll, false, false, skins.horizontalScrollbar, skins.verticalScrollbar, skins.box, GUILayout.Height(160));

            #region Automatic
            if (calcSelect)
            {
                typeID = GUILayout.SelectionGrid(typeID, RCUtils.types, 3, skins.button);

                GUILayout.BeginHorizontal();
                GUILayout.FlexibleSpace();
                if (GUILayout.Toggle(getMass, "Use current craft mass", skins.button, GUILayout.Width(150)))
                {
                    getMass = true;
                }
                GUILayout.FlexibleSpace();
                if (GUILayout.Toggle(!getMass, "Input craft mass", skins.button, GUILayout.Width(150)))
                {
                    getMass = false;
                }
                GUILayout.FlexibleSpace();
                GUILayout.EndHorizontal();

                if (getMass)
                {
                    GUILayout.Label("Currently using " + (useDry ? "dry mass" : "wet mass"), skins.label);
                    if (useDry)
                    {
                        if (GUILayout.Button("Switch to wet mass", skins.button, GUILayout.Width(125)))
                        {
                            useDry = false;
                        }
                    }
                    else
                    {
                        if (GUILayout.Button("Switch to dry mass", skins.button, GUILayout.Width(125)))
                        {
                            useDry = true;
                        }
                    }
                }

                else
                {
                    string m = mass;
                    this.editorGUI.CreateEntryArea("Mass to use (t):", ref m, 0.1f, 10000, 100);
                    mass = m;
                }

                GUILayout.Space(5);
                GUILayout.BeginHorizontal();
                if (typeID == 0)
                {
                    if (RCUtils.CanParse(landingSpeed) && RCUtils.CheckRange(float.Parse(landingSpeed), 0.1f, 300))
                    {
                        GUILayout.Label("Wanted touchdown speed (m/s):", skins.label);
                    }
                    else
                    {
                        GUILayout.Label("Wanted touchdown speed (m/s):", RCUtils.redLabel);
                    }
                }
                else if (typeID == 1)
                {
                    if (RCUtils.CanParse(landingSpeed) && RCUtils.CheckRange(float.Parse(landingSpeed), 0.1f, 5000))
                    {
                        GUILayout.Label("Wanted speed at target alt (m/s):", skins.label);
                    }
                    else
                    {
                        GUILayout.Label("Wanted speed at target alt (m/s):", RCUtils.redLabel);
                    }
                }
                else
                {
                    if (RCUtils.CanParse(landingSpeed) && RCUtils.CheckRange(float.Parse(landingSpeed), 0.1f, 300))
                    {
                        GUILayout.Label("Planned landing speed (m/s):", skins.label);
                    }
                    else
                    {
                        GUILayout.Label("Planned landing speed (m/s):", RCUtils.redLabel);
                    }
                }
                GUILayout.FlexibleSpace();
                landingSpeed = GUILayout.TextField(landingSpeed, 10, skins.textField, GUILayout.Width(100));
                GUILayout.EndHorizontal();

                if (typeID == 2)
                {
                    string decel = deceleration;
                    this.editorGUI.CreateEntryArea("Wanted deceleration (m/s²):", ref decel, 0.1f, 100, 100);
                    deceleration = decel;
                }

                if (typeID == 1)
                {
                    string depAlt = refDepAlt;
                    this.editorGUI.CreateEntryArea("Target altitude (m):", ref depAlt, 10, (float)body.GetMaxAtmosphereAltitude(), 100);
                    refDepAlt = depAlt;
                }

                string chutes = chuteCount;
                this.editorGUI.CreateEntryArea("Parachutes used (parts):", ref chutes, 1, 100, 100);
                chuteCount = chutes;
            }
            #endregion

            #region Manual
            else
            {
                //Predeployed diameter
                string preDep = preDepDiam, dep = depDiam;
                this.editorGUI.CreateEntryArea("Predeployed diameter (m):", ref preDep, 0.5f, model.maxDiam / 2, 100);
                if (RCUtils.CanParse(preDepDiam))
                {
                    GUILayout.Label("Resulting area: " + RCUtils.GetArea(float.Parse(preDepDiam)).ToString("0.00") + "m²", skins.label);
                }
                else
                {
                    GUILayout.Label("Resulting predeployed area: --- m²", skins.label);
                }

                //Deployed diameter
                this.editorGUI.CreateEntryArea("Deployed diameter (m):", ref dep, 1, model.maxDiam, 100);
                if (RCUtils.CanParse(depDiam))
                {
                    GUILayout.Label("Resulting area: " + RCUtils.GetArea(float.Parse(depDiam)).ToString("0.00") + "m²", skins.label);
                }
                else
                {
                    GUILayout.Label("Resulting deployed area: --- m²", skins.label);
                }
                preDepDiam = preDep;
                depDiam    = dep;
            }
            #endregion

            GUILayout.EndScrollView();
            #endregion

            #region Specific
            //Pressure/alt toggle
            GUILayout.Space(5);
            GUILayout.BeginHorizontal();
            if (GUILayout.Toggle(isPressure, "Pressure predeployment", skins.toggle))
            {
                if (!isPressure)
                {
                    isPressure        = true;
                    this.predepClause = this.parachute.minPressure.ToString();
                }
            }
            GUILayout.FlexibleSpace();
            if (GUILayout.Toggle(!isPressure, "Altitude predeployment", skins.toggle))
            {
                if (isPressure)
                {
                    isPressure        = false;
                    this.predepClause = this.parachute.minDeployment.ToString();
                }
            }
            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();

            GUILayout.Space(5);
            GUILayout.BeginHorizontal();
            if (isPressure)
            {
                if (RCUtils.CanParse(predepClause) && RCUtils.CheckRange(float.Parse(predepClause), 0.0001f, (float)body.GetPressureASL()))
                {
                    GUILayout.Label("Predeployment pressure (atm):", skins.label);
                }
                else
                {
                    GUILayout.Label("Predeployment pressure (atm):", RCUtils.redLabel);
                }
            }
            else
            {
                if (RCUtils.CanParse(predepClause) && RCUtils.CheckRange(float.Parse(predepClause), 10, (float)body.GetMaxAtmosphereAltitude()))
                {
                    GUILayout.Label("Predeployment altitude (m):", skins.label);
                }
                else
                {
                    GUILayout.Label("Predeployment altitude (m):", RCUtils.redLabel);
                }
            }
            GUILayout.FlexibleSpace();
            predepClause = GUILayout.TextField(predepClause, 10, skins.textField, GUILayout.Width(150));
            GUILayout.EndHorizontal();

            //Deployment altitude
            this.editorGUI.CreateEntryArea("Deployment altitude", ref deploymentAlt, 10, (float)body.GetMaxAtmosphereAltitude());

            //Cut altitude
            GUILayout.Space(5);
            GUILayout.BeginHorizontal();
            if (RCUtils.CanParseWithEmpty(cutAlt) && RCUtils.CheckRange(RCUtils.ParseWithEmpty(cutAlt), -1, (float)body.GetMaxAtmosphereAltitude()))
            {
                GUILayout.Label("Autocut altitude (m):", skins.label);
            }
            else
            {
                GUILayout.Label("Autocut altitude (m):", RCUtils.redLabel);
            }
            GUILayout.FlexibleSpace();
            cutAlt = GUILayout.TextField(cutAlt, 10, skins.textField, GUILayout.Width(150));
            GUILayout.EndHorizontal();

            //Predeployment speed
            this.editorGUI.CreateEntryArea("Pre deployment speed (s):", ref preDepSpeed, 0.5f, 5);

            //Deployment speed
            this.editorGUI.CreateEntryArea("Deployment speed (s):", ref depSpeed, 1, 10);
            #endregion
        }
Example #15
0
        //Main GUI window
        private void Window(int id)
        {
            GUILayout.BeginVertical();

            #region Info labels
            GUILayout.Label("Selected part: " + this.part.partInfo.title, skins.label);
            GUILayout.Label("Symmetry counterparts: " + (this.part.symmetryCounterparts.Count), skins.label);
            GUILayout.Label("Case mass: " + rcModule.caseMass + "t", skins.label);
            GUILayout.Label("Total part mass: " + this.part.TotalMass().ToString("0.###") + "t", skins.label);
            #endregion

            #region Presets
            GUILayout.BeginHorizontal();
            if (GUILayout.Button("Select a preset", skins.button))
            {
                this.presetVisible = !this.presetVisible;
            }

            if (GUILayout.Button("Save as preset...", skins.button))
            {
                this.presetSaveVisible = !this.presetSaveVisible;
            }
            GUILayout.EndHorizontal();
            #endregion

            #region Planet selector
            GUILayout.Space(10);
            GUILayout.BeginHorizontal(GUILayout.Height(30));
            GUILayout.BeginVertical();
            GUILayout.FlexibleSpace();
            GUILayout.Label("Target planet:", skins.label);
            GUILayout.FlexibleSpace();
            GUILayout.EndVertical();
            planets = GUILayout.SelectionGrid(planets, bodies.GetNames(), 4, skins.button, GUILayout.Width(250));
            GUILayout.EndHorizontal();
            body = bodies.GetBody(planets);
            #endregion

            #region Size cyclers
            if (sizes.Count > 0)
            {
                GUILayout.BeginHorizontal(GUILayout.Height(20));
                GUILayout.BeginVertical();
                GUILayout.FlexibleSpace();
                GUILayout.Label("Cycle part size", skins.label);
                GUILayout.EndVertical();
                GUILayout.FlexibleSpace();
                if (GUILayout.Button("Previous size", skins.button, GUILayout.Width(125)))
                {
                    size--;
                    if (size < 0)
                    {
                        size = sizes.Count - 1;
                    }
                }
                if (GUILayout.Button("Next size", skins.button, GUILayout.Width(125)))
                {
                    size++;
                    if (size > sizes.Count - 1)
                    {
                        size = 0;
                    }
                }
                GUILayout.EndHorizontal();
            }
            #endregion

            GUILayout.Space(5);
            mainScroll = GUILayout.BeginScrollView(mainScroll, false, false, skins.horizontalScrollbar, skins.verticalScrollbar);
            GUILayout.BeginHorizontal();
            GUILayout.BeginVertical();

            #region Texture selectors
            GUILayout.Space(5);
            main.TextureSelector();
            #endregion

            #region General
            //Materials editor
            GUILayout.Space(5);
            main.MaterialsSelector();

            //MustGoDown
            GUILayout.Space(5);
            GUILayout.BeginHorizontal(GUILayout.MaxWidth(window.width));
            GUILayout.Label("Must go down to deploy:", skins.label);
            if (GUILayout.Toggle(mustGoDown, "True", skins.toggle))
            {
                mustGoDown = true;
            }
            GUILayout.FlexibleSpace();
            if (GUILayout.Toggle(!mustGoDown, "False", skins.toggle))
            {
                mustGoDown = false;
            }
            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();

            //DeployOnGround
            GUILayout.Space(5);
            GUILayout.BeginHorizontal(GUILayout.MaxWidth(window.width));
            GUILayout.Label("Deploy on ground contact:", skins.label);
            if (GUILayout.Toggle(deployOnGround, "True", skins.toggle))
            {
                deployOnGround = true;
            }
            GUILayout.FlexibleSpace();
            if (GUILayout.Toggle(!deployOnGround, "False", skins.toggle))
            {
                deployOnGround = false;
            }
            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();

            //Timer
            GUILayout.Space(5);
            GUILayout.BeginHorizontal();
            if (RCUtils.CanParseTime(timer) && RCUtils.CheckRange(RCUtils.ParseTime(timer), 0, 3600))
            {
                GUILayout.Label("Deployment timer:", skins.label);
            }
            else
            {
                GUILayout.Label("Deployment timer:", RCUtils.redLabel);
            }
            GUILayout.FlexibleSpace();
            timer = GUILayout.TextField(timer, 10, skins.textField, GUILayout.Width(150));
            GUILayout.EndHorizontal();

            //Spares
            GUILayout.Space(5);
            GUILayout.BeginHorizontal();
            if (RCUtils.CanParseWithEmpty(spares) && RCUtils.CheckRange(RCUtils.ParseWithEmpty(spares), -1, 10) && RCUtils.IsWholeNumber(RCUtils.ParseWithEmpty(spares)))
            {
                GUILayout.Label("Spare chutes:", skins.label);
            }
            else
            {
                GUILayout.Label("Spare chutes:", RCUtils.redLabel);
            }
            GUILayout.FlexibleSpace();
            spares = GUILayout.TextField(spares, 10, skins.textField, GUILayout.Width(150));
            GUILayout.EndHorizontal();

            //CutSpeed
            CreateEntryArea("Autocut speed (m/s):", ref cutSpeed, 0.01f, 100);
            #endregion

            #region Main
            //Indicator label
            GUILayout.Space(10);
            GUILayout.Label("________________________________________________", RCUtils.boldLabel);
            GUILayout.Label("Main chute:", RCUtils.boldLabel, GUILayout.Width(150));
            GUILayout.Label("‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾", RCUtils.boldLabel);

            main.Calculations();
            #endregion

            #region Secondary
            if (secondaryChute)
            {
                //Indicator label
                GUILayout.Space(10);
                GUILayout.Label("________________________________________________", RCUtils.boldLabel);
                GUILayout.Label("Secondary chute:", RCUtils.boldLabel, GUILayout.Width(150));
                GUILayout.Label("‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾", RCUtils.boldLabel);

                #region Texture selectors
                GUILayout.Space(5);
                secondary.TextureSelector();
                #endregion

                //Materials editor
                GUILayout.Space(5);
                secondary.MaterialsSelector();

                secondary.Calculations();
            }
            #endregion

            GUILayout.EndVertical();
            GUILayout.BeginVertical();
            GUILayout.EndVertical();
            GUILayout.EndHorizontal();
            GUILayout.EndScrollView();

            #region Application
            GUILayout.Space(5);
            if (GUILayout.Button("Apply settings", skins.button))
            {
                Apply(false);
            }

            if (part.symmetryCounterparts.Count > 0)
            {
                if (GUILayout.Button("Apply to all symmetry counterparts", skins.button))
                {
                    Apply(true);
                }
            }
            #endregion

            GUILayout.EndVertical();
        }
Example #16
0
        //Checks if there is a timer and/or a mustGoDown clause active
        public void CheckForWait()
        {
            bool timerSpent = true, goesDown = true;

            //Timer
            if (timer > 0 && deploymentTimer.elapsed.TotalSeconds < timer)
            {
                timerSpent = false;
                if (!deploymentTimer.isRunning)
                {
                    deploymentTimer.Start();
                }
                if (this.vessel.isActiveVessel)
                {
                    float time = timer - (float)deploymentTimer.elapsed.TotalSeconds;
                    if (time < 60)
                    {
                        ScreenMessages.PostScreenMessage(String.Format("Deployment in {0:0.0}s", time), Time.fixedDeltaTime, ScreenMessageStyle.UPPER_CENTER);
                    }
                    else
                    {
                        ScreenMessages.PostScreenMessage(String.Format("Deployment in {0}", RCUtils.ToMinutesSeconds(time)), Time.fixedDeltaTime, ScreenMessageStyle.UPPER_CENTER);
                    }
                }
            }
            else if (deploymentTimer.isRunning)
            {
                deploymentTimer.Stop();
            }

            //Goes down
            if (mustGoDown && this.vessel.verticalSpeed >= 0)
            {
                goesDown = false;
                if (this.vessel.isActiveVessel)
                {
                    ScreenMessages.PostScreenMessage("Deployment awaiting negative vertical velocity", Time.fixedDeltaTime, ScreenMessageStyle.UPPER_CENTER);
                    ScreenMessages.PostScreenMessage(String.Format("Current vertical velocity: {0:0.0}/s", this.vessel.verticalSpeed), Time.fixedDeltaTime, ScreenMessageStyle.UPPER_CENTER);
                }
            }

            //Can deploy or not
            if (timerSpent && goesDown)
            {
                wait       = false;
                showDisarm = false;
                deploymentTimer.Reset();
            }
            else
            {
                this.part.stackIcon.SetIconColor(XKCDColors.LightCyan);
                wait       = true;
                showDisarm = true;
            }
        }
Example #17
0
        //Main GUI window
        private void Window(int id)
        {
            GUILayout.BeginVertical();

            #region Info labels
            StringBuilder builder = new StringBuilder();
            builder.Append("Selected part: ").AppendLine(this.part.partInfo.title);
            builder.Append("Symmetry counterparts: ").AppendLine(this.part.symmetryCounterparts.Count.ToString());
            builder.Append("Case mass: ").Append(rcModule.caseMass.ToString()).Append("t");
            if (sizes.Count > 0)
            {
                builder.Append("\t\t\t\t\tCase cost: ").Append(this.sizes[pChute.size].cost.ToString()).Append("f");
            }
            builder.Append("\nTotal part mass: ").Append(this.part.TotalMass().ToString("0.###")).Append("t");
            builder.Append("\t\t\tTotal case part cost: ").Append(this.part.TotalCost().ToString("0.#")).Append("f");
            GUILayout.Label(builder.ToString(), skins.label);
            #endregion

            #region Presets
            GUILayout.BeginHorizontal();
            if (GUILayout.Button("Select a preset", skins.button))
            {
                this.presetVisible = !this.presetVisible;
            }

            if (GUILayout.Button("Save as preset...", skins.button))
            {
                this.presetSaveVisible = !this.presetSaveVisible;
            }
            GUILayout.EndHorizontal();
            #endregion

            mainScroll = GUILayout.BeginScrollView(mainScroll, false, false, skins.horizontalScrollbar, skins.verticalScrollbar);

            #region Planet selector
            GUILayout.Space(10);
            GUILayout.BeginHorizontal(GUILayout.Height(30));
            GUILayout.BeginVertical();
            GUILayout.FlexibleSpace();
            GUILayout.Label("Target planet:", skins.label);
            GUILayout.FlexibleSpace();
            GUILayout.EndVertical();
            pChute.planets = GUILayout.SelectionGrid(pChute.planets, pChute.bodies.bodyNames, 4, skins.button, GUILayout.Width(250));
            GUILayout.EndHorizontal();
            pChute.body = pChute.bodies.GetBody(pChute.planets);
            #endregion

            #region Size cyclers
            if (sizes.Count > 0)
            {
                GUILayout.BeginHorizontal(GUILayout.Height(20));
                GUILayout.BeginVertical();
                GUILayout.FlexibleSpace();
                GUILayout.Label("Cycle part size", skins.label);
                GUILayout.EndVertical();
                GUILayout.FlexibleSpace();
                if (GUILayout.Button("Previous size", skins.button, GUILayout.Width(125)))
                {
                    pChute.size--;
                    if (pChute.size < 0)
                    {
                        pChute.size = sizes.Count - 1;
                    }
                }
                if (GUILayout.Button("Next size", skins.button, GUILayout.Width(125)))
                {
                    pChute.size++;
                    if (pChute.size > sizes.Count - 1)
                    {
                        pChute.size = 0;
                    }
                }
                GUILayout.EndHorizontal();
            }
            #endregion

            GUILayout.Space(5);
            GUILayout.BeginHorizontal();
            GUILayout.BeginVertical();

            #region Texture selectors
            GUILayout.Space(5);
            chutes[0].TextureSelector();
            #endregion

            #region General
            //Materials editor
            GUILayout.Space(5);
            chutes[0].MaterialsSelector();

            //MustGoDown
            GUILayout.Space(5);
            GUILayout.BeginHorizontal(GUILayout.MaxWidth(window.width));
            GUILayout.Label("Must go down to deploy:", skins.label);
            if (GUILayout.Toggle(pChute.mustGoDown, "True", skins.toggle))
            {
                pChute.mustGoDown = true;
            }
            GUILayout.FlexibleSpace();
            if (GUILayout.Toggle(!pChute.mustGoDown, "False", skins.toggle))
            {
                pChute.mustGoDown = false;
            }
            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();

            //DeployOnGround
            GUILayout.Space(5);
            GUILayout.BeginHorizontal(GUILayout.MaxWidth(window.width));
            GUILayout.Label("Deploy on ground contact:", skins.label);
            if (GUILayout.Toggle(pChute.deployOnGround, "True", skins.toggle))
            {
                pChute.deployOnGround = true;
            }
            GUILayout.FlexibleSpace();
            if (GUILayout.Toggle(!pChute.deployOnGround, "False", skins.toggle))
            {
                pChute.deployOnGround = false;
            }
            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();

            //Timer
            GUILayout.Space(5);
            GUILayout.BeginHorizontal();
            if (RCUtils.CanParseTime(pChute.timer) && RCUtils.CheckRange(RCUtils.ParseTime(pChute.timer), 0, 3600))
            {
                GUILayout.Label("Deployment timer:", skins.label);
            }
            else
            {
                GUILayout.Label("Deployment timer:", RCUtils.redLabel);
            }
            GUILayout.FlexibleSpace();
            pChute.timer = GUILayout.TextField(pChute.timer, 10, skins.textField, GUILayout.Width(150));
            GUILayout.EndHorizontal();

            //Spares
            GUILayout.Space(5);
            GUILayout.BeginHorizontal();
            if (RCUtils.CanParseWithEmpty(pChute.spares) && RCUtils.CheckRange(RCUtils.ParseWithEmpty(pChute.spares), -1, 10) && RCUtils.IsWholeNumber(RCUtils.ParseWithEmpty(pChute.spares)))
            {
                GUILayout.Label("Spare chutes:", skins.label);
            }
            else
            {
                GUILayout.Label("Spare chutes:", RCUtils.redLabel);
            }
            GUILayout.FlexibleSpace();
            pChute.spares = GUILayout.TextField(pChute.spares, 10, skins.textField, GUILayout.Width(150));
            GUILayout.EndHorizontal();

            //CutSpeed
            CreateEntryArea("Autocut speed (m/s):", ref pChute.cutSpeed, 0.01f, 100);

            //LandingAlt
            CreateEntryArea("Landing alt (m):", ref pChute.landingAlt, 0, (float)pChute.body.GetMaxAtmosphereAltitude());
            #endregion

            #region Main
            //Indicator label
            GUILayout.Space(10);
            GUILayout.Label("________________________________________________", RCUtils.boldLabel);
            GUILayout.Label("Main chute:", RCUtils.boldLabel, GUILayout.Width(150));
            GUILayout.Label("‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾", RCUtils.boldLabel);

            chutes[0].Calculations();
            #endregion

            #region Secondary
            if (pChute.secondaryChute)
            {
                for (int i = 1; i < chutes.Count; i++)
                {
                    ChuteTemplate chute = chutes[i];

                    //Indicator label
                    GUILayout.Space(10);
                    GUILayout.Label("________________________________________________", RCUtils.boldLabel);
                    GUILayout.Label("Chute #" + (i + 1) + " :", RCUtils.boldLabel, GUILayout.Width(150));
                    GUILayout.Label("‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾", RCUtils.boldLabel);

                    #region Texture selectors
                    GUILayout.Space(5);
                    chute.TextureSelector();
                    #endregion

                    //Materials editor
                    GUILayout.Space(5);
                    chute.MaterialsSelector();

                    chute.Calculations();
                }
            }
            #endregion

            GUILayout.EndVertical();
            GUILayout.BeginVertical();
            GUILayout.EndVertical();
            GUILayout.EndHorizontal();
            GUILayout.EndScrollView();

            #region Application
            GUILayout.Space(5);
            if (GUILayout.Button("Apply settings", skins.button))
            {
                pChute.Apply(false);
            }

            if (part.symmetryCounterparts.Count > 0)
            {
                if (GUILayout.Button("Apply to all symmetry counterparts", skins.button))
                {
                    pChute.Apply(true);
                }
            }
            #endregion

            GUILayout.EndVertical();
        }
Example #18
0
        //Calculations GUI core
        internal void Calculations()
        {
            #region Calculations
            //Selection mode
            GuiUtils.CreateTwinToggle("Calculations mode:", ref this.calcSelect, 300, new string[] { "Automatic", "Manual" });
            GUILayout.Space(5);

            //Calculations
            this.parachuteScroll = GUILayout.BeginScrollView(this.parachuteScroll, false, false, GUI.skin.horizontalScrollbar, GUI.skin.verticalScrollbar, GUI.skin.box, GUILayout.Height(160));
            string label;
            float  max, min;

            #region Automatic
            if (this.calcSelect)
            {
                this.TypeID = GUILayout.SelectionGrid(this.TypeID, EnumUtils.GetNames <ParachuteType>(), 3);
                GUILayout.BeginHorizontal();
                GUILayout.FlexibleSpace();
                if (GUILayout.Toggle(this.getMass, "Use current craft mass", GUILayout.Width(150)))
                {
                    this.getMass = true;
                }
                GUILayout.FlexibleSpace();
                if (GUILayout.Toggle(!this.getMass, "Input craft mass", GUILayout.Width(150)))
                {
                    this.getMass = false;
                }
                GUILayout.FlexibleSpace();
                GUILayout.EndHorizontal();

                if (this.getMass)
                {
                    GUILayout.Label("Currently using " + (this.useDry ? "dry mass" : "wet mass"));
                    if (GUILayout.Button("Switch to " + (this.useDry ? "wet mass" : "dry mass"), GUILayout.Width(125)))
                    {
                        this.useDry = !this.useDry;
                    }
                }

                else
                {
                    GuiUtils.CreateEntryArea("Mass to use (t):", ref this.mass, 0.1f, 10000, 100);
                }
                max = 300;
                switch (this.Type)
                {
                case ParachuteType.MAIN:
                    label = "Wanted touchdown speed (m/s):"; break;

                case ParachuteType.DROGUE:
                    label = "Wanted speed at target alt (m/s):"; max = 5000; break;

                case ParachuteType.DRAG:
                    label = "Planned landing speed (m/s):"; break;

                default:
                    label = string.Empty; break;
                }
                GuiUtils.CreateEntryArea(label, ref this.landingSpeed, 0.1f, max, 100);

                if (this.Type == ParachuteType.DROGUE)
                {
                    GuiUtils.CreateEntryArea("Target altitude (m):", ref this.refDepAlt, 10, (float)this.Body.GetMaxAtmosphereAltitude(), 100);
                }

                if (this.Type == ParachuteType.DRAG)
                {
                    GuiUtils.CreateEntryArea("Wanted deceleration (m/s²):", ref this.deceleration, 0.1f, 100, 100);
                }

                GuiUtils.CreateEntryArea("Parachutes used (parachutes):", ref this.chuteCount, 1, 100, 100);
            }
            #endregion

            #region Manual
            else
            {
                float p, d;
                if (!float.TryParse(this.preDepDiam, out p))
                {
                    p = -1;
                }
                if (!float.TryParse(this.depDiam, out d))
                {
                    d = -1;
                }

                //Predeployed diameter
                GuiUtils.CreateEntryArea("Predeployed diameter (m):", ref this.preDepDiam, 0.5f, d, 100);
                if (p != -1)
                {
                    GUILayout.Label("Resulting area: " + RCUtils.GetArea(p).ToString("0.00") + "m²");
                }
                else
                {
                    GUILayout.Label("Resulting predeployed area: --- m²");
                }

                //Deployed diameter
                GuiUtils.CreateEntryArea("Deployed diameter (m):", ref this.depDiam, 1, this.PChute.textures == null ? 70 : this.Model.MaxDiam, 100);
                if (d != 1)
                {
                    GUILayout.Label("Resulting area: " + RCUtils.GetArea(d).ToString("0.00") + "m²");
                }
                else
                {
                    GUILayout.Label("Resulting deployed area: --- m²");
                }
            }
            #endregion

            GUILayout.EndScrollView();
            #endregion

            #region Specific
            //Pressure/alt toggle
            GUILayout.Space(5);
            GUILayout.BeginHorizontal();
            if (GUILayout.Toggle(this.isPressure, "Pressure predeployment"))
            {
                if (!this.isPressure)
                {
                    this.isPressure   = true;
                    this.predepClause = this.Parachute.minPressure.ToString();
                }
            }
            GUILayout.FlexibleSpace();
            if (GUILayout.Toggle(!this.isPressure, "Altitude predeployment"))
            {
                if (this.isPressure)
                {
                    this.isPressure   = false;
                    this.predepClause = this.Parachute.minDeployment.ToString();
                }
            }
            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();

            //Pressure/alt selection
            if (this.isPressure)
            {
                label = "Predeployment pressure (atm):";
                min   = 0.0001f;
                max   = (float)this.Body.GetPressureAsl();
            }
            else
            {
                label = "Predeployment altitude (m):";
                min   = 10;
                max   = (float)this.Body.GetMaxAtmosphereAltitude();
            }
            GuiUtils.CreateEntryArea(label, ref this.predepClause, min, max);

            //Deployment altitude
            GuiUtils.CreateEntryArea("Deployment altitude", ref this.deploymentAlt, 10, (float)this.Body.GetMaxAtmosphereAltitude());

            //Cut altitude
            GuiUtils.CreateEmptyEntryArea("Autocut altitude (m):", ref this.cutAlt, -1, (float)this.Body.GetMaxAtmosphereAltitude());

            //Predeployment speed
            GuiUtils.CreateEntryArea("Pre deployment speed (s):", ref this.preDepSpeed, 0.5f, 5);

            //Deployment speed
            GuiUtils.CreateEntryArea("Deployment speed (s):", ref this.depSpeed, 1, 10);
            #endregion
        }