示例#1
0
 public List <Thing> ThingsOfDef(ThingDef def)
 {
     return(this.ThingsMatching(ThingRequest.ForDef(def)));
 }
示例#2
0
 public List <Thing> ThingsInGroup(ThingRequestGroup group)
 {
     return(this.ThingsMatching(ThingRequest.ForGroup(group)));
 }
示例#3
0
        public static Thing ClosestThing_Regionwise_ReachablePrioritized(IntVec3 root, Map map, ThingRequest thingReq, PathEndMode peMode, TraverseParms traverseParams, float maxDistance = 9999f, Predicate <Thing> validator = null, Func <Thing, float> priorityGetter = null, int minRegions = 24, int maxRegions = 30)
        {
            if (!thingReq.IsUndefined && !thingReq.CanBeFoundInRegion)
            {
                Log.ErrorOnce("ClosestThing_Regionwise_ReachablePrioritized with thing request group " + thingReq.group + ". This will never find anything because this group is never stored in regions. Most likely a global search should have been used.", 738476712);
                return(null);
            }
            if (EarlyOutSearch(root, map, thingReq, null, validator))
            {
                return(null);
            }
            if (maxRegions < minRegions)
            {
                Log.ErrorOnce("maxRegions < minRegions", 754343);
            }
            Thing result = null;

            if (!thingReq.IsUndefined)
            {
                result = RegionwiseBFSWorker(root, map, thingReq, peMode, traverseParams, validator, priorityGetter, minRegions, maxRegions, maxDistance, out int _);
            }
            return(result);
        }
示例#4
0
        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("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           = -3.40282347E+38f;
            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) ? 0f : 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;
                                }
                            }
                        }
                    }
                }
                return(regionsSeenScan >= minRegions && closestThing != null);
            };

            RegionTraverser.BreadthFirstTraverse(region, entryCondition, regionProcessor, maxRegions, traversableRegionTypes);
            regionsSeen = regionsSeenScan;
            return(closestThing);
        }
示例#5
0
        public static Thing ClosestThing_Regionwise_ReachablePrioritized(IntVec3 root, Map map, ThingRequest thingReq, PathEndMode peMode, TraverseParms traverseParams, float maxDistance = 9999f, Predicate <Thing> validator = null, Func <Thing, float> priorityGetter = null, int minRegions = 24, int maxRegions = 30)
        {
            if (GenClosest.EarlyOutSearch(root, map, thingReq, null))
            {
                return(null);
            }
            if (maxRegions < minRegions)
            {
                Log.ErrorOnce("maxRegions < minRegions", 754343);
            }
            Thing result = null;

            if (!thingReq.IsUndefined)
            {
                result = GenClosest.RegionwiseBFSWorker(root, map, thingReq, peMode, traverseParams, validator, priorityGetter, minRegions, maxRegions, maxDistance, RegionType.Set_Passable, false);
            }
            return(result);
        }
示例#6
0
        /// <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,
                                                                    forceAllowGlobalSearch: 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
                }
            }
        }