Пример #1
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);
        }
Пример #2
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);
 }
Пример #3
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);
        }
Пример #4
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);
        }
Пример #5
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);
        }
Пример #6
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);
            }
        }
Пример #7
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("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);
                    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);
        }
Пример #8
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);
            }
        }
Пример #9
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);
        }
Пример #10
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);
        }
Пример #11
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
                    }), false);
                    return(false);
                }
            }
            bool result;

            if (!c.InBounds(this.map))
            {
                result = false;
            }
            else if (!c.Fogged(this.map))
            {
                result = true;
            }
            else
            {
                Region region = c.GetRegion(this.map, RegionType.Set_Passable);
                if (region == null)
                {
                    result = false;
                }
                else
                {
                    RegionEntryPredicate entryCondition = (Region from, Region r) => r.Allows(traverseParms, false);
                    bool            foundReg            = false;
                    RegionProcessor regionProcessor     = delegate(Region r)
                    {
                        bool result2;
                        if (!r.AnyCell.Fogged(this.map))
                        {
                            foundReg = true;
                            result2  = true;
                        }
                        else
                        {
                            result2 = false;
                        }
                        return(result2);
                    };
                    RegionTraverser.BreadthFirstTraverse(region, entryCondition, regionProcessor, 9999, RegionType.Set_Passable);
                    result = foundReg;
                }
            }
            return(result);
        }
Пример #12
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);
        }