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