/// <summary> /// Updates part highlight renderer list, sends message to SSTUFlagDecal to update its renderer, /// sends message to FAR to update voxels, or if createDefaultCube==true will re-render the 'default' stock drag cube for the part<para/> /// Should be called anytime the model geometry in a part is changed -- either models added/deleted, procedural meshes updated. Other methods exist for pure drag-cube updating in SSTUStockInterop. /// </summary> /// <param name="part"></param> /// <param name="createDefaultCube"></param> public static void onPartGeometryUpdate(Part part, bool createDefaultCube) { if (!HighLogic.LoadedSceneIsEditor && !HighLogic.LoadedSceneIsFlight) { return; } //noop on prefabs //MonoBehaviour.print(System.Environment.StackTrace); SSTUStockInterop.updatePartHighlighting(part); part.airlock = locateAirlock(part); partGeometryUpdate(part); if (isFARInstalled()) { SSTUStockInterop.addFarUpdatePart(part); //FARdebug(part); //part.SendMessage("GeometryPartModuleRebuildMeshData"); } else if (createDefaultCube && (HighLogic.LoadedSceneIsEditor || HighLogic.LoadedSceneIsFlight)) { SSTUStockInterop.addDragUpdatePart(part); } if (HighLogic.LoadedSceneIsEditor && part.parent == null && part != EditorLogic.RootPart) //likely the part under the cursor; this fixes problems with modular parts not wanting to attach to stuff { part.gameObject.SetLayerRecursive(1, 2097152); //1<<21 = Part Triggers get skipped by the relayering (hatches, ladders, ??) } }
/// <summary> /// Restore the currently selected modules' models, and restore their current texture-set selection /// Removes any existing models from special-named root transforms with no attempt at re-use /// </summary> private void restoreModels() { topDockModule.setupModel(getTopDockRoot(true), ModelOrientation.TOP); topModule.setupModel(getTopRoot(true), ModelOrientation.TOP); coreModule.setupModel(getCoreRoot(false), ModelOrientation.CENTRAL, true);//setup model on prefab part and don't touch it after that bottomModule.setupModel(getBottomRoot(true), ModelOrientation.BOTTOM); bottomDockModule.setupModel(getBottomDockRoot(true), ModelOrientation.BOTTOM); solarModule.enable(getSolarRoot(true), 0); topModule.enableTextureSet(currentTopTexture); coreModule.enableTextureSet(currentCoreTexture); bottomModule.enableTextureSet(currentBottomTexture); //control transforms need to exist during part initialization //else things will explode if one of those transforms is the reference transform when a vessel is reloaded //so create them on prefab and restore on other instances if (!HighLogic.LoadedSceneIsEditor && !HighLogic.LoadedSceneIsFlight) { Transform modelRoot = part.transform.FindRecursive("model"); topDockTransform = new GameObject(topDockName).transform; topDockTransform.NestToParent(modelRoot); topDockTransform.Rotate(-90, 0, 0, Space.Self); topControlTransform = new GameObject(topDockName + "Control").transform; topControlTransform.NestToParent(modelRoot); bottomDockTransform = new GameObject(bottomDockName).transform; bottomDockTransform.NestToParent(modelRoot); bottomDockTransform.Rotate(90, 0, 0, Space.Self); bottomControlTransform = new GameObject(bottomDockName + "Control").transform; bottomControlTransform.NestToParent(modelRoot); bottomControlTransform.Rotate(180, 0, 0, Space.Self); } else { topDockTransform = part.transform.FindRecursive(topDockName); topControlTransform = part.transform.FindRecursive(topDockName + "Control"); bottomDockTransform = part.transform.FindRecursive(bottomDockName); bottomControlTransform = part.transform.FindRecursive(bottomDockName + "Control"); } SSTUStockInterop.updatePartHighlighting(part); }
private void removeParachuteCap(String name, bool jettison) { if (String.IsNullOrEmpty(name)) { return; } Transform tr = part.transform.FindRecursive(name); if (tr == null) { return; } if (jettison) { Vector3 force = (part.transform.up * 100) + (part.transform.forward * 10); GameObject jettisoned = SSTUUtils.createJettisonedObject(tr.gameObject, part.rb.velocity, force, 0.15f); SSTUStockInterop.updatePartHighlighting(part); } else { GameObject.Destroy(tr.gameObject); } }
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 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); }