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 }