protected virtual void setMountModuleFromEditor(String newMountType, bool updateSymmetry) { MountModelData newModule = Array.Find(mountModules, m => m.name == newMountType); currentMountModule.destroyCurrentModel(); currentMountModule = newModule; newModule.setupModel(part, getMountRootTransform(false), ModelOrientation.BOTTOM); currentMountType = newModule.name; if (!currentMountModule.isValidTextureSet(currentMountTexture)) { currentMountTexture = currentMountModule.getDefaultTextureSet(); } currentMountModule.enableTextureSet(currentMountTexture); currentMountModule.updateTextureUIControl(this, "currentMountTexture", currentMountTexture); updateEditorStats(true); if (updateSymmetry) { foreach (Part p in part.symmetryCounterparts) { p.GetComponent <SSTUModularFuelTank>().setMountModuleFromEditor(newMountType, false); } } SSTUStockInterop.fireEditorUpdate(); SSTUModInterop.onPartGeometryUpdate(part, true); }
/// <summary> /// Restores ModelData instances from config node data, and populates the 'currentModule' instances with the currently enabled modules. /// </summary> private void loadConfigData() { ConfigNode node = SSTUStockInterop.getPartModuleConfig(part, this); ConfigNode[] tankNodes = node.GetNodes("TANK"); ConfigNode[] mountNodes = node.GetNodes("CAP"); ConfigNode[] fuelNodes = node.GetNodes("FUELTYPE"); ConfigNode[] limitNodes = node.GetNodes("TECHLIMIT"); mainTankModules = SingleModelData.parseModels(tankNodes); int len = mountNodes.Length; ConfigNode mountNode; List <MountModelData> noses = new List <MountModelData>(); List <MountModelData> mounts = new List <MountModelData>(); for (int i = 0; i < len; i++) { mountNode = mountNodes[i]; if (mountNode.GetBoolValue("useForNose", true)) { mountNode.SetValue("nose", "true"); noses.Add(new MountModelData(mountNode)); } if (mountNode.GetBoolValue("useForMount", true)) { mountNode.SetValue("nose", "false"); mounts.Add(new MountModelData(mountNode)); } } mountModules = mounts.ToArray(); noseModules = noses.ToArray(); topNodeNames = SSTUUtils.parseCSV(topManagedNodeNames); bottomNodeNames = SSTUUtils.parseCSV(bottomManagedNodeNames); currentMainTankModule = Array.Find(mainTankModules, m => m.name == currentTankType); if (currentMainTankModule == null) { MonoBehaviour.print("ERROR: Could not locate tank type for: " + currentTankType + ". reverting to first available tank type."); currentMainTankModule = mainTankModules[0]; currentTankType = currentMainTankModule.name; } currentNoseModule = Array.Find(noseModules, m => m.name == currentNoseType); if (currentNoseModule == null) { MonoBehaviour.print("ERROR: Could not locate nose type for: " + currentNoseType + ". reverting to first available nose type."); currentNoseModule = noseModules[0]; currentNoseType = currentNoseModule.name; } currentMountModule = Array.Find(mountModules, m => m.name == currentMountType); if (currentMountModule == null) { MonoBehaviour.print("ERROR: Could not locate mount type for: " + currentMountType + ". reverting to first available mount type."); currentMountModule = mountModules[0]; currentMountType = currentMountModule.name; } if (!currentMainTankModule.isValidTextureSet(currentTankTexture)) { currentTankTexture = currentMainTankModule.getDefaultTextureSet(); } if (!currentNoseModule.isValidTextureSet(currentNoseTexture)) { currentNoseTexture = currentNoseModule.getDefaultTextureSet(); } if (!currentMountModule.isValidTextureSet(currentMountTexture)) { currentMountTexture = currentMountModule.getDefaultTextureSet(); } currentNoseModule.updateTextureUIControl(this, "currentNoseTexture", currentNoseTexture); currentMainTankModule.updateTextureUIControl(this, "currentTankTexture", currentTankTexture); currentMountModule.updateTextureUIControl(this, "currentMountTexture", currentMountTexture); }
/// <summary> /// Updates the selected mount model from user input /// </summary> /// <param name="nextDef"></param> private void updateMountModelFromEditor(MountModelData nextDef) { removeCurrentModel(currentMountModule); currentMountModule = nextDef; currentMount = nextDef.name; setupModel(currentMountModule, part.transform.FindRecursive("model").FindOrCreate(baseTransformName), ModelOrientation.BOTTOM); updateModules(true); updateModels(); updateFuelVolume(); updatePartResources(); updateGuiState(); }
/// <summary> /// Enable a specific engine mount type by index. If the given index is not valid, the engine layout will revert to the 'no mount' state (for fairing/engine position/node positions).<para/> /// Updates the engine mount positions based on their definitions, and adjusts mass of the part based on the default part mass + mass for the mount. /// </summary> /// <param name="index"></param> private void enableMount(int index, bool userInput) { //basic vars setup for enabling the mount currentMountOption = engineMounts[index]; //determine if this mount is already enabled (e.g. being called during OnStart); if already enabled, use the current layout spacing and mount scale values rather than defaults bool init = currentMountName != currentMountOption.name; currentMountName = currentMountOption.name; currentMountSize = init? currentMountOption.defaultDiameter : currentMountSize; currentEngineSpacing = init? (currentMountOption.engineSpacing > 0 ? currentMountOption.engineSpacing : defaultEngineSpacing) : currentEngineSpacing; restoreEditorFields();//this updates the editor adjust values for the new-updated mount size bool hasLayout = currentMountOption.layoutNames != null && currentMountOption.layoutNames.Length > 0; String localLayoutName = init ? (hasLayout ? currentMountOption.layoutNames[0] : defaultLayoutName) : (currentEngineLayout); SSTUEngineLayout layout = getEngineLayout(localLayoutName); currentEngineLayout = localLayoutName; String modelName = currentMountOption.modelDefinition.modelName; int numOfModels = currentMountOption.singleModel ? 1 : layout.positions.Count; if (!String.IsNullOrEmpty(modelName))//has mount model { Transform[] potentialMountModels = part.transform.FindChildren(modelName); if (potentialMountModels.Length != numOfModels) { clearMountModels(); GameObject mountModel = GameDatabase.Instance.GetModelPrefab(modelName); Transform modelBase = part.transform.FindRecursive(mountTransformName); if (mountModel == null || modelBase == null) { return; } if (currentMountOption.singleModel) { GameObject mountClone = (GameObject)GameObject.Instantiate(mountModel); mountClone.name = mountModel.name; mountClone.transform.name = mountModel.transform.name; mountClone.transform.NestToParent(modelBase); mountClone.SetActive(true); } else { GameObject mountClone; foreach (SSTUEnginePosition position in layout.positions) { mountClone = (GameObject)GameObject.Instantiate(mountModel); mountClone.name = mountModel.name; mountClone.transform.name = mountModel.transform.name; mountClone.transform.NestToParent(modelBase); mountClone.SetActive(true); } } } } else { clearMountModels(); } //update the current mount positions and cached vars for stuff like fairing and engine position updateMountPositions(userInput); if (currentMountOption.singleModel) { part.mass = partDefaultMass + currentMountOption.modelDefinition.mass; } else { part.mass = partDefaultMass + (currentMountOption.modelDefinition.mass * layout.positions.Count); } }
/// <summary> /// Loads all of the part definitions and values from the stashed config node data /// </summary> private void loadConfigData() { ConfigNode node = SSTUConfigNodeUtils.parseConfigNode(configNodeData); fuelTypes = FuelTypeData.parseFuelTypeData(node.GetNodes("FUELTYPE")); currentFuelTypeData = Array.Find(fuelTypes, l => l.name == currentFuelType); if (currentFuelTypeData == null) { MonoBehaviour.print("ERROR: Could not locate fuel type for: " + currentFuelType + ". reverting to default fuel type of: " + defaultFuelType); currentFuelType = defaultFuelType; currentFuelTypeData = Array.Find(fuelTypes, l => l.name == currentFuelType); initializedResources = false; } reserveFuelTypeData = FuelTypes.INSTANCE.getFuelTypeData(reserveFuelType); //mandatory nodes, -all- tank types must have these ConfigNode tankUpperNode = node.GetNode("TANKUPPER"); ConfigNode upperTopCapNode = node.GetNode("TANKUPPERTOPCAP"); ConfigNode upperBottomCapNode = node.GetNode("TANKUPPERBOTTOMCAP"); ConfigNode[] limitNodes = node.GetNodes("TECHLIMIT"); ConfigNode rcsNode = node.GetNode("RCS"); ConfigNode[] mountNodes = node.GetNodes("MOUNT"); upperModule = new SingleModelData(tankUpperNode); upperTopCapModule = new SingleModelData(upperTopCapNode); upperBottomCapModule = new SingleModelData(upperBottomCapNode); rcsModule = new SSTUCustomUpperStageRCS(rcsNode); //load mount configs int len = mountNodes.Length; mountModules = new MountModelData[len]; for (int i = 0; i < len; i++) { mountModules[i] = new MountModelData(mountNodes[i]); } currentMountModule = Array.Find(mountModules, l => l.name == currentMount); if (splitTank) { //fields that are only populated by split-tank type upper-stages ConfigNode tankLowerNode = node.GetNode("TANKLOWER"); ConfigNode lowerBottomCapNode = node.GetNode("TANKLOWERBOTTOMCAP"); ConfigNode[] intertankNodes = node.GetNodes("INTERTANK"); lowerModule = new SingleModelData(tankLowerNode); lowerBottomCapModule = new SingleModelData(lowerBottomCapNode); //load intertank configs len = intertankNodes.Length; intertankModules = new SingleModelData[len]; for (int i = 0; i < len; i++) { intertankModules[i] = new SingleModelData(intertankNodes[i]); } currentIntertankModule = Array.Find(intertankModules, l => l.name == currentIntertank); } len = limitNodes.Length; techLimits = new TechLimitHeightDiameter[len]; for (int i = 0; i < len; i++) { techLimits[i] = new TechLimitHeightDiameter(limitNodes[i]); } }
private void setNoseModuleFromEditor(MountModelData newModule, bool updateSymmetry) { currentNoseModule.destroyCurrentModel(); currentNoseModule = newModule; newModule.setupModel(part, part.transform.FindRecursive("model"), ModelOrientation.TOP); currentNoseType = newModule.name; if (!currentNoseModule.isValidTextureSet(currentNoseTexture)) { currentNoseTexture = currentNoseModule.modelDefinition.defaultTextureSet; } currentNoseModule.enableTextureSet(currentNoseTexture); updateEditorStats(true); if (updateSymmetry) { foreach (Part p in part.symmetryCounterparts) { SSTUModularFuelTank mft = p.GetComponent<SSTUModularFuelTank>(); MountModelData mt = Array.Find(mft.noseModules, t => t.name == newModule.name); mft.setNoseModuleFromEditor(mt, false); } } }
/// <summary> /// Restores ModelData instances from config node data, and populates the 'currentModule' instances with the currently enabled modules. /// </summary> private void loadConfigData() { ConfigNode node = SSTUConfigNodeUtils.parseConfigNode(configNodeData); ConfigNode[] tankNodes = node.GetNodes("TANK"); ConfigNode[] mountNodes = node.GetNodes("CAP"); ConfigNode[] fuelNodes = node.GetNodes("FUELTYPE"); ConfigNode[] limitNodes = node.GetNodes("TECHLIMIT"); mainTankModules = SingleModelData.parseModels(tankNodes); int len = mountNodes.Length; ConfigNode mountNode; List<MountModelData> noses = new List<MountModelData>(); List<MountModelData> mounts = new List<MountModelData>(); for (int i = 0; i < len; i++) { mountNode = mountNodes[i]; if (mountNode.GetBoolValue("useForNose", true)) { mountNode.SetValue("nose", "true"); noses.Add(new MountModelData(mountNode)); } if (mountNode.GetBoolValue("useForMount", true)) { mountNode.SetValue("nose", "false"); mounts.Add(new MountModelData(mountNode)); } } mountModules = mounts.ToArray(); noseModules = noses.ToArray(); fuelTypes = FuelTypeData.parseFuelTypeData(fuelNodes); len = limitNodes.Length; techLimits = TechLimitHeightDiameter.loadTechLimits(limitNodes); topNodeNames = SSTUUtils.parseCSV(topManagedNodeNames); bottomNodeNames = SSTUUtils.parseCSV(bottomManagedNodeNames); currentMainTankModule = Array.Find(mainTankModules, m => m.name == currentTankType); if (currentMainTankModule == null) { MonoBehaviour.print("ERROR: Could not locate tank type for: " + currentTankType + ". reverting to first available tank type."); currentMainTankModule = mainTankModules[0]; currentTankType = currentMainTankModule.name; } currentNoseModule = Array.Find(noseModules, m => m.name == currentNoseType); if (currentNoseModule == null) { MonoBehaviour.print("ERROR: Could not locate nose type for: " + currentNoseType + ". reverting to first available nose type."); currentNoseModule = noseModules[0]; currentNoseType = currentNoseModule.name; } currentMountModule = Array.Find(mountModules, m => m.name == currentMountType); if (currentMountModule == null) { MonoBehaviour.print("ERROR: Could not locate mount type for: " + currentMountType + ". reverting to first available mount type."); currentMountModule = mountModules[0]; currentMountType = currentMountModule.name; } currentFuelTypeData = Array.Find(fuelTypes, m => m.name == currentFuelType); if (currentFuelTypeData == null) { MonoBehaviour.print("ERROR: Could not locate fuel type for: " + currentFuelType + ". reverting to first available fuel type."); FuelTypeData d = fuelTypes[0]; currentFuelType = d.name; currentFuelTypeData = d; initializedResources = false; } if (!currentMainTankModule.isValidTextureSet(currentTankTexture)) { currentTankTexture = currentMainTankModule.modelDefinition.defaultTextureSet; } if (!currentNoseModule.isValidTextureSet(currentNoseTexture)) { currentNoseTexture = currentNoseModule.modelDefinition.defaultTextureSet; } if (!currentMountModule.isValidTextureSet(currentMountTexture)) { currentMountTexture = currentMountModule.modelDefinition.defaultTextureSet; } }
private MountModelData getNextCap(MountModelData[] mounts, MountModelData currentMount, String[] nodeNames, bool iterateBackwards) { return SSTUUtils.findNextEligible<MountModelData>(mounts, m => m == currentMount, l => l.canSwitchTo(part, nodeNames), iterateBackwards); }
/// <summary> /// Update the nose module from user input in the editor /// </summary> /// <param name="newNose"></param> /// <param name="updateSymmetry"></param> private void updateNoseFromEditor(String newNose, bool updateSymmetry) { MountModelData mod = Array.Find(noseModules, m => m.name == newNose); if (mod != null && mod != currentNoseModule) { currentNoseModule.destroyCurrentModel(); mod.setupModel(part, part.transform.FindRecursive(baseTransformName), ModelOrientation.TOP); currentNoseModule = mod; currentNoseName = currentNoseModule.name; } if (!currentNoseModule.isValidTextureSet(currentNoseTexture)) { currentNoseTexture = currentNoseModule.modelDefinition.defaultTextureSet; } currentNoseModule.enableTextureSet(currentNoseTexture); updateModelScaleAndPosition(); updatePartResources(); updatePartMass(); updateAttachnodes(true); updateEditorValues(); updateGui(); if (updateSymmetry) { foreach (Part p in part.symmetryCounterparts) { p.GetComponent<SSTUModularBooster>().updateNoseFromEditor(newNose, false); } GameEvents.onEditorShipModified.Fire(EditorLogic.fetch.ship); } }
/// <summary> /// Loads the current configuration from the cached persistent config node data /// </summary> private void loadConfigNodeData() { ConfigNode node = SSTUConfigNodeUtils.parseConfigNode(configNodeData); //load singular fuel type data from config node; //using a node so that it may have the custom fields defined for mass fraction/etc on a per-part basis fuelTypeData = new FuelTypeData(node.GetNode("FUELTYPE")); //load all main tank model datas mainModules = SRBModelData.parseSRBModels(node.GetNodes("MAINMODEL")); currentMainModule = Array.Find(mainModules, m => m.name == currentMainName); if (currentMainModule == null) { currentMainModule = mainModules[0]; currentMainName = currentMainModule.name; } if (!currentMainModule.isValidTextureSet(currentMainTexture)) { currentMainTexture = currentMainModule.modelDefinition.defaultTextureSet; } //load nose modules from NOSE nodes ConfigNode[] noseNodes = node.GetNodes("NOSE"); ConfigNode noseNode; int length = noseNodes.Length; List<MountModelData> noseModulesTemp = new List<MountModelData>(); for (int i = 0; i < length; i++) { noseNode = noseNodes[i]; noseModulesTemp.Add(new MountModelData(noseNode)); } this.noseModules = noseModulesTemp.ToArray(); currentNoseModule = Array.Find(this.noseModules, m => m.name == currentNoseName); if (currentNoseModule == null) { currentNoseModule = this.noseModules[0];//not having a mount defined is an error, at least one mount must be defined, crashing at this point is acceptable currentNoseName = currentNoseModule.name; } if (!currentNoseModule.isValidTextureSet(currentNoseTexture)) { currentNoseTexture = currentNoseModule.modelDefinition.defaultTextureSet; } //load nose modules from NOZZLE nodes ConfigNode[] nozzleNodes = node.GetNodes("NOZZLE"); ConfigNode nozzleNode; length = nozzleNodes.Length; List<SRBNozzleData> nozzleModulesTemp = new List<SRBNozzleData>(); for (int i = 0; i < length; i++) { nozzleNode = nozzleNodes[i]; nozzleModulesTemp.Add(new SRBNozzleData(nozzleNode)); } this.nozzleModules = nozzleModulesTemp.ToArray(); currentNozzleModule = Array.Find(this.nozzleModules, m => m.name == currentNozzleName); if (currentNozzleModule == null) { currentNozzleModule = this.nozzleModules[0];//not having a mount defined is an error, at least one mount must be defined, crashing at this point is acceptable currentNozzleName = currentNozzleModule.name; } if (!currentNozzleModule.isValidTextureSet(currentNozzleTexture)) { currentNozzleTexture = currentNozzleModule.modelDefinition.defaultTextureSet; } //reset existing gimbal/thrust transforms, remove them from the model hierarchy resetTransformParents();//this resets the thrust transform parent in case it was changed during prefab; we don't want to delete the thrust transform Transform parentTransform = part.transform.FindRecursive("model").FindOrCreate(baseTransformName); //finally, clear any existing models from prefab, and initialize the currently configured models SSTUUtils.destroyChildren(parentTransform); currentNoseModule.setupModel(part, parentTransform, ModelOrientation.TOP); currentNozzleModule.setupModel(part, parentTransform, ModelOrientation.BOTTOM); currentMainModule.setupModel(part, parentTransform, ModelOrientation.CENTRAL); //lastly, re-insert gimbal and thrust transforms into model hierarchy and reset default gimbal rotation offset currentNozzleModule.setupTransformDefaults(part.transform.FindRecursive(thrustTransformName), part.transform.FindRecursive(gimbalTransformName)); }