Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // FoodUtility
- using System;
- using System.Collections.Generic;
- using Verse;
- using Verse.AI;
- 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, bool forceScanWholeMap = 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 = (((int)eater.needs.food.CurCategory < 2) ? FoodPreferability.MealAwful : FoodPreferability.RawBad);
- }
- Predicate<Thing> foodValidator = delegate(Thing t)
- {
- Building_NutrientPasteDispenser building_NutrientPasteDispenser = t as Building_NutrientPasteDispenser;
- if (building_NutrientPasteDispenser != null)
- {
- if (!allowDispenserFull || !getterCanManipulate || (int)ThingDefOf.MealNutrientPaste.ingestible.preferability < (int)minPref || (int)ThingDefOf.MealNutrientPaste.ingestible.preferability > (int)maxPref || !eater.WillEat(ThingDefOf.MealNutrientPaste, getter) || (t.Faction != getter.Faction && t.Faction != getter.HostFaction) || (!allowForbidden && t.IsForbidden(getter)) || !building_NutrientPasteDispenser.powerComp.PowerOn || (!allowDispenserEmpty && !building_NutrientPasteDispenser.HasEnoughFeedstockInHoppers()) || !t.InteractionCell.Standable(t.Map) || !IsFoodSourceOnMapSociallyProper(t, getter, eater, allowSociallyImproper) || getter.IsWildMan() || !getter.Map.reachability.CanReachNonLocal(getter.Position, new TargetInfo(t.InteractionCell, t.Map), PathEndMode.OnCell, TraverseParms.For(getter, Danger.Some)))
- {
- return false;
- }
- }
- else if ((int)t.def.ingestible.preferability < (int)minPref || (int)t.def.ingestible.preferability > (int)maxPref || !eater.WillEat(t, getter) || !t.def.IsNutritionGivingIngestible || !t.IngestibleNow || (!allowCorpse && t is Corpse) || (!allowDrug && t.def.IsDrug) || (!allowForbidden && t.IsForbidden(getter)) || (!desperate && t.IsNotFresh()) || t.IsDessicated() || !IsFoodSourceOnMapSociallyProper(t, getter, eater, allowSociallyImproper) || (!getter.AnimalAwareOf(t) && !forceScanWholeMap) || !getter.CanReserve(t))
- {
- return false;
- }
- 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);
- Predicate<Thing> validator = foodValidator;
- bestThing = SpawnedFoodSearchInnerScan(eater2, position, searchSet, peMode, traverseParams, 9999f, validator);
- if (allowHarvest && getterCanManipulate)
- {
- Thing thing = GenClosest.ClosestThingReachable(searchRegionsMax: (!forceScanWholeMap || bestThing != null) ? 30 : (-1), root: getter.Position, map: getter.Map, thingReq: ThingRequest.ForGroup(ThingRequestGroup.HarvestablePlant), peMode: PathEndMode.Touch, traverseParams: TraverseParms.For(getter), maxDistance: 9999f, validator: delegate(Thing x)
- {
- Plant plant = (Plant)x;
- if (!plant.HarvestableNow)
- {
- return false;
- }
- ThingDef harvestedThingDef = plant.def.plant.harvestedThingDef;
- if (!harvestedThingDef.IsNutritionGivingIngestible)
- {
- return false;
- }
- if (!eater.WillEat(harvestedThingDef, getter))
- {
- return false;
- }
- if (!getter.CanReserve(plant))
- {
- return false;
- }
- if (!allowForbidden && plant.IsForbidden(getter))
- {
- return false;
- }
- if (bestThing != null && (int)GetFinalIngestibleDef(bestThing).ingestible.preferability >= (int)harvestedThingDef.ingestible.preferability)
- {
- return false;
- }
- return true;
- });
- if (thing != null)
- {
- bestThing = thing;
- foodDef = GetFinalIngestibleDef(thing, harvest: true);
- }
- }
- if (foodDef == null && bestThing != null)
- {
- foodDef = GetFinalIngestibleDef(bestThing);
- }
- }
- else
- {
- int maxRegionsToScan = GetMaxRegionsToScan(getter, forceScanWholeMap);
- filtered.Clear();
- foreach (Thing item in GenRadial.RadialDistinctThingsAround(getter.Position, getter.Map, 2f, useCenter: 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)
- {
- filtered.Add(pawn.CurJob.GetTarget(TargetIndex.A).Thing);
- }
- }
- bool flag = !allowForbidden && ForbidUtility.CaresAboutForbidden(getter, cellTarget: true) && getter.playerSettings != null && getter.playerSettings.EffectiveAreaRestrictionInPawnCurrentMap != null;
- Predicate<Thing> predicate = delegate(Thing t)
- {
- if (!foodValidator(t))
- {
- return false;
- }
- if (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);
- Predicate<Thing> validator = predicate;
- bool ignoreEntirelyForbiddenRegions = flag;
- bestThing = GenClosest.ClosestThingReachable(position, map, thingReq, peMode, traverseParams, 9999f, validator, null, 0, maxRegionsToScan, forceGlobalSearch: false, RegionType.Set_Passable, ignoreEntirelyForbiddenRegions);
- filtered.Clear();
- if (bestThing == null)
- {
- desperate = true;
- position = getter.Position;
- map = getter.Map;
- thingReq = thingRequest;
- peMode = PathEndMode.ClosestTouch;
- traverseParams = TraverseParms.For(getter);
- validator = foodValidator;
- ignoreEntirelyForbiddenRegions = flag;
- bestThing = GenClosest.ClosestThingReachable(position, map, thingReq, peMode, traverseParams, 9999f, validator, null, 0, maxRegionsToScan, forceGlobalSearch: false, RegionType.Set_Passable, ignoreEntirelyForbiddenRegions);
- }
- if (bestThing != null)
- {
- foodDef = GetFinalIngestibleDef(bestThing);
- }
- }
- return bestThing;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement