Ejemplo n.º 1
0
        public static void DebugFoodSearchFromMouse_Update()
        {
            IntVec3 root = UI.MouseCell();
            Pawn    pawn = Find.Selector.SingleSelectedThing as Pawn;

            if (pawn != null && pawn.Map == Find.VisibleMap)
            {
                Thing thing = FoodUtility.SpawnedFoodSearchInnerScan(pawn, root, Find.VisibleMap.listerThings.ThingsInGroup(ThingRequestGroup.FoodSourceNotPlantOrTree), PathEndMode.ClosestTouch, TraverseParms.For(TraverseMode.PassDoors, Danger.Deadly, false), 9999f, null);
                if (thing != null)
                {
                    GenDraw.DrawLineBetween(root.ToVector3Shifted(), thing.Position.ToVector3Shifted());
                }
            }
        }
Ejemplo n.º 2
0
        public static Thing BestFoodSourceOnMap(Pawn getter, Pawn eater, bool desperate, out ThingDef foodDef, FoodPreferability maxPref = FoodPreferability.MealLavish, bool allowPlant = true, bool allowDrug = true, bool allowCorpse = true, bool allowDispenserFull = true, bool allowDispenserEmpty = true, bool allowForbidden = false, bool allowSociallyImproper = false, bool allowHarvest = false)
        {
            foodDef = null;
            bool getterCanManipulate = getter.RaceProps.ToolUser && getter.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation);

            if (!getterCanManipulate && getter != eater)
            {
                Log.Error(getter + " tried to find food to bring to " + eater + " but " + getter + " is incapable of Manipulation.");
                return(null);
            }
            FoodPreferability minPref;

            if (eater.NonHumanlikeOrWildMan())
            {
                minPref = FoodPreferability.NeverForNutrition;
            }
            else if (desperate)
            {
                minPref = FoodPreferability.DesperateOnly;
            }
            else
            {
                minPref = (FoodPreferability)(((int)eater.needs.food.CurCategory <= 2) ? 4 : 6);
            }
            Predicate <Thing> foodValidator = delegate(Thing t)
            {
                if (!allowForbidden && t.IsForbidden(getter))
                {
                    return(false);
                }
                Building_NutrientPasteDispenser building_NutrientPasteDispenser = t as Building_NutrientPasteDispenser;
                if (building_NutrientPasteDispenser != null)
                {
                    if (allowDispenserFull && (int)ThingDefOf.MealNutrientPaste.ingestible.preferability >= (int)minPref && (int)ThingDefOf.MealNutrientPaste.ingestible.preferability <= (int)maxPref && getterCanManipulate && !getter.IsWildMan() && (t.Faction == getter.Faction || t.Faction == getter.HostFaction) && building_NutrientPasteDispenser.powerComp.PowerOn && (allowDispenserEmpty || building_NutrientPasteDispenser.HasEnoughFeedstockInHoppers()) && FoodUtility.IsFoodSourceOnMapSociallyProper(t, getter, eater, allowSociallyImproper) && t.InteractionCell.Standable(t.Map) && getter.Map.reachability.CanReachNonLocal(getter.Position, new TargetInfo(t.InteractionCell, t.Map, false), PathEndMode.OnCell, TraverseParms.For(getter, Danger.Some, TraverseMode.ByPawn, false)))
                    {
                        goto IL_025e;
                    }
                    return(false);
                }
                if ((int)t.def.ingestible.preferability < (int)minPref)
                {
                    return(false);
                }
                if ((int)t.def.ingestible.preferability > (int)maxPref)
                {
                    return(false);
                }
                if (t.IngestibleNow && t.def.IsNutritionGivingIngestible && (allowCorpse || !(t is Corpse)) && (allowDrug || !t.def.IsDrug) && (desperate || !t.IsNotFresh()) && !t.IsDessicated() && eater.RaceProps.WillAutomaticallyEat(t) && FoodUtility.IsFoodSourceOnMapSociallyProper(t, getter, eater, allowSociallyImproper) && getter.AnimalAwareOf(t) && getter.CanReserve(t, 1, -1, null, false))
                {
                    goto IL_025e;
                }
                return(false);

IL_025e:
                return(true);
            };
            ThingRequest thingRequest = ((eater.RaceProps.foodType & (FoodTypeFlags.Plant | FoodTypeFlags.Tree)) == FoodTypeFlags.None || !allowPlant) ? ThingRequest.ForGroup(ThingRequestGroup.FoodSourceNotPlantOrTree) : ThingRequest.ForGroup(ThingRequestGroup.FoodSource);
            Thing        bestThing;

            if (getter.RaceProps.Humanlike)
            {
                Pawn              eater2         = eater;
                IntVec3           position       = getter.Position;
                List <Thing>      searchSet      = getter.Map.listerThings.ThingsMatching(thingRequest);
                PathEndMode       peMode         = PathEndMode.ClosestTouch;
                TraverseParms     traverseParams = TraverseParms.For(getter, Danger.Deadly, TraverseMode.ByPawn, false);
                Predicate <Thing> validator      = foodValidator;
                bestThing = FoodUtility.SpawnedFoodSearchInnerScan(eater2, position, searchSet, peMode, traverseParams, 9999f, validator);
                if (allowHarvest && getterCanManipulate)
                {
                    Thing thing = GenClosest.ClosestThingReachable(getter.Position, getter.Map, ThingRequest.ForGroup(ThingRequestGroup.HarvestablePlant), PathEndMode.Touch, TraverseParms.For(getter, Danger.Deadly, TraverseMode.ByPawn, false), 9999f, delegate(Thing x)
                    {
                        Plant plant = (Plant)x;
                        if (!plant.HarvestableNow)
                        {
                            return(false);
                        }
                        ThingDef harvestedThingDef = plant.def.plant.harvestedThingDef;
                        if (!harvestedThingDef.IsNutritionGivingIngestible)
                        {
                            return(false);
                        }
                        if (!getter.CanReserve(plant, 1, -1, null, false))
                        {
                            return(false);
                        }
                        if (!allowForbidden && plant.IsForbidden(getter))
                        {
                            return(false);
                        }
                        if (bestThing != null && (int)FoodUtility.GetFinalIngestibleDef(bestThing, false).ingestible.preferability >= (int)harvestedThingDef.ingestible.preferability)
                        {
                            return(false);
                        }
                        return(true);
                    }, null, 0, 30, false, RegionType.Set_Passable, false);
                    if (thing != null)
                    {
                        bestThing = thing;
                        foodDef   = FoodUtility.GetFinalIngestibleDef(thing, true);
                    }
                }
                if (foodDef == null && bestThing != null)
                {
                    foodDef = FoodUtility.GetFinalIngestibleDef(bestThing, false);
                }
            }
            else
            {
                int searchRegionsMax = 30;
                if (getter.Faction == Faction.OfPlayer)
                {
                    searchRegionsMax = 100;
                }
                FoodUtility.filtered.Clear();
                foreach (Thing item in GenRadial.RadialDistinctThingsAround(getter.Position, getter.Map, 2f, true))
                {
                    Pawn pawn = item as Pawn;
                    if (pawn != null && pawn != getter && pawn.RaceProps.Animal && pawn.CurJob != null && pawn.CurJob.def == JobDefOf.Ingest && pawn.CurJob.GetTarget(TargetIndex.A).HasThing)
                    {
                        FoodUtility.filtered.Add(pawn.CurJob.GetTarget(TargetIndex.A).Thing);
                    }
                }
                bool flag = !allowForbidden && ForbidUtility.CaresAboutForbidden(getter, true) && getter.playerSettings != null && getter.playerSettings.EffectiveAreaRestrictionInPawnCurrentMap != null;
                Predicate <Thing> predicate = delegate(Thing t)
                {
                    if (!foodValidator(t))
                    {
                        return(false);
                    }
                    if (FoodUtility.filtered.Contains(t))
                    {
                        return(false);
                    }
                    if (!(t is Building_NutrientPasteDispenser) && (int)t.def.ingestible.preferability <= 2)
                    {
                        return(false);
                    }
                    if (t.IsNotFresh())
                    {
                        return(false);
                    }
                    return(true);
                };
                IntVec3           position       = getter.Position;
                Map               map            = getter.Map;
                ThingRequest      thingReq       = thingRequest;
                PathEndMode       peMode         = PathEndMode.ClosestTouch;
                TraverseParms     traverseParams = TraverseParms.For(getter, Danger.Deadly, TraverseMode.ByPawn, false);
                Predicate <Thing> validator      = predicate;
                bool              ignoreEntirelyForbiddenRegions = flag;
                bestThing = GenClosest.ClosestThingReachable(position, map, thingReq, peMode, traverseParams, 9999f, validator, null, 0, searchRegionsMax, false, RegionType.Set_Passable, ignoreEntirelyForbiddenRegions);
                FoodUtility.filtered.Clear();
                if (bestThing == null)
                {
                    desperate      = true;
                    position       = getter.Position;
                    map            = getter.Map;
                    thingReq       = thingRequest;
                    peMode         = PathEndMode.ClosestTouch;
                    traverseParams = TraverseParms.For(getter, Danger.Deadly, TraverseMode.ByPawn, false);
                    validator      = foodValidator;
                    ignoreEntirelyForbiddenRegions = flag;
                    bestThing = GenClosest.ClosestThingReachable(position, map, thingReq, peMode, traverseParams, 9999f, validator, null, 0, searchRegionsMax, false, RegionType.Set_Passable, ignoreEntirelyForbiddenRegions);
                }
                if (bestThing != null)
                {
                    foodDef = FoodUtility.GetFinalIngestibleDef(bestThing, false);
                }
            }
            return(bestThing);
        }