private void loadConfigNodeData(ConfigNode node)
        {
            ConfigNode[] layoutNodes = node.GetNodes("LAYOUT");
            loadEngineLayouts(layoutNodes);

            if (String.IsNullOrEmpty(currentEngineLayoutName))
            {
                currentEngineLayoutName = engineLayouts[0].layoutName;
            }
            currentEngineLayout = Array.Find(engineLayouts, m => m.layoutName == currentEngineLayoutName);

            if (currentEngineLayout == null)
            {
                currentEngineLayout = engineLayouts[0];
                currentEngineLayoutName = currentEngineLayout.layoutName;
            }
            if (!currentEngineLayout.isValidMount(currentMountName))//catches the case of an uninitilized part and those where mount data has been removed from the config.
            {
                currentMountName = currentEngineLayout.defaultMount;
                currentMountDiameter = currentEngineLayout.getMountData(currentMountName).initialDiameter;
                currentEngineSpacing = currentEngineLayout.getEngineSpacing(engineScale, currentEngineLayout.getMountData(currentMountName));
                editorEngineSpacingAdjust = prevEngineSpacingAdjust = 0f;
            }
            currentMountData = currentEngineLayout.getMountData(currentMountName);
            if (currentMountDiameter > currentMountData.maxDiameter) { currentMountDiameter = currentMountData.maxDiameter; }
            if (currentMountDiameter < currentMountData.minDiameter) { currentMountDiameter = currentMountData.minDiameter; }
        }
        private void loadEngineLayouts(ConfigNode[] moduleLayoutNodes)
        {
            Dictionary<String, SSTUEngineLayout> allBaseLayouts = SSTUEngineLayout.getAllLayoutsDict();
            Dictionary<String, ConfigNode> layoutConfigNodes = new Dictionary<string, ConfigNode>();
            String name;
            ConfigNode localLayoutNode;
            int len = moduleLayoutNodes.Length;
            for (int i = 0; i < len; i++)
            {
                localLayoutNode = moduleLayoutNodes[i];
                name = localLayoutNode.GetStringValue("name");
                if (allBaseLayouts.ContainsKey(name))
                {
                    if (localLayoutNode.GetBoolValue("remove", false))//remove any layouts flagged for removal
                    {
                        allBaseLayouts.Remove(name);
                    }
                    else
                    {
                        layoutConfigNodes.Add(name, localLayoutNode);
                    }
                }
            }

            len = allBaseLayouts.Keys.Count;
            engineLayouts = new EngineClusterLayoutData[len];
            int index = 0;
            foreach (String key in allBaseLayouts.Keys)
            {
                localLayoutNode = null;
                layoutConfigNodes.TryGetValue(key, out localLayoutNode);
                engineLayouts[index] = new EngineClusterLayoutData(allBaseLayouts[key], localLayoutNode, engineScale, engineSpacing, engineMountDiameter, diameterIncrement, upperStageMounts, lowerStageMounts);
                index++;
            }
            //sort usable layout list by the # of positions in the layout, 1..2..3..x..99
            Array.Sort(engineLayouts, delegate (EngineClusterLayoutData x, EngineClusterLayoutData y) { return x.getLayoutData().positions.Count - y.getLayoutData().positions.Count; });
        }
        private void updateLayoutFromEditor(String newLayout, bool updateSymmetry)
        {
            currentEngineLayoutName = newLayout;
            currentEngineLayout = Array.Find(engineLayouts, m => m.layoutName == newLayout);
            if (currentMountName == "Mount-None" && currentEngineLayout.isValidMount(currentMountName))
            {
                //NOOP
            }
            else
            {
                currentMountName = currentEngineLayout.defaultMount;
            }

            bool useModelSelectionGUI = HighLogic.CurrentGame.Parameters.CustomParams<SSTUGameSettings>().useModelSelectGui;
            Fields["guiMountOption"].guiActiveEditor = !useModelSelectionGUI && currentEngineLayout.mountData.Length > 1;
            Events["selectMountEvent"].guiActiveEditor = useModelSelectionGUI && currentEngineLayout.mountData.Length > 1;
            currentMountData = currentEngineLayout.getMountData(currentMountName);
            currentMountDiameter = currentMountData.initialDiameter;
            currentEngineSpacing = currentEngineLayout.getEngineSpacing(engineScale, currentMountData) + editorEngineSpacingAdjust;
            setupMountModel();
            updateMountTexture();
            positionMountModel();
            setupEngineModels();
            positionEngineModels();
            reInitEngineModule();
            updateNodePositions(true);
            updateDragCubes();
            updateEditorFields();
            updateMountSizeGuiControl(true, currentMountData.initialDiameter);
            updateMountOptionsGuiControl();
            updateMountTextureOptionsGuiControl();
            updatePartCostAndMass();
            updateGuiState();
            updateFairing(true);
            if (updateSymmetry)
            {
                foreach (Part p in part.symmetryCounterparts) { p.GetComponent<SSTUModularEngineCluster>().updateLayoutFromEditor(newLayout, false); }
            }
        }