public static void GetSmashableThingsNear(Pawn pawn, IntVec3 near, List <Thing> outCandidates, Predicate <Thing> customValidator = null, int extraMinBuildingOrItemMarketValue = 0, int maxDistance = 40) { outCandidates.Clear(); if (!pawn.CanReach(near, PathEndMode.OnCell, Danger.Deadly, false, TraverseMode.ByPawn)) { return; } Region region = near.GetRegion(pawn.Map, RegionType.Set_Passable); if (region == null) { return; } TraverseParms traverseParams = TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false); RegionTraverser.BreadthFirstTraverse(region, (Region from, Region to) => to.Allows(traverseParams, false), delegate(Region r) { List <Thing> list = r.ListerThings.ThingsInGroup(ThingRequestGroup.BuildingArtificial); for (int i = 0; i < list.Count; i++) { if (list[i].Position.InHorDistOf(near, (float)maxDistance) && TantrumMentalStateUtility.CanSmash(pawn, list[i], true, customValidator, extraMinBuildingOrItemMarketValue)) { outCandidates.Add(list[i]); } } List <Thing> list2 = r.ListerThings.ThingsInGroup(ThingRequestGroup.HaulableEver); for (int j = 0; j < list2.Count; j++) { if (list2[j].Position.InHorDistOf(near, (float)maxDistance) && TantrumMentalStateUtility.CanSmash(pawn, list2[j], true, customValidator, extraMinBuildingOrItemMarketValue)) { outCandidates.Add(list2[j]); } } List <Thing> list3 = r.ListerThings.ThingsInGroup(ThingRequestGroup.Pawn); for (int k = 0; k < list3.Count; k++) { if (list3[k].Position.InHorDistOf(near, (float)maxDistance) && TantrumMentalStateUtility.CanSmash(pawn, list3[k], true, customValidator, extraMinBuildingOrItemMarketValue)) { outCandidates.Add(list3[k]); } } return(false); }, 40, RegionType.Set_Passable); }
public static bool TryFindPrisonerReleaseCell(Pawn prisoner, Pawn warden, out IntVec3 result) { if (prisoner.Map != warden.Map) { result = IntVec3.Invalid; return(false); } Region region = prisoner.GetRegion(); if (region == null) { result = default(IntVec3); return(false); } TraverseParms traverseParms = TraverseParms.For(warden); bool needMapEdge = prisoner.Faction != warden.Faction; IntVec3 foundResult = IntVec3.Invalid; RegionProcessor regionProcessor = delegate(Region r) { if (needMapEdge) { if (!r.Room.TouchesMapEdge) { return(false); } } else if (r.Room.isPrisonCell) { return(false); } foundResult = r.RandomCell; return(true); }; RegionTraverser.BreadthFirstTraverse(region, (Region from, Region r) => r.Allows(traverseParms, isDestination: false), regionProcessor, 999); if (foundResult.IsValid) { result = foundResult; return(true); } result = default(IntVec3); return(false); }
/// <summary> /// This method is a direct copy/paste of the <see cref="RefuelWorkGiverUtility"/> private FindAllFuel method. /// /// Finds all relevant ammo in order of distance. /// </summary> /// <param name="pawn"></param> /// <param name="reloadable"></param> /// <returns></returns> private static List <Thing> FindAllAmmo(Pawn pawn, Building_TurretGunCE reloadable) { int quantity = reloadable.CompAmmo.MissingToFullMagazine; var ammoKind = reloadable.CompAmmo.SelectedAmmo; Predicate <Thing> validator = (Thing potentialAmmo) => { if (potentialAmmo.IsForbidden(pawn) || !pawn.CanReserve(potentialAmmo)) { return(false); } return(GetPathCost(pawn, potentialAmmo) <= MaxPathCost); }; Region region = reloadable.Position.GetRegion(pawn.Map); TraverseParms traverseParams = TraverseParms.For(pawn); Verse.RegionEntryPredicate entryCondition = (Region from, Region r) => r.Allows(traverseParams, isDestination: false); var chosenThings = new List <Thing>(); int accumulatedQuantity = 0; Verse.RegionProcessor regionProcessor = (Region r) => { List <Thing> list = r.ListerThings.ThingsMatching(ThingRequest.ForDef(ammoKind)); foreach (var thing in list) { 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); }
private bool SaturatedAt(IntVec3 c, float plantDensity, bool cavePlants, float wholeMapNumDesiredPlants) { int num = GenRadial.NumCellsInRadius(20f); if (wholeMapNumDesiredPlants * ((float)num / (float)map.Area) <= 4f || !map.Biome.wildPlantsCareAboutLocalFertility) { return((float)map.listerThings.ThingsInGroup(ThingRequestGroup.Plant).Count >= wholeMapNumDesiredPlants); } float numDesiredPlantsLocally = 0f; int numPlants = 0; RegionTraverser.BreadthFirstTraverse(c, map, (Region from, Region to) => c.InHorDistOf(to.extentsClose.ClosestCellTo(c), 20f), delegate(Region reg) { numDesiredPlantsLocally += GetDesiredPlantsCountIn(reg, c, plantDensity); numPlants += reg.ListerThings.ThingsInGroup(ThingRequestGroup.Plant).Count; return(false); }); return((float)numPlants >= numDesiredPlantsLocally); }
public static void NotifyFacilitiesAboutChangedLOSBlockers(List <Region> affectedRegions) { if (FacilitiesUtility.working) { Log.Warning("Tried to update facilities while already updating."); return; } FacilitiesUtility.working = true; try { FacilitiesUtility.visited.Clear(); for (int i = 0; i < affectedRegions.Count; i++) { if (!FacilitiesUtility.visited.Contains(affectedRegions[i])) { RegionTraverser.BreadthFirstTraverse(affectedRegions[i], (Region from, Region r) => !FacilitiesUtility.visited.Contains(r), delegate(Region x) { FacilitiesUtility.visited.Add(x); List <Thing> list = x.ListerThings.ThingsInGroup(ThingRequestGroup.BuildingArtificial); for (int j = 0; j < list.Count; j++) { CompFacility compFacility = list[j].TryGetComp <CompFacility>(); CompAffectedByFacilities compAffectedByFacilities = list[j].TryGetComp <CompAffectedByFacilities>(); if (compFacility != null) { compFacility.Notify_LOSBlockerSpawnedOrDespawned(); } if (compAffectedByFacilities != null) { compAffectedByFacilities.Notify_LOSBlockerSpawnedOrDespawned(); } } return(false); }, FacilitiesUtility.RegionsToSearch, RegionType.Set_Passable); } } } finally { FacilitiesUtility.working = false; FacilitiesUtility.visited.Clear(); } }
private static bool TryFindSpotToPlaceHaulableCloseTo(Thing haulable, Pawn worker, IntVec3 center, out IntVec3 spot) { Region region = center.GetRegion(worker.Map, RegionType.Set_Passable); bool result; if (region == null) { spot = center; result = false; } else { TraverseParms traverseParms = TraverseParms.For(worker, Danger.Deadly, TraverseMode.ByPawn, false); IntVec3 foundCell = IntVec3.Invalid; RegionTraverser.BreadthFirstTraverse(region, (Region from, Region r) => r.Allows(traverseParms, false), delegate(Region r) { HaulAIUtility.candidates.Clear(); HaulAIUtility.candidates.AddRange(r.Cells); HaulAIUtility.candidates.Sort((IntVec3 a, IntVec3 b) => a.DistanceToSquared(center).CompareTo(b.DistanceToSquared(center))); for (int i = 0; i < HaulAIUtility.candidates.Count; i++) { IntVec3 intVec = HaulAIUtility.candidates[i]; if (HaulAIUtility.HaulablePlaceValidator(haulable, worker, intVec)) { foundCell = intVec; return(true); } } return(false); }, 100, RegionType.Set_Passable); if (foundCell.IsValid) { spot = foundCell; result = true; } else { spot = center; result = false; } } return(result); }
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); } return(filter.Allows(x) ? true : false); }; Region region = refuelable.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); }
private static bool EnoughLowerOrderPlantsNearby2(WildPlantSpawner __instance, IntVec3 c, float plantDensity, float radiusToScan, ThingDef plantDef) { float num = 0f; //tmpPlantDefsLowerOrder.Clear(); List <ThingDef> tmpPlantDefsLowerOrder = new List <ThingDef>(); List <ThingDef> allWildPlants = map(__instance).Biome.AllWildPlants; for (int i = 0; i < allWildPlants.Count; i++) { ThingDef wildPlant = allWildPlants[i]; if (null != wildPlant) { if (wildPlant.plant.wildOrder < plantDef.plant.wildOrder) { num += GetCommonalityPctOfPlant2(__instance, wildPlant); tmpPlantDefsLowerOrder.Add(wildPlant); } } } float numDesiredPlantsLocally = 0f; int numPlantsLowerOrder = 0; RegionTraverser.BreadthFirstTraverse(c, map(__instance), (Region from, Region to) => c.InHorDistOf(to.extentsClose.ClosestCellTo(c), radiusToScan), delegate(Region reg) { numDesiredPlantsLocally += GetDesiredPlantsCountIn2(map(__instance), reg, c, plantDensity); for (int j = 0; j < tmpPlantDefsLowerOrder.Count; j++) { numPlantsLowerOrder += reg.ListerThings.ThingsOfDef(tmpPlantDefsLowerOrder[j]).Count; } return(false); }); float num2 = numDesiredPlantsLocally * num; if (num2 < 4f) { return(true); } return((float)numPlantsLowerOrder / num2 >= 0.57f); }
public static bool EnemiesAreNearby(Pawn pawn, int regionsToScan = 9, bool passDoors = false) { TraverseParms tp = (!passDoors) ? TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false) : TraverseParms.For(TraverseMode.PassDoors, Danger.Deadly, false); bool foundEnemy = false; RegionTraverser.BreadthFirstTraverse(pawn.Position, pawn.Map, (Region from, Region to) => to.Allows(tp, false), delegate(Region r) { List <Thing> list = r.ListerThings.ThingsInGroup(ThingRequestGroup.AttackTarget); for (int i = 0; i < list.Count; i++) { if (list[i].HostileTo(pawn)) { foundEnemy = true; return(true); } } return(foundEnemy); }, regionsToScan, RegionType.Set_Passable); return(foundEnemy); }
public static Region BrrrClosestRegionWithinTemperatureRange(IntVec3 root, Map map, FloatRange tempRange, TraverseParms traverseParms, RegionType traversableRegionTypes = RegionType.Set_Passable) { var region = root.GetRegion(map, traversableRegionTypes); if (region == null) { return(null); } bool entryCondition(Region from, Region r) { return(r.Allows(traverseParms, false)); } Region foundReg = null; bool regionProcessor(Region r) { if (r.IsDoorway) { return(false); } if (!tempRange.Includes(r.Room.Temperature)) { return(false); } if (!Settings.AllowUnsafeAreas && !r.Cells.Any(vec3 => vec3.InAllowedArea(traverseParms.pawn))) { return(false); } foundReg = r; return(true); } RegionTraverser.BreadthFirstTraverse(region, entryCondition, regionProcessor, 9999, traversableRegionTypes); return(foundReg); }
// Token: 0x06000435 RID: 1077 RVA: 0x0002D9FC File Offset: 0x0002BDFC private Job FleeLargeFireJob(Pawn pawn) { List <Thing> list = pawn.Map.listerThings.ThingsInGroup(ThingRequestGroup.Fire); if (list.Count < 60) { return(null); } TraverseParms tp = TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false); Fire closestFire = null; float closestDistSq = -1f; int firesCount = 0; RegionTraverser.BreadthFirstTraverse(pawn.Position, pawn.Map, (Region from, Region to) => to.Allows(tp, false), delegate(Region x) { List <Thing> list2 = x.ListerThings.ThingsInGroup(ThingRequestGroup.Fire); for (int i = 0; i < list2.Count; i++) { float num = (float)pawn.Position.DistanceToSquared(list2[i].Position); if (num <= 400f) { if (closestFire == null || num < closestDistSq) { closestDistSq = num; closestFire = (Fire)list2[i]; } firesCount++; } } return(closestDistSq <= 100f && firesCount >= 60); }, 18, RegionType.Set_Passable); if (closestDistSq <= 100f && firesCount >= 60) { Job job = this.FleeJob(pawn, closestFire); if (job != null) { return(job); } } return(null); }
static void Postfix(Bombardment __instance) { RegionTraverser.BreadthFirstTraverse(__instance.Position, __instance.Map, (from, to) => true, region => { region.ListerThings.ThingsInGroup(ThingRequestGroup.Pawn) .Select(p => (Pawn)p) .Where(p => !p.Downed && !p.Dead && !p.Drafted) .Where(p => p.CurJobDef != JobDefOf.Flee && !p.Downed) .Where(p => p.Position.DistanceTo(__instance.Position) <= 24.0f) .ToList() .ForEach(pawn => { var threats = new List <Thing> { __instance }; var fleeDest1 = CellFinderLoose.GetFleeDest(pawn, threats, pawn.Position.DistanceTo(__instance.Position) + Bombardment.EffectiveRadius); pawn.jobs.StartJob(new Job(JobDefOf.Flee, fleeDest1, (LocalTargetInfo)__instance), JobCondition.InterruptOptional, null, false, true, null, new JobTag?()); }); return(false); }, 25, RegionType.Set_All); }
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); }
public static bool InDangerousCombat(Pawn pawn) { Region root = pawn.GetRegion(RegionType.Set_Passable); bool found = false; RegionTraverser.BreadthFirstTraverse(root, (Region r1, Region r2) => r2.Room == root.Room, (Region r) => r.ListerThings.ThingsInGroup(ThingRequestGroup.Pawn).Any(delegate(Thing t) { Pawn pawn2 = t as Pawn; bool result; if (pawn2 != null && !pawn2.Downed && (float)(pawn.Position - pawn2.Position).LengthHorizontalSquared < 144f && pawn2.HostileTo(pawn.Faction)) { found = true; result = true; } else { result = false; } return(result); }), 9, RegionType.Set_Passable); return(found); }
private Job FleeLargeFireJob(Pawn pawn) { if (pawn.Map.listerThings.ThingsInGroup(ThingRequestGroup.Fire).Count < 60) { return(null); } TraverseParms tp = TraverseParms.For(pawn); Fire closestFire = null; float closestDistSq = -1f; int firesCount = 0; RegionTraverser.BreadthFirstTraverse(pawn.Position, pawn.Map, (Region from, Region to) => to.Allows(tp, isDestination : false), delegate(Region x) { List <Thing> list = x.ListerThings.ThingsInGroup(ThingRequestGroup.Fire); for (int i = 0; i < list.Count; i++) { float num = pawn.Position.DistanceToSquared(list[i].Position); if (!(num > 400f)) { if (closestFire == null || num < closestDistSq) { closestDistSq = num; closestFire = (Fire)list[i]; } firesCount++; } } return(closestDistSq <= 100f && firesCount >= 60); }, 18); if (closestDistSq <= 100f && firesCount >= 60) { Job job = FleeJob(pawn, closestFire); if (job != null) { return(job); } } return(null); }
public override void StartExplosion(SoundDef explosionSound, List <Thing> ignoredThings) { bool flag = !base.Spawned; if (flag) { Log.Error("Called StartExplosion() on unspawned thing.", false); } else { this.startTick = Find.TickManager.TicksGame; this.ignoredThings = ignoredThings; this.damagedThings.Clear(); this.addedCellsAffectedOnlyByDamage.Clear(); bool applyDamageToExplosionCellsNeighbors = this.applyDamageToExplosionCellsNeighbors; if (applyDamageToExplosionCellsNeighbors) { this.AddCellsNeighbors(this.cellsToAffect); } this.damType.Worker.ExplosionStart(this, this.cellsToAffect); this.PlayExplosionSound(explosionSound); MoteMaker.MakeWaterSplash(base.Position.ToVector3Shifted(), base.Map, this.radius * 6f, 20f); this.cellsToAffect.Sort((IntVec3 a, IntVec3 b) => this.GetCellAffectTick(b).CompareTo(this.GetCellAffectTick(a))); RegionTraverser.BreadthFirstTraverse(base.Position, base.Map, (Region from, Region to) => true, delegate(Region x) { List <Thing> allThings = x.ListerThings.AllThings; for (int i = allThings.Count - 1; i >= 0; i--) { bool spawned = allThings[i].Spawned; if (spawned) { allThings[i].Notify_Explosion(this); } } return(false); }, 25, RegionType.Set_Passable); } }
public static void GetInsultCandidatesFor(Pawn bully, List <Pawn> outCandidates, bool allowPrisoners = true) { outCandidates.Clear(); Region region = bully.GetRegion(); if (region != null) { TraverseParms traverseParams = TraverseParms.For(bully); RegionTraverser.BreadthFirstTraverse(region, (Region from, Region to) => to.Allows(traverseParams, isDestination : false), delegate(Region r) { List <Thing> list = r.ListerThings.ThingsInGroup(ThingRequestGroup.Pawn); for (int i = 0; i < list.Count; i++) { Pawn pawn = (Pawn)list[i]; if (CanChaseAndInsult(bully, pawn, skipReachabilityCheck: true, allowPrisoners)) { outCandidates.Add(pawn); } } return(false); }, 40); } }
private static IntVec3 TryFindSnowmanBuildCell(Pawn pawn) { if (!CellFinder.TryFindClosestRegionWith(pawn.GetRegion(), TraverseParms.For(pawn), (Region r) => r.Room.PsychologicallyOutdoors, 100, out Region rootReg)) { return(IntVec3.Invalid); } IntVec3 result = IntVec3.Invalid; RegionTraverser.BreadthFirstTraverse(rootReg, (Region from, Region r) => r.Room == rootReg.Room, delegate(Region r) { for (int i = 0; i < 5; i++) { IntVec3 randomCell = r.RandomCell; if (IsGoodSnowmanCell(randomCell, pawn)) { result = randomCell; return(true); } } return(false); }, 30); return(result); }
private static int BreadthFirstTraverse(Pawn pawn, TraverseParms tp, float closestDistSq, Fire closestFire, int firesCount) { RegionTraverser.BreadthFirstTraverse(pawn.Position, pawn.Map, (Region from, Region to) => to.Allows(tp, isDestination : false), delegate(Region x) { List <Thing> list = x.ListerThings.ThingsInGroup(ThingRequestGroup.Fire); for (int i = 0; i < list.Count; i++) { float num = pawn.Position.DistanceToSquared(list[i].Position); if (!(num > 400f)) { if (closestFire == null || num < closestDistSq) { closestDistSq = num; closestFire = (Fire)list[i]; } firesCount++; } } return(closestDistSq <= 100f && firesCount >= 60); }, 18); return(firesCount); }
public static void GetInsultCandidatesFor(Pawn bully, List <Pawn> outCandidates, bool allowPrisoners = true) { outCandidates.Clear(); Region region = bully.GetRegion(RegionType.Set_Passable); if (region != null) { TraverseParms traverseParams = TraverseParms.For(bully, Danger.Deadly, TraverseMode.ByPawn, false); RegionTraverser.BreadthFirstTraverse(region, (Region from, Region to) => to.Allows(traverseParams, false), delegate(Region r) { List <Thing> list = r.ListerThings.ThingsInGroup(ThingRequestGroup.Pawn); for (int i = 0; i < list.Count; i++) { Pawn pawn = (Pawn)list[i]; if (InsultingSpreeMentalStateUtility.CanChaseAndInsult(bully, pawn, true, allowPrisoners)) { outCandidates.Add(pawn); } } return(false); }, 40, RegionType.Set_Passable); } }
// Token: 0x06000007 RID: 7 RVA: 0x0000219C File Offset: 0x0000039C public List <IntVec3> ValidCellsAround(IntVec3 pos, Map map, CellRect rect) { CompBell.validCells.Clear(); bool flag = !pos.InBounds(map); List <IntVec3> result; if (flag) { result = CompBell.validCells; } else { Region region = pos.GetRegion(map, RegionType.Set_Passable); bool flag2 = region == null; if (flag2) { result = CompBell.validCells; } else { RegionTraverser.BreadthFirstTraverse(region, (Region from, Region r) => r.door == null, delegate(Region r) { foreach (IntVec3 item in r.Cells) { bool flag3 = this.InDistOfRect(item, pos, rect); if (flag3) { CompBell.validCells.Add(item); } } return(false); }, 13, RegionType.Set_Passable); result = CompBell.validCells; } } return(result); }
private bool ShouldStartEscaping(Pawn pawn) { bool result; if (!pawn.guest.IsPrisoner || pawn.guest.HostFaction != Faction.OfPlayer || !pawn.guest.PrisonerIsSecure) { result = false; } else { Room room = pawn.GetRoom(RegionType.Set_Passable); if (room.TouchesMapEdge) { result = true; } else { bool found = false; RegionTraverser.BreadthFirstTraverse(room.Regions[0], (Region from, Region reg) => reg.portal == null || reg.portal.FreePassage, delegate(Region reg) { bool result2; if (reg.Room.TouchesMapEdge) { found = true; result2 = true; } else { result2 = false; } return(result2); }, 25, RegionType.Set_Passable); result = found; } } return(result); }
private static Region ClosestRegionWithinTemperatureRange(IntVec3 root, Map map, FloatRange tempRange, TraverseParms traverseParms, RegionType traversableRegionTypes = RegionType.Set_Passable) { Region region = root.GetRegion(map, traversableRegionTypes); Region result; if (region == null) { result = null; } else { RegionEntryPredicate entryCondition = (Region from, Region r) => r.Allows(traverseParms, false); Region foundReg = null; RegionProcessor regionProcessor = delegate(Region r) { bool result2; if (r.portal != null) { result2 = false; } else if (tempRange.Includes(r.Room.Temperature)) { foundReg = r; result2 = true; } else { result2 = false; } return(result2); }; RegionTraverser.BreadthFirstTraverse(region, entryCondition, regionProcessor, 9999, traversableRegionTypes); result = foundReg; } return(result); }
private bool ShouldStartEscaping(Pawn pawn) { if (!pawn.guest.IsPrisoner || pawn.guest.HostFaction != Faction.OfPlayer || !pawn.guest.PrisonerIsSecure) { return(false); } Room room = pawn.GetRoom(); if (room.TouchesMapEdge) { return(true); } bool found = false; RegionTraverser.BreadthFirstTraverse(room.Regions[0], delegate(Region from, Region reg) { if (reg.door != null && !reg.door.FreePassage) { return(false); } return(true); }, delegate(Region reg) { if (reg.Room.TouchesMapEdge) { found = true; return(true); } return(false); }, 25); if (found) { return(true); } return(false); }
private static bool TryFindSpotToPlaceHaulableCloseTo(Thing haulable, Pawn worker, IntVec3 center, out IntVec3 spot) { Region region = center.GetRegion(worker.Map); if (region == null) { spot = center; return(false); } TraverseParms traverseParms = TraverseParms.For(worker); IntVec3 foundCell = IntVec3.Invalid; RegionTraverser.BreadthFirstTraverse(region, (Region from, Region r) => r.Allows(traverseParms, isDestination : false), delegate(Region r) { candidates.Clear(); candidates.AddRange(r.Cells); candidates.Sort((IntVec3 a, IntVec3 b) => a.DistanceToSquared(center).CompareTo(b.DistanceToSquared(center))); for (int i = 0; i < candidates.Count; i++) { IntVec3 intVec = candidates[i]; if (HaulablePlaceValidator(haulable, worker, intVec)) { foundCell = intVec; return(true); } } return(false); }, 100); if (foundCell.IsValid) { spot = foundCell; return(true); } spot = center; return(false); }
public static bool ShouldStartFleeing(Pawn pawn) { List <Thing> list = pawn.Map.listerThings.ThingsInGroup(ThingRequestGroup.AlwaysFlee); for (int i = 0; i < list.Count; i++) { if (SelfDefenseUtility.ShouldFleeFrom(list[i], pawn, true, false)) { return(true); } } bool foundThreat = false; Region region = pawn.GetRegion(RegionType.Set_Passable); if (region == null) { return(false); } RegionTraverser.BreadthFirstTraverse(region, (Region from, Region reg) => reg.portal == null || reg.portal.Open, delegate(Region reg) { List <Thing> list2 = reg.ListerThings.ThingsInGroup(ThingRequestGroup.AttackTarget); int num = 0; while (num < list2.Count) { if (!SelfDefenseUtility.ShouldFleeFrom(list2[num], pawn, true, true)) { num++; continue; } foundThreat = true; break; } return(foundThreat); }, 9, RegionType.Set_Passable); return(foundThreat); }
private static bool IsSafeDropSpot(IntVec3 cell, Map map, Faction faction, IntVec2?size = null, int distToEdge = 25, int distToHostiles = 35, int distToFires = 15) { Faction factionBaseFaction = map.ParentFaction ?? Faction.OfPlayer; if (size.HasValue) { foreach (IntVec3 item in GenAdj.OccupiedRect(cell, Rot4.North, size.Value)) { if (!IsGoodDropSpot(item, map, allowFogged: false, canRoofPunch: false, allowIndoors: false)) { return(false); } } } else if (!IsGoodDropSpot(cell, map, allowFogged: false, canRoofPunch: false, allowIndoors: false)) { return(false); } if (distToEdge > 0 && cell.CloseToEdge(map, distToEdge)) { return(false); } if (faction != null) { foreach (IAttackTarget item2 in map.attackTargetsCache.TargetsHostileToFaction(faction)) { if (!item2.ThreatDisabled(null) && item2.Thing.Position.InHorDistOf(cell, distToHostiles)) { return(false); } } } if (!map.reachability.CanReachFactionBase(cell, factionBaseFaction)) { return(false); } if (size.HasValue) { foreach (IntVec3 cell2 in CellRect.CenteredOn(cell, size.Value.x, size.Value.z).Cells) { if (CellHasCrops(cell2)) { return(false); } } } else if (CellHasCrops(cell)) { return(false); } float minDistToFiresSq = distToFires * distToFires; float closestDistSq = float.MaxValue; int firesCount = 0; RegionTraverser.BreadthFirstTraverse(cell, map, (Region from, Region to) => true, delegate(Region x) { List <Thing> list = x.ListerThings.ThingsInGroup(ThingRequestGroup.Fire); for (int i = 0; i < list.Count; i++) { float num = cell.DistanceToSquared(list[i].Position); if (!(num > minDistToFiresSq)) { if (num < closestDistSq) { closestDistSq = num; } firesCount++; } } return(closestDistSq <= minDistToFiresSq && firesCount >= 5); }, 15); if (closestDistSq <= minDistToFiresSq && firesCount >= 5) { return(false); } return(true); bool CellHasCrops(IntVec3 c) { Plant plant = c.GetPlant(map); if (plant != null && plant.sown) { return(map.zoneManager.ZoneAt(c) is Zone_Growing); } return(false); } }
// RimWorld.FoodUtility private static Pawn BestPawnToHuntForPredator(Pawn predator, bool forceScanWholeMap) { if (predator.meleeVerbs.TryGetMeleeVerb(null) == null) { return(null); } bool flag = false; float summaryHealthPercent = predator.health.summaryHealth.SummaryHealthPercent; if (summaryHealthPercent < 0.25f) { flag = true; } tmpPredatorCandidates.Clear(); int maxRegionsToScan = GetMaxRegionsToScan(predator, forceScanWholeMap); if (maxRegionsToScan < 0) { tmpPredatorCandidates.AddRange(predator.Map.mapPawns.AllPawnsSpawned); } else { TraverseParms traverseParms = TraverseParms.For(predator, Danger.Deadly, TraverseMode.ByPawn, false); RegionTraverser.BreadthFirstTraverse(predator.Position, predator.Map, (Region from, Region to) => to.Allows(traverseParms, true), delegate(Region x) { List <Thing> list = x.ListerThings.ThingsInGroup(ThingRequestGroup.Pawn); for (int j = 0; j < list.Count; j++) { bool XenoInfection = (((Pawn)list[j]).health.hediffSet.HasHediff(XenomorphDefOf.RRY_FaceHuggerInfection) || ((Pawn)list[j]).health.hediffSet.HasHediff(XenomorphDefOf.RRY_HiddenXenomorphImpregnation) || ((Pawn)list[j]).health.hediffSet.HasHediff(XenomorphDefOf.RRY_XenomorphImpregnation)) ? true : false; bool IsXenos = (((Pawn)list[j]).kindDef == XenomorphDefOf.RRY_Xenomorph_Drone || ((Pawn)list[j]).kindDef == XenomorphDefOf.RRY_Xenomorph_FaceHugger || ((Pawn)list[j]).kindDef == XenomorphDefOf.RRY_Xenomorph_Queen || ((Pawn)list[j]).kindDef == XenomorphDefOf.RRY_Xenomorph_Runner || ((Pawn)list[j]).kindDef == XenomorphDefOf.RRY_Xenomorph_Warrior) ? true : false; if (!XenoInfection && !IsXenos) { tmpPredatorCandidates.Add((Pawn)list[j]); } else { // Log.Message(string.Format("{0} cannae hunt {2} XenoInfection:{1} IsXenos:{3}", predator.Label, XenoInfection, ((Pawn)list[j]).Label, IsXenos)); } } return(false); }, 999999, RegionType.Set_Passable); } Pawn pawn = null; float num = 0f; bool tutorialMode = TutorSystem.TutorialMode; for (int i = 0; i < tmpPredatorCandidates.Count; i++) { Pawn pawn2 = tmpPredatorCandidates[i]; if (predator.GetRoom(RegionType.Set_Passable) == pawn2.GetRoom(RegionType.Set_Passable)) { if (predator != pawn2) { if (!flag || pawn2.Downed) { if (IsAcceptablePreyFor(predator, pawn2)) { if (predator.CanReach(pawn2, PathEndMode.ClosestTouch, Danger.Deadly, false, TraverseMode.ByPawn)) { if (!pawn2.IsForbidden(predator) && !(XenoInfection(pawn2))) { if (!tutorialMode || pawn2.Faction != Faction.OfPlayer) { float preyScoreFor = FoodUtility.GetPreyScoreFor(predator, pawn2); if (preyScoreFor > num || pawn == null) { num = preyScoreFor; pawn = pawn2; } } } } } } } } } tmpPredatorCandidates.Clear(); return(pawn); }
private static bool TryFindSpotToPlaceHaulableCloseTo(Thing haulable, Pawn worker, IntVec3 center, out IntVec3 spot) { List <string> debugMessages = new List <string>(); Region region = center.GetRegion(worker.Map); if (region == null) { spot = center; return(false); } TraverseParms traverseParms = TraverseParms.For(worker, Danger.Deadly, TraverseMode.ByPawn, false); IntVec3 foundCell = IntVec3.Invalid; RegionTraverser.BreadthFirstTraverse(region, (Region from, Region r) => r.Allows(traverseParms, false), delegate(Region r) { candidates.Clear(); candidates.AddRange(r.Cells); // This function helps to identify cells which are part of the haulable's current stockpile // (which it is not supposed to be in. bool currentStockpile(IntVec3 slot) => worker.Map.haulDestinationManager.SlotGroupAt(haulable.Position).CellsList.Contains(slot); // We remove cells which we could never haul this thing to. candidates.RemoveAll(currentStockpile); candidates.Sort((IntVec3 a, IntVec3 b) => a.DistanceToSquared(center).CompareTo(b.DistanceToSquared(center))); IntVec3 intVec; for (int i = 0; i < candidates.Count; i++) { intVec = candidates[i]; if (HaulablePlaceValidator(haulable, worker, intVec, out string debugMsg)) { foundCell = intVec; if (CTS_Loader.settings.debug) { debugMessages.Add(debugMsg); } //Debugging output. if (debugMessages.Count != 0) { foreach (string s in debugMessages) { Log.Message(s); } } return(true); } else if (CTS_Loader.settings.debug) { debugMessages.Add(debugMsg); } } //Debugging output. if (debugMessages.Count != 0) { foreach (string s in debugMessages) { Log.Message(s); } } return(false); }, cellsToSearch); if (foundCell.IsValid) { spot = foundCell; return(true); } spot = center; return(false); }
//public class JobGiver_SeekAllowedArea : ThinkNode_JobGiver public static bool SeekAllowedArea_TryGiveJob(JobGiver_SeekAllowedArea __instance, Pawn pawn, ref Job __result) { if (!pawn.AnimalOrWildMan()) { return(true); } if (pawn.playerSettings == null) { return(true); } //StringBuilder res = new StringBuilder(); //Log.Message($"{pawn.Label} sought an allowed area."); if (!pawn.Position.IsForbidden(pawn)) { //Log.Message("Not Forbidden cur position"); __result = null; return(false); } if (Traverse.Create(__instance).Method("HasJobWithSpawnedAllowedTarget", pawn).GetValue <bool>()) { //Log.Message("Has job with spawned allowed target"); __result = null; return(false); } Region region = pawn.GetRegion(RegionType.Set_Passable); if (region == null) { //Log.Message("No passable region"); __result = null; return(false); } var allows = false; TraverseParms traverseParms = TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false); RegionEntryPredicate entryCondition = (Region from, Region r) => { allows = r.Allows(traverseParms, false); if (allows) { //Log.Message("Move allowed."); return(true); } //Log.Message("Entry barred"); if (r.door == null) { //Log.Message("Door Null"); //Log.Message("Return True"); } ByteGrid avoidGrid = traverseParms.pawn.GetAvoidGrid(true); if (avoidGrid != null && avoidGrid[r.door.Position] == 255) { //Log.Message("Door Position == 255"); //Log.Message("Return False"); } if (traverseParms.pawn.HostileTo(r.door)) { //Log.Message("Door Position == 255"); //Log.Message("CanPhysicallyPass: "******"CanBash: " + traverseParms.canBash.ToString()); } //Log.Message("door.CanPhysicallyPass(tp.pawn) == " + r.door.CanPhysicallyPass(traverseParms.pawn)); //Log.Message("!r.door.IsForbiddenToPass(traverseParms.pawn); == " + !r.door.IsForbiddenToPass(traverseParms.pawn)); //Log.Message("Return " + (r.door.CanPhysicallyPass(traverseParms.pawn) && !r.door.IsForbiddenToPass(traverseParms.pawn))); //return this.door.CanPhysicallyPass(tp.pawn) && !this.door.IsForbiddenToPass(tp.pawn); return(false); }; Region reg = null; RegionProcessor regionProcessor = delegate(Region r) { if (r.IsDoorway && r?.ListerThings?.AllThings?.Any(x => x is Building_DoorRegionHandler) == false) { Log.Message("Doorway disallowed"); return(false); } if (!r.IsForbiddenEntirely(pawn)) { Log.Message("Allowed passage"); reg = r; return(true); } return(false); }; RegionTraverser.BreadthFirstTraverse(region, entryCondition, regionProcessor, 9999, RegionType.Set_Passable); if (reg == null) { Log.Message(pawn.LabelShort + " No region found"); __result = null; return(false); } IntVec3 c; if (!reg.TryFindRandomCellInRegionUnforbidden(pawn, null, out c)) { Log.Message(pawn.LabelShort + " Failed to find random cell in region unforbidden"); __result = null; return(false); } __result = new Job(JobDefOf.Goto, c); return(false); }