Пример #1
0
        private int CombineNewRegionsIntoContiguousGroups()
        {
            int num = 0;

            for (int i = 0; i < newRegions.Count; i++)
            {
                if (newRegions[i].newRegionGroupIndex < 0)
                {
                    RegionTraverser.FloodAndSetNewRegionIndex(newRegions[i], num);
                    num++;
                }
            }
            return(num);
        }
Пример #2
0
 public static void FloodAndSetNewRegionIndex(Region root, int newRegionGroupIndex)
 {
     root.newRegionGroupIndex = newRegionGroupIndex;
     if (root.type.AllowsMultipleRegionsPerRoom())
     {
         RegionEntryPredicate entryCondition  = (Region from, Region r) => r.type == root.type && r.newRegionGroupIndex < 0;
         RegionProcessor      regionProcessor = delegate(Region r)
         {
             r.newRegionGroupIndex = newRegionGroupIndex;
             return(false);
         };
         RegionTraverser.BreadthFirstTraverse(root, entryCondition, regionProcessor, 999999, RegionType.Set_All);
     }
 }
Пример #3
0
 private void CreateOrAttachToExistingRooms(int numRegionGroups)
 {
     for (int i = 0; i < numRegionGroups; i++)
     {
         this.currentRegionGroup.Clear();
         for (int j = 0; j < this.newRegions.Count; j++)
         {
             if (this.newRegions[j].newRegionGroupIndex == i)
             {
                 this.currentRegionGroup.Add(this.newRegions[j]);
             }
         }
         if (!this.currentRegionGroup[0].type.AllowsMultipleRegionsPerRoom())
         {
             if (this.currentRegionGroup.Count != 1)
             {
                 Log.Error("Region type doesn't allow multiple regions per room but there are >1 regions in this group.");
             }
             Room room = Room.MakeNew(this.map);
             this.currentRegionGroup[0].Room = room;
             this.newRooms.Add(room);
         }
         else
         {
             bool flag  = default(bool);
             Room room2 = this.FindCurrentRegionGroupNeighborWithMostRegions(out flag);
             if (room2 == null)
             {
                 Room item = RegionTraverser.FloodAndSetRooms(this.currentRegionGroup[0], this.map, null);
                 this.newRooms.Add(item);
             }
             else if (!flag)
             {
                 for (int k = 0; k < this.currentRegionGroup.Count; k++)
                 {
                     this.currentRegionGroup[k].Room = room2;
                 }
                 this.reusedOldRooms.Add(room2);
             }
             else
             {
                 RegionTraverser.FloodAndSetRooms(this.currentRegionGroup[0], this.map, room2);
                 this.reusedOldRooms.Add(room2);
             }
         }
     }
 }
Пример #4
0
 private void CreateOrAttachToExistingRooms(int numRegionGroups)
 {
     for (int i = 0; i < numRegionGroups; i++)
     {
         currentRegionGroup.Clear();
         for (int j = 0; j < newRegions.Count; j++)
         {
             if (newRegions[j].newRegionGroupIndex == i)
             {
                 currentRegionGroup.Add(newRegions[j]);
             }
         }
         if (!currentRegionGroup[0].type.AllowsMultipleRegionsPerRoom())
         {
             if (currentRegionGroup.Count != 1)
             {
                 Log.Error("Region type doesn't allow multiple regions per room but there are >1 regions in this group.");
             }
             Room room = Room.MakeNew(map);
             currentRegionGroup[0].Room = room;
             newRooms.Add(room);
         }
         else
         {
             bool multipleOldNeighborRooms;
             Room room2 = FindCurrentRegionGroupNeighborWithMostRegions(out multipleOldNeighborRooms);
             if (room2 == null)
             {
                 Room item = RegionTraverser.FloodAndSetRooms(currentRegionGroup[0], map, null);
                 newRooms.Add(item);
             }
             else if (!multipleOldNeighborRooms)
             {
                 for (int k = 0; k < currentRegionGroup.Count; k++)
                 {
                     currentRegionGroup[k].Room = room2;
                 }
                 reusedOldRooms.Add(room2);
             }
             else
             {
                 RegionTraverser.FloodAndSetRooms(currentRegionGroup[0], map, room2);
                 reusedOldRooms.Add(room2);
             }
         }
     }
 }
Пример #5
0
        public bool CanReachMapEdge(IntVec3 c, TraverseParms traverseParms)
        {
            if (traverseParms.pawn != null)
            {
                if (!traverseParms.pawn.Spawned)
                {
                    return(false);
                }
                if (traverseParms.pawn.Map != this.map)
                {
                    Log.Error(string.Concat(new object[]
                    {
                        "Called CanReachMapEdge() with a pawn spawned not on this map. This means that we can't check his reachability here. Pawn's current map should have been used instead of this one. pawn=",
                        traverseParms.pawn,
                        " pawn.Map=",
                        traverseParms.pawn.Map,
                        " map=",
                        this.map
                    }), false);
                    return(false);
                }
            }
            Region region = c.GetRegion(this.map, RegionType.Set_Passable);

            if (region == null)
            {
                return(false);
            }
            if (region.Room.TouchesMapEdge)
            {
                return(true);
            }
            RegionEntryPredicate entryCondition = (Region from, Region r) => r.Allows(traverseParms, false);
            bool            foundReg            = false;
            RegionProcessor regionProcessor     = delegate(Region r)
            {
                if (r.Room.TouchesMapEdge)
                {
                    foundReg = true;
                    return(true);
                }
                return(false);
            };

            RegionTraverser.BreadthFirstTraverse(region, entryCondition, regionProcessor, 9999, RegionType.Set_Passable);
            return(foundReg);
        }
Пример #6
0
 public void BreadthFirstTraverseWork(Region root, RegionEntryPredicate entryCondition, RegionProcessor regionProcessor, int maxRegions, RegionType traversableRegionTypes)
 {
     if ((root.type & traversableRegionTypes) == RegionType.None)
     {
         return;
     }
     this.closedIndex += 1u;
     this.open.Clear();
     this.numRegionsProcessed = 0;
     this.QueueNewOpenRegion(root);
     while (this.open.Count > 0)
     {
         Region region = this.open.Dequeue();
         if (DebugViewSettings.drawRegionTraversal)
         {
             region.Debug_Notify_Traversed();
         }
         if (regionProcessor != null && regionProcessor(region))
         {
             this.FinalizeSearch();
             return;
         }
         if (RegionTraverser.ShouldCountRegion(region))
         {
             this.numRegionsProcessed++;
         }
         if (this.numRegionsProcessed >= maxRegions)
         {
             this.FinalizeSearch();
             return;
         }
         for (int i = 0; i < region.links.Count; i++)
         {
             RegionLink regionLink = region.links[i];
             for (int j = 0; j < 2; j++)
             {
                 Region region2 = regionLink.regions[j];
                 if (region2 != null && region2.closedIndex[this.closedArrayPos] != this.closedIndex && (region2.type & traversableRegionTypes) != RegionType.None && (entryCondition == null || entryCondition(region, region2)))
                 {
                     this.QueueNewOpenRegion(region2);
                 }
             }
         }
     }
     this.FinalizeSearch();
 }
Пример #7
0
        public static bool TryFindRandomReachableCellNear(IntVec3 root, Map map, float radius, TraverseParms traverseParms, Predicate <IntVec3> cellValidator, Predicate <Region> regionValidator, out IntVec3 result, int maxRegions = 999999)
        {
            bool result2;

            if (map == null)
            {
                Log.ErrorOnce("Tried to find reachable cell in a null map", 61037855, false);
                result  = IntVec3.Invalid;
                result2 = false;
            }
            else
            {
                Region region = root.GetRegion(map, RegionType.Set_Passable);
                if (region == null)
                {
                    result  = IntVec3.Invalid;
                    result2 = false;
                }
                else
                {
                    CellFinder.workingRegions.Clear();
                    float radSquared = radius * radius;
                    RegionTraverser.BreadthFirstTraverse(region, (Region from, Region r) => r.Allows(traverseParms, true) && (radius > 1000f || r.extentsClose.ClosestDistSquaredTo(root) <= radSquared) && (regionValidator == null || regionValidator(r)), delegate(Region r)
                    {
                        CellFinder.workingRegions.Add(r);
                        return(false);
                    }, maxRegions, RegionType.Set_Passable);
                    while (CellFinder.workingRegions.Count > 0)
                    {
                        Region region2 = CellFinder.workingRegions.RandomElementByWeight((Region r) => (float)r.CellCount);
                        if (region2.TryFindRandomCellInRegion((IntVec3 c) => (float)(c - root).LengthHorizontalSquared <= radSquared && (cellValidator == null || cellValidator(c)), out result))
                        {
                            CellFinder.workingRegions.Clear();
                            return(true);
                        }
                        CellFinder.workingRegions.Remove(region2);
                    }
                    result = IntVec3.Invalid;
                    CellFinder.workingRegions.Clear();
                    result2 = false;
                }
            }
            return(result2);
        }
Пример #8
0
        public static bool WithinRegions(this IntVec3 A, IntVec3 B, Map map, int regionLookCount, TraverseParms traverseParams, RegionType traversableRegionTypes = RegionType.Set_Passable)
        {
            Region region = A.GetRegion(map, traversableRegionTypes);
            bool   result;

            if (region == null)
            {
                result = false;
            }
            else
            {
                Region regB = B.GetRegion(map, traversableRegionTypes);
                if (regB == null)
                {
                    result = false;
                }
                else if (region == regB)
                {
                    result = true;
                }
                else
                {
                    RegionEntryPredicate entryCondition = (Region from, Region r) => r.Allows(traverseParams, false);
                    bool            found           = false;
                    RegionProcessor regionProcessor = delegate(Region r)
                    {
                        bool result2;
                        if (r == regB)
                        {
                            found   = true;
                            result2 = true;
                        }
                        else
                        {
                            result2 = false;
                        }
                        return(result2);
                    };
                    RegionTraverser.BreadthFirstTraverse(region, entryCondition, regionProcessor, regionLookCount, traversableRegionTypes);
                    result = found;
                }
            }
            return(result);
        }
Пример #9
0
        public bool CanReachUnfogged(IntVec3 c, TraverseParms traverseParms)
        {
            if (traverseParms.pawn != null)
            {
                if (!traverseParms.pawn.Spawned)
                {
                    return(false);
                }
                if (traverseParms.pawn.Map != map)
                {
                    Log.Error(string.Concat("Called CanReachUnfogged() with a pawn spawned not on this map. This means that we can't check his reachability here. Pawn's current map should have been used instead of this one. pawn=", traverseParms.pawn, " pawn.Map=", traverseParms.pawn.Map, " map=", map));
                    return(false);
                }
            }
            if (!c.InBounds(map))
            {
                return(false);
            }
            if (!c.Fogged(map))
            {
                return(true);
            }
            Region region = c.GetRegion(map);

            if (region == null)
            {
                return(false);
            }
            RegionEntryPredicate entryCondition = (Region from, Region r) => r.Allows(traverseParms, isDestination: false);
            bool            foundReg            = false;
            RegionProcessor regionProcessor     = delegate(Region r)
            {
                if (!r.AnyCell.Fogged(map))
                {
                    foundReg = true;
                    return(true);
                }
                return(false);
            };

            RegionTraverser.BreadthFirstTraverse(region, entryCondition, regionProcessor, 9999);
            return(foundReg);
        }
Пример #10
0
 public static void AllRegionsNear(List <Region> results, Region root, int maxRegions, TraverseParms traverseParms, Predicate <Region> validator = null, Pawn pawnToAllow = null, RegionType traversableRegionTypes = RegionType.Set_Passable)
 {
     if (results == null)
     {
         Log.ErrorOnce("Attempted to call AllRegionsNear with an invalid results list", 60733193, false);
         return;
     }
     results.Clear();
     if (root == null)
     {
         Log.ErrorOnce("Attempted to call AllRegionsNear with an invalid root", 9107839, false);
         return;
     }
     RegionTraverser.BreadthFirstTraverse(root, (Region from, Region r) => (validator == null || validator(r)) && r.Allows(traverseParms, true) && (pawnToAllow == null || !r.IsForbiddenEntirely(pawnToAllow)), delegate(Region r)
     {
         results.Add(r);
         return(false);
     }, maxRegions, traversableRegionTypes);
 }
Пример #11
0
        public static Region RandomRegionNear(Region root, int maxRegions, TraverseParms traverseParms, Predicate <Region> validator = null, Pawn pawnToAllow = null, RegionType traversableRegionTypes = RegionType.Set_Passable)
        {
            if (root == null)
            {
                throw new ArgumentNullException("root");
            }
            if (maxRegions <= 1)
            {
                return(root);
            }
            workingRegions.Clear();
            RegionTraverser.BreadthFirstTraverse(root, (Region from, Region r) => (validator == null || validator(r)) && r.Allows(traverseParms, isDestination : true) && (pawnToAllow == null || !r.IsForbiddenEntirely(pawnToAllow)), delegate(Region r)
            {
                workingRegions.Add(r);
                return(false);
            }, maxRegions, traversableRegionTypes);
            Region result = workingRegions.RandomElementByWeight((Region r) => r.CellCount);

            workingRegions.Clear();
            return(result);
        }
Пример #12
0
        public static bool TryFindClosestRegionWith(Region rootReg, TraverseParms traverseParms, Predicate <Region> validator, int maxRegions, out Region result, RegionType traversableRegionTypes = RegionType.Set_Passable)
        {
            if (rootReg == null)
            {
                result = null;
                return(false);
            }
            Region localResult = null;

            RegionTraverser.BreadthFirstTraverse(rootReg, (Region from, Region r) => r.Allows(traverseParms, isDestination : true), delegate(Region r)
            {
                if (validator(r))
                {
                    localResult = r;
                    return(true);
                }
                return(false);
            }, maxRegions, traversableRegionTypes);
            result = localResult;
            return(result != null);
        }
Пример #13
0
        public static void DoClamor(Pawn source, float radius, ClamorType type)
        {
            IntVec3 root   = source.Position;
            Region  region = source.GetRegion(RegionType.Set_Passable);

            if (region != null)
            {
                RegionTraverser.BreadthFirstTraverse(region, (Region from, Region r) => r.portal == null || r.portal.Open, delegate(Region r)
                {
                    List <Thing> list = r.ListerThings.ThingsInGroup(ThingRequestGroup.Pawn);
                    for (int i = 0; i < list.Count; i++)
                    {
                        Pawn pawn = list[i] as Pawn;
                        if (pawn.Position.InHorDistOf(root, radius))
                        {
                            pawn.HearClamor(source, type);
                        }
                    }
                    return(false);
                }, 15, RegionType.Set_Passable);
            }
        }
Пример #14
0
        public static void DoClamor(Thing source, float radius, ClamorDef type)
        {
            IntVec3 root   = source.Position;
            Region  region = source.GetRegion();

            if (region != null)
            {
                RegionTraverser.BreadthFirstTraverse(region, (Region from, Region r) => r.door == null || r.door.Open, delegate(Region r)
                {
                    List <Thing> list = r.ListerThings.ThingsInGroup(ThingRequestGroup.Pawn);
                    for (int i = 0; i < list.Count; i++)
                    {
                        Pawn pawn = list[i] as Pawn;
                        float num = Mathf.Clamp01(pawn.health.capacities.GetLevel(PawnCapacityDefOf.Hearing));
                        if (num > 0f && pawn.Position.InHorDistOf(root, radius * num))
                        {
                            pawn.HearClamor(source, type);
                        }
                    }
                    return(false);
                }, 15);
            }
        }
Пример #15
0
        public static bool WithinRegions(this IntVec3 A, IntVec3 B, Map map, int regionLookCount, TraverseParms traverseParams, RegionType traversableRegionTypes = RegionType.Set_Passable)
        {
            if (traverseParams.mode == TraverseMode.PassAllDestroyableThings)
            {
                throw new ArgumentException("traverseParams (PassAllDestroyableThings not supported)");
            }
            Region region = A.GetRegion(map, traversableRegionTypes);

            if (region == null)
            {
                return(false);
            }
            Region regB = B.GetRegion(map, traversableRegionTypes);

            if (regB == null)
            {
                return(false);
            }
            if (region == regB)
            {
                return(true);
            }
            RegionEntryPredicate entryCondition = (Region from, Region r) => r.Allows(traverseParams, false);
            bool            found           = false;
            RegionProcessor regionProcessor = delegate(Region r)
            {
                if (r == regB)
                {
                    found = true;
                    return(true);
                }
                return(false);
            };

            RegionTraverser.BreadthFirstTraverse(region, entryCondition, regionProcessor, regionLookCount, traversableRegionTypes);
            return(found);
        }
Пример #16
0
        public static Thing RegionwiseBFSWorker(IntVec3 root, Map map, ThingRequest req, PathEndMode peMode, TraverseParms traverseParams, Predicate <Thing> validator, Func <Thing, float> priorityGetter, int minRegions, int maxRegions, float maxDistance, out int regionsSeen, RegionType traversableRegionTypes = RegionType.Set_Passable, bool ignoreEntirelyForbiddenRegions = false)
        {
            regionsSeen = 0;
            if (traverseParams.mode == TraverseMode.PassAllDestroyableThings)
            {
                Log.Error("RegionwiseBFSWorker with traverseParams.mode PassAllDestroyableThings. Use ClosestThingGlobal.");
                return(null);
            }
            if (traverseParams.mode == TraverseMode.PassAllDestroyableThingsNotWater)
            {
                Log.Error("RegionwiseBFSWorker with traverseParams.mode PassAllDestroyableThingsNotWater. Use ClosestThingGlobal.");
                return(null);
            }
            if (!req.IsUndefined && !req.CanBeFoundInRegion)
            {
                Log.ErrorOnce(string.Concat("RegionwiseBFSWorker with thing request group ", req.group, ". This group is never stored in regions. Most likely a global search should have been used."), 385766189);
                return(null);
            }
            Region region = root.GetRegion(map, traversableRegionTypes);

            if (region == null)
            {
                return(null);
            }
            float maxDistSquared = maxDistance * maxDistance;
            RegionEntryPredicate entryCondition = delegate(Region from, Region to)
            {
                if (!to.Allows(traverseParams, isDestination: false))
                {
                    return(false);
                }
                return(maxDistance > 5000f || to.extentsClose.ClosestDistSquaredTo(root) < maxDistSquared);
            };
            Thing           closestThing       = null;
            float           closestDistSquared = 9999999f;
            float           bestPrio           = float.MinValue;
            int             regionsSeenScan    = 0;
            RegionProcessor regionProcessor    = delegate(Region r)
            {
                if (RegionTraverser.ShouldCountRegion(r))
                {
                    regionsSeenScan++;
                }
                if (!r.IsDoorway && !r.Allows(traverseParams, isDestination: true))
                {
                    return(false);
                }
                if (!ignoreEntirelyForbiddenRegions || !r.IsForbiddenEntirely(traverseParams.pawn))
                {
                    List <Thing> list = r.ListerThings.ThingsMatching(req);
                    for (int i = 0; i < list.Count; i++)
                    {
                        Thing thing = list[i];
                        if (ReachabilityWithinRegion.ThingFromRegionListerReachable(thing, r, peMode, traverseParams.pawn))
                        {
                            float num = ((priorityGetter != null) ? priorityGetter(thing) : 0f);
                            if (!(num < bestPrio))
                            {
                                float num2 = (thing.Position - root).LengthHorizontalSquared;
                                if ((num > bestPrio || num2 < closestDistSquared) && num2 < maxDistSquared && (validator == null || validator(thing)))
                                {
                                    closestThing       = thing;
                                    closestDistSquared = num2;
                                    bestPrio           = num;
                                }
                            }
                        }
                    }
                }
                return(regionsSeenScan >= minRegions && closestThing != null);
            };

            RegionTraverser.BreadthFirstTraverse(region, entryCondition, regionProcessor, maxRegions, traversableRegionTypes);
            regionsSeen = regionsSeenScan;
            return(closestThing);
        }
Пример #17
0
 static RegionTraverser()
 {
     RegionTraverser.RecreateWorkers();
 }
Пример #18
0
        public static Thing RegionwiseBFSWorker(IntVec3 root, Map map, ThingRequest req, PathEndMode peMode, TraverseParms traverseParams, Predicate <Thing> validator, Func <Thing, float> priorityGetter, int minRegions, int maxRegions, float maxDistance, RegionType traversableRegionTypes = RegionType.Set_Passable, bool ignoreEntirelyForbiddenRegions = false)
        {
            if (traverseParams.mode == TraverseMode.PassAllDestroyableThings)
            {
                Log.Error("RegionwiseBFSWorker with traverseParams.mode PassAllDestroyableThings. Use ClosestThingGlobal.");
                return(null);
            }
            Region region = root.GetRegion(map, traversableRegionTypes);

            if (region == null)
            {
                return(null);
            }
            float maxDistSquared = maxDistance * maxDistance;
            RegionEntryPredicate entryCondition = delegate(Region from, Region to)
            {
                if (!to.Allows(traverseParams, false))
                {
                    return(false);
                }
                return(maxDistance > 5000.0 || to.extentsClose.ClosestDistSquaredTo(root) < maxDistSquared);
            };
            Thing           closestThing       = null;
            float           closestDistSquared = 9999999f;
            float           bestPrio           = -3.40282347E+38f;
            int             regionsSeen        = 0;
            RegionProcessor regionProcessor    = delegate(Region r)
            {
                if (r.portal == null && !r.Allows(traverseParams, true))
                {
                    return(false);
                }
                if (!ignoreEntirelyForbiddenRegions || !r.IsForbiddenEntirely(traverseParams.pawn))
                {
                    List <Thing> list = r.ListerThings.ThingsMatching(req);
                    for (int i = 0; i < list.Count; i++)
                    {
                        Thing thing = list[i];
                        if (ReachabilityWithinRegion.ThingFromRegionListerReachable(thing, r, peMode, traverseParams.pawn))
                        {
                            float num = (float)((priorityGetter == null) ? 0.0 : priorityGetter(thing));
                            if (!(num < bestPrio))
                            {
                                float num2 = (float)(thing.Position - root).LengthHorizontalSquared;
                                if ((num > bestPrio || num2 < closestDistSquared) && num2 < maxDistSquared && (validator == null || validator(thing)))
                                {
                                    closestThing       = thing;
                                    closestDistSquared = num2;
                                    bestPrio           = num;
                                }
                            }
                        }
                    }
                }
                regionsSeen++;
                return(regionsSeen >= minRegions && closestThing != null);
            };

            RegionTraverser.BreadthFirstTraverse(region, entryCondition, regionProcessor, maxRegions, traversableRegionTypes);
            return(closestThing);
        }