public void setCellsToAffect() { if (this.status == "stable") { return; } IntVec3 pos = this.parent.Position; Map map = this.parent.Map; this.affectableCells.Clear(); this.boundaryCellsRough.Clear(); this.boundaryCells.Clear(); this.affectableCellsAtmosphere.Clear(); if (!pos.InBounds(map)) { return; } int maxArea = (int)Math.Round(this.width + this.Props.borderSize + 5); Region region = pos.GetRegion(map, RegionType.Set_Passable); if (region == null) { return; } RegionTraverser.BreadthFirstTraverse(region, (Region from, Region r) => r.door == null, delegate(Region r) { foreach (IntVec3 current in r.Cells) { if (current.InHorDistOf(pos, this.width)) { this.affectableCells.Add(current); } else if (current.InHorDistOf(pos, this.width + 2)) { this.boundaryCellsRough.Add(current); } else if (current.InHorDistOf(pos, this.width + this.Props.borderSize + 1)) { this.boundaryCells.Add(current); } else if (current.InHorDistOf(pos, this.width + this.Props.borderSize + 5)) { this.affectableCellsAtmosphere.Add(current); } } return(false); }, maxArea, RegionType.Set_Passable); return; }
// Copied with minor changes so we don't have to call a private function on the FoodUtility object private static Pawn BestPawnToHuntForPredator(Pawn predator, bool forceScanWholeMap) { if (predator.meleeVerbs.TryGetMeleeVerb(null) == null) { return(null); } bool seriouslyWounded = (predator.health.summaryHealth.SummaryHealthPercent < 0.25f); tempPreyCandidates.Clear(); if (GetMaxRegionsToScan(predator, forceScanWholeMap) < 0) { tempPreyCandidates.AddRange(predator.Map.mapPawns.AllPawnsSpawned); } else { TraverseParms traverseParms = TraverseParms.For(predator); RegionTraverser.BreadthFirstTraverse(predator.Position, predator.Map, (Region from, Region to) => to.Allows(traverseParms, isDestination : true), delegate(Region x) { List <Thing> list = x.ListerThings.ThingsInGroup(ThingRequestGroup.Pawn); for (int j = 0; j < list.Count; j++) { tempPreyCandidates.Add((Pawn)list[j]); } return(false); }); } Pawn bestPrey = null; float bestPreyScore = 0f; bool tutorialMode = TutorSystem.TutorialMode; foreach (Pawn potentialPrey in tempPreyCandidates) { bool sameRoom = predator.GetRoom() == potentialPrey.GetRoom(); bool acceptablePrey = IsAcceptablePreyFor(predator, potentialPrey); if (predator != potentialPrey && sameRoom && (!seriouslyWounded || potentialPrey.Downed) && acceptablePrey && predator.CanReach(potentialPrey, PathEndMode.ClosestTouch, Danger.Deadly) && !potentialPrey.IsForbidden(predator) && (!tutorialMode || potentialPrey.Faction != Faction.OfPlayer)) { float preyScoreFor = GetPreyScoreFor(predator, potentialPrey); if (preyScoreFor > bestPreyScore || bestPrey == null) { bestPreyScore = preyScoreFor; bestPrey = potentialPrey; } } } tempPreyCandidates.Clear(); return(bestPrey); }
public static bool ShouldStartFleeing(ref bool __result, Pawn pawn) { List <Thing> thingList1 = pawn.Map.listerThings.ThingsInGroup(ThingRequestGroup.AlwaysFlee); lock (thingList1) { for (int index = 0; index < thingList1.Count; ++index) { Thing t = thingList1[index]; if (null != t) { if (SelfDefenseUtility.ShouldFleeFrom(t, pawn, true, false)) { __result = true; return(false); } } } } bool foundThreat = false; Region region = pawn.GetRegion(RegionType.Set_Passable); if (region == null) { __result = false; return(false); } RegionTraverser.BreadthFirstTraverse(region, (RegionEntryPredicate)((from, reg) => reg.door == null || reg.door.Open), (RegionProcessor)(reg => { List <Thing> thingList2 = reg.ListerThings.ThingsInGroup(ThingRequestGroup.AttackTarget); lock (thingList2) { for (int index = 0; index < thingList2.Count; ++index) { Thing t = thingList2[index]; if (null != t) { if (SelfDefenseUtility.ShouldFleeFrom(t, pawn, true, true)) { foundThreat = true; break; } } } } return(foundThreat); }), 9, RegionType.Set_Passable); __result = foundThreat; return(false); }
public static void BreadthFirstTraverse(IntVec3 start, Map map2, RegionEntryPredicate entryCondition, RegionProcessor regionProcessor, int maxRegions = 999999, RegionType traversableRegionTypes = RegionType.Set_Passable) { Region region = start.GetRegion(map2, traversableRegionTypes); if (region == null) { return; } lock (region) { RegionTraverser.BreadthFirstTraverse(region, entryCondition, regionProcessor, maxRegions, traversableRegionTypes); } }
private static Pawn BestPawnToHuntForPredator(Pawn predator, bool forceScanWholeMap) { if (predator.meleeVerbs.TryGetMeleeVerb(null) == null) { return(null); } bool flag = false; if (predator.health.summaryHealth.SummaryHealthPercent < 0.25f) { flag = true; } tmpPredatorCandidates.Clear(); if (GetMaxRegionsToScan(predator, forceScanWholeMap) < 0) { tmpPredatorCandidates.AddRange(predator.Map.mapPawns.AllPawnsSpawned); } else { TraverseParms traverseParms = TraverseParms.For(predator); RegionTraverser.BreadthFirstTraverse(predator.Position, predator.Map, (Region from, Region to) => to.Allows(traverseParms, isDestination : true), delegate(Region x) { List <Thing> list = x.ListerThings.ThingsInGroup(ThingRequestGroup.Pawn); for (int j = 0; j < list.Count; j++) { tmpPredatorCandidates.Add((Pawn)list[j]); } return(false); }); } 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() == pawn2.GetRoom() && predator != pawn2 && (!flag || pawn2.Downed) && IsAcceptablePreyFor(predator, pawn2) && predator.CanReach(pawn2, PathEndMode.ClosestTouch, Danger.Deadly) && !pawn2.IsForbidden(predator) && (!tutorialMode || pawn2.Faction != Faction.OfPlayer)) { float preyScoreFor = GetPreyScoreFor(predator, pawn2); if (preyScoreFor > num || pawn == null) { num = preyScoreFor; pawn = pawn2; } } } tmpPredatorCandidates.Clear(); return(pawn); }
private static void CreateOrAttachToExistingRooms2(RegionAndRoomUpdater __instance, int numRegionGroups) { for (int i = 0; i < numRegionGroups; i++) { currentRegionGroup(__instance).Clear(); for (int j = 0; j < newRegions(__instance).Count; j++) { if (newRegions(__instance)[j].newRegionGroupIndex == i) { currentRegionGroup(__instance).Add(newRegions(__instance)[j]); } } if (!currentRegionGroup(__instance)[0].type.AllowsMultipleRegionsPerRoom()) { if (currentRegionGroup(__instance).Count != 1) { Log.Error("Region type doesn't allow multiple regions per room but there are >1 regions in this group."); } Room room = Room.MakeNew(map(__instance)); currentRegionGroup(__instance)[0].Room = room; newRooms(__instance).Add(room); continue; } bool multipleOldNeighborRooms; Room room2 = FindCurrentRegionGroupNeighborWithMostRegions2(__instance, out multipleOldNeighborRooms); if (room2 == null) { Room item = RegionTraverser.FloodAndSetRooms(currentRegionGroup(__instance)[0], map(__instance), null); newRooms(__instance).Add(item); } else if (!multipleOldNeighborRooms) { for (int k = 0; k < currentRegionGroup(__instance).Count; k++) { currentRegionGroup(__instance)[k].Room = room2; } reusedOldRooms(__instance).Add(room2); } else { RegionTraverser.FloodAndSetRooms(currentRegionGroup(__instance)[0], map(__instance), room2); reusedOldRooms(__instance).Add(room2); } } }
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 = (Thing x) => !x.IsForbidden(pawn) && pawn.CanReserve(x, 1, -1, null, false) && filter.Allows(x); IntVec3 position = refuelable.Position; Region region = position.GetRegion(pawn.Map, RegionType.Set_Passable); TraverseParms traverseParams = TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false); RegionEntryPredicate entryCondition = (Region from, Region r) => r.Allows(traverseParams, 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)) { if (!chosenThings.Contains(thing)) { if (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, RegionType.Set_Passable); List <Thing> result; if (accumulatedQuantity >= quantity) { result = chosenThings; } else { result = null; } return(result); }
public static Lord FindLordToJoin(Thing spawner, Type lordJobType, bool shouldTryJoinParentLord, Func <Thing, List <Pawn> > spawnedPawnSelector = null) { if (spawner.Spawned) { if (shouldTryJoinParentLord) { Lord lord = (spawner as Building)?.GetLord(); if (lord != null) { return(lord); } } if (spawnedPawnSelector == null) { spawnedPawnSelector = ((Thing s) => s.TryGetComp <CompSpawnerPawn>()?.spawnedPawns); } Predicate <Pawn> hasJob = delegate(Pawn x) { Lord lord2 = x.GetLord(); return(lord2 != null && lord2.LordJob.GetType() == lordJobType); }; Pawn foundPawn = null; RegionTraverser.BreadthFirstTraverse(spawner.GetRegion(), (Region from, Region to) => true, delegate(Region r) { List <Thing> list = r.ListerThings.ThingsOfDef(spawner.def); for (int i = 0; i < list.Count; i++) { if (list[i].Faction == spawner.Faction) { List <Pawn> list2 = spawnedPawnSelector(list[i]); if (list2 != null) { foundPawn = list2.Find(hasJob); } if (foundPawn != null) { return(true); } } } return(false); }, 40); if (foundPawn != null) { return(foundPawn.GetLord()); } } return(null); }
private static int CombineNewRegionsIntoContiguousGroups2(RegionAndRoomUpdater __instance) { int num = 0; for (int i = 0; i < newRegions(__instance).Count; i++) { if (newRegions(__instance)[i].newRegionGroupIndex < 0) { RegionTraverser.FloodAndSetNewRegionIndex(newRegions(__instance)[i], num); num++; } } return(num); }
public override void StartExplosion(SoundDef explosionSound, List <Thing> ignoredThings) { if (!base.Spawned) { Log.Error("Called StartExplosion() on unspawned thing."); return; } startTick = Find.TickManager.TicksGame; this.ignoredThings = ignoredThings; cellsToAffect.Clear(); damagedThings.Clear(); addedCellsAffectedOnlyByDamage.Clear(); cellsToAffect.AddRange(damType.Worker.ExplosionCellsToHit(this)); if (applyDamageToExplosionCellsNeighbors) { AddCellsNeighbors(cellsToAffect); } if (validator != null) { for (int i = 0; i < cellsToAffect.Count; i++) { IntVec3 cell = cellsToAffect[i]; if (validator(cell)) { cellsToAffect.Remove(cell); } } } damType.Worker.ExplosionStart(this, cellsToAffect); PlayExplosionSound(explosionSound); MoteMaker.MakeWaterSplash(base.Position.ToVector3Shifted(), base.Map, radius * 6f, 20f); cellsToAffect.Sort((IntVec3 a, IntVec3 b) => GetCellAffectTick(b).CompareTo(GetCellAffectTick(a))); RegionTraverser.BreadthFirstTraverse(base.Position, base.Map, (Region from, Region to) => true, delegate(Region x) { List <Thing> allThings = x.ListerThings.AllThings; for (int num = allThings.Count - 1; num >= 0; num--) { if (allThings[num].Spawned) { allThings[num].Notify_Explosion(this); } } return(false); }, 25); }
static void HavePawnsFleeFromOrbitalStrikes(OrbitalStrike __instance) { if (__instance.Destroyed) { return; } RegionTraverser.BreadthFirstTraverse(__instance.Position, __instance.Map, (from, to) => true, region => { region.ListerThings.ThingsInGroup(ThingRequestGroup.Pawn) .OfType <Pawn>() .Where(p => p.Position.DistanceTo(__instance.Position) <= 20) .Where(CanStartFleeingBecauseOfPawnAction) .Do(pawn => pawn.mindState.StartFleeingBecauseOfPawnAction(__instance)); return(false); }, 25, RegionType.Set_All); }
public static bool StartExplosion(Explosion __instance, SoundDef explosionSound, List <Thing> ignoredThings) { Thing thing = __instance; if (!thing.Spawned) { Log.Error("Called StartExplosion() on unspawned thing."); return(false); } startTick(__instance) = Find.TickManager.TicksGame; ignoredThingsFR(__instance) = ignoredThings; //List<IntVec3> cells = cellsToAffect(__instance); List <IntVec3> cells = getCellsToAffectFromDict(__instance); lock (cells) { cells.Clear(); damagedThings(__instance).Clear(); addedCellsAffectedOnlyByDamage(__instance).Clear(); cells.AddRange(__instance.damType.Worker.ExplosionCellsToHit(__instance).ToList()); if (__instance.applyDamageToExplosionCellsNeighbors) { AddCellsNeighbors2(__instance, cells); } __instance.damType.Worker.ExplosionStart(__instance, cells); PlayExplosionSound2(__instance, explosionSound); MoteMaker.MakeWaterSplash(thing.Position.ToVector3Shifted(), thing.Map, __instance.radius * 6f, 20f); cells.Sort((IntVec3 a, IntVec3 b) => GetCellAffectTick2(__instance, b).CompareTo(GetCellAffectTick2(__instance, a))); } RegionTraverser.BreadthFirstTraverse(thing.Position, thing.Map, (Region from, Region to) => true, delegate(Region x) { List <Thing> allThings = x.ListerThings.AllThings; for (int num = allThings.Count - 1; num >= 0; num--) { if (allThings[num].Spawned) { allThings[num].Notify_Explosion(__instance); } } return(false); }, 25); return(false); }
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(string.Concat(new object[] { "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 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; if (pawn2 != null && !pawn2.Downed && (float)(pawn.Position - pawn2.Position).LengthHorizontalSquared < 144.0 && pawn2.HostileTo(pawn.Faction)) { found = true; return(true); } return(false); }), 9, RegionType.Set_Passable); return(found); }
/// <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_Turret reloadable) { var compAmmo = reloadable.GetAmmo(); int quantity = compAmmo.MissingToFullMagazine; var ammoKind = 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); }
protected override Job TryGiveJob(Pawn pawn) { if (!pawn.Position.IsForbidden(pawn)) { return(null); } if (this.HasJobWithSpawnedAllowedTarget(pawn)) { return(null); } Region region = pawn.GetRegion(RegionType.Set_Passable); if (region == null) { return(null); } TraverseParms traverseParms = TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false); RegionEntryPredicate entryCondition = (Region from, Region r) => r.Allows(traverseParms, false); Region reg = null; RegionProcessor regionProcessor = delegate(Region r) { if (r.portal != null) { return(false); } if (!r.IsForbiddenEntirely(pawn)) { reg = r; return(true); } return(false); }; RegionTraverser.BreadthFirstTraverse(region, entryCondition, regionProcessor, 9999, RegionType.Set_Passable); if (reg == null) { return(null); } IntVec3 c; if (!reg.TryFindRandomCellInRegionUnforbidden(pawn, null, out c)) { return(null); } return(new Job(JobDefOf.Goto, c)); }
private Job FleeLargeFireJob(Pawn pawn) { List <Thing> list = pawn.Map.listerThings.ThingsInGroup(ThingRequestGroup.Fire); Job result; if (list.Count < 60) { result = null; } else { 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); } } result = null; } return(result); }
public static void NotifyFacilitiesAboutChangedLOSBlockers(List <Region> affectedRegions) { if (FacilitiesUtility.working) { Log.Warning("Tried to update facilities while already updating."); } else { 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(); } } }
protected override Job TryGiveJob(Pawn pawn) { if (!pawn.Position.IsForbidden(pawn)) { return(null); } if (HasJobWithSpawnedAllowedTarget(pawn)) { return(null); } Region region = pawn.GetRegion(); if (region == null) { return(null); } TraverseParms traverseParms = TraverseParms.For(pawn); RegionEntryPredicate entryCondition = (Region from, Region r) => r.Allows(traverseParms, isDestination: false); Region reg = null; RegionProcessor regionProcessor = delegate(Region r) { if (r.IsDoorway) { return(false); } if (!r.IsForbiddenEntirely(pawn)) { reg = r; return(true); } return(false); }; RegionTraverser.BreadthFirstTraverse(region, entryCondition, regionProcessor, 9999); if (reg != null) { if (!reg.TryFindRandomCellInRegionUnforbidden(pawn, null, out IntVec3 result)) { return(null); } return(JobMaker.MakeJob(JobDefOf.Goto, result)); } return(null); }
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)) { return; } Region region = near.GetRegion(pawn.Map); if (region == null) { return; } TraverseParms traverseParams = TraverseParms.For(pawn); RegionTraverser.BreadthFirstTraverse(region, (Region from, Region to) => to.Allows(traverseParams, isDestination : 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, maxDistance) && CanSmash(pawn, list[i], skipReachabilityCheck: 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, maxDistance) && CanSmash(pawn, list2[j], skipReachabilityCheck: 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, maxDistance) && CanSmash(pawn, list3[k], skipReachabilityCheck: true, customValidator, extraMinBuildingOrItemMarketValue)) { outCandidates.Add(list3[k]); } } return(false); }, 40); }
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 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); }
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); }
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); }
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 void ClearAllMapsAndWorld() { if (Current.Game != null && Current.Game.Maps != null) { List <Map> maps = Find.Maps; FieldInfo[] fields = typeof(Map).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); for (int i = 0; i < fields.Length; i++) { if (fields[i].FieldType.IsClass) { for (int j = 0; j < maps.Count; j++) { fields[i].SetValue(maps[j], null); } } } maps.Clear(); Current.Game.currentMapIndex = -1; } if (Find.World != null) { World world = Find.World; FieldInfo[] fields2 = typeof(World).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); for (int k = 0; k < fields2.Length; k++) { if (fields2[k].FieldType.IsClass) { fields2[k].SetValue(world, null); } } } BillUtility.Clipboard = null; RegionTraverser.RecreateWorkers(); SelectionDrawer.Clear(); WorldSelectionDrawer.Clear(); List <MainButtonDef> allDefsListForReading = DefDatabase <MainButtonDef> .AllDefsListForReading; for (int l = 0; l < allDefsListForReading.Count; l++) { allDefsListForReading[l].Notify_ClearingAllMapsMemory(); } }
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); }
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); 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> 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); if (closestDistSq <= 100f && firesCount >= 60) { Job job = 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); }