Exemple #1
0
        public static bool RegionwiseBFSWorker(ref Thing __result,
                                               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.", false);
                __result = (Thing)null;
                return(false);
            }
            if (traverseParams.mode == TraverseMode.PassAllDestroyableThingsNotWater)
            {
                Log.Error("RegionwiseBFSWorker with traverseParams.mode PassAllDestroyableThingsNotWater. Use ClosestThingGlobal.", false);
                __result = (Thing)null;
                return(false);
            }
            if (!req.IsUndefined && !req.CanBeFoundInRegion)
            {
                Log.ErrorOnce("RegionwiseBFSWorker with thing request group " + (object)req.group + ". This group is never stored in regions. Most likely a global search should have been used.", 385766189, false);
                __result = (Thing)null;
                return(false);
            }
            Region region = root.GetRegion(map, traversableRegionTypes);

            if (region == null)
            {
                __result = (Thing)null;
                return(false);
            }
            float maxDistSquared = maxDistance * maxDistance;
            RegionEntryPredicate entryCondition = (RegionEntryPredicate)((from, to) =>
            {
                if (!to.Allows(traverseParams, false))
                {
                    return(false);
                }
                return((double)maxDistance > 5000.0 || (double)to.extentsClose.ClosestDistSquaredTo(root) < (double)maxDistSquared);
            });
            Thing           closestThing       = (Thing)null;
            float           closestDistSquared = 9999999f;
            float           bestPrio           = float.MinValue;
            int             regionsSeenScan    = 0;
            RegionProcessor regionProcessor    = (RegionProcessor)(r =>
            {
                if (RegionTraverser.ShouldCountRegion(r))
                {
                    ++regionsSeenScan;
                }
                if (!r.IsDoorway && !r.Allows(traverseParams, true))
                {
                    return(false);
                }
                if (!ignoreEntirelyForbiddenRegions || !r.IsForbiddenEntirely(traverseParams.pawn))
                {
                    Thing[] arrayThingList;
                    List <Thing> thingList = r.ListerThings.ThingsMatching(req);
                    lock (thingList)
                    {
                        arrayThingList = thingList.ToArray();
                    }
                    for (int index = 0; index < arrayThingList.Length; ++index)
                    {
                        Thing thing = arrayThingList[index];
                        if (ReachabilityWithinRegion.ThingFromRegionListerReachable(thing, r, peMode, traverseParams.pawn))
                        {
                            float num = priorityGetter != null ? priorityGetter(thing) : 0.0f;
                            if ((double)num >= (double)bestPrio)
                            {
                                float horizontalSquared = (float)(thing.Position - root).LengthHorizontalSquared;
                                if (((double)num > (double)bestPrio || (double)horizontalSquared < (double)closestDistSquared) && (double)horizontalSquared < (double)maxDistSquared && (validator == null || validator(thing)))
                                {
                                    closestThing = thing;
                                    closestDistSquared = horizontalSquared;
                                    bestPrio = num;
                                }
                            }
                        }
                    }
                }
                return(regionsSeenScan >= minRegions && closestThing != null);
            });

            RegionTraverser.BreadthFirstTraverse(region, entryCondition, regionProcessor, maxRegions, traversableRegionTypes);
            regionsSeen = regionsSeenScan;
            __result    = closestThing;
            return(false);
        }
Exemple #2
0
        public static Plant RegionwiseBFSWorker(IntVec3 root, Map map, ThingRequest req, PathEndMode peMode, TraverseParms traverseParams, Predicate <Plant> 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.", false);
                return(null);
            }
            if (traverseParams.mode == TraverseMode.PassAllDestroyableThingsNotWater)
            {
                Log.Error("RegionwiseBFSWorker with traverseParams.mode PassAllDestroyableThingsNotWater. Use ClosestThingGlobal.", false);
                return(null);
            }
            if (!req.IsUndefined && !req.CanBeFoundInRegion)
            {
                Log.ErrorOnce("RegionwiseBFSWorker with thing request group " + req.group + ". This group is never stored in regions. Most likely a global search should have been used.", 385766189, false);
                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);
            Plant           closestPlant        = null;
            float           closestDistSquared  = 9999999f;
            float           bestPrio            = -3.40282347E+38f;
            int             regionsSeenScan     = 0;
            RegionProcessor regionProcessor     = delegate(Region r)
            {
                if (RegionTraverser.ShouldCountRegion(r))
                {
                    regionsSeenScan++;
                }
                if (!r.IsDoorway && !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++)
                    {
                        Plant plant = list[i] as Plant;
                        if (ReachabilityWithinRegion.ThingFromRegionListerReachable(plant, r, peMode, traverseParams.pawn))
                        {
                            float num = (priorityGetter == null) ? 0f : priorityGetter(plant);
                            if (num >= bestPrio)
                            {
                                float num2 = (plant.Position - root).LengthHorizontalSquared;
                                if ((num > bestPrio || num2 < closestDistSquared) && num2 < maxDistSquared && (validator == null || validator(plant)))
                                {
                                    closestPlant       = plant;
                                    closestDistSquared = num2;
                                    bestPrio           = num;
                                }
                            }
                        }
                    }
                }
                return(regionsSeenScan >= minRegions && closestPlant != null);
            };

            RegionTraverser.BreadthFirstTraverse(region, entryCondition, regionProcessor, maxRegions, traversableRegionTypes);
            regionsSeen = regionsSeenScan;
            return(closestPlant);
        }
        public static Thing RegionwiseBFSWorker(IntVec3 root, Map map, List <Thing> thingList, PathEndMode peMode, TraverseParms traverseParams, Predicate <Thing> validator, Func <Thing, float> priorityGetter, int minRegions, int maxRegions, float mDsq, out int regionsSeen, RegionType traversableRegionTypes = RegionType.Set_Passable, bool ignoreEntirelyForbiddenRegions = false)
        {
            regionsSeen = 0;
            if (traverseParams.mode == TraverseMode.PassAllDestroyableThings)
            {
                Log.Error("CombatExtended :: RegionwiseBFSWorker with traverseParams.mode PassAllDestroyableThings. Use ClosestThingGlobal.", false);
                return(null);
            }
            if (traverseParams.mode == TraverseMode.PassAllDestroyableThingsNotWater)
            {
                Log.Error("CombatExtended :: RegionwiseBFSWorker with traverseParams.mode PassAllDestroyableThingsNotWater. Use ClosestThingGlobal.", false);
                return(null);
            }
            Region region = root.GetRegion(map, traversableRegionTypes);

            if (region == null)
            {
                return(null);
            }

            RegionEntryPredicate entryCondition = (Region from, Region to) => to.Allows(traverseParams, false) && (mDsq > 25000000f || to.extentsClose.ClosestDistSquaredTo(root) < mDsq);
            Thing           closestThing        = null;
            int             regionsSeenScan2    = 0;
            float           closestDistSquared  = 9999999f;
            float           bestPrio            = -1;
            RegionProcessor regionProcessor     = delegate(Region r)
            {
                int regionsSeenScan;
                if (RegionTraverser.ShouldCountRegion(r))
                {
                    regionsSeenScan = regionsSeenScan2;
                    regionsSeenScan2++;
                }
                if (!r.IsDoorway && !r.Allows(traverseParams, true))
                {
                    return(false);
                }
                if (!ignoreEntirelyForbiddenRegions || !r.IsForbiddenEntirely(traverseParams.pawn))
                {
                    foreach (var item in thingList)
                    {
                        if (ReachabilityWithinRegion.ThingFromRegionListerReachable(item, r, peMode, traverseParams.pawn))
                        {
                            float num = (priorityGetter != null) ? priorityGetter(item) : 0f;
                            if (num >= bestPrio)
                            {
                                float num2 = (float)(item.Position - root).LengthHorizontalSquared;
                                if ((num > bestPrio || num2 < closestDistSquared) && num2 < mDsq && (validator == null || validator(item)))
                                {
                                    closestThing       = item;
                                    closestDistSquared = num2;
                                    bestPrio           = num;
                                }
                            }
                        }
                    }
                }
                return(regionsSeenScan2 >= minRegions && closestThing != null);
            };

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