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