/// <summary> /// Creates a new ChuteTemplate from the given ProceduralChute /// </summary> /// <param name="pChute">Module to create the object from</param> /// <param name="node">ConfigNode to load the data from</param> /// <param name="id">Index of the ChuteTemplate</param> public ChuteTemplate(ProceduralChute pChute, ConfigNode node, int id) { this.pChute = pChute; this.id = id; this.templateGUI = new TemplateGUI(this); if (node != null) { Load(node); } }
//Renders the RealChute editor GUI internal void RenderGUI() { if (!HighLogic.LoadedSceneIsEditor) { return; } GUI.skin = HighLogic.Skin; if (this.visible) { this.window = GUILayout.Window(this.mainId, this.window, Window, "RealChute Parachute Editor " + RCUtils.AssemblyVersion, GUILayout.MaxWidth(420), GUILayout.MaxHeight(Screen.height - 375)); } foreach (ChuteTemplate chute in this.Chutes) { TemplateGUI gui = chute.templateGUI; if (gui.materialsVisible) { gui.materialsWindow = GUILayout.Window(gui.matId, gui.materialsWindow, gui.MaterialsWindow, "Parachute material", GUILayout.MaxWidth(375), GUILayout.MaxHeight(275)); } } if (this.failedVisible) { this.failedWindow = GUILayout.Window(this.failedId, this.failedWindow, ApplicationFailed, "Error", GUILayout.MaxWidth(300), GUILayout.MaxHeight(300)); } if (this.successfulVisible) { this.successfulWindow = GUILayout.Window(this.successId, this.successfulWindow, ApplicationSucceeded, "Success", GUILayout.MaxWidth(300), GUILayout.MaxHeight(200), GUILayout.ExpandHeight(true)); } if (this.presetVisible) { this.presetsWindow = GUILayout.Window(this.pChute.presetId, this.presetsWindow, Presets, "Presets", GUILayout.MaxWidth(400), GUILayout.MaxHeight(500)); } if (this.presetSaveVisible) { this.presetsSaveWindow = GUILayout.Window(this.presetSaveId, this.presetsSaveWindow, SavePreset, "Save as preset", GUILayout.MaxWidth(350), GUILayout.MaxHeight(400)); } if (this.presetWarningVisible) { this.presetsWarningWindow = GUILayout.Window(this.presetWarningId, this.presetsWarningWindow, PresetWarning, "Warning", GUILayout.Width(200), GUILayout.Height(100)); } }
//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, this.body.GetMaxTemperatureAtAlt(alt)); double speed = double.Parse(this.templateGUI.landingSpeed); 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; } } }
//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; } } }