protected virtual void setMainTankModuleFromEditor(String newMainTank, bool updateSymmetry) { SingleModelData newModule = Array.Find(mainTankModules, m => m.name == newMainTank); currentMainTankModule.destroyCurrentModel(); currentMainTankModule = newModule; currentMainTankModule.setupModel(part, getTankRootTransform(false), ModelOrientation.CENTRAL); currentTankType = newModule.name; if (!currentMainTankModule.isValidTextureSet(currentTankTexture)) { currentTankTexture = currentMainTankModule.getDefaultTextureSet(); } currentMainTankModule.enableTextureSet(currentTankTexture); currentMainTankModule.updateTextureUIControl(this, "currentTankTexture", currentTankTexture); updateUIScaleControls(); updateEditorStats(true); if (updateSymmetry) { foreach (Part p in part.symmetryCounterparts) { p.GetComponent <SSTUModularFuelTank>().setMainTankModuleFromEditor(newMainTank, false); } } SSTUStockInterop.fireEditorUpdate(); SSTUModInterop.onPartGeometryUpdate(part, true); }
public override void OnStart(StartState state) { base.OnStart(state); initialize(); string[] names = SingleModelData.getModelNames(modelData); this.updateUIChooseOptionControl("currentModel", names, names, true, currentModel); Fields["currentModel"].uiControlEditor.onFieldChanged = modelSelected; }
private void onModelChanged(SingleModelData prev, SingleModelData cur) { updateModulePositions(); updateAttachNodes(true); updateCost(); updateMass(); updateDragCubes(); updateResourceVolume(); updateGUI(); }
public static SingleModelData[] parseModels(ConfigNode[] modelNodes) { int len = modelNodes.Length; SingleModelData[] datas = new SingleModelData[len]; for (int i = 0; i < len; i++) { datas[i] = new SingleModelData(modelNodes[i]); } return(datas); }
private void setupModel() { if (!String.IsNullOrEmpty(modelDefinition.modelName)) { Transform baseTransform = getBaseTransform(); SingleModelData smd = new SingleModelData(modelDefinition.name); smd.setupModel(baseTransform, ModelOrientation.CENTRAL); GameObject model = smd.model; model.transform.localScale = new Vector3(scale, scale, scale); } }
private void updateAnimationControl(string id, SingleModelData model, int layer) { if (string.IsNullOrEmpty(id)) { return; } SSTUAnimateControlled module = SSTUAnimateControlled.locateAnimationController(part, id); if (module != null) { module.initializeExternal(model.getAnimationData(model.model.transform, layer)); } }
private void initializeGUI() { bool useModelSelectionGUI = HighLogic.CurrentGame.Parameters.CustomParams <SSTUGameSettings>().useModelSelectGui; string[] names = SingleModelData.getAvailableModelNames(topDockModules, this); this.updateUIChooseOptionControl("currentTopDock", names, names, true, currentTopDock); Fields["currentTopDock"].uiControlEditor.onFieldChanged = onTopDockChanged; Fields["currentTopDock"].guiActiveEditor = names.Length > 1; names = SingleModelData.getValidSelectionNames(part, topModules, topNodeNames); this.updateUIChooseOptionControl("currentTop", names, names, true, currentTop); Fields["currentTop"].uiControlEditor.onFieldChanged = onTopChanged; Fields["currentTop"].guiActiveEditor = !useModelSelectionGUI && names.Length > 1; Events["selectTopEvent"].guiActiveEditor = useModelSelectionGUI && names.Length > 1; names = SingleModelData.getModelNames(coreModules); this.updateUIChooseOptionControl("currentCore", names, names, true, currentCore); Fields["currentCore"].uiControlEditor.onFieldChanged = onCoreChanged; Fields["currentCore"].guiActiveEditor = coreModules.Length > 1; names = SingleModelData.getValidSelectionNames(part, bottomModules, bottomNodeNames); this.updateUIChooseOptionControl("currentBottom", names, names, true, currentBottom); Fields["currentBottom"].uiControlEditor.onFieldChanged = onBottomChanged; Fields["currentBottom"].guiActiveEditor = !useModelSelectionGUI && names.Length > 1; Events["selectBottomEvent"].guiActiveEditor = useModelSelectionGUI && names.Length > 1; names = SingleModelData.getAvailableModelNames(bottomDockModules, this); this.updateUIChooseOptionControl("currentBottomDock", names, names, true, currentBottomDock); Fields["currentBottomDock"].uiControlEditor.onFieldChanged = onBottomDockChanged; Fields["currentBottomDock"].guiActiveEditor = names.Length > 1; names = SolarData.getNames(solarModules, part, this); this.updateUIChooseOptionControl("currentSolar", names, names, true, currentSolar); Fields["currentSolar"].uiControlEditor.onFieldChanged = onSolarChanged; Fields["currentSolar"].guiActiveEditor = names.Length > 1; names = topModule.modelDefinition.getTextureSetNames(); this.updateUIChooseOptionControl("currentTopTexture", names, names, true, currentTopTexture); Fields["currentTopTexture"].uiControlEditor.onFieldChanged = onTopTextureChanged; Fields["currentTopTexture"].guiActiveEditor = names.Length > 1; names = coreModule.modelDefinition.getTextureSetNames(); this.updateUIChooseOptionControl("currentCoreTexture", names, names, true, currentCoreTexture); Fields["currentCoreTexture"].uiControlEditor.onFieldChanged = onCoreTextureChanged; Fields["currentCoreTexture"].guiActiveEditor = names.Length > 1; names = bottomModule.modelDefinition.getTextureSetNames(); this.updateUIChooseOptionControl("currentBottomTexture", names, names, true, currentBottomTexture); Fields["currentBottomTexture"].uiControlEditor.onFieldChanged = onBottomTextureChanged; Fields["currentBottomTexture"].guiActiveEditor = names.Length > 1; }
private void updateGUI() { bool useModelSelectionGUI = HighLogic.CurrentGame.Parameters.CustomParams <SSTUGameSettings>().useModelSelectGui; string[] moduleNames = SingleModelData.getValidSelectionNames(part, topModules, topNodeNames); this.updateUIChooseOptionControl("currentTop", moduleNames, moduleNames, true, currentTop); Fields["currentTop"].guiActiveEditor = !useModelSelectionGUI && moduleNames.Length > 1; Events["selectTopEvent"].guiActiveEditor = useModelSelectionGUI && moduleNames.Length > 1; moduleNames = SingleModelData.getValidSelectionNames(part, bottomModules, bottomNodeNames); this.updateUIChooseOptionControl("currentBottom", moduleNames, moduleNames, true, currentBottom); Fields["currentBottom"].guiActiveEditor = !useModelSelectionGUI && moduleNames.Length > 1; Events["selectBottomEvent"].guiActiveEditor = useModelSelectionGUI && moduleNames.Length > 1; }
/// <summary> /// Find the given ModelData from the input array for the input name. If not found, returns null. /// </summary> /// <param name="models"></param> /// <param name="name"></param> /// <returns></returns> public static SingleModelData findModel(SingleModelData[] models, string name) { SingleModelData model = null; int len = models.Length; for (int i = 0; i < len; i++) { if (models[i].name == name) { model = models[i]; break; } } return(model); }
private void setBottomDockEditor(string newBottomDock, bool updateSymmetry) { currentBottomDock = newBottomDock; SingleModelData prev = bottomDockModule; bottomDockModule.destroyCurrentModel(); bottomDockModule = SingleModelData.findModel(bottomDockModules, currentBottomDock); bottomDockModule.setupModel(getBottomDockRoot(false), ModelOrientation.BOTTOM); onModelChanged(prev, bottomDockModule); updateDockingModules(true); if (updateSymmetry) { foreach (Part p in part.symmetryCounterparts) { p.GetComponent <SSTUModularStationCore>().setBottomDockEditor(newBottomDock, false); } } }
/// <summary> /// Parse an array of models given an array of ConfigNodes for those models. Simple utility / convenience method for part initialization. /// </summary> /// <param name="modelNodes"></param> /// <returns></returns> public static SingleModelData[] parseModels(ConfigNode[] modelNodes, bool insertDefault = false) { int len = modelNodes.Length; SingleModelData[] datas; if (len == 0 && insertDefault) { datas = new SingleModelData[1]; datas[0] = new SingleModelData("Mount-None"); return(datas); } datas = new SingleModelData[len]; for (int i = 0; i < len; i++) { datas[i] = new SingleModelData(modelNodes[i]); } return(datas); }
/// <summary> /// Loads all of the part definitions and values from the stashed config node data /// </summary> private void loadConfigData() { ConfigNode node = SSTUConfigNodeUtils.parseConfigNode(configNodeData); noseModule = new ModelModule <SingleModelData, SSTUModularUpperStage>(part, this, getRootTransform("MUSNose"), ModelOrientation.TOP, nameof(nosePersistentData), nameof(currentNose), nameof(currentNoseTexture)); noseModule.getSymmetryModule = m => m.noseModule; noseModule.setupModelList(SingleModelData.parseModels(node.GetNodes("NOSE"))); noseModule.setupModel(); upperModule = new ModelModule <SingleModelData, SSTUModularUpperStage>(part, this, getRootTransform("MUSUpper"), ModelOrientation.TOP, nameof(upperPersistentData), nameof(currentUpper), nameof(currentUpperTexture)); upperModule.getSymmetryModule = m => m.upperModule; upperModule.setupModelList(SingleModelData.parseModels(node.GetNodes("UPPER"))); upperModule.setupModel(); intertankModule = new ModelModule <SingleModelData, SSTUModularUpperStage>(part, this, getRootTransform("MUSIntertank"), ModelOrientation.TOP, nameof(intertankPersistentData), nameof(currentIntertank), nameof(currentIntertankTexture)); intertankModule.getSymmetryModule = m => m.intertankModule; intertankModule.setupModelList(SingleModelData.parseModels(node.GetNodes("INTERTANK"))); intertankModule.setupModel(); lowerModule = new ModelModule <SingleModelData, SSTUModularUpperStage>(part, this, getRootTransform("MUSLower"), ModelOrientation.TOP, nameof(lowerPersistentData), nameof(currentLower), nameof(currentLowerTexture)); lowerModule.getSymmetryModule = m => m.lowerModule; lowerModule.setupModelList(SingleModelData.parseModels(node.GetNodes("LOWER"))); lowerModule.setupModel(); mountModule = new ModelModule <SingleModelData, SSTUModularUpperStage>(part, this, getRootTransform("MUSMount"), ModelOrientation.BOTTOM, nameof(mountPersistentData), nameof(currentMount), nameof(currentMountTexture)); mountModule.getSymmetryModule = m => m.mountModule; mountModule.setupModelList(SingleModelData.parseModels(node.GetNodes("MOUNT"))); mountModule.setupModel(); rcsModule = new ModelModule <SSTUModularUpperStageRCS, SSTUModularUpperStage>(part, this, getRootTransform("MUSRCS"), ModelOrientation.CENTRAL, nameof(rcsPersistentData), nameof(currentRCS), nameof(currentRCSTexture)); rcsModule.getSymmetryModule = m => m.rcsModule; rcsModule.setupModelList(SingleModelData.parseModels(node.GetNodes("RCS"), m => new SSTUModularUpperStageRCS(m))); rcsModule.setupModel(); updateRCSModule(); if (!splitTank) { intertankModule.model.destroyCurrentModel(); lowerModule.model.destroyCurrentModel(); } }
private void updateAnimationControl(string id, SingleModelData model, int layer) { if (string.IsNullOrEmpty(id)) { return; } SSTUAnimateControlled module = SSTUAnimateControlled.locateAnimationController(part, id); if (module == null) { MonoBehaviour.print("ERROR: Could not locate controller for name: " + id); return; } else if (module != null && model.model != null) { module.initializeExternal(model.getAnimationData(model.model.transform, layer)); } else if (module != null) { module.initializeExternal(new SSTUAnimData[0]); } }
private void setCoreEditor(string newCore, bool updateSymmetry) { currentCore = newCore; SingleModelData prev = coreModule; coreModule.destroyCurrentModel(); coreModule = SingleModelData.findModel(coreModules, currentCore); coreModule.setupModel(getCoreRoot(false), ModelOrientation.CENTRAL); onModelChanged(prev, coreModule); if (!coreModule.isValidTextureSet(currentCoreTexture)) { currentCoreTexture = coreModule.getDefaultTextureSet(); } coreModule.enableTextureSet(currentCoreTexture); coreModule.updateTextureUIControl(this, "currentCoreTexture", currentCoreTexture); if (updateSymmetry) { foreach (Part p in part.symmetryCounterparts) { p.GetComponent <SSTUModularStationCore>().setCoreEditor(newCore, false); } } }
private void setBottomEditor(string newBottom, bool updateSymmetry) { currentBottom = newBottom; SingleModelData prev = bottomModule; bottomModule.destroyCurrentModel(); bottomModule = SingleModelData.findModel(bottomModules, currentBottom); bottomModule.setupModel(getBottomRoot(false), ModelOrientation.BOTTOM); onModelChanged(prev, bottomModule); if (!bottomModule.isValidTextureSet(currentBottomTexture)) { currentBottomTexture = bottomModule.getDefaultTextureSet(); } bottomModule.enableTextureSet(currentBottomTexture); bottomModule.updateTextureUIControl(this, "currentBottomTexture", currentBottomTexture); if (updateSymmetry) { foreach (Part p in part.symmetryCounterparts) { p.GetComponent <SSTUModularStationCore>().setBottomEditor(newBottom, false); } } }
private void setTopEditor(string newTop, bool updateSymmetry) { currentTop = newTop; SingleModelData prev = topModule; topModule.destroyCurrentModel(); topModule = SingleModelData.findModel(topModules, currentTop); topModule.setupModel(getTopRoot(false), ModelOrientation.TOP); onModelChanged(prev, topModule); if (!topModule.isValidTextureSet(currentTopTexture)) { currentTopTexture = topModule.getDefaultTextureSet(); } topModule.enableTextureSet(currentTopTexture); topModule.updateTextureUIControl(this, "currentTopTexture", currentTopTexture); if (updateSymmetry) { foreach (Part p in part.symmetryCounterparts) { p.GetComponent <SSTUModularStationCore>().setTopEditor(newTop, false); } } }
public void enable(Transform root, float yOffset) { SSTUUtils.destroyChildren(root); int len = positions.Length; rootTransforms = new Transform[len]; models = new SingleModelData[len]; Vector3 pos; for (int i = 0; i < len; i++) { rootTransforms[i] = new GameObject(root.name + "-" + i).transform; pos = positions[i].position.CopyVector(); pos.y += yOffset; rootTransforms[i].parent = root; rootTransforms[i].position = root.position; rootTransforms[i].rotation = root.rotation; rootTransforms[i].localPosition = pos; rootTransforms[i].Rotate(positions[i].rotation, Space.Self); models[i] = new SingleModelData(modelName); models[i].setupModel(rootTransforms[i], ModelOrientation.TOP); rootTransforms[i].localScale = positions[i].scale; } }
private void setMainTankModuleFromEditor(SingleModelData newModule, bool updateSymmetry) { currentMainTankModule.destroyCurrentModel(); currentMainTankModule = newModule; currentMainTankModule.setupModel(part, part.transform.FindRecursive("model"), ModelOrientation.CENTRAL); currentTankType = newModule.name; if (!currentMainTankModule.isValidTextureSet(currentTankTexture)) { currentTankTexture = currentMainTankModule.modelDefinition.defaultTextureSet; } currentMainTankModule.enableTextureSet(currentTankTexture); updateEditorStats(true); if (updateSymmetry) { foreach (Part p in part.symmetryCounterparts) { SSTUModularFuelTank mft = p.GetComponent<SSTUModularFuelTank>(); SingleModelData mt = Array.Find(mft.mainTankModules, t => t.name == newModule.name); mft.setMainTankModuleFromEditor(mt, false); } } }
/// <summary> /// Restores SSTUCustomFuelTankPart instances from config node data, and populates the 'currentModule' instances with the currently selected module. /// </summary> private void loadConfigData() { ConfigNode node = SSTUNodeUtils.parseConfigNode(configNodeData); ConfigNode[] tankNodes = node.GetNodes("TANK"); ConfigNode[] mountNodes = node.GetNodes("CAP"); ConfigNode[] fuelNodes = node.GetNodes("FUELTYPE"); ConfigNode[] limitNodes = node.GetNodes("TECHLIMIT"); ConfigNode[] textureNodes = node.GetNodes("TEXTURESET"); int len = tankNodes.Length; mainTankModules = new SingleModelData[len]; for (int i = 0; i < len; i++) { mainTankModules[i] = new SingleModelData(tankNodes[i]); } len = mountNodes.Length; ConfigNode mountNode; List<CustomFuelTankMount> noses = new List<CustomFuelTankMount>(); List<CustomFuelTankMount> mounts = new List<CustomFuelTankMount>(); for (int i = 0; i < len; i++) { mountNode = mountNodes[i]; if (mountNode.GetBoolValue("useForNose", true)) { noses.Add(new CustomFuelTankMount(mountNode, true)); } if (mountNode.GetBoolValue("useForMount", true)) { mounts.Add(new CustomFuelTankMount(mountNode, false)); } } mountModules = mounts.ToArray(); noseModules = noses.ToArray(); len = fuelNodes.Length; fuelTypes = new FuelTypeData[len]; for (int i = 0; i < len; i++) { fuelTypes[i] = new FuelTypeData(fuelNodes[i]); } len = limitNodes.Length; techLimits = new TechLimitHeightDiameter[len]; for (int i = 0; i < len; i++) { techLimits[i] = new TechLimitHeightDiameter(limitNodes[i]); } len = textureNodes.Length; textureSets = new TextureSet[len]; for (int i = 0; i < len; i++) { textureSets[i] = TextureSets.INSTANCE.getTextureSet(textureNodes[i].GetStringValue("name")); } topNodeNames = SSTUUtils.parseCSV(topManagedNodeNames); bottomNodeNames = SSTUUtils.parseCSV(bottomManagedNodeNames); }
private void initialize() { if (initialized) { return; } initialized = true; double hsp = 1; double dens = 1; if (heatSoak) { PartResourceDefinition resource = PartResourceLibrary.Instance.GetDefinition(resourceName); hsp = resource.specificHeatCapacity; dens = resource.density; } else { resource = part.Resources[resourceName]; if (resource != null) { hsp = resource.info.specificHeatCapacity; dens = resource.info.density; } else { hsp = PhysicsGlobals.StandardSpecificHeatCapacity; dens = 0.005f; } } fluxPerResourceUnit = hsp * ablationEfficiency * dens; baseSkinIntMult = part.skinInternalConductionMult; baseCondMult = part.heatConductivity; ConfigNode node = SSTUConfigNodeUtils.parseConfigNode(configNodeData); //stand-alone modular heat-shield setup if (standAlonePart) { ConfigNode[] modelNodes = node.GetNodes("MODEL"); model = new ModelModule <SingleModelData, SSTUModularHeatShield>(part, this, part.transform.FindRecursive("model"), ModelOrientation.CENTRAL, nameof(modelPersistentData), nameof(currentShieldModel), nameof(currentShieldTexture)); model.setupModelList(SingleModelData.parseModels(modelNodes)); model.setupModel(); model.model.updateScaleForDiameter(currentDiameter); model.setPosition(0, ModelOrientation.CENTRAL); model.model.updateModel(); updateAttachNodes(false); updateDragCube(); } ConfigNode[] typeNodes = node.GetNodes("SHIELDTYPE"); shieldTypeData = HeatShieldTypeData.load(typeNodes); currentShieldTypeData = Array.Find(shieldTypeData, m => m.baseType.name == currentShieldType); updateModuleStats(); updatePartCost(); if (!initializedResources && (HighLogic.LoadedSceneIsEditor || HighLogic.LoadedSceneIsFlight)) { updatePartResources(); initializedResources = true; } }
private void setBottomEditor(string newBottom, bool updateSymmetry) { currentBottom = newBottom; SingleModelData prev = bottomModule; bottomModule.destroyCurrentModel(); bottomModule = SingleModelData.findModel(bottomModules, currentBottom); bottomModule.setupModel(getBottomRoot(false), ModelOrientation.BOTTOM); onModelChanged(prev, bottomModule); if (!bottomModule.isValidTextureSet(currentBottomTexture)) { currentBottomTexture = bottomModule.getDefaultTextureSet(); } bottomModule.enableTextureSet(currentBottomTexture); bottomModule.updateTextureUIControl(this, "currentBottomTexture", currentBottomTexture); if (updateSymmetry) { foreach (Part p in part.symmetryCounterparts) { p.GetComponent<SSTUModularStationCore>().setBottomEditor(newBottom, 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[] tankSetsNodes = node.GetNodes("TANKSET"); ConfigNode[] tankNodes = node.GetNodes("TANK"); ConfigNode[] mountNodes = node.GetNodes("CAP"); ConfigNode[] limitNodes = node.GetNodes("TECHLIMIT"); tankSets = TankSet.parseSets(tankSetsNodes); //if no sets exist, initialize a default set to add all models to if (tankSets.Length == 0) { tankSets = new TankSet[1]; ConfigNode defaultSetNode = new ConfigNode("TANKSET"); defaultSetNode.AddValue("name", "default"); tankSets[0] = new TankSet(defaultSetNode); } mainTankModules = ModelData.parseModels<TankModelData>(tankNodes, m => new TankModelData(m)); int len = mainTankModules.Length; TankSet set; for (int i = 0; i < len; i++) { set = Array.Find(tankSets, m => m.name == mainTankModules[i].setName); //if set is not found by name, add it to the first set which is guaranteed to exist due to the default-set-adding code above. if (set == null) { set = tankSets[0]; } set.addModel(mainTankModules[i]); } len = mountNodes.Length; ConfigNode mountNode; List<SingleModelData> noses = new List<SingleModelData>(); List<SingleModelData> mounts = new List<SingleModelData>(); for (int i = 0; i < len; i++) { mountNode = mountNodes[i]; if (mountNode.GetBoolValue("useForNose", true)) { mountNode.SetValue("nose", "true"); noses.Add(new SingleModelData(mountNode)); } if (mountNode.GetBoolValue("useForMount", true)) { mountNode.SetValue("nose", "false"); mounts.Add(new SingleModelData(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; } currentTankSetModule = Array.Find(tankSets, m => m.name == currentMainTankModule.setName); currentTankSet = currentTankSetModule.name; lastSelectedVariant = currentMainTankModule.variantName; 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(); } }
private void init(bool start) { if (initialized) { return; } initialized = true; topNodeNames = SSTUUtils.parseCSV(topManagedNodes); bottomNodeNames = SSTUUtils.parseCSV(bottomManagedNodes); ConfigNode node = SSTUConfigNodeUtils.parseConfigNode(configNodeData); coreModules = SingleModelData.parseModels(node.GetNodes("CORE")); List<ConfigNode> tops = new List<ConfigNode>(); List<ConfigNode> bottoms = new List<ConfigNode>(); ConfigNode[] mNodes = node.GetNodes("CAP"); ConfigNode mNode; int len = mNodes.Length; for (int i = 0; i < len; i++) { mNode = mNodes[i]; if (mNode.GetBoolValue("useForTop", true)) { tops.Add(mNode); } if (mNode.GetBoolValue("useForBottom", true)) { bottoms.Add(mNode); } } topModules = SingleModelData.parseModels(tops.ToArray()); bottomModules = SingleModelData.parseModels(bottoms.ToArray()); tops.Clear(); bottoms.Clear(); mNodes = node.GetNodes("DOCK"); len = mNodes.Length; for (int i = 0; i < len; i++) { mNode = mNodes[i]; if (mNode.GetBoolValue("useForTop", true)) { tops.Add(mNode); } if (mNode.GetBoolValue("useForBottom", true)) { bottoms.Add(mNode); } } topDockModules = SingleModelData.parseModels(tops.ToArray()); bottomDockModules = SingleModelData.parseModels(bottoms.ToArray()); tops.Clear(); bottoms.Clear(); mNodes = node.GetNodes("SOLAR"); len = mNodes.Length; solarModules = new SolarData[len]; for (int i = 0; i < len; i++) { mNode = mNodes[i]; solarModules[i] = new SolarData(mNode); } topDockModule = SingleModelData.findModel(topDockModules, currentTopDock); topModule = SingleModelData.findModel(topModules, currentTop); coreModule = SingleModelData.findModel(coreModules, currentCore); bottomModule = SingleModelData.findModel(bottomModules, currentBottom); bottomDockModule = SingleModelData.findModel(bottomDockModules, currentBottomDock); solarModule = Array.Find(solarModules, m => m.name == currentSolar);//TODO cleanup if (!topModule.isValidTextureSet(currentTopTexture)) { currentTopTexture = topModule.getDefaultTextureSet(); } if (!coreModule.isValidTextureSet(currentCoreTexture)) { currentCoreTexture = coreModule.getDefaultTextureSet(); } if (!bottomModule.isValidTextureSet(currentBottomTexture)) { currentBottomTexture = bottomModule.getDefaultTextureSet(); } restoreModels(); updateModulePositions(); updateMass(); updateCost(); updateAttachNodes(false); if (HighLogic.LoadedSceneIsEditor || HighLogic.LoadedSceneIsFlight) { ModuleDockingNode[] mdns = part.GetComponents<ModuleDockingNode>(); if (mdns.Length > 0) { if (topDockModule.model != null) { topDockPartModule = mdns[0]; } if (bottomDockModule.model != null) { bottomDockPartModule = mdns.Length > 1 ? mdns[1] : mdns[0]; } } updateDockingModules(start); } //resources are updated in Start(), to ensure that the dependent modules have loaded }
private void setTopDockEditor(string newDock, bool updateSymmetry) { currentTopDock = newDock; SingleModelData prev = topDockModule; topDockModule.destroyCurrentModel(); topDockModule = SingleModelData.findModel(topDockModules, currentTopDock); topDockModule.setupModel(getTopDockRoot(false), ModelOrientation.TOP); onModelChanged(prev, topDockModule); updateDockingModules(true); if (updateSymmetry) { foreach(Part p in part.symmetryCounterparts) { p.GetComponent<SSTUModularStationCore>().setTopDockEditor(currentTopDock, false); } } }
private void initialize(bool start) { if (initialized) { return; } initialized = true; topNodeNames = SSTUUtils.parseCSV(topManagedNodes); bottomNodeNames = SSTUUtils.parseCSV(bottomManagedNodes); ConfigNode node = SSTUConfigNodeUtils.parseConfigNode(configNodeData); coreModule = new ModelModule <ServiceModuleCoreModel, SSTUModularServiceModule>(part, this, getRootTransform("MSC-CORE", true), ModelOrientation.TOP, nameof(coreModulePersistentData), nameof(currentCore), nameof(currentCoreTexture)); coreModule.getSymmetryModule = m => m.coreModule; coreModule.setupModelList(ModelData.parseModels(node.GetNodes("CORE"), m => new ServiceModuleCoreModel(m))); topModule = new ModelModule <SingleModelData, SSTUModularServiceModule>(part, this, getRootTransform("MSC-TOP", true), ModelOrientation.TOP, nameof(topModulePersistentData), nameof(currentTop), nameof(currentTopTexture)); topModule.getSymmetryModule = m => m.topModule; topModule.getValidSelections = m => topModule.models.FindAll(s => s.canSwitchTo(part, topNodeNames)); bottomModule = new ModelModule <SingleModelData, SSTUModularServiceModule>(part, this, getRootTransform("MSC-BOTTOM", true), ModelOrientation.BOTTOM, nameof(bottomModulePersistentData), nameof(currentBottom), nameof(currentBottomTexture)); bottomModule.getSymmetryModule = m => m.bottomModule; bottomModule.getValidSelections = m => bottomModule.models.FindAll(s => s.canSwitchTo(part, bottomNodeNames)); solarModule = new ModelModule <SolarData, SSTUModularServiceModule>(part, this, getRootTransform("MSC-Solar", true), ModelOrientation.CENTRAL, null, nameof(currentSolar), null); solarModule.getSymmetryModule = m => m.solarModule; solarModule.setupModelList(ModelData.parseModels(node.GetNodes("SOLAR"), m => new SolarData(m))); solarModule.getValidSelections = delegate(IEnumerable <SolarData> all) { //System.Linq.Enumerable.Where(all, s => s.isAvailable(upgradesApplied)); float scale = coreModule.model.currentDiameterScale; //find all solar panels that are unlocked via upgrades/tech-tree List <SolarData> unlocked = solarModule.models.FindAll(s => s.isAvailable(upgradesApplied)); //filter those to find only the ones available for the current List <SolarData> availableByScale = unlocked.FindAll(s => coreModule.model.isValidSolarOption(s.name, scale)); return(availableByScale); }; solarModule.preModelSetup = delegate(SolarData d) { d.positions = coreModule.model.getPanelConfiguration(d.name).getScaledPositions(coreModule.model.currentDiameterScale); }; rcsModule = new ModelModule <ServiceModuleRCSModelData, SSTUModularServiceModule>(part, this, getRootTransform("MSC-Rcs", true), ModelOrientation.CENTRAL, null, nameof(currentRCS), null); rcsModule.getSymmetryModule = m => m.rcsModule; rcsModule.setupModelList(ModelData.parseModels(node.GetNodes("RCS"), m => new ServiceModuleRCSModelData(m))); rcsModule.getValidSelections = m => rcsModule.models.FindAll(s => s.isAvailable(upgradesApplied)); List <ConfigNode> tops = new List <ConfigNode>(); List <ConfigNode> bottoms = new List <ConfigNode>(); ConfigNode[] mNodes = node.GetNodes("CAP"); ConfigNode mNode; int len = mNodes.Length; for (int i = 0; i < len; i++) { mNode = mNodes[i]; if (mNode.GetBoolValue("useForTop", true)) { tops.Add(mNode); } if (mNode.GetBoolValue("useForBottom", true)) { bottoms.Add(mNode); } } topModule.setupModelList(SingleModelData.parseModels(tops.ToArray())); bottomModule.setupModelList(SingleModelData.parseModels(bottoms.ToArray())); tops.Clear(); bottoms.Clear(); topModule.setupModel(); coreModule.setupModel(); coreModule.model.updateScaleForDiameter(currentDiameter); bottomModule.setupModel(); solarModule.setupModel(); rcsModule.setupModel(); rcsModule.model.renameThrustTransforms(rcsThrustTransformName); updateModulePositions(); updateMassAndCost(); updateAttachNodes(false); SSTUStockInterop.updatePartHighlighting(part); }
private void setCoreEditor(string newCore, bool updateSymmetry) { currentCore = newCore; SingleModelData prev = coreModule; coreModule.destroyCurrentModel(); coreModule = SingleModelData.findModel(coreModules, currentCore); coreModule.setupModel(getCoreRoot(false), ModelOrientation.CENTRAL); onModelChanged(prev, coreModule); if (!coreModule.isValidTextureSet(currentCoreTexture)) { currentCoreTexture = coreModule.getDefaultTextureSet(); } coreModule.enableTextureSet(currentCoreTexture); coreModule.updateTextureUIControl(this, "currentCoreTexture", currentCoreTexture); if (updateSymmetry) { foreach (Part p in part.symmetryCounterparts) { p.GetComponent<SSTUModularStationCore>().setCoreEditor(newCore, false); } } }
protected virtual void setNoseModuleFromEditor(String newNoseType, bool updateSymmetry) { currentNoseType = newNoseType; SingleModelData newModule = Array.Find(noseModules, m => m.name == newNoseType); currentNoseModule.destroyCurrentModel(); currentNoseModule = newModule; newModule.setupModel(getNoseRootTransform(false), ModelOrientation.TOP); currentNoseType = newModule.name; if (!currentNoseModule.isValidTextureSet(currentNoseTexture)) { currentNoseTexture = currentNoseModule.getDefaultTextureSet(); } currentNoseModule.enableTextureSet(currentNoseTexture); currentNoseModule.updateTextureUIControl(this, "currentNoseTexture", currentNoseTexture); updateEditorStats(true); if (updateSymmetry) { foreach (Part p in part.symmetryCounterparts) { p.GetComponent<SSTUModularFuelTank>().setNoseModuleFromEditor(newNoseType, false); } } SSTUStockInterop.fireEditorUpdate(); SSTUModInterop.onPartGeometryUpdate(part, true); }
private void setTopEditor(string newTop, bool updateSymmetry) { currentTop = newTop; SingleModelData prev = topModule; topModule.destroyCurrentModel(); topModule = SingleModelData.findModel(topModules, currentTop); topModule.setupModel(getTopRoot(false), ModelOrientation.TOP); onModelChanged(prev, topModule); if (!topModule.isValidTextureSet(currentTopTexture)) { currentTopTexture = topModule.getDefaultTextureSet(); } topModule.enableTextureSet(currentTopTexture); topModule.updateTextureUIControl(this, "currentTopTexture", currentTopTexture); if (updateSymmetry) { foreach (Part p in part.symmetryCounterparts) { p.GetComponent<SSTUModularStationCore>().setTopEditor(newTop, false); } } }
private void init(bool start) { if (initialized) { return; } initialized = true; topNodeNames = SSTUUtils.parseCSV(topManagedNodes); bottomNodeNames = SSTUUtils.parseCSV(bottomManagedNodes); ConfigNode node = SSTUConfigNodeUtils.parseConfigNode(configNodeData); coreModules = SingleModelData.parseModels(node.GetNodes("CORE")); List <ConfigNode> tops = new List <ConfigNode>(); List <ConfigNode> bottoms = new List <ConfigNode>(); ConfigNode[] mNodes = node.GetNodes("CAP"); ConfigNode mNode; int len = mNodes.Length; for (int i = 0; i < len; i++) { mNode = mNodes[i]; if (mNode.GetBoolValue("useForTop", true)) { tops.Add(mNode); } if (mNode.GetBoolValue("useForBottom", true)) { bottoms.Add(mNode); } } topModules = SingleModelData.parseModels(tops.ToArray()); bottomModules = SingleModelData.parseModels(bottoms.ToArray()); tops.Clear(); bottoms.Clear(); mNodes = node.GetNodes("DOCK"); len = mNodes.Length; for (int i = 0; i < len; i++) { mNode = mNodes[i]; if (mNode.GetBoolValue("useForTop", true)) { tops.Add(mNode); } if (mNode.GetBoolValue("useForBottom", true)) { bottoms.Add(mNode); } } topDockModules = SingleModelData.parseModels(tops.ToArray()); bottomDockModules = SingleModelData.parseModels(bottoms.ToArray()); tops.Clear(); bottoms.Clear(); mNodes = node.GetNodes("SOLAR"); len = mNodes.Length; solarModules = new SolarData[len]; for (int i = 0; i < len; i++) { mNode = mNodes[i]; solarModules[i] = new SolarData(mNode); } topDockModule = SingleModelData.findModel(topDockModules, currentTopDock); topModule = SingleModelData.findModel(topModules, currentTop); coreModule = SingleModelData.findModel(coreModules, currentCore); bottomModule = SingleModelData.findModel(bottomModules, currentBottom); bottomDockModule = SingleModelData.findModel(bottomDockModules, currentBottomDock); solarModule = Array.Find(solarModules, m => m.name == currentSolar);//TODO cleanup //validate selections for sub-modules that may require unlocks if (HighLogic.LoadedSceneIsEditor || HighLogic.LoadedSceneIsFlight) { if (!topDockModule.isAvailable(upgradesApplied)) { topDockModule = Array.Find(topDockModules, m => m.isAvailable(upgradesApplied)); } if (!bottomDockModule.isAvailable(upgradesApplied)) { bottomDockModule = Array.Find(bottomDockModules, m => m.isAvailable(upgradesApplied)); } if (!solarModule.isAvailable(this)) { solarModule = Array.Find(solarModules, m => m.isAvailable(this)); } currentTopDock = topDockModule.name; currentBottomDock = bottomDockModule.name; currentSolar = solarModule.name; } if (!topModule.isValidTextureSet(currentTopTexture)) { currentTopTexture = topModule.getDefaultTextureSet(); } if (!coreModule.isValidTextureSet(currentCoreTexture)) { currentCoreTexture = coreModule.getDefaultTextureSet(); } if (!bottomModule.isValidTextureSet(currentBottomTexture)) { currentBottomTexture = bottomModule.getDefaultTextureSet(); } restoreModels(); updateModulePositions(); updateMass(); updateCost(); updateAttachNodes(false); if (HighLogic.LoadedSceneIsEditor || HighLogic.LoadedSceneIsFlight) { ModuleDockingNode[] mdns = part.GetComponents <ModuleDockingNode>(); if (mdns.Length > 0) { if (topDockModule.model != null) { topDockPartModule = mdns[0]; } if (bottomDockModule.model != null) { bottomDockPartModule = mdns.Length > 1 ? mdns[1] : mdns[0]; } } updateDockingModules(start); } //resources are updated in Start(), to ensure that the dependent modules have loaded }
/// <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[] tankSetsNodes = node.GetNodes("TANKSET"); ConfigNode[] tankNodes = node.GetNodes("TANK"); ConfigNode[] mountNodes = node.GetNodes("CAP"); ConfigNode[] limitNodes = node.GetNodes("TECHLIMIT"); tankSets = TankSet.parseSets(tankSetsNodes); //if no sets exist, initialize a default set to add all models to if (tankSets.Length == 0) { tankSets = new TankSet[1]; ConfigNode defaultSetNode = new ConfigNode("TANKSET"); defaultSetNode.AddValue("name", "default"); tankSets[0] = new TankSet(defaultSetNode); } mainTankModules = ModelData.parseModels <TankModelData>(tankNodes, m => new TankModelData(m)); int len = mainTankModules.Length; TankSet set; for (int i = 0; i < len; i++) { set = Array.Find(tankSets, m => m.name == mainTankModules[i].setName); //if set is not found by name, add it to the first set which is guaranteed to exist due to the default-set-adding code above. if (set == null) { set = tankSets[0]; } set.addModel(mainTankModules[i]); } len = mountNodes.Length; ConfigNode mountNode; List <SingleModelData> noses = new List <SingleModelData>(); List <SingleModelData> mounts = new List <SingleModelData>(); for (int i = 0; i < len; i++) { mountNode = mountNodes[i]; if (mountNode.GetBoolValue("useForNose", true)) { mountNode.SetValue("nose", "true"); noses.Add(new SingleModelData(mountNode)); } if (mountNode.GetBoolValue("useForMount", true)) { mountNode.SetValue("nose", "false"); mounts.Add(new SingleModelData(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; } currentTankSetModule = Array.Find(tankSets, m => m.name == currentMainTankModule.setName); currentTankSet = currentTankSetModule.name; lastSelectedVariant = currentMainTankModule.variantName; 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(); } }
private void updateModuleTexture(SingleModelData module, TextureSet set) { if (module.model == null) { return; }//model may be null if the module has no model (e.g. 'None' mount type) set.enable(module.model.transform); }
/// <summary> /// Loads the current configuration from the cached persistent config node data /// </summary> private void loadConfigNodeData() { ConfigNode node = SSTUConfigNodeUtils.parseConfigNode(configNodeData); //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.getDefaultTextureSet(); } //load nose modules from NOSE nodes ConfigNode[] noseNodes = node.GetNodes("NOSE"); ConfigNode noseNode; int length = noseNodes.Length; List<SingleModelData> noseModulesTemp = new List<SingleModelData>(); for (int i = 0; i < length; i++) { noseNode = noseNodes[i]; noseModulesTemp.Add(new SingleModelData(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.getDefaultTextureSet(); } //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.getDefaultTextureSet(); } //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(parentTransform, ModelOrientation.TOP); currentNozzleModule.setupModel(parentTransform, ModelOrientation.BOTTOM); currentMainModule.setupModel(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)); //if had custom thrust curve data, reload it now (else it will default to whatever is on the engine) if (!string.IsNullOrEmpty(thrustCurveData)) { thrustCurveCache = new FloatCurve(); string[] keySplits = thrustCurveData.Split(':'); string[] valSplits; int len = keySplits.Length; float key, value, inTan, outTan; for (int i = 0; i < len; i++) { valSplits = keySplits[i].Split(','); key = float.Parse(valSplits[0]); value = float.Parse(valSplits[1]); inTan = float.Parse(valSplits[2]); outTan = float.Parse(valSplits[3]); thrustCurveCache.Add(key, value, inTan, outTan); } } if (!string.IsNullOrEmpty(presetCurveName)) { ConfigNode[] presetNodes = GameDatabase.Instance.GetConfigNodes("SSTU_THRUSTCURVE"); int len = presetNodes.Length; for (int i = 0; i < len; i++) { if (presetNodes[i].GetStringValue("name") == presetCurveName) { thrustCurveCache = presetNodes[i].GetFloatCurve("curve"); break; } } } }
/// <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]); } }
public static SingleModelData[] parseModels(ConfigNode[] modelNodes) { int len = modelNodes.Length; SingleModelData[] datas = new SingleModelData[len]; for (int i = 0; i < len; i++) { datas[i] = new SingleModelData(modelNodes[i]); } return datas; }
/// <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) { SingleModelData mod = Array.Find(noseModules, m => m.name == newNose); if (mod != null && mod != currentNoseModule) { currentNoseModule.destroyCurrentModel(); mod.setupModel(part.transform.FindRecursive(baseTransformName), ModelOrientation.TOP); currentNoseModule = mod; } currentNoseName = currentNoseModule.name; if (!currentNoseModule.isValidTextureSet(currentNoseTexture)) { currentNoseTexture = currentNoseModule.getDefaultTextureSet(); } currentNoseModule.enableTextureSet(currentNoseTexture); currentNoseModule.updateTextureUIControl(this, "currentNoseTexture", currentNoseTexture); updateModelScaleAndPosition(); updateEffectsScale(); updateContainerVolume(); updatePartMass(); updatePartCost(); updateAttachnodes(true); updateEditorValues(); updateGui(); if (updateSymmetry) { foreach (Part p in part.symmetryCounterparts) { p.GetComponent<SSTUModularBooster>().updateNoseFromEditor(newNose, false); } } SSTUStockInterop.fireEditorUpdate(); SSTUModInterop.onPartGeometryUpdate(part, true); }
/// <summary> /// If tank is uninitialized (no current tank type), will load the default values for tank type/diameter/nose/mount/fuel type into the 'current' slots. /// Will populate the 'currentModuleX' slot with the module for the loaded current-name /// </summary> private void loadTankModules() { currentMainTankModule = Array.Find(mainTankModules, m => m.name == currentTankType); currentNoseModule = Array.Find(noseModules, m => m.name == currentNoseType); currentMountModule = Array.Find(mountModules, m => m.name == currentMountType); currentFuelTypeData = Array.Find(fuelTypes, m => m.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, m => m.name == currentFuelType); initializedResources = false; } }
private void initialize(bool start) { if (initialized) { return; } initialized = true; topNodeNames = SSTUUtils.parseCSV(topManagedNodes); bottomNodeNames = SSTUUtils.parseCSV(bottomManagedNodes); ConfigNode node = SSTUConfigNodeUtils.parseConfigNode(configNodeData); coreModule = new ModelModule <SingleModelData, SSTUModularStationCore>(part, this, getRootTransform("MSC-CORE", true), ModelOrientation.TOP, nameof(coreModulePersistentData), nameof(currentCore), nameof(currentCoreTexture)); coreModule.getSymmetryModule = m => m.coreModule; coreModule.setupModelList(SingleModelData.parseModels(node.GetNodes("CORE"))); topModule = new ModelModule <SingleModelData, SSTUModularStationCore>(part, this, getRootTransform("MSC-TOP", true), ModelOrientation.TOP, nameof(topModulePersistentData), nameof(currentTop), nameof(currentTopTexture)); topModule.getSymmetryModule = m => m.topModule; topModule.getValidSelections = m => topModule.models.FindAll(s => s.canSwitchTo(part, topNodeNames)); bottomModule = new ModelModule <SingleModelData, SSTUModularStationCore>(part, this, getRootTransform("MSC-BOTTOM", true), ModelOrientation.BOTTOM, nameof(bottomModulePersistentData), nameof(currentBottom), nameof(currentBottomTexture)); bottomModule.getSymmetryModule = m => m.bottomModule; bottomModule.getValidSelections = m => bottomModule.models.FindAll(s => s.canSwitchTo(part, bottomNodeNames)); solarModule = new ModelModule <SolarData, SSTUModularStationCore>(part, this, getRootTransform("MSC-Solar", true), ModelOrientation.CENTRAL, null, nameof(currentSolar), null); solarModule.getSymmetryModule = m => m.solarModule; solarModule.setupModelList(SingleModelData.parseModels(node.GetNodes("SOLAR"), m => new SolarData(m))); solarModule.getValidSelections = m => solarModule.models.FindAll(s => s.isAvailable(upgradesApplied)); List <ConfigNode> tops = new List <ConfigNode>(); List <ConfigNode> bottoms = new List <ConfigNode>(); ConfigNode[] mNodes = node.GetNodes("CAP"); ConfigNode mNode; int len = mNodes.Length; for (int i = 0; i < len; i++) { mNode = mNodes[i]; if (mNode.GetBoolValue("useForTop", true)) { tops.Add(mNode); } if (mNode.GetBoolValue("useForBottom", true)) { bottoms.Add(mNode); } } topModule.setupModelList(SingleModelData.parseModels(tops.ToArray())); bottomModule.setupModelList(SingleModelData.parseModels(bottoms.ToArray())); tops.Clear(); bottoms.Clear(); topModule.setupModel(); coreModule.setupModel();//TODO -- only setup core module if not the prefab part -- else need to add transform updating/fx-updating for RCS and engine modules, as they lack proper handling for transform swapping at runtime bottomModule.setupModel(); solarModule.setupModel(); updateModulePositions(); updateMassAndCost(); updateAttachNodes(false); SSTUStockInterop.updatePartHighlighting(part); }
private void setMainTankModuleFromEditor(SingleModelData newModule, bool updateSymmetry) { currentMainTankModule.destroyCurrentModel(); currentMainTankModule = newModule; currentMainTankModule.setupModel(part, part.transform.FindRecursive("model")); currentTankType = newModule.name; updateEditorStats(true); if (updateSymmetry) { foreach (Part p in part.symmetryCounterparts) { SSTUModularFuelTank mft = p.GetComponent<SSTUModularFuelTank>(); SingleModelData mt = Array.Find(mft.mainTankModules, t => t.name == newModule.name); mft.setMainTankModuleFromEditor(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 SingleModelData getNextTankLength(SingleModelData currentModule, bool iterateBackwards) { if (!SSTUUtils.isResearchGame()) { return SSTUUtils.findNext(mainTankModules, m => m == currentModule, iterateBackwards); } return SSTUUtils.findNextEligible<SingleModelData>(mainTankModules, m => m == currentMainTankModule, l => l.height <= techLimitMaxHeight, iterateBackwards); }
private void initialize() { if (heatCurve == null) { heatCurve = new FloatCurve(); heatCurve.Add(0, 0.00002f);//very minimal initial ablation factor heatCurve.Add(50, 0.00005f);//ramp it up fairly quickly though heatCurve.Add(150, 0.00015f); heatCurve.Add(500, 0.00050f); heatCurve.Add(750, 0.00075f); heatCurve.Add(1000, 0.00100f); heatCurve.Add(2000, 0.00400f); heatCurve.Add(3000, 0.00800f);//generally, things will explode before this point heatCurve.Add(10000, 0.05000f);//but just in case, continue the curve up to insane levels } double hsp = 1; double dens = 1; if (heatSoak) { PartResourceDefinition resource = PartResourceLibrary.Instance.GetDefinition(resourceName); hsp = resource.specificHeatCapacity; dens = resource.density; } else { resource = part.Resources[resourceName]; if (resource != null) { hsp = resource.info.specificHeatCapacity; dens = resource.info.density; } else { hsp = PhysicsGlobals.StandardSpecificHeatCapacity; dens = 0.005f; } } useToFluxMultiplier = hsp * ablationEfficiency * dens * ablationMult; baseSkinIntMult = part.skinInternalConductionMult; //stand-alone modular heat-shield setup if (standAlonePart) { if (string.IsNullOrEmpty(modelName)) { MonoBehaviour.print("SEVERE ERROR: SSTUModularHeatShield could has no model specified for part: " + part.name); } if (!String.IsNullOrEmpty(transformsToRemove)) { SSTUUtils.removeTransforms(part, SSTUUtils.parseCSV(transformsToRemove)); } shieldTypeNames = SSTUDatabase.getHeatShieldNames(); ConfigNode modelNode = new ConfigNode("MODEL"); modelNode.AddValue("name", modelName); mainModelData = new SingleModelData(modelNode); mainModelData.setupModel(part.transform.FindRecursive("model"), ModelOrientation.CENTRAL, true); setModelDiameter(currentDiameter); updateAttachNodes(false); updateDragCube(); updateEditorFields(); } ConfigNode node = SSTUConfigNodeUtils.parseConfigNode(configNodeData); ConfigNode[] typeNodes = node.GetNodes("SHIELDTYPE"); int len = typeNodes.Length; shieldTypeNames = new string[len]; for (int i = 0; i < len; i++) { shieldTypeNames[i] = typeNodes[i].GetStringValue("name"); } if (shieldTypeNames.Length == 0) { shieldTypeNames = new string[] { "Medium" }; } currentShieldTypeData = SSTUDatabase.getHeatShieldType(currentShieldType); heatCurve = currentShieldTypeData.heatCurve; updatePartCost(); if (!initializedResources && (HighLogic.LoadedSceneIsEditor || HighLogic.LoadedSceneIsFlight)) { updatePartResources(); initializedResources = true; } }
/// <summary> /// Updates the current intertank mesh/model from user input /// </summary> /// <param name="newDef"></param> private void updateIntertankModelFromEditor(SingleModelData newDef) { removeCurrentModel(currentIntertankModule); currentIntertankModule = newDef; currentIntertank = newDef.name; setupModel(currentIntertankModule, part.transform.FindRecursive("model").FindOrCreate(baseTransformName), ModelOrientation.CENTRAL); updateModules(true); updateModels(); updateTankStats(); updatePartResources(); updateGuiState(); }
private void initialize() { if (heatCurve == null) { heatCurve = new FloatCurve(); heatCurve.Add(0, 0.00002f); //very minimal initial ablation factor heatCurve.Add(50, 0.00005f); //ramp it up fairly quickly though heatCurve.Add(150, 0.00015f); heatCurve.Add(500, 0.00050f); heatCurve.Add(750, 0.00075f); heatCurve.Add(1000, 0.00100f); heatCurve.Add(2000, 0.00400f); heatCurve.Add(3000, 0.00800f); //generally, things will explode before this point heatCurve.Add(10000, 0.05000f); //but just in case, continue the curve up to insane levels } double hsp = 1; double dens = 1; if (heatSoak) { PartResourceDefinition resource = PartResourceLibrary.Instance.GetDefinition(resourceName); hsp = resource.specificHeatCapacity; dens = resource.density; } else { resource = part.Resources[resourceName]; if (resource != null) { hsp = resource.info.specificHeatCapacity; dens = resource.info.density; } else { hsp = PhysicsGlobals.StandardSpecificHeatCapacity; dens = 0.005f; } } useToFluxMultiplier = hsp * ablationEfficiency * dens * ablationMult; baseSkinIntMult = part.skinInternalConductionMult; //stand-alone modular heat-shield setup if (standAlonePart) { if (string.IsNullOrEmpty(modelName)) { MonoBehaviour.print("SEVERE ERROR: SSTUModularHeatShield could has no model specified for part: " + part.name); } if (!String.IsNullOrEmpty(transformsToRemove)) { SSTUUtils.removeTransforms(part, SSTUUtils.parseCSV(transformsToRemove)); } shieldTypeNames = SSTUDatabase.getHeatShieldNames(); ConfigNode modelNode = new ConfigNode("MODEL"); modelNode.AddValue("name", modelName); mainModelData = new SingleModelData(modelNode); mainModelData.setupModel(part.transform.FindRecursive("model"), ModelOrientation.CENTRAL, true); setModelDiameter(currentDiameter); updateAttachNodes(false); updateDragCube(); updateEditorFields(); } ConfigNode node = SSTUConfigNodeUtils.parseConfigNode(configNodeData); ConfigNode[] typeNodes = node.GetNodes("SHIELDTYPE"); int len = typeNodes.Length; shieldTypeNames = new string[len]; for (int i = 0; i < len; i++) { shieldTypeNames[i] = typeNodes[i].GetStringValue("name"); } if (shieldTypeNames.Length == 0) { shieldTypeNames = new string[] { "Medium" }; } currentShieldTypeData = SSTUDatabase.getHeatShieldType(currentShieldType); heatCurve = currentShieldTypeData.heatCurve; updatePartCost(); if (!initializedResources && (HighLogic.LoadedSceneIsEditor || HighLogic.LoadedSceneIsFlight)) { updatePartResources(); initializedResources = 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); }