Ejemplo n.º 1
0
        public static void Dilate(List <int> tiles, int count, Predicate <int> extraPredicate = null)
        {
            if (count <= 0)
            {
                return;
            }
            WorldFloodFiller arg_6D_0 = Find.WorldFloodFiller;
            int             rootTile  = -1;
            Predicate <int> arg_4D_0  = extraPredicate;

            if (extraPredicate == null)
            {
                arg_4D_0 = ((int x) => true);
            }
            Predicate <int>       passCheck = arg_4D_0;
            Func <int, int, bool> processor = delegate(int tile, int traversalDist)
            {
                if (traversalDist > count)
                {
                    return(true);
                }
                if (traversalDist != 0)
                {
                    tiles.Add(tile);
                }
                return(false);
            };
            List <int> tiles2 = tiles;

            arg_6D_0.FloodFill(rootTile, passCheck, processor, 2147483647, tiles2);
        }
        public override void GenerateWhereAppropriate()
        {
            WorldGrid worldGrid  = Find.WorldGrid;
            int       tilesCount = worldGrid.TilesCount;

            this.edgeTiles.Clear();
            for (int i = 0; i < tilesCount; i++)
            {
                if (this.IsRoot(i))
                {
                    this.edgeTiles.Add(i);
                }
            }
            if (this.edgeTiles.Any <int>())
            {
                this.group.Clear();
                WorldFloodFiller worldFloodFiller = Find.WorldFloodFiller;
                int                   rootTile    = -1;
                Predicate <int>       passCheck   = (int x) => this.CanTraverse(x);
                Func <int, int, bool> processor   = delegate(int tile, int traversalDist)
                {
                    this.group.Add(tile);
                    return(false);
                };
                List <int> extraRootTiles = this.edgeTiles;
                worldFloodFiller.FloodFill(rootTile, passCheck, processor, int.MaxValue, extraRootTiles);
                this.group.RemoveAll((int x) => worldGrid[x].feature != null);
                if (this.group.Count >= this.def.minSize && this.group.Count <= this.def.maxSize)
                {
                    base.AddFeature(this.group, this.group);
                }
            }
        }
        public static void Dilate(List <int> tiles, int count, Predicate <int> extraPredicate = null)
        {
            if (count <= 0)
            {
                return;
            }
            WorldFloodFiller worldFloodFiller = Find.WorldFloodFiller;
            int             rootTile          = -1;
            Predicate <int> predicate         = extraPredicate;

            if (extraPredicate == null)
            {
                predicate = ((int x) => true);
            }
            Predicate <int>       passCheck = predicate;
            Func <int, int, bool> processor = delegate(int tile, int traversalDist)
            {
                if (traversalDist > count)
                {
                    return(true);
                }
                if (traversalDist != 0)
                {
                    tiles.Add(tile);
                }
                return(false);
            };
            List <int> tiles2 = tiles;

            worldFloodFiller.FloodFill(rootTile, passCheck, processor, int.MaxValue, tiles2);
        }
Ejemplo n.º 4
0
        public override void GenerateWhereAppropriate()
        {
            WorldGrid worldGrid  = Find.WorldGrid;
            int       tilesCount = worldGrid.TilesCount;

            edgeTiles.Clear();
            for (int i = 0; i < tilesCount; i++)
            {
                if (IsRoot(i))
                {
                    edgeTiles.Add(i);
                }
            }
            if (edgeTiles.Any())
            {
                group.Clear();
                WorldFloodFiller worldFloodFiller = Find.WorldFloodFiller;
                int                   rootTile    = -1;
                Predicate <int>       passCheck   = (int x) => CanTraverse(x);
                Func <int, int, bool> processor   = delegate(int tile, int traversalDist)
                {
                    group.Add(tile);
                    return(false);
                };
                List <int> extraRootTiles = edgeTiles;
                worldFloodFiller.FloodFill(rootTile, passCheck, processor, 2147483647, extraRootTiles);
                group.RemoveAll((int x) => worldGrid[x].feature != null);
                if (group.Count >= def.minSize && group.Count <= def.maxSize)
                {
                    AddFeature(group, group);
                }
            }
        }
Ejemplo n.º 5
0
        public static void Erode(List <int> tiles, int count, Predicate <int> extraPredicate = null)
        {
            if (count <= 0)
            {
                return;
            }
            WorldGrid worldGrid = Find.WorldGrid;

            GenPlanetMorphology.tilesSet.Clear();
            GenPlanetMorphology.tilesSet.AddRange(tiles);
            GenPlanetMorphology.tmpEdgeTiles.Clear();
            for (int i = 0; i < tiles.Count; i++)
            {
                worldGrid.GetTileNeighbors(tiles[i], GenPlanetMorphology.tmpNeighbors);
                for (int j = 0; j < GenPlanetMorphology.tmpNeighbors.Count; j++)
                {
                    if (!GenPlanetMorphology.tilesSet.Contains(GenPlanetMorphology.tmpNeighbors[j]))
                    {
                        GenPlanetMorphology.tmpEdgeTiles.Add(tiles[i]);
                        break;
                    }
                }
            }
            if (!GenPlanetMorphology.tmpEdgeTiles.Any <int>())
            {
                return;
            }
            GenPlanetMorphology.tmpOutput.Clear();
            Predicate <int> predicate;

            if (extraPredicate != null)
            {
                predicate = ((int x) => GenPlanetMorphology.tilesSet.Contains(x) && extraPredicate(x));
            }
            else
            {
                predicate = ((int x) => GenPlanetMorphology.tilesSet.Contains(x));
            }
            WorldFloodFiller arg_13F_0      = Find.WorldFloodFiller;
            int                   rootTile  = -1;
            Predicate <int>       passCheck = predicate;
            Func <int, int, bool> processor = delegate(int tile, int traversalDist)
            {
                if (traversalDist >= count)
                {
                    GenPlanetMorphology.tmpOutput.Add(tile);
                }
                return(false);
            };
            List <int> extraRootTiles = GenPlanetMorphology.tmpEdgeTiles;

            arg_13F_0.FloodFill(rootTile, passCheck, processor, 2147483647, extraRootTiles);
            tiles.Clear();
            tiles.AddRange(GenPlanetMorphology.tmpOutput);
        }
 public static void Erode(List <int> tiles, int count, Predicate <int> extraPredicate = null)
 {
     if (count > 0)
     {
         WorldGrid worldGrid = Find.WorldGrid;
         GenPlanetMorphology.tilesSet.Clear();
         GenPlanetMorphology.tilesSet.AddRange(tiles);
         GenPlanetMorphology.tmpEdgeTiles.Clear();
         for (int i = 0; i < tiles.Count; i++)
         {
             worldGrid.GetTileNeighbors(tiles[i], GenPlanetMorphology.tmpNeighbors);
             int num = 0;
             while (num < GenPlanetMorphology.tmpNeighbors.Count)
             {
                 if (GenPlanetMorphology.tilesSet.Contains(GenPlanetMorphology.tmpNeighbors[num]))
                 {
                     num++;
                     continue;
                 }
                 GenPlanetMorphology.tmpEdgeTiles.Add(tiles[i]);
                 break;
             }
         }
         if (GenPlanetMorphology.tmpEdgeTiles.Any())
         {
             GenPlanetMorphology.tmpOutput.Clear();
             Predicate <int>  predicate        = (extraPredicate == null) ? ((Predicate <int>)((int x) => GenPlanetMorphology.tilesSet.Contains(x))) : ((Predicate <int>)((int x) => GenPlanetMorphology.tilesSet.Contains(x) && extraPredicate(x)));
             WorldFloodFiller worldFloodFiller = Find.WorldFloodFiller;
             int                   rootTile    = -1;
             Predicate <int>       passCheck   = predicate;
             Func <int, int, bool> processor   = delegate(int tile, int traversalDist)
             {
                 if (traversalDist >= count)
                 {
                     GenPlanetMorphology.tmpOutput.Add(tile);
                 }
                 return(false);
             };
             List <int> extraRootTiles = GenPlanetMorphology.tmpEdgeTiles;
             worldFloodFiller.FloodFill(rootTile, passCheck, processor, 2147483647, extraRootTiles);
             tiles.Clear();
             tiles.AddRange(GenPlanetMorphology.tmpOutput);
         }
     }
 }
Ejemplo n.º 7
0
 public void ConstructComponents()
 {
     worldObjects         = new WorldObjectsHolder();
     factionManager       = new FactionManager();
     worldPawns           = new WorldPawns();
     gameConditionManager = new GameConditionManager(this);
     storyState           = new StoryState(this);
     renderer             = new WorldRenderer();
     UI                 = new WorldInterface();
     debugDrawer        = new WorldDebugDrawer();
     dynamicDrawManager = new WorldDynamicDrawManager();
     pathFinder         = new WorldPathFinder();
     pathPool           = new WorldPathPool();
     reachability       = new WorldReachability();
     floodFiller        = new WorldFloodFiller();
     ticksAbsCache      = new ConfiguredTicksAbsAtGameStartCache();
     components.Clear();
     FillComponents();
 }
Ejemplo n.º 8
0
 public void ConstructComponents()
 {
     this.worldObjects         = new WorldObjectsHolder();
     this.factionManager       = new FactionManager();
     this.uniqueIDsManager     = new UniqueIDsManager();
     this.worldPawns           = new WorldPawns();
     this.settings             = new WorldSettings();
     this.gameConditionManager = new GameConditionManager(null);
     this.storyState           = new StoryState(this);
     this.renderer             = new WorldRenderer();
     this.UI                 = new WorldInterface();
     this.debugDrawer        = new WorldDebugDrawer();
     this.dynamicDrawManager = new WorldDynamicDrawManager();
     this.pathFinder         = new WorldPathFinder();
     this.pathPool           = new WorldPathPool();
     this.reachability       = new WorldReachability();
     this.floodFiller        = new WorldFloodFiller();
     this.ticksAbsCache      = new ConfiguredTicksAbsAtGameStartCache();
     this.components.Clear();
     this.FillComponents();
 }
Ejemplo n.º 9
0
 public static void Dilate(List <int> tiles, int count, Predicate <int> extraPredicate = null)
 {
     if (count > 0)
     {
         WorldFloodFiller worldFloodFiller = Find.WorldFloodFiller;
         int                   rootTile    = -1;
         Predicate <int>       passCheck   = extraPredicate ?? ((Predicate <int>)((int x) => true));
         Func <int, int, bool> processor   = delegate(int tile, int traversalDist)
         {
             if (traversalDist > count)
             {
                 return(true);
             }
             if (traversalDist != 0)
             {
                 tiles.Add(tile);
             }
             return(false);
         };
         List <int> extraRootTiles = tiles;
         worldFloodFiller.FloodFill(rootTile, passCheck, processor, 2147483647, extraRootTiles);
     }
 }
        private void CalculateContiguousGroups()
        {
            WorldGrid        worldGrid        = Find.WorldGrid;
            WorldFloodFiller worldFloodFiller = Find.WorldFloodFiller;
            int   minSize           = this.MinSize;
            int   maxSize           = this.MaxSize;
            float maxPctOfWholeArea = this.MaxPctOfWholeArea;
            int   maxPassageWidth   = this.MaxPassageWidth;

            FeatureWorker.ClearVisited();
            FeatureWorker.ClearGroupSizes();
            for (int i = 0; i < this.roots.Count; i++)
            {
                int num = this.roots[i];
                if (!FeatureWorker.visited[num])
                {
                    FeatureWorker_Protrusion.tmpGroup.Clear();
                    worldFloodFiller.FloodFill(num, (int x) => this.rootsSet.Contains(x), delegate(int x)
                    {
                        FeatureWorker.visited[x] = true;
                        FeatureWorker_Protrusion.tmpGroup.Add(x);
                    }, int.MaxValue, null);
                    for (int j = 0; j < FeatureWorker_Protrusion.tmpGroup.Count; j++)
                    {
                        FeatureWorker.groupSize[FeatureWorker_Protrusion.tmpGroup[j]] = FeatureWorker_Protrusion.tmpGroup.Count;
                    }
                }
            }
            FeatureWorker.ClearVisited();
            for (int k = 0; k < this.rootsWithoutSmallPassages.Count; k++)
            {
                int num2 = this.rootsWithoutSmallPassages[k];
                if (!FeatureWorker.visited[num2])
                {
                    this.currentGroup.Clear();
                    worldFloodFiller.FloodFill(num2, (int x) => this.rootsWithoutSmallPassagesSet.Contains(x), delegate(int x)
                    {
                        FeatureWorker.visited[x] = true;
                        this.currentGroup.Add(x);
                    }, int.MaxValue, null);
                    if (this.currentGroup.Count >= minSize)
                    {
                        GenPlanetMorphology.Dilate(this.currentGroup, maxPassageWidth * 2, (int x) => this.rootsSet.Contains(x));
                        if (this.currentGroup.Count <= maxSize)
                        {
                            float num3 = (float)this.currentGroup.Count / (float)FeatureWorker.groupSize[num2];
                            if (num3 <= maxPctOfWholeArea)
                            {
                                if (this.def.canTouchWorldEdge || !this.currentGroup.Any((int x) => worldGrid.IsOnEdge(x)))
                                {
                                    this.currentGroupMembers.Clear();
                                    for (int l = 0; l < this.currentGroup.Count; l++)
                                    {
                                        if (this.IsMember(this.currentGroup[l]))
                                        {
                                            this.currentGroupMembers.Add(this.currentGroup[l]);
                                        }
                                    }
                                    if (this.currentGroupMembers.Count >= minSize)
                                    {
                                        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);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 11
0
        private void CalculateContiguousGroups()
        {
            WorldFloodFiller worldFloodFiller = Find.WorldFloodFiller;
            WorldGrid        worldGrid        = Find.WorldGrid;
            int   tilesCount = worldGrid.TilesCount;
            int   minSize    = this.MinSize;
            int   maxSize    = this.MaxSize;
            int   maxPossiblyAllowedSizeToTake        = this.MaxPossiblyAllowedSizeToTake;
            float maxPossiblyAllowedSizePctOfMeToTake = this.MaxPossiblyAllowedSizePctOfMeToTake;

            FeatureWorker.ClearVisited();
            FeatureWorker.ClearGroupSizes();
            for (int i = 0; i < this.possiblyAllowed.Count; i++)
            {
                int num = this.possiblyAllowed[i];
                if (!FeatureWorker.visited[num])
                {
                    if (!this.rootsSet.Contains(num))
                    {
                        FeatureWorker_FloodFill.tmpGroup.Clear();
                        worldFloodFiller.FloodFill(num, (int x) => this.possiblyAllowedSet.Contains(x) && !this.rootsSet.Contains(x), delegate(int x)
                        {
                            FeatureWorker.visited[x] = true;
                            FeatureWorker_FloodFill.tmpGroup.Add(x);
                        }, 2147483647, null);
                        for (int j = 0; j < FeatureWorker_FloodFill.tmpGroup.Count; j++)
                        {
                            FeatureWorker.groupSize[FeatureWorker_FloodFill.tmpGroup[j]] = FeatureWorker_FloodFill.tmpGroup.Count;
                        }
                    }
                }
            }
            for (int k = 0; k < this.roots.Count; k++)
            {
                int num2 = this.roots[k];
                if (!FeatureWorker.visited[num2])
                {
                    int initialMembersCountClamped = 0;
                    worldFloodFiller.FloodFill(num2, (int x) => (this.rootsSet.Contains(x) || this.possiblyAllowedSet.Contains(x)) && this.IsMember(x), delegate(int x)
                    {
                        FeatureWorker.visited[x] = true;
                        initialMembersCountClamped++;
                        return(initialMembersCountClamped >= minSize);
                    }, 2147483647, null);
                    if (initialMembersCountClamped >= minSize)
                    {
                        int initialRootsCount = 0;
                        worldFloodFiller.FloodFill(num2, (int x) => this.rootsSet.Contains(x), delegate(int x)
                        {
                            FeatureWorker.visited[x] = true;
                            initialRootsCount++;
                        }, 2147483647, null);
                        if (initialRootsCount >= minSize && initialRootsCount <= maxSize)
                        {
                            int traversedRootsCount = 0;
                            this.currentGroup.Clear();
                            worldFloodFiller.FloodFill(num2, (int x) => this.rootsSet.Contains(x) || (this.possiblyAllowedSet.Contains(x) && FeatureWorker.groupSize[x] <= maxPossiblyAllowedSizeToTake && (float)FeatureWorker.groupSize[x] <= maxPossiblyAllowedSizePctOfMeToTake * (float)Mathf.Max(traversedRootsCount, initialRootsCount) && FeatureWorker.groupSize[x] < maxSize), delegate(int x)
                            {
                                FeatureWorker.visited[x] = true;
                                if (this.rootsSet.Contains(x))
                                {
                                    traversedRootsCount++;
                                }
                                this.currentGroup.Add(x);
                            }, 2147483647, null);
                            if (this.currentGroup.Count >= minSize && this.currentGroup.Count <= maxSize)
                            {
                                if (this.def.canTouchWorldEdge || !this.currentGroup.Any((int x) => worldGrid.IsOnEdge(x)))
                                {
                                    this.currentGroupMembers.Clear();
                                    for (int l = 0; l < this.currentGroup.Count; l++)
                                    {
                                        if (this.IsMember(this.currentGroup[l]))
                                        {
                                            this.currentGroupMembers.Add(this.currentGroup[l]);
                                        }
                                    }
                                    if (this.currentGroupMembers.Count >= minSize)
                                    {
                                        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);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 12
0
        private void CalculateContiguousGroups()
        {
            WorldFloodFiller worldFloodFiller = Find.WorldFloodFiller;
            WorldGrid        worldGrid        = Find.WorldGrid;

            _ = worldGrid.TilesCount;
            int   minSize = MinSize;
            int   maxSize = MaxSize;
            int   maxPossiblyAllowedSizeToTake        = MaxPossiblyAllowedSizeToTake;
            float maxPossiblyAllowedSizePctOfMeToTake = MaxPossiblyAllowedSizePctOfMeToTake;

            FeatureWorker.ClearVisited();
            FeatureWorker.ClearGroupSizes();
            for (int i = 0; i < possiblyAllowed.Count; i++)
            {
                int num = possiblyAllowed[i];
                if (!FeatureWorker.visited[num] && !rootsSet.Contains(num))
                {
                    tmpGroup.Clear();
                    worldFloodFiller.FloodFill(num, (int x) => possiblyAllowedSet.Contains(x) && !rootsSet.Contains(x), delegate(int x)
                    {
                        FeatureWorker.visited[x] = true;
                        tmpGroup.Add(x);
                    });
                    for (int j = 0; j < tmpGroup.Count; j++)
                    {
                        FeatureWorker.groupSize[tmpGroup[j]] = tmpGroup.Count;
                    }
                }
            }
            for (int k = 0; k < roots.Count; k++)
            {
                int num2 = roots[k];
                if (FeatureWorker.visited[num2])
                {
                    continue;
                }
                int initialMembersCountClamped = 0;
                worldFloodFiller.FloodFill(num2, (int x) => (rootsSet.Contains(x) || possiblyAllowedSet.Contains(x)) && IsMember(x), delegate(int x)
                {
                    FeatureWorker.visited[x] = true;
                    initialMembersCountClamped++;
                    return(initialMembersCountClamped >= minSize);
                });
                if (initialMembersCountClamped < minSize)
                {
                    continue;
                }
                int initialRootsCount = 0;
                worldFloodFiller.FloodFill(num2, (int x) => rootsSet.Contains(x), delegate(int x)
                {
                    FeatureWorker.visited[x] = true;
                    initialRootsCount++;
                });
                if (initialRootsCount < minSize || initialRootsCount > maxSize)
                {
                    continue;
                }
                int traversedRootsCount = 0;
                currentGroup.Clear();
                worldFloodFiller.FloodFill(num2, (int x) => rootsSet.Contains(x) || (possiblyAllowedSet.Contains(x) && FeatureWorker.groupSize[x] <= maxPossiblyAllowedSizeToTake && (float)FeatureWorker.groupSize[x] <= maxPossiblyAllowedSizePctOfMeToTake * (float)Mathf.Max(traversedRootsCount, initialRootsCount) && FeatureWorker.groupSize[x] < maxSize), delegate(int x)
                {
                    FeatureWorker.visited[x] = true;
                    if (rootsSet.Contains(x))
                    {
                        traversedRootsCount++;
                    }
                    currentGroup.Add(x);
                });
                if (currentGroup.Count < minSize || currentGroup.Count > maxSize || (!def.canTouchWorldEdge && currentGroup.Any((int x) => worldGrid.IsOnEdge(x))))
                {
                    continue;
                }
                currentGroupMembers.Clear();
                for (int l = 0; l < currentGroup.Count; l++)
                {
                    if (IsMember(currentGroup[l]))
                    {
                        currentGroupMembers.Add(currentGroup[l]);
                    }
                }
                if (currentGroupMembers.Count >= minSize)
                {
                    if (currentGroup.Any((int x) => worldGrid[x].feature == null))
                    {
                        currentGroup.RemoveAll((int x) => worldGrid[x].feature != null);
                    }
                    AddFeature(currentGroupMembers, currentGroup);
                }
            }
        }
Ejemplo n.º 13
0
        public static bool FloodFill(WorldFloodFiller __instance, int rootTile, Predicate <int> passCheck, Func <int, int, bool> processor, int maxTilesToProcess = int.MaxValue, IEnumerable <int> extraRootTiles = null)
        {
            if (openSet == null)
            {
                openSet = new Queue <int>();
            }
            if (traversalDistance == null)
            {
                traversalDistance = new List <int>();
            }
            if (visited == null)
            {
                visited = new List <int>();
            }

            if (working)
            {
                Log.Error("Nested FloodFill calls are not allowed. This will cause bugs.");
            }

            working = true;
            int j = 0;

            for (int count = visited.Count; j < count; j++)
            {
                traversalDistance[visited[j]] = -1;
            }
            visited.Clear();
            openSet.Clear();
            if (rootTile != -1 && extraRootTiles == null && !passCheck(rootTile))
            {
                working = false;
                return(false);
            }

            int tilesCount = Find.WorldGrid.TilesCount;

            if (traversalDistance.Count != tilesCount)
            {
                traversalDistance.Clear();
                for (int i = 0; i < tilesCount; i++)
                {
                    traversalDistance.Add(-1);
                }
            }

            WorldGrid  worldGrid = Find.WorldGrid;
            List <int> tileIDToNeighbors_offsets = worldGrid.tileIDToNeighbors_offsets;
            List <int> tileIDToNeighbors_values  = worldGrid.tileIDToNeighbors_values;

            openSet.Clear();
            if (rootTile != -1)
            {
                visited.Add(rootTile);
                traversalDistance[rootTile] = 0;
                openSet.Enqueue(rootTile);
            }

            if (extraRootTiles != null)
            {
                visited.AddRange(extraRootTiles);
                IList <int> list = extraRootTiles as IList <int>;
                if (list != null)
                {
                    for (int k = 0; k < list.Count; k++)
                    {
                        int num3 = list[k];
                        traversalDistance[num3] = 0;
                        openSet.Enqueue(num3);
                    }
                }
                else
                {
                    foreach (int extraRootTile in extraRootTiles)
                    {
                        traversalDistance[extraRootTile] = 0;
                        openSet.Enqueue(extraRootTile);
                    }
                }
            }

            loop3(processor, maxTilesToProcess, tileIDToNeighbors_offsets,
                  tileIDToNeighbors_values, passCheck, tilesCount);

            working = false;
            return(false);
        }
Ejemplo n.º 14
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);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 15
0
        public static bool FloodFill(WorldFloodFiller __instance, int rootTile, Predicate <int> passCheck, Func <int, int, bool> processor, int maxTilesToProcess = int.MaxValue, IEnumerable <int> extraRootTiles = null)
        {
            bool        working           = false;
            Queue <int> openSet           = new Queue <int>();
            List <int>  traversalDistance = new List <int>();
            List <int>  visited           = new List <int>();

            if (working)
            {
                Log.Error("Nested FloodFill calls are not allowed. This will cause bugs.");
            }

            working = true;
            //ClearVisited();
            if (rootTile != -1 && extraRootTiles == null && !passCheck(rootTile))
            {
                working = false;
                return(false);
            }

            int tilesCount = Find.WorldGrid.TilesCount;
            int num        = tilesCount;

            if (traversalDistance.Count != tilesCount)
            {
                traversalDistance.Clear();
                for (int i = 0; i < tilesCount; i++)
                {
                    traversalDistance.Add(-1);
                }
            }

            WorldGrid  worldGrid = Find.WorldGrid;
            List <int> tileIDToNeighbors_offsets = worldGrid.tileIDToNeighbors_offsets;
            List <int> tileIDToNeighbors_values  = worldGrid.tileIDToNeighbors_values;
            int        num2 = 0;

            openSet.Clear();
            if (rootTile != -1)
            {
                visited.Add(rootTile);
                traversalDistance[rootTile] = 0;
                openSet.Enqueue(rootTile);
            }

            if (extraRootTiles != null)
            {
                visited.AddRange(extraRootTiles);
                IList <int> list = extraRootTiles as IList <int>;
                if (list != null)
                {
                    for (int j = 0; j < list.Count; j++)
                    {
                        int num3 = list[j];
                        traversalDistance[num3] = 0;
                        openSet.Enqueue(num3);
                    }
                }
                else
                {
                    foreach (int extraRootTile in extraRootTiles)
                    {
                        traversalDistance[extraRootTile] = 0;
                        openSet.Enqueue(extraRootTile);
                    }
                }
            }

            while (openSet.Count > 0)
            {
                int num4 = openSet.Dequeue();
                int num5 = traversalDistance[num4];
                if (processor(num4, num5))
                {
                    break;
                }

                num2++;
                if (num2 == maxTilesToProcess)
                {
                    break;
                }

                int num6 = (num4 + 1 < tileIDToNeighbors_offsets.Count) ? tileIDToNeighbors_offsets[num4 + 1] : tileIDToNeighbors_values.Count;
                for (int k = tileIDToNeighbors_offsets[num4]; k < num6; k++)
                {
                    int num7 = tileIDToNeighbors_values[k];
                    if (traversalDistance[num7] == -1 && passCheck(num7))
                    {
                        visited.Add(num7);
                        openSet.Enqueue(num7);
                        traversalDistance[num7] = num5 + 1;
                    }
                }

                if (openSet.Count > num)
                {
                    Log.Error("Overflow on world flood fill (>" + num + " cells). Make sure we're not flooding over the same area after we check it.");
                    working = false;
                    return(false);
                }
            }

            working = false;
            return(false);
        }
        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);
            }
        }
Ejemplo n.º 17
0
        private void CalculateContiguousGroups()
        {
            WorldGrid        worldGrid        = Find.WorldGrid;
            WorldFloodFiller worldFloodFiller = Find.WorldFloodFiller;
            int   minSize           = MinSize;
            int   maxSize           = MaxSize;
            float maxPctOfWholeArea = MaxPctOfWholeArea;
            int   maxPassageWidth   = MaxPassageWidth;

            FeatureWorker.ClearVisited();
            FeatureWorker.ClearGroupSizes();
            for (int i = 0; i < roots.Count; i++)
            {
                int num = roots[i];
                if (!FeatureWorker.visited[num])
                {
                    tmpGroup.Clear();
                    worldFloodFiller.FloodFill(num, (int x) => rootsSet.Contains(x), delegate(int x)
                    {
                        FeatureWorker.visited[x] = true;
                        tmpGroup.Add(x);
                    });
                    for (int j = 0; j < tmpGroup.Count; j++)
                    {
                        FeatureWorker.groupSize[tmpGroup[j]] = tmpGroup.Count;
                    }
                }
            }
            FeatureWorker.ClearVisited();
            for (int k = 0; k < rootsWithoutSmallPassages.Count; k++)
            {
                int num2 = rootsWithoutSmallPassages[k];
                if (FeatureWorker.visited[num2])
                {
                    continue;
                }
                currentGroup.Clear();
                worldFloodFiller.FloodFill(num2, (int x) => rootsWithoutSmallPassagesSet.Contains(x), delegate(int x)
                {
                    FeatureWorker.visited[x] = true;
                    currentGroup.Add(x);
                });
                if (currentGroup.Count < minSize)
                {
                    continue;
                }
                GenPlanetMorphology.Dilate(currentGroup, maxPassageWidth * 2, (int x) => rootsSet.Contains(x));
                if (currentGroup.Count > maxSize || (float)currentGroup.Count / (float)FeatureWorker.groupSize[num2] > maxPctOfWholeArea || (!def.canTouchWorldEdge && currentGroup.Any((int x) => worldGrid.IsOnEdge(x))))
                {
                    continue;
                }
                currentGroupMembers.Clear();
                for (int l = 0; l < currentGroup.Count; l++)
                {
                    if (IsMember(currentGroup[l]))
                    {
                        currentGroupMembers.Add(currentGroup[l]);
                    }
                }
                if (currentGroupMembers.Count >= minSize)
                {
                    if (currentGroup.Any((int x) => worldGrid[x].feature == null))
                    {
                        currentGroup.RemoveAll((int x) => worldGrid[x].feature != null);
                    }
                    AddFeature(currentGroupMembers, currentGroup);
                }
            }
        }
Ejemplo n.º 18
0
        private void AssignBestDrawPos(WorldFeature newFeature, List <int> tilesForTextDrawPosCalculation)
        {
            WorldGrid worldGrid = Find.WorldGrid;

            tmpEdgeTiles.Clear();
            tmpTilesForTextDrawPosCalculationSet.Clear();
            tmpTilesForTextDrawPosCalculationSet.AddRange(tilesForTextDrawPosCalculation);
            Vector3 a = Vector3.zero;

            for (int i = 0; i < tilesForTextDrawPosCalculation.Count; i++)
            {
                int num = tilesForTextDrawPosCalculation[i];
                a += worldGrid.GetTileCenter(num);
                bool flag = worldGrid.IsOnEdge(num);
                if (!flag)
                {
                    worldGrid.GetTileNeighbors(num, tmpNeighbors);
                    for (int j = 0; j < tmpNeighbors.Count; j++)
                    {
                        if (!tmpTilesForTextDrawPosCalculationSet.Contains(tmpNeighbors[j]))
                        {
                            flag = true;
                            break;
                        }
                    }
                }
                if (flag)
                {
                    tmpEdgeTiles.Add(num);
                }
            }
            a /= (float)tilesForTextDrawPosCalculation.Count;
            if (!tmpEdgeTiles.Any())
            {
                tmpEdgeTiles.Add(tilesForTextDrawPosCalculation.RandomElement());
            }
            int bestTileDist = 0;

            tmpTraversedTiles.Clear();
            WorldFloodFiller worldFloodFiller = Find.WorldFloodFiller;
            int                   rootTile    = -1;
            Predicate <int>       passCheck   = (int x) => tmpTilesForTextDrawPosCalculationSet.Contains(x);
            Func <int, int, bool> processor   = delegate(int tile, int traversalDist)
            {
                tmpTraversedTiles.Add(new Pair <int, int>(tile, traversalDist));
                bestTileDist = traversalDist;
                return(false);
            };
            List <int> extraRootTiles = tmpEdgeTiles;

            worldFloodFiller.FloodFill(rootTile, passCheck, processor, 2147483647, extraRootTiles);
            int   num2 = -1;
            float num3 = -1f;

            for (int k = 0; k < tmpTraversedTiles.Count; k++)
            {
                if (tmpTraversedTiles[k].Second == bestTileDist)
                {
                    Vector3 tileCenter   = worldGrid.GetTileCenter(tmpTraversedTiles[k].First);
                    float   sqrMagnitude = (tileCenter - a).sqrMagnitude;
                    if (num2 == -1 || sqrMagnitude < num3)
                    {
                        num2 = tmpTraversedTiles[k].First;
                        num3 = sqrMagnitude;
                    }
                }
            }
            float maxDrawSizeInTiles = (float)bestTileDist * 2f * 1.2f;

            newFeature.drawCenter         = worldGrid.GetTileCenter(num2);
            newFeature.maxDrawSizeInTiles = maxDrawSizeInTiles;
        }