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); } }
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); } } } } } } } } }