private bool IsDockedDockingPortPassable(Part thisPart, Part otherPart) { bool retVal = false; // First things first - does this part even support CLS? If it does not then the dockingPort is certain to be impassable. ModuleConnectedLivingSpace clsModThis = (ModuleConnectedLivingSpace)thisPart; if (null == clsModThis) { //Debug.Log("Part " + thisPart.partInfo.title + "(" + thisPart.uid + ") does not seem to support CLS. Setting it as impassable."); return(false); } else { // As it does support CLS, first set the passable value to the the "passable" field for this part retVal = clsModThis.passable; } // Loop through all the ModuleDockingNodes for this part and check if any are docked to the other part. IEnumerator <ModuleDockingNode> epNodes = thisPart.Modules.OfType <ModuleDockingNode>().GetEnumerator(); while (epNodes.MoveNext()) { if (epNodes.Current == null) { continue; } if (CheckForNodeDockedToPart(epNodes.Current, otherPart)) { // We have found the ModuleDockingNode that represents the docking connection on this part. //Debug.Log("Found docking node that represents the docking connection to the 'other' part"); // First consider if this docked connection has an accompanying AttachNode may be defined as (im)passable by CLS. if (epNodes.Current.referenceNode.id != string.Empty) { //Debug.Log("docking node uses a referenceAttachNode called: " + docNode.referenceNode.id + " In the meantime, passablenodes: " + clsModThis.passablenodes + " impassablenodes: " + clsModThis.impassablenodes); if (clsModThis.passablenodes.Contains(epNodes.Current.referenceNode.id)) { retVal = true; } if (clsModThis.impassablenodes.Contains(epNodes.Current.referenceNode.id)) { retVal = false; } } // Second, if there is no AttachNode, what about the type / size of the docking port else { //Debug.Log("docking node does not use referenceNode.id, instead considering the nodeType: " + docNode.nodeType + " In the meantime, impassableDockingNodeTypes:" + clsModThis.impassableDockingNodeTypes + " passableDockingNodeTypes:" + clsModThis.passableDockingNodeTypes); if (clsModThis.impassableDockingNodeTypes.Contains(epNodes.Current.nodeType)) { retVal = false; // Docking node is of an impassable type. } if (clsModThis.passableDockingNodeTypes.Contains(epNodes.Current.nodeType)) { retVal = true; // Docking node is of a passable type. } } // third, consider if there is an open / closed hatch { ModuleDockingHatch docHatch = GetHatchForDockingNode(epNodes.Current); if (docHatch != null) { // The dockingNode is actually a DockingNodeHatch :) if (!docHatch.HatchOpen) { //Debug.Log("DockingNodeHatch is closed and so can not be passed through"); retVal = false; // Hatch in the docking node is closed, so it is impassable } } } break; } } //Debug.Log("returning " + retVal); return(retVal); }
private void CheckAndFixDockingHatches(List <Part> listParts) { foreach (Part part in listParts) { // If the part does not have any modules set up then move to the next part if (null == part.Modules) { continue; } List <ModuleDockingNode> listDockNodes = new List <ModuleDockingNode>(); List <ModuleDockingHatch> listDockHatches = new List <ModuleDockingHatch>(); // Build a temporary list of docking nodes to consider. This is necassery can we can not add hatch modules to the modules list while we are enumerating the very same list! foreach (ModuleDockingNode dockNode in part.Modules.OfType <ModuleDockingNode>()) { listDockNodes.Add(dockNode); } foreach (ModuleDockingHatch dockHatch in part.Modules.OfType <ModuleDockingHatch>()) { listDockHatches.Add(dockHatch); } // First go through all the hatches. If any do not refer to a dockingPort then remove it. foreach (ModuleDockingHatch dockHatch in listDockHatches) { // I know we are making abit of a meal of this. It is unclear to me what the unset vakues will be, and this way we are catching every possibility. It seems that open (3) is the open that gets called, but I will leave this as is for now. if ("" == dockHatch.docNodeAttachmentNodeName && "" == dockHatch.docNodeTransformName) { Debug.Log("Found a hatch that does not reference a docking node. Removing it from the part.(1)"); part.RemoveModule(dockHatch); } else if (string.Empty == dockHatch.docNodeAttachmentNodeName && string.Empty == dockHatch.docNodeTransformName) { Debug.Log("Found a hatch that does not reference a docking node. Removing it from the part.(2)"); part.RemoveModule(dockHatch); } else if (null == dockHatch.docNodeAttachmentNodeName && null == dockHatch.docNodeTransformName) { Debug.Log("Found a hatch that does not reference a docking node. Removing it from the part.(3)"); part.RemoveModule(dockHatch); } else if ((null == dockHatch.docNodeAttachmentNodeName || string.Empty == dockHatch.docNodeAttachmentNodeName || "" == dockHatch.docNodeAttachmentNodeName) && ("" == dockHatch.docNodeTransformName || string.Empty == dockHatch.docNodeTransformName || null == dockHatch.docNodeTransformName)) { Debug.Log("Found a hatch that does not reference a docking node. Removing it from the part.(4)"); part.RemoveModule(dockHatch); } } // Now because we might have removed for dodgy hatches, rebuild the hatch list. listDockHatches.Clear(); foreach (ModuleDockingHatch dockHatch in part.Modules.OfType <ModuleDockingHatch>()) { listDockHatches.Add(dockHatch); } // Now go through all the dockingPorts and add hatches for any docking ports that do not have one. foreach (ModuleDockingNode dockNode in listDockNodes) { // Does this docking node have a corresponding hatch? ModuleDockingHatch hatch = null; foreach (ModuleDockingHatch h in listDockHatches) { if (h.IsRelatedDockingNode(dockNode)) { hatch = h; break; } } if (null == hatch) { // There is no corresponding hatch - add one. ConfigNode node = new ConfigNode("MODULE"); node.AddValue("name", "ModuleDockingHatch"); if (dockNode.referenceAttachNode != string.Empty) { // Debug.Log("Adding ModuleDockingHatch to part " + part.partInfo.title + " and the docking node that uses attachNode " + dockNode.referenceAttachNode); node.AddValue("docNodeAttachmentNodeName", dockNode.referenceAttachNode); } else { if (dockNode.nodeTransformName != string.Empty) { // Debug.Log("Adding ModuleDockingHatch to part " + part.partInfo.title + " and the docking node that uses transform " + dockNode.nodeTransformName); node.AddValue("docNodeTransformName", dockNode.nodeTransformName); } } { // This block is required as calling AddModule and passing in the node throws an exception if Awake has not been called. The method Awaken uses reflection to call then private method Awake. See http://forum.kerbalspaceprogram.com/threads/27851 for more information. PartModule pm = part.AddModule("ModuleDockingHatch"); if (Awaken(pm)) { // Debug.Log("Loading the ModuleDockingHatch config"); pm.Load(node); } else { Debug.LogWarning("Failed to call Awaken so the config has not been loaded."); } } } } } }
// Method to add Docking Hatches to all parts that have Docking Nodes private void AddHatchModuleToParts() { // If we are in the editor or if flight, take a look at the active vesssel and add a ModuleDockingHatch to any part that has a ModuleDockingNode without a corresponding ModuleDockingHatch List <Part> listParts; if (HighLogic.LoadedSceneIsEditor && null != EditorLogic.startPod) { listParts = EditorLogic.SortedShipList; } else if (HighLogic.LoadedSceneIsFlight && null != FlightGlobals.ActiveVessel && null != FlightGlobals.ActiveVessel.Parts) { listParts = FlightGlobals.ActiveVessel.Parts; } else { listParts = new List <Part>(); } foreach (Part part in listParts) { try { // If the part does not have any modules set up then move to the next part if (null == part.Modules) { continue; } List <ModuleDockingNode> listDockNodes = new List <ModuleDockingNode>(); List <ModuleDockingHatch> listDockHatches = new List <ModuleDockingHatch>(); // Build a temporary list of docking nodes to consider. This is necassery can we can not add hatch modules to the modules list while we are enumerating the very same list! foreach (ModuleDockingNode dockNode in part.Modules.OfType <ModuleDockingNode>()) { listDockNodes.Add(dockNode); } foreach (ModuleDockingHatch dockHatch in part.Modules.OfType <ModuleDockingHatch>()) { listDockHatches.Add(dockHatch); } foreach (ModuleDockingNode dockNode in listDockNodes) { // Does this docking node have a corresponding hatch? ModuleDockingHatch hatch = null; foreach (ModuleDockingHatch h in listDockHatches) { if (h.IsRelatedDockingNode(dockNode)) { hatch = h; break; } } if (null == hatch) { // There is no corresponding hatch - add one. ConfigNode node = new ConfigNode("MODULE"); node.AddValue("name", "ModuleDockingHatch"); if (dockNode.referenceAttachNode != string.Empty) { //Debug.Log("Adding ModuleDockingHatch to part " + part.partInfo.title + " and the docking node that uses attachNode " + dockNode.referenceAttachNode); node.AddValue("docNodeAttachmentNodeName", dockNode.referenceAttachNode); } else { if (dockNode.nodeTransformName != string.Empty) { //Debug.Log("Adding ModuleDockingHatch to part " + part.partInfo.title + " and the docking node that uses transform " + dockNode.nodeTransformName); node.AddValue("docNodeTransformName", dockNode.nodeTransformName); } } { // This block is required as calling AddModule and passing in the node throws an exception if Awake has not been called. The method Awaken uses reflection to call then private method Awake. See http://forum.kerbalspaceprogram.com/threads/27851 for more information. PartModule pm = part.AddModule("ModuleDockingHatch"); if (Awaken(pm)) { //Debug.Log("Loading the ModuleDockingHatch config"); pm.Load(node); } else { Debug.LogWarning("Failed to call Awaken so the config has not been loaded."); } } } } } catch (Exception ex) { Debug.LogException(ex); } } }
// Method to add Docking Hatches to all parts that have Docking Nodes private void AddHatchModuleToPartPrefabs() { IEnumerable <AvailablePart> parts = PartLoader.LoadedPartsList.Where(p => p.partPrefab != null); foreach (AvailablePart part in parts) { Part partPrefab = part.partPrefab; // If the part does not have any modules set up then move to the next part if (null == partPrefab.Modules) { continue; } List <ModuleDockingNode> listDockNodes = new List <ModuleDockingNode>(); List <ModuleDockingHatch> listDockHatches = new List <ModuleDockingHatch>(); // Build a temporary list of docking nodes to consider. This is necassery can we can not add hatch modules to the modules list while we are enumerating the very same list! foreach (ModuleDockingNode dockNode in partPrefab.Modules.OfType <ModuleDockingNode>()) { listDockNodes.Add(dockNode); } foreach (ModuleDockingHatch dockHatch in partPrefab.Modules.OfType <ModuleDockingHatch>()) { listDockHatches.Add(dockHatch); } foreach (ModuleDockingNode dockNode in listDockNodes) { // Does this docking node have a corresponding hatch? ModuleDockingHatch hatch = null; foreach (ModuleDockingHatch h in listDockHatches) { if (h.IsRelatedDockingNode(dockNode)) { hatch = h; break; } } if (null == hatch) { // There is no corresponding hatch - add one. ConfigNode node = new ConfigNode("MODULE"); node.AddValue("name", "ModuleDockingHatch"); if (dockNode.referenceAttachNode != string.Empty) { Debug.Log("Adding ModuleDockingHatch to part " + part.title + " and the docking node that uses attachNode " + dockNode.referenceAttachNode); node.AddValue("docNodeAttachmentNodeName", dockNode.referenceAttachNode); } else { if (dockNode.nodeTransformName != string.Empty) { Debug.Log("Adding ModuleDockingHatch to part " + part.title + " and the docking node that uses transform " + dockNode.nodeTransformName); node.AddValue("docNodeTransformName", dockNode.nodeTransformName); } } { // This block is required as calling AddModule and passing in the node throws an exception if Awake has not been called. The method Awaken uses reflection to call then private method Awake. See http://forum.kerbalspaceprogram.com/threads/27851 for more information. PartModule pm = partPrefab.AddModule("ModuleDockingHatch"); if (Awaken(pm)) { Debug.Log("Loading the ModuleDockingHatch config"); pm.Load(node); } else { Debug.LogWarning("Failed to call Awaken so the config has not been loaded."); } } } } } }