//Copies all fields to the symmetry counterpart public void CopyFromOriginal(RealChuteModule module, ProceduralChute pChute) { Parachute sym = module.parachutes[id]; ChuteTemplate template = pChute.chutes[id]; parachute = pChute.rcModule.parachutes[id]; material = sym.mat; parachute.deployedDiameter = sym.deployedDiameter; parachute.preDeployedDiameter = sym.preDeployedDiameter; isPressure = sym.minIsPressure; if (isPressure) { parachute.minPressure = sym.minPressure; } else { parachute.minDeployment = sym.minDeployment; } parachute.deploymentAlt = sym.deploymentAlt; parachute.cutAlt = sym.cutAlt; parachute.preDeploymentSpeed = sym.preDeploymentSpeed; parachute.deploymentSpeed = sym.deploymentSpeed; this.chuteID = template.chuteID; this.typeID = template.typeID; this.modelID = template.modelID; this.materialsID = template.materialsID; this.isPressure = template.isPressure; this.calcSelect = template.calcSelect; this.getMass = template.getMass; this.useDry = template.useDry; this.preDepDiam = template.preDepDiam; this.depDiam = template.depDiam; this.predepClause = template.predepClause; this.mass = template.mass; this.landingSpeed = template.landingSpeed; this.deceleration = template.deceleration; this.refDepAlt = template.refDepAlt; this.chuteCount = template.chuteCount; this.deploymentAlt = template.deploymentAlt; this.cutAlt = template.cutAlt; this.preDepSpeed = template.preDepSpeed; this.depSpeed = template.depSpeed; }
/// <summary> /// Generates a new TemplateGUI from the given ChuteTemplate /// </summary> /// <param name="template"></param> public TemplateGUI(ChuteTemplate template) { this.template = template; }
public override void OnStart(PartModule.StartState state) { if ((!HighLogic.LoadedSceneIsEditor && !HighLogic.LoadedSceneIsFlight) || !CompatibilityChecker.IsCompatible()) { return; } //Identification of the RealChuteModule if (this.part.Modules.Contains("RealChuteModule")) { rcModule = this.part.Modules["RealChuteModule"] as RealChuteModule; } else { return; } if (!rcModule.isTweakable) { return; } secondaryChute = rcModule.secondaryChute; if (textureLibrary != "none") { textureLib.TryGetConfig(textureLibrary, ref textures); } bodies = AtmoPlanets.fetch; main = new ChuteTemplate(this, false); if (secondaryChute) { secondary = new ChuteTemplate(this, true); } //Initialization of sizes if (sizes.Count <= 0 && moduleNodes.Keys.Contains(this.part.partInfo.name)) { print("[RealChute]: Reloading size nodes for " + this.part.partInfo.name); moduleNodes.TryGetValue(this.part.partInfo.name, out sizes); } //Creates an instance of the texture library if (textureLibrary != "none") { cases = textures.caseNames; canopies = textures.canopyNames; models = textures.modelNames; textures.TryGetCase(caseID, type, ref parachuteCase); lastCaseID = caseID; } if (HighLogic.LoadedSceneIsEditor) { //Windows initiation this.window = new Rect(5, 370, 420, Screen.height - 375); this.materialsWindow = new Rect(matX, matY, 375, 280); this.secMaterialsWindow = new Rect(matX, matY, 375, 280); this.failedWindow = new Rect(Screen.width / 2 - 150, Screen.height / 2 - 150, 300, 300); this.successfulWindow = new Rect(Screen.width / 2 - 150, Screen.height / 2 - 25, 300, 50); this.presetsWindow = new Rect(Screen.width / 2 - 200, Screen.height / 2 - 250, 400, 500); this.presetsSaveWindow = new Rect(Screen.width / 2 - 175, Screen.height / 2 - 110, 350, 220); this.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.parachuteName).parent; } //Updates the part if (textureLibrary != "none") { UpdateCaseTexture(this.part, rcModule); } UpdateScale(this.part, rcModule); }
//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(); }
//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(); }
//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; } } }