public static Room FloodAndSetRooms(Region root, Map map, Room existingRoom)
        {
            Room floodingRoom;

            if (existingRoom == null)
            {
                floodingRoom = Room.MakeNew(map);
            }
            else
            {
                floodingRoom = existingRoom;
            }
            root.Room = floodingRoom;
            if (!root.type.AllowsMultipleRegionsPerRoom())
            {
                return(floodingRoom);
            }
            RegionEntryPredicate entryCondition  = (Region from, Region r) => r.type == root.type && r.Room != floodingRoom;
            RegionProcessor      regionProcessor = delegate(Region r)
            {
                r.Room = floodingRoom;
                return(false);
            };

            BreadthFirstTraverse(root, entryCondition, regionProcessor, 999999, RegionType.Set_All);
            return(floodingRoom);
        }
        public static void BreadthFirstTraverse(Region root, RegionEntryPredicate entryCondition, RegionProcessor regionProcessor, int maxRegions = 999999, RegionType traversableRegionTypes = RegionType.Set_Passable)
        {
            if (freeWorkers.Count == 0)
            {
                Log.Error("No free workers for breadth-first traversal. Either BFS recurred deeper than " + NumWorkers + ", or a bug has put this system in an inconsistent state. Resetting.");
                return;
            }
            if (root == null)
            {
                Log.Error("BreadthFirstTraverse with null root region.");
                return;
            }
            BFSWorker bFSWorker = freeWorkers.Dequeue();

            try
            {
                bFSWorker.BreadthFirstTraverseWork(root, entryCondition, regionProcessor, maxRegions, traversableRegionTypes);
            }
            catch (Exception ex)
            {
                Log.Error("Exception in BreadthFirstTraverse: " + ex.ToString());
            }
            finally
            {
                bFSWorker.Clear();
                freeWorkers.Enqueue(bFSWorker);
            }
        }
        private static Region ClosestRegionWithinTemperatureRange(IntVec3 root, Map map, FloatRange tempRange, TraverseParms traverseParms, RegionType traversableRegionTypes = RegionType.Set_Passable)
        {
            Region region = root.GetRegion(map, traversableRegionTypes);

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

            RegionTraverser.BreadthFirstTraverse(region, entryCondition, regionProcessor, 9999, traversableRegionTypes);
            return(foundReg);
        }
        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);

            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, isDestination: false);
            bool            found           = false;
            RegionProcessor regionProcessor = delegate(Region r)
            {
                if (r == regB)
                {
                    found = true;
                    return(true);
                }
                return(false);
            };

            BreadthFirstTraverse(region, entryCondition, regionProcessor, regionLookCount, traversableRegionTypes);
            return(found);
        }
 static RegionTraverser()
 {
     RegionTraverser.freeWorkers = new Queue <RegionTraverser.BFSWorker>();
     RegionTraverser.NumWorkers  = 8;
     RegionTraverser.PassAll     = ((Region from, Region to) => true);
     RegionTraverser.RecreateWorkers();
 }
        private static Region ClosestRegionWithinTemperatureRange(IntVec3 root, Map map, TraverseParms traverseParms, RegionType traversableRegionTypes = RegionType.Set_Passable)
        {
            Region        region  = root.GetRegion(map, traversableRegionTypes);
            MapComp_Noise mapComp = map.GetComponent <MapComp_Noise>();

            if (region == null || mapComp == null)
            {
                return(null);
            }
            RegionEntryPredicate entryCondition = (Region from, Region r) => r.Allows(traverseParms, false);
            Region          foundReg            = null;
            RegionProcessor regionProcessor     = delegate(Region r)
            {
                if (r.IsDoorway)
                {
                    return(false);
                }
                if (NoiseUtility.IsSilentEnough(region))
                {
                    foundReg = r;
                    return(true);
                }
                return(false);
            };

            RegionTraverser.BreadthFirstTraverse(region, entryCondition, regionProcessor, 9999, traversableRegionTypes);
            return(foundReg);
        }
 static RegionTraverser()
 {
     freeWorkers = new Queue <BFSWorker>();
     NumWorkers  = 8;
     PassAll     = (Region from, Region to) => true;
     RecreateWorkers();
 }
 public static void MarkRegionsBFS(Region root, RegionEntryPredicate entryCondition, int maxRegions, int inRadiusMark, RegionType traversableRegionTypes = RegionType.Set_Passable)
 {
     BreadthFirstTraverse(root, entryCondition, delegate(Region r)
     {
         r.mark = inRadiusMark;
         return(false);
     }, maxRegions, traversableRegionTypes);
 }
        public static void BreadthFirstTraverse(IntVec3 start, Map map, RegionEntryPredicate entryCondition, RegionProcessor regionProcessor, int maxRegions = 999999, RegionType traversableRegionTypes = RegionType.Set_Passable)
        {
            Region region = start.GetRegion(map, traversableRegionTypes);

            if (region != null)
            {
                BreadthFirstTraverse(region, entryCondition, regionProcessor, maxRegions, traversableRegionTypes);
            }
        }
        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);
            bool   result;

            if (region == null)
            {
                result = false;
            }
            else if (region.Room.TouchesMapEdge)
            {
                result = true;
            }
            else
            {
                RegionEntryPredicate entryCondition = (Region from, Region r) => r.Allows(traverseParms, false);
                bool            foundReg            = false;
                RegionProcessor regionProcessor     = delegate(Region r)
                {
                    bool result2;
                    if (r.Room.TouchesMapEdge)
                    {
                        foundReg = true;
                        result2  = true;
                    }
                    else
                    {
                        result2 = false;
                    }
                    return(result2);
                };
                RegionTraverser.BreadthFirstTraverse(region, entryCondition, regionProcessor, 9999, RegionType.Set_Passable);
                result = foundReg;
            }
            return(result);
        }
Example #11
0
 public void BreadthFirstTraverseWork(
     Region root,
     RegionEntryPredicate entryCondition,
     RegionProcessor regionProcessor,
     int maxRegions,
     RegionType traversableRegionTypes)
 {
     if ((root.type & traversableRegionTypes) == RegionType.None)
     {
         return;
     }
     ++this.closedIndex;
     this.open.Clear();
     this.numRegionsProcessed = 0;
     this.QueueNewOpenRegion(root);
     while (this.open.Count > 0)
     {
         Region region1 = this.open.Dequeue();
         if (DebugViewSettings.drawRegionTraversal)
         {
             region1.Debug_Notify_Traversed();
         }
         if (regionProcessor != null && regionProcessor(region1))
         {
             this.FinalizeSearch();
             return;
         }
         if (!region1.IsDoorway)
         {
             ++this.numRegionsProcessed;
         }
         if (this.numRegionsProcessed >= maxRegions)
         {
             this.FinalizeSearch();
             return;
         }
         for (int index1 = 0; index1 < region1.links.Count; ++index1)
         {
             RegionLink link = region1.links[index1];
             for (int index2 = 0; index2 < 2; ++index2)
             {
                 Region region2 = link.regions[index2];
                 if (null != region2 && regionTraverser.regionClosedIndex.ContainsKey(region2) == false)
                 {
                     regionTraverser.regionClosedIndex.Add(region2, new uint[8]);
                 }
                 if (region2 != null && (int)regionTraverser.regionClosedIndex[region2][this.closedArrayPos] != (int)this.closedIndex && (region2.type & traversableRegionTypes) != RegionType.None && (entryCondition == null || entryCondition(region1, region2)))
                 {
                     this.QueueNewOpenRegion(region2);
                 }
             }
         }
     }
     this.FinalizeSearch();
 }
Example #12
0
        private static List <Thing> FindAllFuel(Pawn pawn, Thing refuelable)
        {
            int                  quantity            = refuelable.TryGetComp <CompFilteredRefuelable>().GetFuelCountToFullyRefuel();
            ThingFilter          filter              = refuelable.TryGetComp <CompFilteredRefuelable>().FuelFilter;
            Predicate <Thing>    validator           = (Thing x) => !x.IsForbidden(pawn) && pawn.CanReserve(x, 1, -1, null, false) && filter.Allows(x);
            IntVec3              position            = refuelable.Position;
            Region               region              = position.GetRegion(pawn.Map, RegionType.Set_Passable);
            TraverseParms        traverseParams      = TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false);
            RegionEntryPredicate entryCondition      = (Region from, Region r) => r.Allows(traverseParams, false);
            List <Thing>         chosenThings        = new List <Thing>();
            int                  accumulatedQuantity = 0;
            RegionProcessor      regionProcessor     = delegate(Region r)
            {
                List <Thing> list = r.ListerThings.ThingsMatching(ThingRequest.ForGroup(ThingRequestGroup.HaulableEver));
                for (int i = 0; i < list.Count; i++)
                {
                    Thing thing = list[i];
                    bool  flag2 = validator(thing);
                    if (flag2)
                    {
                        bool flag3 = !chosenThings.Contains(thing);
                        if (flag3)
                        {
                            bool flag4 = ReachabilityWithinRegion.ThingFromRegionListerReachable(thing, r, PathEndMode.ClosestTouch, pawn);
                            if (flag4)
                            {
                                chosenThings.Add(thing);
                                accumulatedQuantity += thing.stackCount;
                                bool flag5 = accumulatedQuantity >= quantity;
                                if (flag5)
                                {
                                    return(true);
                                }
                            }
                        }
                    }
                }
                return(false);
            };

            RegionTraverser.BreadthFirstTraverse(region, entryCondition, regionProcessor, 99999, RegionType.Set_Passable);
            bool         flag = accumulatedQuantity >= quantity;
            List <Thing> result;

            if (flag)
            {
                result = chosenThings;
            }
            else
            {
                result = null;
            }
            return(result);
        }
Example #13
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 = (Region from, Region to) => to.Allows(traverseParams, false) && (maxDistance > 5000f || 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 = (priorityGetter == null) ? 0f : 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);
        }
Example #14
0
        public static List <Thing> FindEnoughReservableThings(Pawn pawn, IntVec3 rootCell, IntRange desiredQuantity, Predicate <Thing> validThing)
        {
            Predicate <Thing> validator = delegate(Thing x)
            {
                if (x.IsForbidden(pawn) || !pawn.CanReserve(x))
                {
                    return(false);
                }
                return(validThing(x) ? true : false);
            };
            Region               region2        = rootCell.GetRegion(pawn.Map);
            TraverseParms        traverseParams = TraverseParms.For(pawn);
            RegionEntryPredicate entryCondition = (Region from, Region r) => r.Allows(traverseParams, isDestination: false);
            List <Thing>         chosenThings   = new List <Thing>();
            int accumulatedQuantity             = 0;

            ThingListProcessor(rootCell.GetThingList(region2.Map), region2);
            if (accumulatedQuantity < desiredQuantity.max)
            {
                RegionTraverser.BreadthFirstTraverse(region2, entryCondition, RegionProcessor, 99999);
            }
            if (accumulatedQuantity >= desiredQuantity.min)
            {
                return(chosenThings);
            }
            return(null);

            bool RegionProcessor(Region r)
            {
                List <Thing> things2 = r.ListerThings.ThingsMatching(ThingRequest.ForGroup(ThingRequestGroup.HaulableEver));

                return(ThingListProcessor(things2, r));
            }

            bool ThingListProcessor(List <Thing> things, Region region)
            {
                for (int i = 0; i < things.Count; i++)
                {
                    Thing thing = things[i];
                    if (validator(thing) && !chosenThings.Contains(thing) && ReachabilityWithinRegion.ThingFromRegionListerReachable(thing, region, PathEndMode.ClosestTouch, pawn))
                    {
                        chosenThings.Add(thing);
                        accumulatedQuantity += thing.stackCount;
                        if (accumulatedQuantity >= desiredQuantity.max)
                        {
                            return(true);
                        }
                    }
                }
                return(false);
            }
        }
Example #15
0
 public void MarkRegionsBFS(
     Region root,
     RegionEntryPredicate entryCondition,
     int maxRegions,
     int inRadiusMark,
     RegionType traversableRegionTypes = RegionType.Set_Passable)
 {
     BreadthFirstTraverse(root, entryCondition, (RegionProcessor)(r =>
     {
         r.mark = inRadiusMark;
         return(false);
     }), maxRegions, traversableRegionTypes);
 }
Example #16
0
        public bool CanReachUnfogged(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 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=",
                        this.map
                    }));
                    return(false);
                }
            }
            if (!c.InBounds(this.map))
            {
                return(false);
            }
            if (!c.Fogged(this.map))
            {
                return(true);
            }
            Region region = c.GetRegion(this.map, RegionType.Set_Passable);

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

            RegionTraverser.BreadthFirstTraverse(region, entryCondition, regionProcessor, 9999, RegionType.Set_Passable);
            return(foundReg);
        }
Example #17
0
 public void BreadthFirstTraverseWork(Region root, RegionEntryPredicate entryCondition, RegionProcessor regionProcessor, int maxRegions, RegionType traversableRegionTypes)
 {
     if ((root.type & traversableRegionTypes) == RegionType.None)
     {
         return;
     }
     ProfilerThreadCheck.BeginSample("BreadthFirstTraversal");
     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();
         }
         ProfilerThreadCheck.BeginSample("regionProcessor");
         if (regionProcessor != null && regionProcessor(region))
         {
             this.FinalizeSearch();
             ProfilerThreadCheck.EndSample();
             ProfilerThreadCheck.EndSample();
             return;
         }
         ProfilerThreadCheck.EndSample();
         this.numRegionsProcessed++;
         if (this.numRegionsProcessed >= maxRegions)
         {
             this.FinalizeSearch();
             ProfilerThreadCheck.EndSample();
             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();
     ProfilerThreadCheck.EndSample();
 }
 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);
         };
         BreadthFirstTraverse(root, entryCondition, regionProcessor, 999999, RegionType.Set_All);
     }
 }
Example #19
0
        private static List <Thing> FindAllFuel(Pawn pawn, Thing refuelable)
        {
            int               quantity  = refuelable.TryGetComp <CompRefuelable>().GetFuelCountToFullyRefuel();
            ThingFilter       filter    = refuelable.TryGetComp <CompRefuelable>().Props.fuelFilter;
            Predicate <Thing> validator = delegate(Thing x)
            {
                if (x.IsForbidden(pawn) || !pawn.CanReserve(x))
                {
                    return(false);
                }
                if (!filter.Allows(x))
                {
                    return(false);
                }
                return(true);
            };
            IntVec3              position       = refuelable.Position;
            Region               region         = position.GetRegion(pawn.Map);
            TraverseParms        traverseParams = TraverseParms.For(pawn);
            RegionEntryPredicate entryCondition = (Region from, Region r) => r.Allows(traverseParams, isDestination: false);
            List <Thing>         chosenThings   = new List <Thing>();
            int             accumulatedQuantity = 0;
            RegionProcessor regionProcessor     = delegate(Region r)
            {
                List <Thing> list = r.ListerThings.ThingsMatching(ThingRequest.ForGroup(ThingRequestGroup.HaulableEver));
                for (int i = 0; i < list.Count; i++)
                {
                    Thing thing = list[i];
                    if (validator(thing) && !chosenThings.Contains(thing) && ReachabilityWithinRegion.ThingFromRegionListerReachable(thing, r, PathEndMode.ClosestTouch, pawn))
                    {
                        chosenThings.Add(thing);
                        accumulatedQuantity += thing.stackCount;
                        if (accumulatedQuantity >= quantity)
                        {
                            return(true);
                        }
                    }
                }
                return(false);
            };

            RegionTraverser.BreadthFirstTraverse(region, entryCondition, regionProcessor, 99999);
            if (accumulatedQuantity >= quantity)
            {
                return(chosenThings);
            }
            return(null);
        }
 public void BreadthFirstTraverseWork(Region root, RegionEntryPredicate entryCondition, RegionProcessor regionProcessor, int maxRegions, RegionType traversableRegionTypes)
 {
     if ((root.type & traversableRegionTypes) == 0)
     {
         return;
     }
     closedIndex++;
     open.Clear();
     numRegionsProcessed = 0;
     QueueNewOpenRegion(root);
     while (open.Count > 0)
     {
         Region region = open.Dequeue();
         if (DebugViewSettings.drawRegionTraversal)
         {
             region.Debug_Notify_Traversed();
         }
         if (regionProcessor != null && regionProcessor(region))
         {
             FinalizeSearch();
             return;
         }
         if (ShouldCountRegion(region))
         {
             numRegionsProcessed++;
         }
         if (numRegionsProcessed >= maxRegions)
         {
             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[closedArrayPos] != closedIndex && (region2.type & traversableRegionTypes) != 0 && (entryCondition == null || entryCondition(region, region2)))
                 {
                     QueueNewOpenRegion(region2);
                 }
             }
         }
     }
     FinalizeSearch();
 }
Example #21
0
        protected override Job TryGiveJob(Pawn pawn)
        {
            if (!pawn.Position.IsForbidden(pawn))
            {
                return(null);
            }
            if (this.HasJobWithSpawnedAllowedTarget(pawn))
            {
                return(null);
            }
            Region region = pawn.GetRegion(RegionType.Set_Passable);

            if (region == null)
            {
                return(null);
            }
            TraverseParms        traverseParms  = TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false);
            RegionEntryPredicate entryCondition = (Region from, Region r) => r.Allows(traverseParms, false);
            Region          reg             = null;
            RegionProcessor regionProcessor = delegate(Region r)
            {
                if (r.portal != null)
                {
                    return(false);
                }
                if (!r.IsForbiddenEntirely(pawn))
                {
                    reg = r;
                    return(true);
                }
                return(false);
            };

            RegionTraverser.BreadthFirstTraverse(region, entryCondition, regionProcessor, 9999, RegionType.Set_Passable);
            if (reg == null)
            {
                return(null);
            }
            IntVec3 c;

            if (!reg.TryFindRandomCellInRegionUnforbidden(pawn, null, out c))
            {
                return(null);
            }
            return(new Job(JobDefOf.Goto, c));
        }
Example #22
0
        private static List <Thing> FindAllFuel(Pawn pawn, Thing refuelable)
        {
            CompRefuelable comp     = refuelable.TryGetComp <CompRefuelable>();
            int            quantity = GetFuelCountToFullyRefuel(comp);
            ThingFilter    filter   = new ThingFilter();

            filter = refuelable.TryGetComp <CompSelectFuel>().FuelSettings.filter;
            Predicate <Thing>    validator      = (Thing x) => !x.IsForbidden(pawn) && pawn.CanReserve(x, 1, -1, null, false) && filter.Allows(x);
            IntVec3              position       = refuelable.Position;
            Region               region         = position.GetRegion(pawn.Map, RegionType.Set_Passable); // NOTE: comes out null if refuelable is inside a wall, even with matching RegionType. Why?
            TraverseParms        traverseParams = TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false);
            RegionEntryPredicate entryCondition = (Region from, Region r) => r.Allows(traverseParams, false);
            List <Thing>         chosenThings   = new List <Thing>();
            int             accumulatedQuantity = 0;
            RegionProcessor regionProcessor     = delegate(Region r)
            {
                List <Thing> list = r.ListerThings.ThingsMatching(ThingRequest.ForGroup(ThingRequestGroup.HaulableEver));
                for (int i = 0; i < list.Count; i++)
                {
                    Thing thing = list[i];
                    if (validator(thing))
                    {
                        if (!chosenThings.Contains(thing))
                        {
                            if (ReachabilityWithinRegion.ThingFromRegionListerReachable(thing, r, PathEndMode.ClosestTouch, pawn))
                            {
                                chosenThings.Add(thing);
                                accumulatedQuantity += thing.stackCount;
                                if (accumulatedQuantity >= quantity)
                                {
                                    return(true);
                                }
                            }
                        }
                    }
                }
                return(false);
            };

            RegionTraverser.BreadthFirstTraverse(region, entryCondition, regionProcessor, 99999, RegionType.Set_Passable);
            if (accumulatedQuantity >= quantity)
            {
                return(chosenThings);
            }
            return(null);
        }
Example #23
0
        public static bool BreadthFirstTraverse(
            Region root,
            RegionEntryPredicate entryCondition,
            RegionProcessor regionProcessor,
            int maxRegions = 999999,
            RegionType traversableRegionTypes = RegionType.Set_Passable)
        {
            RegionTraverser2 regionTraverser;
            int t = Thread.CurrentThread.ManagedThreadId;

            lock (regionTraverser2Dict)
            {
                if (!regionTraverser2Dict.TryGetValue(t, out regionTraverser))
                {
                    regionTraverser = new RegionTraverser2();
                    regionTraverser2Dict.Add(t, regionTraverser);
                }
            }

            if (regionTraverser.freeWorkers.Count == 0)
            {
                Log.Error("No free workers for breadth-first traversal. Either BFS recurred deeper than " + regionTraverser.NumWorkers + ", or a bug has put this system in an inconsistent state. Resetting.", false);
            }
            else if (root == null)
            {
                Log.Error("BreadthFirstTraverse with null root region.", false);
            }
            else
            {
                BFSWorker_Patch bfsWorker = regionTraverser.freeWorkers.Dequeue();
                try
                {
                    bfsWorker.BreadthFirstTraverseWork(root, entryCondition, regionProcessor, maxRegions, traversableRegionTypes);
                }
                catch (Exception ex)
                {
                    Log.Error("Exception in BreadthFirstTraverse: " + ex.ToString(), false);
                }
                finally
                {
                    bfsWorker.Clear();
                    regionTraverser.freeWorkers.Enqueue(bfsWorker);
                }
            }
            return(false);
        }
        protected override Job TryGiveJob(Pawn pawn)
        {
            if (!pawn.Position.IsForbidden(pawn))
            {
                return(null);
            }
            if (HasJobWithSpawnedAllowedTarget(pawn))
            {
                return(null);
            }
            Region region = pawn.GetRegion();

            if (region == null)
            {
                return(null);
            }
            TraverseParms        traverseParms  = TraverseParms.For(pawn);
            RegionEntryPredicate entryCondition = (Region from, Region r) => r.Allows(traverseParms, isDestination: false);
            Region          reg             = null;
            RegionProcessor regionProcessor = delegate(Region r)
            {
                if (r.IsDoorway)
                {
                    return(false);
                }
                if (!r.IsForbiddenEntirely(pawn))
                {
                    reg = r;
                    return(true);
                }
                return(false);
            };

            RegionTraverser.BreadthFirstTraverse(region, entryCondition, regionProcessor, 9999);
            if (reg != null)
            {
                if (!reg.TryFindRandomCellInRegionUnforbidden(pawn, null, out IntVec3 result))
                {
                    return(null);
                }
                return(JobMaker.MakeJob(JobDefOf.Goto, result));
            }
            return(null);
        }
Example #25
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);
        }
Example #26
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("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);
        }
Example #27
0
        public Room FloodAndSetRooms(Region root, Map map, Room existingRoom)
        {
            Room floodingRoom = existingRoom != null ? existingRoom : Room.MakeNew(map);

            root.Room = floodingRoom;
            if (!root.type.AllowsMultipleRegionsPerRoom())
            {
                return(floodingRoom);
            }
            RegionEntryPredicate entryCondition  = ((from, r) => r.type == root.type && r.Room != floodingRoom);
            RegionProcessor      regionProcessor = (r =>
            {
                r.Room = floodingRoom;
                return(false);
            });

            BreadthFirstTraverse(root, entryCondition, regionProcessor, 999999, RegionType.Set_All);
            return(floodingRoom);
        }
Example #28
0
        private bool TryFindBestItem(Pawn pawn, ThingDef thingDef, int need, List <ThingCount> chosen)
        {
            chosen.Clear();

            Region rootReg = Position.GetRegion(pawn.Map);

            if (rootReg == null)
            {
                return(false);
            }

            Predicate <Thing>    baseValidator       = (Thing t) => t.Spawned && !t.IsForbidden(pawn) && pawn.CanReserve(t);
            TraverseParms        traverseParams      = TraverseParms.For(pawn);
            RegionEntryPredicate entryCondition      = (Region from, Region r) => r.Allows(traverseParams, isDestination: false);
            int             adjacentRegionsAvailable = rootReg.Neighbors.Count((Region region) => entryCondition(rootReg, region));
            bool            found           = false;
            RegionProcessor regionProcessor = delegate(Region r)
            {
                List <Thing> list = r.ListerThings.ThingsOfDef(thingDef);
                for (int i = 0; i < list.Count; i++)
                {
                    Thing thing = list[i];

                    int count = Mathf.Min(thing.stackCount, need);
                    chosen.Add(new ThingCount(thing, count));
                    need -= count;

                    if (need <= 0)
                    {
                        found = true;
                        return(true);
                    }
                }
                return(false);
            };

            RegionTraverser.BreadthFirstTraverse(rootReg, entryCondition, regionProcessor, 99999);

            return(found);
        }
Example #29
0
        public bool CanReachMapEdge(IntVec3 c, TraverseParms traverseParms)
        {
            if (traverseParms.pawn != null)
            {
                if (!traverseParms.pawn.Spawned)
                {
                    return(false);
                }
                if (traverseParms.pawn.Map != map)
                {
                    Log.Error(string.Concat("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=", map));
                    return(false);
                }
            }
            Region region = c.GetRegion(map);

            if (region == null)
            {
                return(false);
            }
            if (region.Room.TouchesMapEdge)
            {
                return(true);
            }
            RegionEntryPredicate entryCondition = (Region from, Region r) => r.Allows(traverseParms, isDestination: 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);
            return(foundReg);
        }
Example #30
0
        public bool WithinRegions(
            IntVec3 A,
            IntVec3 B,
            Map map,
            int regionLookCount,
            TraverseParms traverseParams,
            RegionType traversableRegionTypes = RegionType.Set_Passable)
        {
            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 = ((from, r) => r.Allows(traverseParams, false));
            bool            found           = false;
            RegionProcessor regionProcessor = (r =>
            {
                if (r != regB)
                {
                    return(false);
                }
                found = true;
                return(true);
            });

            BreadthFirstTraverse(region, entryCondition, regionProcessor, regionLookCount, traversableRegionTypes);
            return(found);
        }