/// <summary> /// Creates a parachute object from the given RealChuteModule /// </summary> /// <param name="module">RealChuteModule to create the Parachute from</param> /// <param name="secondary">Wether this Parachute is the main or secondary parachute</param> public Parachute(RealChuteModule module, bool secondary) { this.module = module; this.secondary = secondary; if (this.secondary && this.material == "empty") { this.material = sec.material; } this.module.materials.TryGetMaterial(material, ref mat); this.parachute = this.part.FindModelTransform(parachuteName); this.cap = this.part.FindModelTransform(capName); this.parachute.gameObject.SetActive(false); this.part.InitiateAnimation(preDeploymentAnimation); this.part.InitiateAnimation(deploymentAnimation); if (!this.module.initiated) { deploymentState = DeploymentStates.STOWED; depState = "STOWED"; played = false; this.cap.gameObject.SetActive(true); } if (HighLogic.LoadedSceneIsFlight) { deploymentState = getState; if (this.module.capOff) { this.part.stackIcon.SetIconColor(XKCDColors.Red); this.cap.gameObject.SetActive(false); } } }
//Modifies the size of a part private void UpdateScale(Part part, RealChuteModule module) { if (sizes.Count <= 1 || !moduleNodes.Keys.Contains(this.part.partInfo.name)) { return; } SizeNode size = sizes[this.size], lastSize = sizes[this.lastSize]; part.transform.GetChild(0).localScale = Vector3.Scale(originalSize, size.size); module.caseMass = size.caseMass; if ((HighLogic.LoadedSceneIsEditor && part == EditorLogic.SortedShipList[0]) || (HighLogic.LoadedSceneIsFlight && this.vessel.rootPart == part)) { if (part.findAttachNode("top") != null) { AttachNode topNode = part.findAttachNode("top"); topNode.position = size.topNode; topNode.size = size.topNodeSize; if (topNode.attachedPart != null) { float topDifference = size.topNode.y - lastSize.topNode.y; topNode.attachedPart.transform.Translate(0, topDifference, 0, part.transform); if (part.findAttachNode("top").attachedPart.GetAllChildren().Count > 0) { topNode.attachedPart.GetAllChildren().ForEach(p => p.transform.Translate(0, topDifference, 0, part.transform)); } } } if (part.findAttachNode("bottom") != null) { AttachNode bottomNode = part.findAttachNode("bottom"); bottomNode.position = size.bottomNode; bottomNode.size = size.bottomNodeSize; if (bottomNode.attachedPart != null) { float bottomDifference = size.bottomNode.y - lastSize.bottomNode.y; bottomNode.attachedPart.transform.Translate(0, bottomDifference, 0, part.transform); if (part.findAttachNode("bottom").attachedPart.GetAllChildren().Count > 0) { bottomNode.attachedPart.GetAllChildren().ForEach(p => p.transform.Translate(0, bottomDifference, 0, part.transform)); } } } } else if (part.findAttachNode("bottom") != null && part.findAttachNode("bottom").attachedPart != null && part.parent != null && part.findAttachNode("bottom").attachedPart == part.parent) { AttachNode bottomNode = part.findAttachNode("bottom"); bottomNode.position = size.bottomNode; bottomNode.size = size.bottomNodeSize; float bottomDifference = size.bottomNode.y - lastSize.bottomNode.y; part.transform.Translate(0, -bottomDifference, 0, part.transform); if (part.findAttachNode("top") != null) { AttachNode topNode = part.findAttachNode("top"); topNode.position = size.topNode; topNode.size = size.topNodeSize; float topDifference = size.topNode.y - lastSize.topNode.y; if (part.GetAllChildren().Count > 0) { part.GetAllChildren().ForEach(p => p.transform.Translate(0, -(bottomDifference - topDifference), 0, part.transform)); } } } else if (part.findAttachNode("top") != null && part.findAttachNode("top").attachedPart != null && part.parent != null && part.findAttachNode("top").attachedPart == part.parent) { AttachNode topNode = part.findAttachNode("top"); topNode.position = size.topNode; topNode.size = size.topNodeSize; float topDifference = size.topNode.y - lastSize.topNode.y; part.transform.Translate(0, -topDifference, 0, part.transform); if (part.findAttachNode("bottom") != null) { AttachNode bottomNode = part.findAttachNode("bottom"); bottomNode.position = size.bottomNode; bottomNode.size = size.bottomNodeSize; float bottomDifference = size.bottomNode.y - lastSize.bottomNode.y; if (part.GetAllChildren().Count > 0) { part.GetAllChildren().ForEach(p => p.transform.Translate(0, -(topDifference - bottomDifference), 0, part.transform)); } } } float scaleX = part.transform.GetChild(0).localScale.x / Vector3.Scale(originalSize, lastSize.size).x; float scaleZ = part.transform.GetChild(0).localScale.z / Vector3.Scale(originalSize, lastSize.size).z; Vector3 chute = main.chute.forcePosition - part.transform.position; main.chute.parachute.transform.Translate(chute.x * (scaleX - 1), 0, chute.z * (scaleZ - 1), part.transform); if (secondaryChute) { Vector3 secChute = secondary.chute.forcePosition - part.transform.position; secondary.chute.parachute.transform.Translate(secChute.x * (scaleX - 1), 0, secChute.z * (scaleZ - 1), part.transform); } if (part.children.Count(p => p.attachMode == AttachModes.SRF_ATTACH) > 0) { List<Part> surfaceAttached = new List<Part>(part.children.Where(p => p.attachMode == AttachModes.SRF_ATTACH)); surfaceAttached.Where(p => p.GetAllChildren().Count > 0).ToList().ForEach(p => surfaceAttached.AddRange(p.GetAllChildren())); foreach (Part p in surfaceAttached) { Vector3 v = p.transform.position - part.transform.position; p.transform.Translate(v.x * (scaleX - 1), 0, v.z * (scaleZ - 1), part.transform); } } this.lastSize = this.size; }
//Modifies the case texture of a part private void UpdateCaseTexture(Part part, RealChuteModule module) { if (textureLibrary == "none" || currentCase == "none") { return; } if (textures.TryGetCase(caseID, type, ref parachuteCase)) { if (string.IsNullOrEmpty(parachuteCase.textureURL)) { Debug.LogWarning("[RealChute]: The " + textures.caseNames[caseID] + "URL is empty"); lastCaseID = caseID; return; } Texture2D texture = GameDatabase.Instance.GetTexture(parachuteCase.textureURL, false); if (texture == null) { Debug.LogWarning("[RealChute]: The " + textures.caseNames[caseID] + "texture is null"); lastCaseID = caseID; return; } part.GetPartRenderers(module).ForEach(r => r.material.mainTexture = texture); } lastCaseID = caseID; }
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); }
/// <summary> /// Creates a parachute object from the given RealChuteModule /// </summary> /// <param name="module">RealChuteModule to create the Parachute from</param> /// <param name="node">ConfigNode to create the parachute from</param> public Parachute(RealChuteModule module, ConfigNode node) { this.module = module; Load(node); }
//Modifies the case texture of a part private void UpdateCaseTexture(Part part, RealChuteModule module) { if (this.textures == null) { return; } if (this.textures.TryGetCase(this.caseID, this.type, ref this.parachuteCase)) { if (string.IsNullOrEmpty(this.parachuteCase.textureURL)) { Debug.LogWarning("[RealChute]: The " + this.parachuteCase.name + "URL is empty"); this.lastCaseID = this.caseID; return; } Texture2D texture = GameDatabase.Instance.GetTexture(this.parachuteCase.textureURL, false); if (texture == null) { Debug.LogWarning("[RealChute]: The " + this.parachuteCase.name + "texture is null"); this.lastCaseID = this.caseID; return; } this.part.GetPartRenderers(module).ForEach(r => r.material.mainTexture = texture); } this.lastCaseID = this.caseID; }
//Modifies the size of a part private void UpdateScale(Part part, RealChuteModule module) { //Thanks to Brodicus for the optimization here if (this.sizes.Count <= 1) { return; } SizeNode size = this.sizes[this.size], lastSize = this.sizes[this.lastSize]; Transform root = this.part.transform.GetChild(0); root.localScale = Vector3.Scale(this.originalSize, size.size); module.caseMass = size.caseMass; AttachNode topNode = null, bottomNode = null; bool hasTopNode = part.TryGetAttachNodeById("top", out topNode); bool hasBottomNode = part.TryGetAttachNodeById("bottom", out bottomNode); List<Part> allTopChildParts = null, allBottomChildParts = null; // If this is the root part, move things for the top and the bottom. if ((HighLogic.LoadedSceneIsEditor && this.part == EditorLogic.SortedShipList[0]) || (HighLogic.LoadedSceneIsFlight && this.vessel.rootPart == this.part)) { if (hasTopNode) { topNode.position = size.topNode; topNode.size = size.topNodeSize; if (topNode.attachedPart != null) { float topDifference = size.topNode.y - lastSize.topNode.y; topNode.attachedPart.transform.Translate(0, topDifference, 0, this.part.transform); if (allTopChildParts == null) { allTopChildParts = topNode.attachedPart.GetAllChildren(); } allTopChildParts.ForEach(c => c.transform.Translate(0, topDifference, 0, this.part.transform)); } } if (hasBottomNode) { bottomNode.position = size.bottomNode; bottomNode.size = size.bottomNodeSize; if (bottomNode.attachedPart != null) { float bottomDifference = size.bottomNode.y - lastSize.bottomNode.y; bottomNode.attachedPart.transform.Translate(0, bottomDifference, 0, this.part.transform); if (allBottomChildParts == null) { allBottomChildParts = bottomNode.attachedPart.GetAllChildren(); } allBottomChildParts.ForEach(c => c.transform.Translate(0, bottomDifference, 0, this.part.transform)); } } } // If not root and parent is attached to the bottom else if (hasBottomNode && CheckParentNode(bottomNode)) { bottomNode.position = size.bottomNode; bottomNode.size = size.bottomNodeSize; float bottomDifference = size.bottomNode.y - lastSize.bottomNode.y; this.part.transform.Translate(0, -bottomDifference, 0, this.part.transform); if (hasTopNode) { topNode.position = size.topNode; topNode.size = size.topNodeSize; if (topNode.attachedPart != null) { float diff = size.topNode.y - lastSize.topNode.y - bottomDifference; topNode.attachedPart.transform.Translate(0, diff, 0, this.part.transform); if (allTopChildParts == null) { allTopChildParts = topNode.attachedPart.GetAllChildren(); } allTopChildParts.ForEach(c => c.transform.Translate(0, diff, 0, this.part.transform)); } } } // If not root and parent is attached to the top else if (hasTopNode && CheckParentNode(topNode)) { topNode.position = size.topNode; topNode.size = size.topNodeSize; float topDifference = size.topNode.y - lastSize.topNode.y; this.part.transform.Translate(0, -topDifference, 0, this.part.transform); if (hasBottomNode) { bottomNode.position = size.bottomNode; bottomNode.size = size.bottomNodeSize; if (bottomNode.attachedPart != null) { float diff = size.bottomNode.y - lastSize.bottomNode.y - topDifference; bottomNode.attachedPart.transform.Translate(0, diff, 0, part.transform); if (allBottomChildParts == null) { allBottomChildParts = bottomNode.attachedPart.GetAllChildren(); } allBottomChildParts.ForEach(c => c.transform.Translate(0, diff, 0, part.transform)); } } } //Parachute transforms Vector3 scale = Vector3.Scale(this.originalSize, lastSize.size); float scaleX = root.localScale.x / scale.x; float scaleY = root.localScale.y / scale.y; float scaleZ = root.localScale.z / scale.z; foreach (Parachute chute in this.rcModule.parachutes) { Vector3 pos = chute.forcePosition - this.part.transform.position; chute.parachute.transform.Translate(pos.x * (scaleX - 1), pos.y * (scaleY - 1), pos.z * (scaleZ - 1), this.part.transform); } //Surface attached parts if (this.part.children.Exists(c => c.attachMode == AttachModes.SRF_ATTACH)) { foreach (Part child in this.part.children) { if (child.attachMode == AttachModes.SRF_ATTACH) { Vector3 vX = new Vector3(), vY = new Vector3(); vX = (child.transform.localPosition + child.transform.localRotation * child.srfAttachNode.position) - this.part.transform.position; vY = child.transform.position - this.part.transform.position; child.transform.Translate(vX.x * (scaleX - 1), vY.y * (scaleY - 1), vX.z * (scaleZ - 1), this.part.transform); child.GetAllChildren().ForEach(c => c.transform.Translate(vX.x * (scaleX - 1), vY.y * (scaleY - 1), vX.z * (scaleZ - 1), this.part.transform)); } } } this.lastSize = this.size; this.part.SendMessage("RC_Rescale", new Vector3(scaleX, scaleY, scaleZ)); }
//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; }
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")) { this.rcModule = this.part.Modules["RealChuteModule"] as RealChuteModule; } else { return; } this.secondaryChute = this.rcModule.secondaryChute; if (!string.IsNullOrEmpty(this.textureLibrary)) { this.textureLib.TryGetConfig(this.textureLibrary, ref this.textures); } this.bodies = AtmoPlanets.fetch; this.body = this.bodies.GetBody(this.planets); //Initializes ChuteTemplates if (this.chutes.Count <= 0) { if (this.node == null && !PersistentManager.instance.TryGetNode<ProceduralChute>(this.part.name, ref this.node)) { return; } LoadChutes(); } this.chutes.ForEach(c => c.Initialize()); if (this.sizes.Count <= 0) { this.sizes = this.sizeLib.GetSizes(this.part.partInfo.name); } //Creates an instance of the texture library this.editorGUI = new EditorGUI(this); if (HighLogic.LoadedSceneIsEditor) { //Windows initiation this.editorGUI.window = new Rect(5, 370, 420, Screen.height - 375); this.chutes.ForEach(c => { c.templateGUI.materialsWindow = new Rect(this.editorGUI.matX, this.editorGUI.matY, 375, 275); c.templateGUI.drag = new Rect(0, 0, 375, 25); }); 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 (HighLogic.CurrentGame.Mode == Game.Modes.CAREER) { float level = 0; switch (EditorDriver.editorFacility) { case EditorFacility.VAB: level = ScenarioUpgradeableFacilities.GetFacilityLevel(SpaceCenterFacility.VehicleAssemblyBuilding); break; case EditorFacility.SPH: level = ScenarioUpgradeableFacilities.GetFacilityLevel(SpaceCenterFacility.SpaceplaneHangar); break; default: break; } if (GameVariables.Instance.UnlockedActionGroupsStock(level)) { Events.ForEach(e => e.guiActiveEditor = false); } } else { Events.ForEach(e => e.guiActiveEditor = false); } //Gets the original part state if (this.textures != null && this.caseID == -1) { if (this.caseID == -1) { if (this.textures.TryGetCase(this.currentCase, ref this.parachuteCase)) { this.caseID = this.textures.GetCaseIndex(this.parachuteCase.name); } } else { this.textures.TryGetCase(this.caseID, this.type, ref this.parachuteCase); } this.lastCaseID = this.caseID; } if (!this.initiated) { if (!this.bodies.TryGetBodyIndex("Kerbin", ref this.planets)) { this.planets = 0; } this.body = this.bodies.GetBody(planets); //Identification of the values from the RealChuteModule this.mustGoDown = this.rcModule.mustGoDown; this.deployOnGround = this.rcModule.deployOnGround; this.timer = this.rcModule.timer + "s"; this.cutSpeed = this.rcModule.cutSpeed.ToString(); if (this.rcModule.spareChutes != -1) { this.spares = this.rcModule.spareChutes.ToString(); } this.originalSize = this.part.transform.GetChild(0).localScale; this.initiated = true; } } else if (this.textures != null) { this.textures.TryGetCase(this.caseID, this.type, ref this.parachuteCase); this.lastCaseID = this.caseID; } if (this.parent == null) { this.parent = this.part.FindModelTransform(this.rcModule.parachutes[0].parachuteName).parent; } //Updates the part if (this.textures != null) { UpdateCaseTexture(this.part, this.rcModule); this.editorGUI.cases = this.textures.caseNames; this.editorGUI.canopies = this.textures.canopyNames; this.editorGUI.models = this.textures.modelNames; } UpdateScale(this.part, this.rcModule); }
//Modifies the size of a part private void UpdateScale(Part part, RealChuteModule module) { //Thanks to Brodicus for the help here if (sizes.Count <= 1) { return; } SizeNode size = sizes[this.size], lastSize = sizes[this.lastSize]; Transform root = part.transform.GetChild(0); root.localScale = Vector3.Scale(originalSize, size.size); module.caseMass = size.caseMass; AttachNode topNode = null, bottomNode = null; bool hasTopNode = part.TryGetAttachNodeById("top", out topNode); bool hasBottomNode = part.TryGetAttachNodeById("bottom", out bottomNode); List <Part> allTopChildParts = null, allBottomChildParts = null; // If this is the root part, move things for the top and the bottom. if ((HighLogic.LoadedSceneIsEditor && part == EditorLogic.SortedShipList[0]) || (HighLogic.LoadedSceneIsFlight && this.vessel.rootPart == part)) { if (hasTopNode) { topNode.position = size.topNode; topNode.size = size.topNodeSize; if (topNode.attachedPart != null) { float topDifference = size.topNode.y - lastSize.topNode.y; topNode.attachedPart.transform.Translate(0, topDifference, 0, part.transform); if (allTopChildParts == null) { allTopChildParts = topNode.attachedPart.GetAllChildren(); } allTopChildParts.ForEach(c => c.transform.Translate(0, topDifference, 0, part.transform)); } } if (hasBottomNode) { bottomNode.position = size.bottomNode; bottomNode.size = size.bottomNodeSize; if (bottomNode.attachedPart != null) { float bottomDifference = size.bottomNode.y - lastSize.bottomNode.y; bottomNode.attachedPart.transform.Translate(0, bottomDifference, 0, part.transform); if (allBottomChildParts == null) { allBottomChildParts = bottomNode.attachedPart.GetAllChildren(); } allBottomChildParts.ForEach(c => c.transform.Translate(0, bottomDifference, 0, part.transform)); } } } // If not root and parent is attached to the bottom else if (hasBottomNode && CheckParentNode(bottomNode)) { bottomNode.position = size.bottomNode; bottomNode.size = size.bottomNodeSize; float bottomDifference = size.bottomNode.y - lastSize.bottomNode.y; part.transform.Translate(0, -bottomDifference, 0, part.transform); if (hasTopNode) { topNode.position = size.topNode; topNode.size = size.topNodeSize; if (topNode.attachedPart != null) { float topDifference = size.topNode.y - lastSize.topNode.y; topNode.attachedPart.transform.Translate(0, topDifference - bottomDifference, 0, part.transform); if (allTopChildParts == null) { allTopChildParts = topNode.attachedPart.GetAllChildren(); } allTopChildParts.ForEach(c => c.transform.Translate(0, topDifference - bottomDifference, 0, part.transform)); } } } // If not root and parent is attached to the top else if (hasTopNode && CheckParentNode(topNode)) { topNode.position = size.topNode; topNode.size = size.topNodeSize; float topDifference = size.topNode.y - lastSize.topNode.y; part.transform.Translate(0, -topDifference, 0, part.transform); if (hasBottomNode) { bottomNode.position = size.bottomNode; bottomNode.size = size.bottomNodeSize; if (bottomNode.attachedPart != null) { float bottomDifference = size.bottomNode.y - lastSize.bottomNode.y; bottomNode.attachedPart.transform.Translate(0, bottomDifference - topDifference, 0, part.transform); if (allBottomChildParts == null) { allBottomChildParts = bottomNode.attachedPart.GetAllChildren(); } allBottomChildParts.ForEach(c => c.transform.Translate(0, bottomDifference - topDifference, 0, part.transform)); } } } //Parachute transforms float scaleX = root.localScale.x / Vector3.Scale(originalSize, lastSize.size).x; float scaleY = root.localScale.y / Vector3.Scale(originalSize, lastSize.size).y; float scaleZ = root.localScale.z / Vector3.Scale(originalSize, lastSize.size).z; foreach (Parachute chute in rcModule.parachutes) { Vector3 pos = chute.forcePosition - part.transform.position; chute.parachute.transform.Translate(pos.x * (scaleX - 1), pos.y * (scaleY - 1), pos.z * (scaleZ - 1), part.transform); } //Surface attached parts if (part.children.Any(c => c.attachMode == AttachModes.SRF_ATTACH)) { foreach (Part child in part.children) { if (child.attachMode == AttachModes.SRF_ATTACH) { Vector3 vX = new Vector3(), vY = new Vector3(); vX = (child.transform.localPosition + child.transform.localRotation * child.srfAttachNode.position) - part.transform.position; vY = child.transform.position - part.transform.position; child.transform.Translate(vX.x * (scaleX - 1), vY.y * (scaleY - 1), vX.z * (scaleZ - 1), part.transform); child.GetAllChildren().ForEach(c => c.transform.Translate(vX.x * (scaleX - 1), vY.y * (scaleY - 1), vX.z * (scaleZ - 1), part.transform)); } } } this.lastSize = this.size; }
public override void OnStart(StartState state) { if (!HighLogic.LoadedSceneIsEditor && !HighLogic.LoadedSceneIsFlight || !CompatibilityChecker.IsAllCompatible()) { return; } //Identification of the RealChuteModule if (this.part.Modules.Contains("RealChuteModule")) { this.rcModule = (RealChuteModule)this.part.Modules["RealChuteModule"]; } else { return; } this.secondaryChute = this.rcModule.SecondaryChute; if (!string.IsNullOrEmpty(this.textureLibrary)) { TextureLibrary.Instance.TryGetConfig(this.textureLibrary, ref this.textures); } this.body = AtmoPlanets.Instance.GetBody(this.planets); //Initializes ChuteTemplates if (this.chutes.Count <= 0) { if (this.node == null && !PersistentManager.Instance.TryGetNode <ProceduralChute>(this.part.name, ref this.node)) { return; } LoadChutes(); } this.chutes.ForEach(c => c.Initialize()); if (this.sizes.Count <= 0) { this.sizes = PersistentManager.Instance.GetSizes(this.part.partInfo.name); } //Creates an instance of the texture library this.editorGUI = new EditorGUI(this); if (HighLogic.LoadedSceneIsEditor) { //Windows initiation this.editorGUI.window = new Rect(5, 390, 420, Screen.height - 395); this.chutes.ForEach(c => { c.templateGUI.materialsWindow = new Rect(this.editorGUI.matX, this.editorGUI.matY, 375, 275); c.templateGUI.drag = new Rect(0, 0, 375, 25); }); 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 (HighLogic.CurrentGame.Mode == Game.Modes.CAREER) { float level = 0; bool isVab = true; switch (EditorDriver.editorFacility) { case EditorFacility.VAB: level = ScenarioUpgradeableFacilities.GetFacilityLevel(SpaceCenterFacility.VehicleAssemblyBuilding); break; case EditorFacility.SPH: level = ScenarioUpgradeableFacilities.GetFacilityLevel(SpaceCenterFacility.SpaceplaneHangar); isVab = false; break; } if (GameVariables.Instance.UnlockedActionGroupsStock(level, isVab)) { this.Events.ForEach(e => e.guiActiveEditor = false); } } else { this.Events.ForEach(e => e.guiActiveEditor = false); } //Gets the original part state if (this.textures != null && this.caseId == -1) { if (this.caseId == -1) { if (this.textures.TryGetCase(this.currentCase, ref this.parachuteCase)) { this.caseId = this.textures.GetCaseIndex(this.parachuteCase.Name); } } else { this.textures.TryGetCase(this.caseId, this.type, ref this.parachuteCase); } this.lastCaseId = this.caseId; } if (!this.initiated) { if (!AtmoPlanets.Instance.TryGetBodyIndex("Kerbin", ref this.planets)) { this.planets = 0; } this.body = AtmoPlanets.Instance.GetBody(this.planets); //Identification of the values from the RealChuteModule this.mustGoDown = this.rcModule.mustGoDown; this.deployOnGround = this.rcModule.deployOnGround; this.timer = this.rcModule.timer + "s"; this.cutSpeed = this.rcModule.cutSpeed.ToString(); if (this.rcModule.spareChutes != -1) { this.spares = this.rcModule.spareChutes.ToString(); } this.originalSize = this.part.transform.GetChild(0).localScale; this.initiated = true; } } else if (this.textures != null) { this.textures.TryGetCase(this.caseId, this.type, ref this.parachuteCase); this.lastCaseId = this.caseId; } if (this.parent == null) { this.parent = this.part.FindModelTransform(this.rcModule.parachutes[0].parachuteName).parent; } //Updates the part if (this.textures != null) { UpdateCaseTexture(this.rcModule); this.editorGUI.cases = this.textures.CaseNames; this.editorGUI.canopies = this.textures.CanopyNames; this.editorGUI.models = this.textures.ModelNames; } UpdateScale(this.part, this.rcModule); }
//Modifies the size of a part private void UpdateScale(Part part, RealChuteModule module) { //Thanks to Brodicus for the optimization here if (this.sizes.Count <= 1) { return; } SizeNode size = this.sizes[this.size], lastSize = this.sizes[this.lastSize]; Transform root = this.part.transform.GetChild(0); root.localScale = Vector3.Scale(this.originalSize, size.Size); module.caseMass = size.CaseMass; module.UpdateMass(); AttachNode topNode, bottomNode; bool hasTopNode = part.TryGetAttachNodeById("top", out topNode); bool hasBottomNode = part.TryGetAttachNodeById("bottom", out bottomNode); List <Part> allTopChildParts, allBottomChildParts; // If this is the root part, move things for the top and the bottom. if (HighLogic.LoadedSceneIsEditor && this.part == EditorLogic.SortedShipList[0] || HighLogic.LoadedSceneIsFlight && this.vessel.rootPart == this.part) { if (hasTopNode) { topNode.position = size.TopNode; topNode.size = size.TopNodeSize; if (topNode.attachedPart != null) { float topDifference = size.TopNode.y - lastSize.TopNode.y; topNode.attachedPart.transform.Translate(0, topDifference, 0, this.part.transform); allTopChildParts = topNode.attachedPart.GetAllChildren(); allTopChildParts.ForEach(c => c.transform.Translate(0, topDifference, 0, this.part.transform)); } } if (hasBottomNode) { bottomNode.position = size.BottomNode; bottomNode.size = size.BottomNodeSize; if (bottomNode.attachedPart != null) { float bottomDifference = size.BottomNode.y - lastSize.BottomNode.y; bottomNode.attachedPart.transform.Translate(0, bottomDifference, 0, this.part.transform); allBottomChildParts = bottomNode.attachedPart.GetAllChildren(); allBottomChildParts.ForEach(c => c.transform.Translate(0, bottomDifference, 0, this.part.transform)); } } } // If not root and parent is attached to the bottom else if (hasBottomNode && CheckParentNode(bottomNode)) { bottomNode.position = size.BottomNode; bottomNode.size = size.BottomNodeSize; float bottomDifference = size.BottomNode.y - lastSize.BottomNode.y; this.part.transform.Translate(0, -bottomDifference, 0, this.part.transform); if (hasTopNode) { topNode.position = size.TopNode; topNode.size = size.TopNodeSize; if (topNode.attachedPart != null) { float diff = size.TopNode.y - lastSize.TopNode.y - bottomDifference; topNode.attachedPart.transform.Translate(0, diff, 0, this.part.transform); allTopChildParts = topNode.attachedPart.GetAllChildren(); allTopChildParts.ForEach(c => c.transform.Translate(0, diff, 0, this.part.transform)); } } } // If not root and parent is attached to the top else if (hasTopNode && CheckParentNode(topNode)) { topNode.position = size.TopNode; topNode.size = size.TopNodeSize; float topDifference = size.TopNode.y - lastSize.TopNode.y; this.part.transform.Translate(0, -topDifference, 0, this.part.transform); if (hasBottomNode) { bottomNode.position = size.BottomNode; bottomNode.size = size.BottomNodeSize; if (bottomNode.attachedPart != null) { float diff = size.BottomNode.y - lastSize.BottomNode.y - topDifference; bottomNode.attachedPart.transform.Translate(0, diff, 0, part.transform); allBottomChildParts = bottomNode.attachedPart.GetAllChildren(); allBottomChildParts.ForEach(c => c.transform.Translate(0, diff, 0, part.transform)); } } } //Parachute transforms Vector3 scale = Vector3.Scale(this.originalSize, lastSize.Size); float scaleX = root.localScale.x / scale.x; float scaleY = root.localScale.y / scale.y; float scaleZ = root.localScale.z / scale.z; foreach (Parachute chute in this.rcModule.parachutes) { Vector3 pos = chute.ForcePosition - this.part.transform.position; chute.parachute.transform.Translate(pos.x * (scaleX - 1), pos.y * (scaleY - 1), pos.z * (scaleZ - 1), this.part.transform); } //Surface attached parts if (this.part.children.Exists(c => c.attachMode == AttachModes.SRF_ATTACH)) { foreach (Part child in this.part.children) { if (child.attachMode == AttachModes.SRF_ATTACH) { Vector3 vX = (child.transform.localPosition + (child.transform.localRotation * child.srfAttachNode.position)) - this.part.transform.position; Vector3 vY = child.transform.position - this.part.transform.position; child.transform.Translate(vX.x * (scaleX - 1), vY.y * (scaleY - 1), vX.z * (scaleZ - 1), this.part.transform); child.GetAllChildren().ForEach(c => c.transform.Translate(vX.x * (scaleX - 1), vY.y * (scaleY - 1), vX.z * (scaleZ - 1), this.part.transform)); } } } this.lastSize = this.size; this.part.SendMessage("RC_Rescale", new Vector3(scaleX, scaleY, scaleZ)); if (HighLogic.LoadedSceneIsEditor) { GameEvents.onEditorShipModified.Fire(EditorLogic.fetch.ship); } }
public override void OnStart(PartModule.StartState state) { if (!HighLogic.LoadedSceneIsEditor && !HighLogic.LoadedSceneIsFlight) { return; } if (!CompatibilityChecker.IsAllCompatible()) { foreach (BaseAction a in Actions) { a.active = false; } foreach (BaseEvent e in Events) { e.active = false; e.guiActive = false; e.guiActiveEditor = false; } Fields["chuteCount"].guiActive = false; return; } //Staging icon this.part.stagingIcon = "PARACHUTES"; //Autoarming checkup this.settings = RealChuteSettings.fetch; //Part GUI if (spareChutes < 0) { Fields["chuteCount"].guiActive = false; } if (!secondaryChute) { Actions["ActionCut"].guiName = "Cut chute"; cut.guiName = "Cut chute"; } Actions["ActionArm"].active = !settings.autoArm; //Initiates the Parachutes if (this.parachutes.Count <= 0) { RealChuteModule m = this; if (this.node == null && !PersistentManager.instance.TryGetNode <RealChuteModule>(this.part.name, ref this.node)) { return; } LoadParachutes(); } this.parachutes.ForEach(p => p.Initialize()); //First initiation of the part if (!this.initiated) { this.initiated = true; this.armed = false; if (this.spareChutes >= 0) { this.chuteCount = (int)spareChutes; } } //Flight loading if (HighLogic.LoadedSceneIsFlight) { Random random = new Random(); this.parachutes.ForEach(p => p.randomTime = (float)random.NextDouble()); //Hide/show UI event addition GameEvents.onHideUI.Add(HideUI); GameEvents.onShowUI.Add(ShowUI); if (this.canRepack) { SetRepack(); } foreach (DragCube cube in this.part.DragCubes.Cubes) { switch (cube.Name) { case "PACKED": this.part.DragCubes.SetCubeWeight("PACKED", 1); break; case "SEMIDEPLOYED": case "DEPLOYED": this.part.DragCubes.SetCubeWeight(cube.Name, 0); break; default: break; } } } //GUI this.window = new Rect(200, 100, 350, 400); this.drag = new Rect(0, 0, 350, 30); }