Engineer.VesselSimulator.PartSim.GetSourceSet C# (CSharp) Method

GetSourceSet() public method

public GetSourceSet ( int type, List allParts, HashSet visited, LogMsg log, String indent ) : HashSet
type int
allParts List
visited HashSet
log LogMsg
indent String
return HashSet
        public HashSet<PartSim> GetSourceSet(int type, List<PartSim> allParts, HashSet<PartSim> visited, LogMsg log, String indent)
        {
            if (log != null)
            {
                log.buf.AppendLine(indent + "GetSourceSet(" + ResourceContainer.GetResourceName(type) + ") for " + name + ":" + partId);
                indent += "  ";
            }

            HashSet<PartSim> allSources = new HashSet<PartSim>();
            HashSet<PartSim> partSources = null;

            // Rule 1: Each part can be only visited once, If it is visited for second time in particular search it returns empty list.
            if (visited.Contains(this))
            {
                if (log != null)
                    log.buf.AppendLine(indent + "Returning empty set, already visited (" + name + ":" + partId + ")");

                return allSources;
            }

            //if (log != null)
            //    log.buf.AppendLine(indent + "Adding this to visited");

            visited.Add(this);

            // Rule 2: Part performs scan on start of every fuel pipe ending in it. This scan is done in order in which pipes were installed.
            // Then it makes an union of fuel tank sets each pipe scan returned. If the resulting list is not empty, it is returned as result.
            //MonoBehaviour.print("foreach fuel line");

            foreach (PartSim partSim in fuelTargets)
            {
                if (visited.Contains(partSim))
                {
                    //if (log != null)
                    //    log.buf.AppendLine(indent + "Fuel target already visited, skipping (" + partSim.name + ":" + partSim.partId + ")");
                }
                else
                {
                    //if (log != null)
                    //    log.buf.AppendLine(indent + "Adding fuel target as source (" + partSim.name + ":" + partSim.partId + ")");

                    partSources = partSim.GetSourceSet(type, allParts, visited, log, indent);
                    if (partSources.Count > 0)
                    {
                        allSources.UnionWith(partSources);
                        partSources.Clear();
                    }
                }
            }

            if (allSources.Count > 0)
            {
                if (log != null)
                    log.buf.AppendLine(indent + "Returning " + allSources.Count + " fuel target sources (" + name + ":" + partId + ")");

                return allSources;
            }

            // Rule 3: This rule has been removed and merged with rules 4 and 7 to fix issue with fuel tanks with disabled crossfeed

            // Rule 4: Part performs scan on each of its axially mounted neighbors.
            //  Couplers (bicoupler, tricoupler, ...) are an exception, they only scan one attach point on the single attachment side,
            //  skip the points on the side where multiple points are. [Experiment]
            //  Again, the part creates union of scan lists from each of its neighbor and if it is not empty, returns this list.
            //  The order in which mount points of a part are scanned appears to be fixed and defined by the part specification file. [Experiment]
            if (fuelCrossFeed)
            {
                //MonoBehaviour.print("foreach attach node");
                foreach (AttachNodeSim attachSim in attachNodes)
                {
                    if (attachSim.attachedPartSim != null)
                    {
                        if (attachSim.nodeType == AttachNode.NodeType.Stack)
                        {
                            if (!(noCrossFeedNodeKey != null && noCrossFeedNodeKey.Length > 0 && attachSim.id.Contains(noCrossFeedNodeKey)))
                            {
                                if (visited.Contains(attachSim.attachedPartSim))
                                {
                                    //if (log != null)
                                    //    log.buf.AppendLine(indent + "Attached part already visited, skipping (" + attachSim.attachedPartSim.name + ":" + attachSim.attachedPartSim.partId + ")");
                                }
                                else
                                {
                                    //if (log != null)
                                    //    log.buf.AppendLine(indent + "Adding attached part as source (" + attachSim.attachedPartSim.name + ":" + attachSim.attachedPartSim.partId + ")");

                                    partSources = attachSim.attachedPartSim.GetSourceSet(type, allParts, visited, log, indent);
                                    if (partSources.Count > 0)
                                    {
                                        allSources.UnionWith(partSources);
                                        partSources.Clear();
                                    }
                                }
                            }
                            else
                            {
                                //if (log != null)
                                //    log.buf.AppendLine(indent + "AttachNode is noCrossFeedKey, skipping (" + attachSim.attachedPartSim.name + ":" + attachSim.attachedPartSim.partId + ")");
                            }
                        }
                        else
                        {
                            //if (log != null)
                            //    log.buf.AppendLine(indent + "AttachNode is not NodeType.Stack, skipping (" + attachSim.attachedPartSim.name + ":" + attachSim.attachedPartSim.partId + ")");
                        }
                    }
                }

                if (allSources.Count > 0)
                {
                    if (log != null)
                        log.buf.AppendLine(indent + "Returning " + allSources.Count + " attached sources (" + name + ":" + partId + ")");

                    return allSources;
                }
            }
            else
            {
                //if (log != null)
                //    log.buf.AppendLine(indent + "Crossfeed disabled, skipping axial connected parts (" + name + ":" + partId + ")");
            }

            // Rule 5: If the part is fuel container for searched type of fuel (i.e. it has capability to contain that type of fuel and the fuel
            // type was not disabled [Experiment]) and it contains fuel, it returns itself.
            // Rule 6: If the part is fuel container for searched type of fuel (i.e. it has capability to contain that type of fuel and the fuel
            // type was not disabled) but it does not contain the requested fuel, it returns empty list. [Experiment]
            if (resources.HasType(type) && resourceFlowStates[type] != 0)
            {
                if (resources[type] > SimManager.RESOURCE_MIN)
                {
                    allSources.Add(this);

                    if (log != null)
                        log.buf.AppendLine(indent + "Returning enabled tank as only source (" + name + ":" + partId + ")");
                }
                else
                {
                    //if (log != null)
                    //    log.buf.AppendLine(indent + "Returning empty set, enabled tank is empty (" + name + ":" + partId + ")");
                }

                return allSources;
            }

            // Rule 7: If the part is radially attached to another part and it is child of that part in the ship's tree structure, it scans its
            // parent and returns whatever the parent scan returned. [Experiment] [Experiment]
            if (parent != null && parentAttach == AttachModes.SRF_ATTACH)
            {
                if (fuelCrossFeed)
                {
                    if (visited.Contains(parent))
                    {
                        //if (log != null)
                        //    log.buf.AppendLine(indent + "Parent part already visited, skipping (" + parent.name + ":" + parent.partId + ")");
                    }
                    else
                    {
                        allSources = parent.GetSourceSet(type, allParts, visited, log, indent);
                        if (allSources.Count > 0)
                        {
                            if (log != null)
                                log.buf.AppendLine(indent + "Returning " + allSources.Count + " parent sources (" + name + ":" + partId + ")");

                            return allSources;
                        }
                    }
                }
                else
                {
                    //if (log != null)
                    //    log.buf.AppendLine(indent + "Crossfeed disabled, skipping radial parent (" + name + ":" + partId + ")");
                }
            }

            // Rule 8: If all preceding rules failed, part returns empty list.
            //if (log != null)
            //    log.buf.AppendLine(indent + "Returning empty set, no sources found (" + name + ":" + partId + ")");

            return allSources;
        }

Usage Example

Ejemplo n.º 1
0
        // All functions below this point must not rely on the part member (it may be null)
        //

        public HashSet <PartSim> GetSourceSet(int type, List <PartSim> allParts, HashSet <PartSim> visited, LogMsg log, String indent)
        {
            if (log != null)
            {
                log.buf.AppendLine(indent + "GetSourceSet(" + ResourceContainer.GetResourceName(type) + ") for " + name + ":" + partId);
                indent += "  ";
            }

            HashSet <PartSim> allSources  = new HashSet <PartSim>();
            HashSet <PartSim> partSources = null;

            // Rule 1: Each part can be only visited once, If it is visited for second time in particular search it returns empty list.
            if (visited.Contains(this))
            {
                if (log != null)
                {
                    log.buf.AppendLine(indent + "Returning empty set, already visited (" + name + ":" + partId + ")");
                }

                return(allSources);
            }

            //if (log != null)
            //    log.buf.AppendLine(indent + "Adding this to visited");

            visited.Add(this);

            // Rule 2: Part performs scan on start of every fuel pipe ending in it. This scan is done in order in which pipes were installed. Then it makes an union of fuel tank sets each pipe scan returned. If the resulting list is not empty, it is returned as result.
            //MonoBehaviour.print("foreach fuel line");

            foreach (PartSim partSim in fuelTargets)
            {
                if (visited.Contains(partSim))
                {
                    //if (log != null)
                    //    log.buf.AppendLine(indent + "Fuel target already visited, skipping (" + partSim.name + ":" + partSim.partId + ")");
                }
                else
                {
                    //if (log != null)
                    //    log.buf.AppendLine(indent + "Adding fuel target as source (" + partSim.name + ":" + partSim.partId + ")");

                    partSources = partSim.GetSourceSet(type, allParts, visited, log, indent);
                    if (partSources.Count > 0)
                    {
                        allSources.UnionWith(partSources);
                        partSources.Clear();
                    }
                }
            }

            if (allSources.Count > 0)
            {
                if (log != null)
                {
                    log.buf.AppendLine(indent + "Returning " + allSources.Count + " fuel target sources (" + name + ":" + partId + ")");
                }

                return(allSources);
            }

            // Rule 3: This rule has been removed and merged with rules 4 and 7 to fix issue with fuel tanks with disabled crossfeed

            // Rule 4: Part performs scan on each of its axially mounted neighbors.
            //  Couplers (bicoupler, tricoupler, ...) are an exception, they only scan one attach point on the single attachment side, skip the points on the side where multiple points are. [Experiment]
            //  Again, the part creates union of scan lists from each of its neighbor and if it is not empty, returns this list.
            //  The order in which mount points of a part are scanned appears to be fixed and defined by the part specification file. [Experiment]
            if (fuelCrossFeed)
            {
                //MonoBehaviour.print("foreach attach node");
                foreach (AttachNodeSim attachSim in attachNodes)
                {
                    if (attachSim.attachedPartSim != null)
                    {
                        if (/*attachSim.nodeType != AttachNode.NodeType.Surface &&*/
                            !(noCrossFeedNodeKey != null && noCrossFeedNodeKey.Length > 0 && attachSim.id.Contains(noCrossFeedNodeKey)))
                        {
                            if (visited.Contains(attachSim.attachedPartSim))
                            {
                                //if (log != null)
                                //    log.buf.AppendLine(indent + "Attached part already visited, skipping (" + attachSim.attachedPartSim.name + ":" + attachSim.attachedPartSim.partId + ")");
                            }
                            else
                            {
                                //if (log != null)
                                //    log.buf.AppendLine(indent + "Adding attached part as source (" + attachSim.attachedPartSim.name + ":" + attachSim.attachedPartSim.partId + ")");

                                partSources = attachSim.attachedPartSim.GetSourceSet(type, allParts, visited, log, indent);
                                if (partSources.Count > 0)
                                {
                                    allSources.UnionWith(partSources);
                                    partSources.Clear();
                                }
                            }
                        }
                        else
                        {
                            //if (log != null)
                            //    log.buf.AppendLine(indent + "AttachNode is noCrossFeedKey, skipping (" + attachSim.attachedPartSim.name + ":" + attachSim.attachedPartSim.partId + ")");
                        }
                    }
                }

                if (allSources.Count > 0)
                {
                    if (log != null)
                    {
                        log.buf.AppendLine(indent + "Returning " + allSources.Count + " attached sources (" + name + ":" + partId + ")");
                    }

                    return(allSources);
                }
            }
            else
            {
                //if (log != null)
                //    log.buf.AppendLine(indent + "Crossfeed disabled, skipping axial connected parts (" + name + ":" + partId + ")");
            }

            // Rule 5: If the part is fuel container for searched type of fuel (i.e. it has capability to contain that type of fuel and the fuel type was not disabled [Experiment]) and it contains fuel, it returns itself.
            // Rule 6: If the part is fuel container for searched type of fuel (i.e. it has capability to contain that type of fuel and the fuel type was not disabled) but it does not contain the requested fuel, it returns empty list. [Experiment]
            if (resources.HasType(type) && resourceFlowStates[type] != 0)
            {
                if (resources[type] > SimManager.RESOURCE_MIN)
                {
                    allSources.Add(this);

                    if (log != null)
                    {
                        log.buf.AppendLine(indent + "Returning enabled tank as only source (" + name + ":" + partId + ")");
                    }
                }
                else
                {
                    //if (log != null)
                    //    log.buf.AppendLine(indent + "Returning empty set, enabled tank is empty (" + name + ":" + partId + ")");
                }

                return(allSources);
            }

            // Rule 7: If the part is radially attached to another part and it is child of that part in the ship's tree structure, it scans its parent and returns whatever the parent scan returned. [Experiment] [Experiment]
            if (parent != null)
            {
                if (fuelCrossFeed)
                {
                    if (visited.Contains(parent))
                    {
                        //if (log != null)
                        //    log.buf.AppendLine(indent + "Parent part already visited, skipping (" + parent.name + ":" + parent.partId + ")");
                    }
                    else
                    {
                        allSources = parent.GetSourceSet(type, allParts, visited, log, indent);
                        if (allSources.Count > 0)
                        {
                            if (log != null)
                            {
                                log.buf.AppendLine(indent + "Returning " + allSources.Count + " parent sources (" + name + ":" + partId + ")");
                            }

                            return(allSources);
                        }
                    }
                }
                else
                {
                    //if (log != null)
                    //    log.buf.AppendLine(indent + "Crossfeed disabled, skipping radial parent (" + name + ":" + partId + ")");
                }
            }

            // Rule 8: If all preceding rules failed, part returns empty list.
            //if (log != null)
            //    log.buf.AppendLine(indent + "Returning empty set, no sources found (" + name + ":" + partId + ")");

            return(allSources);
        }
All Usage Examples Of Engineer.VesselSimulator.PartSim::GetSourceSet