internal void AddPart(CLSPart p)
    {
      // Add the part to the space, and the space to the part.
      p.Space = this;

      // If this space does not have a name, take the name from the part we just added.
      if ("" == this.name)
      {
        ModuleConnectedLivingSpace modCLS = (ModuleConnectedLivingSpace)p;

        if (null != modCLS)
        {
          this.name = modCLS.spaceName;
        }
      }

      this.parts.Add(p);

      this.maxCrew += ((Part)p).CrewCapacity;

      foreach (CLSKerbal crewMember in p.Crew)
      {
        this.crew.Add(crewMember);
      }
    }
        internal void AddPart(CLSPart p)
        {
            // Add the part to the space, and the space to the part.
            p.Space = this;

            // If this space does not have a name, take the name from the part we just added.
            if ("" == this.name)
            {
                ModuleConnectedLivingSpace modCLS = (ModuleConnectedLivingSpace)p;

                if (null != modCLS)
                {
                    this.name = modCLS.spaceName;
                }
            }

            this.parts.Add(p);

            this.maxCrew += ((Part)p).CrewCapacity;

            foreach (CLSKerbal crewMember in p.Crew)
            {
                this.crew.Add(crewMember);
            }
        }
        internal void AddPart(CLSPart p)
        {
            // Add the part to the space, and the space to the part.
            p.Space = this;

            // If this space does not have a name, take the name from the part we just added.
            if ("" == name)
            {
                ModuleConnectedLivingSpace modCLS = (ModuleConnectedLivingSpace)p;

                if (null != modCLS)
                {
                    name = modCLS.spaceName;
                }
            }

            parts.Add(p);

            maxCrew += ((Part)p).CrewCapacity;

            IEnumerator <ICLSKerbal> eCrew = p.Crew.GetEnumerator();

            while (eCrew.MoveNext())
            {
                if (eCrew.Current == null)
                {
                    continue;
                }
                crew.Add((CLSKerbal)eCrew.Current);
            }
            eCrew.Dispose();
        }
        CLSSpace AddPartToNewSpace(CLSPart p)
        {
            CLSSpace newSpace = new CLSSpace(this);

            listSpaces.Add(newSpace);

            newSpace.AddPart(p);

            return(newSpace);
        }
        CLSSpace AddPartToSpace(CLSPart p, CLSSpace space)
        {
            //Debug.Log($"[CLS]:  AddPartToSpace {((Part)p).name}");

            if (null != space)
            {
                space.AddPart(p);
            }
            else
            {
                Debug.LogError($"Can't add part {((Part)p).partInfo.title} to null space");
            }

            return(space);
        }
        CLSSpace AddPartToSpace(CLSPart p, CLSSpace space)
        {
            Log.dbg("AddPartToSpace {0}", ((Part)p).name);

            if (null != space)
            {
                space.AddPart(p);
            }
            else
            {
                Log.error("Can't add part {0} to null space", ((Part)p).partInfo.title);
            }

            return(space);
        }
        CLSSpace AddPartToSpace(CLSPart p, CLSSpace space)
        {
            //Debug.Log("AddPartToSpace " + ((Part)p).name);

            if (null != space)
            {
                space.AddPart(p);
            }
            else
            {
                Debug.LogError("Can't add part " + ((Part)p).partInfo.title + " to null space");
            }

            return(space);
        }
 public CLSKerbal(ProtoCrewMember k, CLSPart p)
 {
     kerbal = k;
       part = p;
 }
        CLSSpace AddPartToNewSpace(CLSPart p)
        {
            CLSSpace newSpace = new CLSSpace(this);

            this.listSpaces.Add(newSpace);

            newSpace.AddPart(p);

            return newSpace;
        }
        // A method that is called recursively to walk the part tree, and allocate parts to habitable spaces
        private void ProcessPart(Part p, CLSSpace currentSpace , bool dockedToParent=false)
        {
            CLSSpace thisSpace = null;
            CLSPart newPart = new CLSPart(p);

            //Debug.Log("Processing part: " + p.name + " Navigable:"+newPart.Navigable + " Habitable:" + newPart.Habitable);

            // First add this part to the list of all parts for the vessel.
            this.listParts.Add(newPart);

            // Is the part capable of allowing kerbals to pass? If it is add it to the current space, or if there is no current space, to a new space.
            if (newPart.Navigable)
            {
                thisSpace = currentSpace;

                if (null == thisSpace)
                {
                    thisSpace = AddPartToNewSpace(newPart);
                }
                else
                {
                    thisSpace = AddPartToSpace(newPart, thisSpace);
                }
            }

            // Now loop through each of the part's children, consider if there is a navigable connection between them, and then make a recursive call.
            foreach (Part child in p.children)
            {
                // Get the attachment nodes
                AttachNode node = p.findAttachNodeByPart(child);
                AttachNode childNode = child.findAttachNodeByPart(p);
                bool attachmentIsPassable = false;
                bool childAttachmentIsPassable = false;
                bool dockingConnection = false;
                CLSSpace spaceForChild = thisSpace;

                // TODO removed debugging
                //Debug.Log("Considering the connection between " + p.partInfo.title + "(" + p.uid + ") and " + child.partInfo.title + "(" + child.uid + ")");
                {
                    // Is the attachment on "this" part passable?
                    if (null != node)
                    {
                        // The attachment is in the form of an AttachNode - use it to work out if the attachment is passable.
                        attachmentIsPassable = IsNodeNavigable(node, p);
                        //Debug.Log("the attachment on 'this' part is defined by attachment node " + node.id + " and had been given passable=" + attachmentIsPassable);
                    }
                    else
                    {
                        // Could it be that we are dealling with a docked connection?
                        dockingConnection = CheckForDockedPair(p, child);

                        if (true == dockingConnection)
                        {
                            //Debug.Log("The two parts are considered to be docked together.");
                            // The parts are docked, but we still need to have a think about if the docking port is passable.
                            attachmentIsPassable = IsDockedDockingPortPassable(p, child);
                            //Debug.Log("the docked attachment on 'this' part has been given passable=" + attachmentIsPassable);
                        }
                        else
                        {
                            //Debug.Log("The two parts are NOT considered to be docked together - concluding that this part is suface attached");
                            // It is not a AttachNode attachment, and it is not a docked connection either. The only other option is that we are dealing with a surface attachment. Does this part allow surfact attachments to be passable?
                            if (PartHasPassableSurfaceAttachments(p))
                            {
                                attachmentIsPassable = true;
                                //Debug.Log("This part is surface attached and is considered to be passable");
                            }
                        }
                    }
                }

                // Repeat the above block for the child part.
                {
                    // Is the attachment on "this" part passable?
                    if (null != childNode)
                    {
                        // The attachment is in the form of an AttachNode - use it to work out if the attachment is passable.
                        childAttachmentIsPassable = IsNodeNavigable(childNode, child);
                        //Debug.Log("the attachment on the child part is defined by attachment node " + childNode.id + " and had been given passable=" + attachmentIsPassable);
                    }
                    else
                    {
                        if (true == dockingConnection)
                        {
                            //Debug.Log("The two parts are considered to be docked together.");
                            // The parts are docked, but we still need to have a think about if the docking port is passable.
                            childAttachmentIsPassable = IsDockedDockingPortPassable(child, p);
                            //Debug.Log("the docked attachment on the child part has been given passable=" + attachmentIsPassable);
                        }
                        else
                        {
                            //Debug.Log("The two parts are NOT considered to be docked together - concluding that the child part is suface attached");
                            // It is not a AttachNode attachment, and it is not a docked connection either. The only other option is that we are dealing with a surface attachment. Does this part allow surfact attachments to be passable?
                            if (PartHasPassableSurfaceAttachments(child))
                            {
                                childAttachmentIsPassable = true;
                                //Debug.Log("The child part is surface attached and is considered to be passable");
                            }
                        }
                    }
                }

                // So, is it possible to get from this part to the child part?
                if (attachmentIsPassable && childAttachmentIsPassable)
                {
                    // It is possible to pass between this part and the child part - so the child needs to be in the same space as this part.
                    //Debug.Log("The connection between 'this' part and the child part s passable in both directions, so the child part will be added to the same space as this part.");
                    spaceForChild = thisSpace;
                }
                else
                {
                    // it is not possible to get into the child part from this part - it will need to be in a new space.
                    //Debug.Log("The connection between 'this' part and the child part is NOT passable in both directions, so the child part will be added to a new space.");
                    spaceForChild = null;
                }

                // Having work out all the variables, make the recursive call
                ProcessPart(child, spaceForChild, dockingConnection);

                // Was the connection a docking connection - if so we ought to mark the relevant CLSParts
                if (dockingConnection || dockedToParent)
                {
                    newPart.SetDocked(true);
                }
            }
        }
        CLSSpace AddPartToSpace(CLSPart p, CLSSpace space)
        {
            //Debug.Log("AddPartToSpace " + ((Part)p).name);

            if (null != space)
            {
                space.AddPart(p);
            }
            else
            {
                Debug.LogError("Can't add part " + ((Part)p).partInfo.title +" to null space");
            }

            return space;
        }
        // A method that is called recursively to walk the part tree, and allocate parts to habitable spaces
        private void ProcessPart(Part p, CLSSpace currentSpace, bool dockedToParent = false)
        {
            CLSSpace thisSpace = null;
            CLSPart  newPart   = new CLSPart(p);

            //Debug.Log("Processing part: " + p.name + " Navigable:"+newPart.Navigable + " Habitable:" + newPart.Habitable);

            // First add this part to the list of all parts for the vessel.
            listParts.Add(newPart);

            // Is the part capable of allowing kerbals to pass? If it is add it to the current space, or if there is no current space, to a new space.
            if (newPart.Navigable || newPart.modCLS != null)
            {
                thisSpace = currentSpace;

                if (null == thisSpace)
                {
                    thisSpace = AddPartToNewSpace(newPart);
                }
                else
                {
                    thisSpace = AddPartToSpace(newPart, thisSpace);
                }
            }

            // Now loop through each of the part's children, consider if there is a navigable connection between them, and then make a recursive call.
            IEnumerator <Part> eChildren = p.children.GetEnumerator();

            while (eChildren.MoveNext())
            {
                if (eChildren.Current == null)
                {
                    continue;
                }
                // Get the attachment nodes
                AttachNode node                      = p.FindAttachNodeByPart(eChildren.Current);
                AttachNode childNode                 = eChildren.Current.FindAttachNodeByPart(p);
                bool       attachmentIsPassable      = false;
                bool       childAttachmentIsPassable = false;
                bool       dockingConnection         = false;
                CLSSpace   spaceForChild             = thisSpace;

                // TODO removed debugging
                //Debug.Log("Considering the connection between " + p.partInfo.title + "(" + p.uid + ") and " + child.partInfo.title + "(" + child.uid + ")");
                // Is the attachment on "this" part passable?
                if (null != node)
                {
                    // The attachment is in the form of an AttachNode - use it to work out if the attachment is passable.
                    attachmentIsPassable = IsNodeNavigable(node, p);
                    //Debug.Log("the attachment on 'this' part is defined by attachment node " + node.id + " and had been given passable=" + attachmentIsPassable);
                }
                else
                {
                    // Could it be that we are dealing with a docked connection?
                    dockingConnection = CheckForDockedPair(p, eChildren.Current);

                    if (true == dockingConnection)
                    {
                        //Debug.Log("The two parts are considered to be docked together.");
                        // The parts are docked, but we still need to have a think about if the docking port is passable.
                        attachmentIsPassable = IsDockedDockingPortPassable(p, eChildren.Current);
                        //Debug.Log("the docked attachment on 'this' part has been given passable=" + attachmentIsPassable);
                    }
                    else
                    {
                        //Debug.Log("The two parts are NOT considered to be docked together - concluding that this part is suface attached");
                        // It is not a AttachNode attachment, and it is not a docked connection either. The only other option is that we are dealing with a surface attachment. Does this part allow surfact attachments to be passable?
                        if (PartHasPassableSurfaceAttachments(p))
                        {
                            attachmentIsPassable = true;
                            //Debug.Log("This part is surface attached and is considered to be passable");
                        }
                    }
                }

                // Repeat the above block for the child part.
                {
                    // Is the attachment on "this" part passable?
                    if (null != childNode)
                    {
                        // The attachment is in the form of an AttachNode - use it to work out if the attachment is passable.
                        childAttachmentIsPassable = IsNodeNavigable(childNode, eChildren.Current);
                        //Debug.Log("the attachment on the child part is defined by attachment node " + childNode.id + " and had been given passable=" + attachmentIsPassable);
                    }
                    else
                    {
                        if (true == dockingConnection)
                        {
                            //Debug.Log("The two parts are considered to be docked together.");
                            // The parts are docked, but we still need to have a think about if the docking port is passable.
                            childAttachmentIsPassable = IsDockedDockingPortPassable(eChildren.Current, p);
                            //Debug.Log("the docked attachment on the child part has been given passable=" + attachmentIsPassable);
                        }
                        else
                        {
                            //Debug.Log("The two parts are NOT considered to be docked together - concluding that the child part is suface attached");
                            // It is not a AttachNode attachment, and it is not a docked connection either. The only other option is that we are dealing with a surface attachment. Does this part allow surfact attachments to be passable?
                            if (PartHasPassableSurfaceAttachments(eChildren.Current))
                            {
                                childAttachmentIsPassable = true;
                                //Debug.Log("The child part is surface attached and is considered to be passable");
                            }
                        }
                    }
                }

                // So, is it possible to get from this part to the child part?
                if (attachmentIsPassable && childAttachmentIsPassable)
                {
                    // It is possible to pass between this part and the child part - so the child needs to be in the same space as this part.
                    //Debug.Log("The connection between 'this' part and the child part s passable in both directions, so the child part will be added to the same space as this part.");
                    spaceForChild = thisSpace;
                }
                else
                {
                    // it is not possible to get into the child part from this part - it will need to be in a new space.
                    //Debug.Log("The connection between 'this' part and the child part is NOT passable in both directions, so the child part will be added to a new space.");
                    spaceForChild = null;
                }

                // Having work out all the variables, make the recursive call
                ProcessPart(eChildren.Current, spaceForChild, dockingConnection);

                // Was the connection a docking connection - if so we ought to mark the relevant CLSParts
                if (dockingConnection || dockedToParent)
                {
                    newPart.SetDocked(true);
                }
            }
        }
 public CLSKerbal(ProtoCrewMember k,CLSPart p)
 {
     this.kerbal = k;
     this.part = p;
 }
        internal void AddPart(CLSPart p)
        {
            // Add the part to the space, and the space to the part.
              p.Space = this;

              // If this space does not have a name, take the name from the part we just added.
              if ("" == name)
              {
            ModuleConnectedLivingSpace modCLS = (ModuleConnectedLivingSpace)p;

            if (null != modCLS)
            {
              name = modCLS.spaceName;
            }
              }

              parts.Add(p);

              maxCrew += ((Part)p).CrewCapacity;

              IEnumerator<ICLSKerbal> eCrew = p.Crew.GetEnumerator();
              while (eCrew.MoveNext())
              {
            if (eCrew.Current == null) continue;
            crew.Add((CLSKerbal)eCrew.Current);
              }
        }
 public CLSKerbal(ProtoCrewMember k, CLSPart p)
 {
     kerbal = k;
     part   = p;
 }
 internal void Clear()
 {
     this.kerbal = null;
     this.part   = null;
 }
 public CLSKerbal(ProtoCrewMember k, CLSPart p)
 {
     this.kerbal = k;
     this.part   = p;
 }
 internal void Clear()
 {
     this.kerbal = null;
     this.part = null;
 }
 internal void Clear()
 {
     kerbal = null;
     part   = null;
 }
 internal void Clear()
 {
     kerbal = null;
       part = null;
 }