// Throw away all potentially circular references in preparation this object to be thrown away
 internal void Clear()
 {
     this.space = null;
     foreach (CLSKerbal k in crew)
     {
         k.Clear();
     }
     this.crew.Clear();
 }
        CLSSpace AddPartToNewSpace(CLSPart p)
        {
            CLSSpace newSpace = new CLSSpace(this);

            listSpaces.Add(newSpace);

            newSpace.AddPart(p);

            return(newSpace);
        }
Exemple #3
0
        public bool highlighted; // This allows us to remember if a part is SUPPOSED to be highlighted by CLS. We can then use appropriate moments to ensure that it either is or is not.

        public CLSPart(Part p)
        {
            part = p;

            habitable = IsHabitable(part);
            navigable = IsNavigable(part);
            space     = null;

            crew = new List <ICLSKerbal>();
            IEnumerator <ProtoCrewMember> crewmembers = p.protoModuleCrew.GetEnumerator();

            while (crewmembers.MoveNext())
            {
                if (crewmembers.Current == null)
                {
                    continue;
                }
                CLSKerbal kerbal = new CLSKerbal(crewmembers.Current, this);
                crew.Add(kerbal);
            }
            crewmembers.Dispose();

            // Does the part have a CLSModule on it? If so then give the module a reference to ourselves to make its life a bit easier.
            {
                ModuleConnectedLivingSpace m = (ModuleConnectedLivingSpace)this;
                if (null != m)
                {
                    m.clsPart = this;
                }
                else
                {
                    // Do not bother logging warnings about EVAs not being configured for CLS!
                    if (part.Modules.OfType <KerbalEVA>().Count() == 0)
                    {
                        // This part does not have a CLSModule. If it is habitable or navigable then it will not be possible to persist the name of the space in the savefile. Log a warning.
                        if (habitable)
                        {
                            Debug.LogWarning($"Part {part.partInfo.title} is habitable but does not have ModuleConnectedLivingSpace defined in the config. It would be better if it did as some infomation used by CLS will not be saved in the savefile.");
                        }
                        else if (navigable)
                        {
                            Debug.LogWarning($"Part {part.partInfo.title} is passable but does not have ModuleConnectedLivingSpace defined in the config. It would be better if it did as some infomation used by CLS will not be saved in the savefile.");
                        }
                    }
                }
            }

            // Run check for dynamic crew capacity
            if (CLSAddon.dynamicCrewCapacity)
            {
                CheckDCC();
            }
        }
        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);
        }
Exemple #7
0
        // Throw away all potentially circular references in preparation this object to be thrown away
        internal void Clear()
        {
            space = null;
            IEnumerator <ICLSKerbal> eCrew = crew.GetEnumerator();

            while (eCrew.MoveNext())
            {
                if (eCrew.Current == null)
                {
                    continue;
                }
                ((CLSKerbal)eCrew.Current).Clear();
            }
            crew.Clear();
        }
Exemple #8
0
        // Throw away all potentially circular references in preparation this object to be thrown away
        internal void Clear()
        {
            space = null;
            Highlight(false);
            IEnumerator <ICLSKerbal> eCrew = crew.GetEnumerator();

            while (eCrew.MoveNext())
            {
                if (eCrew.Current == null)
                {
                    continue;
                }
                ((CLSKerbal)eCrew.Current).Clear();
            }
            eCrew.Dispose();
            crew.Clear();
        }
 public void MergeSpaces(ICLSSpace space1, ICLSSpace space2)
 {
     if (space1 == space2)
     {
         return;
     }
     if (listSpaces.Contains(space1) && listSpaces.Contains(space2))
     {
         CLSSpace        space1Real = space1 as CLSSpace;
         List <ICLSPart> partsToAdd = space2.Parts;
         for (int i = 0; i < partsToAdd.Count; i++)
         {
             space1Real.AddPart(partsToAdd[i] as CLSPart);
         }
         listSpaces.Remove(space2);
         // Probably should not fire in this method.
         // CLSAddon.onCLSVesselChange.Fire(space1Real.Parts[0].Part.vessel);
     }
 }
        public CLSPart(Part p)
        {
            part = p;

              habitable = IsHabitable(part);
              navigable = IsNavigable(part);
              space = null;

              crew = new List<ICLSKerbal>();
              IEnumerator<ProtoCrewMember> crewmembers = p.protoModuleCrew.GetEnumerator();
              while (crewmembers.MoveNext())
              {
            if (crewmembers.Current == null) continue;
            CLSKerbal kerbal = new CLSKerbal(crewmembers.Current, this);
            crew.Add(kerbal);
              }

              // Does the part have a CLSModule on it? If so then give the module a reference to ourselves to make its life a bit easier.
              {
            ModuleConnectedLivingSpace m = (ModuleConnectedLivingSpace)this;
            if (null != m)
            {
              m.clsPart = this;
            }
            else
            {
              // Do not bother logging warnings about EVAs not being configured for CLS!
              if (part.Modules.OfType<KerbalEVA>().Count() == 0)
              {
            // This part does not have a CLSModule. If it is habitable or navigable then it will not be possible to persist the name of the space in the savefile. Log a warning.
            if (habitable)
            {
              Debug.LogWarning("Part " + part.partInfo.title + " is habitable but does not have ModuleConnectedLivingSpace defined in the config. It would be better if it did as some infomation used by CLS will not be saved in the savefile.");
            }
            else if (navigable)
            {
              Debug.LogWarning("Part " + part.partInfo.title + " is passable but does not have ModuleConnectedLivingSpace defined in the config. It would be better if it did as some infomation used by CLS will not be saved in the savefile.");
            }
              }
            }
              }
        }
        bool highlighted = false; // This allows us to remember if a part is SUPPOSED to be highlighted by CLS. We can then use appropriate moments to ensure that it either is or is not.

        public CLSPart(Part p)
        {
            this.part = p;

            habitable = IsHabitable(this.part);
            navigable = IsNavigable(this.part);
            space     = null;

            this.crew = new List <ICLSKerbal>();
            foreach (ProtoCrewMember crewMember in p.protoModuleCrew)
            {
                CLSKerbal kerbal = new CLSKerbal(crewMember, this);
                this.crew.Add(kerbal);
            }

            // Does the part have a CLSModule on it? If so then give the module a reference to ourselves to make its life a bit easier.
            {
                ModuleConnectedLivingSpace m = (ModuleConnectedLivingSpace)this;
                if (null != m)
                {
                    m.clsPart = this;
                }
                else
                {
                    // Do not bother logging warnings about EVAs not being configured for CLS!
                    if (this.part.Modules.OfType <KerbalEVA>().Count() == 0)
                    {
                        // This part does not have a CLSModule. If it is habitable or navigable then it will not be possible to persist the name of the space in the savefile. Log a warning.
                        if (this.habitable)
                        {
                            Debug.LogWarning("Part " + this.part.partInfo.title + " is habitable but does not have ModuleConnectedLivingSpace defined in the config. It would be better if it did as some infomation used by CLS will not be saved in the savefile.");
                        }
                        else if (this.navigable)
                        {
                            Debug.LogWarning("Part " + this.part.partInfo.title + " is passable but does not have ModuleConnectedLivingSpace defined in the config. It would be better if it did as some infomation used by CLS will not be saved in the savefile.");
                        }
                    }
                }
            }
        }
        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;
        }
 // Throw away all potentially circular references in preparation this object to be thrown away
 internal void Clear()
 {
     this.space = null;
     foreach (CLSKerbal k in crew)
     {
         k.Clear();
     }
     this.crew.Clear();
 }
 // Throw away all potentially circular references in preparation this object to be thrown away
 internal void Clear()
 {
     space = null;
       IEnumerator<ICLSKerbal> eCrew = crew.GetEnumerator();
       while (eCrew.MoveNext())
       {
     if (eCrew.Current == null) continue;
     ((CLSKerbal)eCrew.Current).Clear();
       }
       crew.Clear();
 }
        // 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);
                }
            }
        }