public static bool CanReach(this Pawn pawn, LocalTargetInfo dest, PathEndMode peMode, Danger maxDanger, bool canBash = false, TraverseMode mode = TraverseMode.ByPawn) { return(pawn.Spawned && pawn.Map.reachability.CanReach(pawn.Position, dest, peMode, TraverseParms.For(pawn, maxDanger, mode, canBash))); }
public static bool CanReachMapEdge(this Pawn p) { return(p.Spawned && p.Map.reachability.CanReachMapEdge(p.Position, TraverseParms.For(p, Danger.Deadly, TraverseMode.ByPawn, false))); }
public static bool TryFindRandomSpawnCellForPawnNear(IntVec3 root, Map map, out IntVec3 result, int firstTryWithRadius = 4) { bool result2; if (root.Standable(map) && root.GetFirstPawn(map) == null) { result = root; result2 = true; } else { bool rootFogged = root.Fogged(map); int num = firstTryWithRadius; for (int i = 0; i < 3; i++) { if (CellFinder.TryFindRandomReachableCellNear(root, map, (float)num, TraverseParms.For(TraverseMode.NoPassClosedDoors, Danger.Deadly, false), (IntVec3 c) => c.Standable(map) && (rootFogged || !c.Fogged(map)) && c.GetFirstPawn(map) == null, null, out result, 999999)) { return(true); } num *= 2; } num = firstTryWithRadius + 1; while (!CellFinder.TryRandomClosewalkCellNear(root, map, num, out result, null)) { if (num > map.Size.x / 2 && num > map.Size.z / 2) { result = root; return(false); } num *= 2; } result2 = true; } return(result2); }
/// <summary> Update the graphic if the life stage changed and swap the body graphic if moving </summary> public override void Tick() { base.Tick(); if (GenTicks.TicksAbs % Frameskip != FrameskipOffset) { return; // frameskip } if (!Spawned) { return; } if (Destroyed) { return; } if (pather == null) { return; // this can occur if the pawn leaves the map area } if (Drawer?.renderer == null) { return; } // initialize the replacement graphics (once per lifestage) if (lifeStageBefore != ageTracker.CurKindLifeStage) { SetupReplacements(); lifeStageBefore = ageTracker.CurKindLifeStage; } // avoid hunting tamed animals, accept non-ideal food instead if (Faction != Faction.OfPlayer && jobs?.curJob?.def == JobDefOf.PredatorHunt) { if ((jobs.curJob.targetA.Thing as Pawn)?.Faction == Faction.OfPlayer) { jobs.StopAll(); // stop predator hunt job if (needs.food.TicksStarving < 30000) { // find food var food = GenClosest.ClosestThingReachable(Position, Map, ThingRequest.ForGroup(ThingRequestGroup.HaulableAlways), AI.PathEndMode.OnCell, TraverseParms.For(this, Danger.Deadly, TraverseMode.ByPawn, false), maxDistance: 100f, validator: (thing) => thing.def.category == ThingCategory.Item && thing.def.IsNutritionGivingIngestible /*&& RaceProps.CanEverEat(thing)*/, // omit food preferences customGlobalSearchSet: null, searchRegionsMax: -1, forceGlobalSearch: false); if (food != null) { // try to find other food jobs.StartJob(new AI.Job(JobDefOf.Ingest, food)); } else { // wander until food is found or too starving to continue StartJobWander(); } } else // if desperate { IntVec3 exit_dest; if (RCellFinder.TryFindBestExitSpot(this, out exit_dest, TraverseMode.ByPawn)) { // exit map jobs.StartJob(new AI.Job(JobDefOf.Goto, exit_dest) { exitMapOnArrival = true }); } else { // fallback to wandering StartJobWander(); } } } } // attempt to find a replacement graphic foreach (var replacement in replacements) { if (replacement.TryReplace(Drawer.renderer)) { break; // break on first successful replacement } } }
public static bool TryRandomClosewalkCellNear(IntVec3 root, Map map, int radius, out IntVec3 result, Predicate <IntVec3> extraValidator = null) { return(CellFinder.TryFindRandomReachableCellNear(root, map, (float)radius, TraverseParms.For(TraverseMode.NoPassClosedDoors, Danger.Deadly, false), (IntVec3 c) => c.Standable(map) && (extraValidator == null || extraValidator(c)), null, out result, 999999)); }