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