private void CalculateContiguousGroups()
        {
            WorldFloodFiller worldFloodFiller = Find.WorldFloodFiller;
            WorldGrid        worldGrid        = Find.WorldGrid;
            int minRootGroupSize       = MinRootGroupSize;
            int maxRootGroupSize       = MaxRootGroupSize;
            int minOverallSize         = MinOverallSize;
            int maxOverallSize         = MaxOverallSize;
            int minRootGroupsInCluster = MinRootGroupsInCluster;

            FeatureWorker.ClearVisited();
            FeatureWorker.ClearGroupSizes();
            FeatureWorker.ClearGroupIDs();
            for (int i = 0; i < roots.Count; i++)
            {
                int num = roots[i];
                if (FeatureWorker.visited[num])
                {
                    continue;
                }
                bool anyMember = false;
                tmpGroup.Clear();
                worldFloodFiller.FloodFill(num, (int x) => rootsSet.Contains(x), delegate(int x)
                {
                    FeatureWorker.visited[x] = true;
                    tmpGroup.Add(x);
                    if (!anyMember && IsMember(x, out var _))
                    {
                        anyMember = true;
                    }
                });
                for (int j = 0; j < tmpGroup.Count; j++)
                {
                    FeatureWorker.groupSize[tmpGroup[j]] = tmpGroup.Count;
                    if (anyMember)
                    {
                        FeatureWorker.groupID[tmpGroup[j]] = i + 1;
                    }
                }
            }
            FeatureWorker.ClearVisited();
            for (int k = 0; k < roots.Count; k++)
            {
                int num2 = roots[k];
                if (FeatureWorker.visited[num2] || FeatureWorker.groupSize[num2] < minRootGroupSize || FeatureWorker.groupSize[num2] > maxRootGroupSize || FeatureWorker.groupSize[num2] > maxOverallSize)
                {
                    continue;
                }
                currentGroup.Clear();
                visitedValidGroupIDs.Clear();
                worldFloodFiller.FloodFill(num2, delegate(int x)
                {
                    if (!rootsWithAreaInBetweenSet.Contains(x))
                    {
                        return(false);
                    }
                    if (!CanTraverse(x, out var ifRootThenRootGroupSizeMustMatch2))
                    {
                        return(false);
                    }
                    return((!ifRootThenRootGroupSizeMustMatch2 || !rootsSet.Contains(x) || (FeatureWorker.groupSize[x] >= minRootGroupSize && FeatureWorker.groupSize[x] <= maxRootGroupSize)) ? true : false);
                }, delegate(int x)
                {
                    FeatureWorker.visited[x] = true;
                    currentGroup.Add(x);
                    if (FeatureWorker.groupID[x] != 0 && FeatureWorker.groupSize[x] >= minRootGroupSize && FeatureWorker.groupSize[x] <= maxRootGroupSize)
                    {
                        visitedValidGroupIDs.Add(FeatureWorker.groupID[x]);
                    }
                });
                if (currentGroup.Count < minOverallSize || currentGroup.Count > maxOverallSize || visitedValidGroupIDs.Count < minRootGroupsInCluster || (!def.canTouchWorldEdge && currentGroup.Any((int x) => worldGrid.IsOnEdge(x))))
                {
                    continue;
                }
                currentGroupMembers.Clear();
                for (int l = 0; l < currentGroup.Count; l++)
                {
                    int num3 = currentGroup[l];
                    if (IsMember(num3, out var ifRootThenRootGroupSizeMustMatch) && (!ifRootThenRootGroupSizeMustMatch || !rootsSet.Contains(num3) || (FeatureWorker.groupSize[num3] >= minRootGroupSize && FeatureWorker.groupSize[num3] <= maxRootGroupSize)))
                    {
                        currentGroupMembers.Add(currentGroup[l]);
                    }
                }
                if (currentGroupMembers.Count < minOverallSize)
                {
                    continue;
                }
                if (currentGroup.Any((int x) => worldGrid[x].feature == null))
                {
                    currentGroup.RemoveAll((int x) => worldGrid[x].feature != null);
                }
                AddFeature(currentGroupMembers, currentGroup);
            }
        }
示例#2
0
        private void CalculateContiguousGroups()
        {
            WorldFloodFiller worldFloodFiller = Find.WorldFloodFiller;
            WorldGrid        worldGrid        = Find.WorldGrid;
            int minRootGroupSize       = this.MinRootGroupSize;
            int maxRootGroupSize       = this.MaxRootGroupSize;
            int minOverallSize         = this.MinOverallSize;
            int maxOverallSize         = this.MaxOverallSize;
            int minRootGroupsInCluster = this.MinRootGroupsInCluster;

            FeatureWorker.ClearVisited();
            FeatureWorker.ClearGroupSizes();
            FeatureWorker.ClearGroupIDs();
            for (int i = 0; i < this.roots.Count; i++)
            {
                int num = this.roots[i];
                if (!FeatureWorker.visited[num])
                {
                    bool anyMember = false;
                    FeatureWorker_Cluster.tmpGroup.Clear();
                    worldFloodFiller.FloodFill(num, (int x) => this.rootsSet.Contains(x), delegate(int x)
                    {
                        FeatureWorker.visited[x] = true;
                        FeatureWorker_Cluster.tmpGroup.Add(x);
                        bool flag2;
                        if (!anyMember && this.IsMember(x, out flag2))
                        {
                            anyMember = true;
                        }
                    }, int.MaxValue, null);
                    for (int j = 0; j < FeatureWorker_Cluster.tmpGroup.Count; j++)
                    {
                        FeatureWorker.groupSize[FeatureWorker_Cluster.tmpGroup[j]] = FeatureWorker_Cluster.tmpGroup.Count;
                        if (anyMember)
                        {
                            FeatureWorker.groupID[FeatureWorker_Cluster.tmpGroup[j]] = i + 1;
                        }
                    }
                }
            }
            FeatureWorker.ClearVisited();
            for (int k = 0; k < this.roots.Count; k++)
            {
                int num2 = this.roots[k];
                if (!FeatureWorker.visited[num2])
                {
                    if (FeatureWorker.groupSize[num2] >= minRootGroupSize && FeatureWorker.groupSize[num2] <= maxRootGroupSize)
                    {
                        if (FeatureWorker.groupSize[num2] <= maxOverallSize)
                        {
                            this.currentGroup.Clear();
                            this.visitedValidGroupIDs.Clear();
                            worldFloodFiller.FloodFill(num2, delegate(int x)
                            {
                                bool flag2;
                                return(this.rootsWithAreaInBetweenSet.Contains(x) && this.CanTraverse(x, out flag2) && (!flag2 || !this.rootsSet.Contains(x) || (FeatureWorker.groupSize[x] >= minRootGroupSize && FeatureWorker.groupSize[x] <= maxRootGroupSize)));
                            }, delegate(int x)
                            {
                                FeatureWorker.visited[x] = true;
                                this.currentGroup.Add(x);
                                if (FeatureWorker.groupID[x] != 0 && FeatureWorker.groupSize[x] >= minRootGroupSize && FeatureWorker.groupSize[x] <= maxRootGroupSize)
                                {
                                    this.visitedValidGroupIDs.Add(FeatureWorker.groupID[x]);
                                }
                            }, int.MaxValue, null);
                            if (this.currentGroup.Count >= minOverallSize && this.currentGroup.Count <= maxOverallSize)
                            {
                                if (this.visitedValidGroupIDs.Count >= minRootGroupsInCluster)
                                {
                                    if (this.def.canTouchWorldEdge || !this.currentGroup.Any((int x) => worldGrid.IsOnEdge(x)))
                                    {
                                        this.currentGroupMembers.Clear();
                                        for (int l = 0; l < this.currentGroup.Count; l++)
                                        {
                                            int  num3 = this.currentGroup[l];
                                            bool flag;
                                            if (this.IsMember(num3, out flag))
                                            {
                                                if (!flag || !this.rootsSet.Contains(num3) || (FeatureWorker.groupSize[num3] >= minRootGroupSize && FeatureWorker.groupSize[num3] <= maxRootGroupSize))
                                                {
                                                    this.currentGroupMembers.Add(this.currentGroup[l]);
                                                }
                                            }
                                        }
                                        if (this.currentGroupMembers.Count >= minOverallSize)
                                        {
                                            if (this.currentGroup.Any((int x) => worldGrid[x].feature == null))
                                            {
                                                this.currentGroup.RemoveAll((int x) => worldGrid[x].feature != null);
                                            }
                                            base.AddFeature(this.currentGroupMembers, this.currentGroup);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }