public static void DebugFoodSearchFromMouse_OnGUI() { IntVec3 a = UI.MouseCell(); Pawn pawn = Find.Selector.SingleSelectedThing as Pawn; if (pawn != null && pawn.Map == Find.VisibleMap) { Text.Anchor = TextAnchor.MiddleCenter; Text.Font = GameFont.Tiny; foreach (Thing item in Find.VisibleMap.listerThings.ThingsInGroup(ThingRequestGroup.FoodSourceNotPlantOrTree)) { ThingDef finalIngestibleDef = FoodUtility.GetFinalIngestibleDef(item, false); float num = FoodUtility.FoodOptimality(pawn, item, finalIngestibleDef, (a - item.Position).LengthHorizontal, false); Vector2 vector = item.DrawPos.MapToUIPosition(); Rect rect = new Rect((float)(vector.x - 100.0), (float)(vector.y - 100.0), 200f, 200f); string text = num.ToString("F0"); List <ThoughtDef> list = FoodUtility.ThoughtsFromIngesting(pawn, item, finalIngestibleDef); for (int i = 0; i < list.Count; i++) { string text2 = text; text = text2 + "\n" + list[i].defName + "(" + FoodUtility.FoodOptimalityEffectFromMoodCurve.Evaluate(list[i].stages[0].baseMoodEffect).ToString("F0") + ")"; } Widgets.Label(rect, text); } Text.Anchor = TextAnchor.UpperLeft; } }
public static bool TryFindBestFoodSourceFor(Pawn getter, Pawn eater, bool desperate, out Thing foodSource, out ThingDef foodDef, bool canRefillDispenser = true, bool canUseInventory = true, bool allowForbidden = false, bool allowCorpse = true, bool allowSociallyImproper = false, bool allowHarvest = false, bool forceScanWholeMap = false) { bool flag = getter.RaceProps.ToolUser && getter.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation); bool allowDrug = !eater.IsTeetotaler(); Thing thing = null; if (canUseInventory) { if (flag) { thing = FoodUtility.BestFoodInInventory(getter, null, FoodPreferability.MealAwful, FoodPreferability.MealLavish, 0f, false); } if (thing != null) { if (getter.Faction != Faction.OfPlayer) { foodSource = thing; foodDef = FoodUtility.GetFinalIngestibleDef(foodSource, false); return(true); } CompRottable compRottable = thing.TryGetComp <CompRottable>(); if (compRottable != null && compRottable.Stage == RotStage.Fresh && compRottable.TicksUntilRotAtCurrentTemp < 30000) { foodSource = thing; foodDef = FoodUtility.GetFinalIngestibleDef(foodSource, false); return(true); } } } ThingDef thingDef; ref ThingDef foodDef2 = ref thingDef;
private static Thing SpawnedFoodSearchInnerScan(Pawn eater, IntVec3 root, List <Thing> searchSet, PathEndMode peMode, TraverseParms traverseParams, float maxDistance = 9999f, Predicate <Thing> validator = null) { if (searchSet == null) { return(null); } Pawn pawn = traverseParams.pawn ?? eater; int num = 0; int num2 = 0; Thing result = null; float num3 = 0f; float num4 = -3.40282347E+38f; for (int i = 0; i < searchSet.Count; i++) { Thing thing = searchSet[i]; num2++; float num5 = (float)(root - thing.Position).LengthManhattan; if (!(num5 > maxDistance)) { num3 = FoodUtility.FoodOptimality(eater, thing, FoodUtility.GetFinalIngestibleDef(thing, false), num5, false); if (!(num3 < num4) && pawn.Map.reachability.CanReach(root, thing, peMode, traverseParams) && thing.Spawned && (validator == null || validator(thing))) { result = thing; num4 = num3; num++; } } } return(result); }
protected override Job TryGiveJob(Pawn pawn) { if (pawn.inventory == null) { return(null); } float invNutrition = GetInventoryPackableFoodNutrition(pawn); if (invNutrition > 0.4f) { return(null); } if (pawn.Map.resourceCounter.TotalHumanEdibleNutrition < (float)pawn.Map.mapPawns.ColonistsSpawnedCount * 1.5f) { return(null); } Thing thing = GenClosest.ClosestThing_Regionwise_ReachablePrioritized(pawn.Position, pawn.Map, ThingRequest.ForGroup(ThingRequestGroup.FoodSourceNotPlantOrTree), PathEndMode.ClosestTouch, TraverseParms.For(pawn), 20f, delegate(Thing t) { if (!IsGoodPackableFoodFor(t, pawn) || t.IsForbidden(pawn) || !pawn.CanReserve(t) || !t.IsSociallyProper(pawn)) { return(false); } float num2 = invNutrition + t.GetStatValue(StatDefOf.Nutrition) * (float)t.stackCount; if (num2 < 0.8f) { return(false); } List <ThoughtDef> list = FoodUtility.ThoughtsFromIngesting(pawn, t, FoodUtility.GetFinalIngestibleDef(t)); for (int i = 0; i < list.Count; i++) { if (list[i].stages[0].baseMoodEffect < 0f) { return(false); } } return(true); }, (Thing x) => FoodUtility.FoodOptimality(pawn, x, FoodUtility.GetFinalIngestibleDef(x), 0f)); if (thing == null) { return(null); } float num = pawn.needs.food.MaxLevel - invNutrition; int a = Mathf.FloorToInt(num / thing.GetStatValue(StatDefOf.Nutrition)); a = Mathf.Min(a, thing.stackCount); a = Mathf.Max(a, 1); Job job = new Job(JobDefOf.TakeInventory, thing); job.count = a; return(job); }
private Job IngestJob(Pawn pawn) { Thing thing = BestIngestTarget(pawn); if (thing == null) { return null; } ThingDef finalIngestibleDef = FoodUtility.GetFinalIngestibleDef(thing); Job job = JobMaker.MakeJob(JobDefOf.Ingest, thing); job.count = finalIngestibleDef.ingestible.maxNumToIngestAtOnce; job.ignoreForbidden = IgnoreForbid(pawn); job.overeat = true; return job; }
private Job IngestJob(Pawn pawn) { Thing thing = this.BestIngestTarget(pawn); if (thing == null) { return(null); } ThingDef finalIngestibleDef = FoodUtility.GetFinalIngestibleDef(thing, false); Job job = new Job(JobDefOf.Ingest, thing); job.count = finalIngestibleDef.ingestible.maxNumToIngestAtOnce; job.ignoreForbidden = this.IgnoreForbid(pawn); job.overeat = true; return(job); }
protected override Job TryGiveJob(Pawn pawn) { if (pawn.inventory == null) { return(null); } ThingOwner <Thing> innerContainer = pawn.inventory.innerContainer; for (int i = 0; i < innerContainer.Count; i++) { Thing thing = innerContainer[i]; if (thing.def.ingestible != null && thing.def.ingestible.nutrition > 0.3f && thing.def.ingestible.preferability >= FoodPreferability.MealAwful && pawn.RaceProps.CanEverEat(thing)) { return(null); } } if (pawn.Map.resourceCounter.TotalHumanEdibleNutrition < (float)pawn.Map.mapPawns.ColonistsSpawnedCount * 1.5f) { return(null); } Thing thing2 = GenClosest.ClosestThing_Regionwise_ReachablePrioritized(pawn.Position, pawn.Map, ThingRequest.ForGroup(ThingRequestGroup.FoodSourceNotPlantOrTree), PathEndMode.ClosestTouch, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), 20f, delegate(Thing t) { if (t.def.category != ThingCategory.Item || t.def.ingestible == null || t.def.ingestible.nutrition < 0.3f || t.IsForbidden(pawn) || t is Corpse || !pawn.CanReserve(t, 1, -1, null, false) || !t.IsSociallyProper(pawn) || !pawn.RaceProps.CanEverEat(t)) { return(false); } List <ThoughtDef> list = FoodUtility.ThoughtsFromIngesting(pawn, t, FoodUtility.GetFinalIngestibleDef(t, false)); for (int j = 0; j < list.Count; j++) { if (list[j].stages[0].baseMoodEffect < 0f) { return(false); } } return(true); }, (Thing x) => FoodUtility.FoodOptimality(pawn, x, FoodUtility.GetFinalIngestibleDef(x, false), 0f, false), 24, 30); if (thing2 == null) { return(null); } return(new Job(JobDefOf.TakeInventory, thing2) { count = 1 }); }
private Job IngestJob(Pawn pawn) { Thing thing = this.BestIngestTarget(pawn); Job result; if (thing == null) { result = null; } else { ThingDef finalIngestibleDef = FoodUtility.GetFinalIngestibleDef(thing, false); result = new Job(JobDefOf.Ingest, thing) { count = finalIngestibleDef.ingestible.maxNumToIngestAtOnce, ignoreForbidden = this.IgnoreForbid(pawn), overeat = true }; } return(result); }
protected override Job TryGiveJob(Pawn pawn) { Job result; if (pawn.inventory == null) { result = null; } else { float invNutrition = this.GetInventoryPackableFoodNutrition(pawn); if (invNutrition > 0.4f) { result = null; } else if (pawn.Map.resourceCounter.TotalHumanEdibleNutrition < (float)pawn.Map.mapPawns.ColonistsSpawnedCount * 1.5f) { result = null; } else { Thing thing = GenClosest.ClosestThing_Regionwise_ReachablePrioritized(pawn.Position, pawn.Map, ThingRequest.ForGroup(ThingRequestGroup.FoodSourceNotPlantOrTree), PathEndMode.ClosestTouch, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), 20f, delegate(Thing t) { bool result2; if (!this.IsGoodPackableFoodFor(t, pawn) || t.IsForbidden(pawn) || !pawn.CanReserve(t, 1, -1, null, false) || !t.IsSociallyProper(pawn)) { result2 = false; } else { float num3 = invNutrition + t.GetStatValue(StatDefOf.Nutrition, true) * (float)t.stackCount; if (num3 < 0.8f) { result2 = false; } else { List <ThoughtDef> list = FoodUtility.ThoughtsFromIngesting(pawn, t, FoodUtility.GetFinalIngestibleDef(t, false)); for (int i = 0; i < list.Count; i++) { if (list[i].stages[0].baseMoodEffect < 0f) { return(false); } } result2 = true; } } return(result2); }, (Thing x) => FoodUtility.FoodOptimality(pawn, x, FoodUtility.GetFinalIngestibleDef(x, false), 0f, false), 24, 30); if (thing == null) { result = null; } else { float num = pawn.needs.food.MaxLevel - invNutrition; int num2 = Mathf.FloorToInt(num / thing.GetStatValue(StatDefOf.Nutrition, true)); num2 = Mathf.Min(num2, thing.stackCount); num2 = Mathf.Max(num2, 1); result = new Job(JobDefOf.TakeInventory, thing) { count = num2 }; } } } return(result); }
internal float <> m__1(Thing x) { return(FoodUtility.FoodOptimality(this.pawn, x, FoodUtility.GetFinalIngestibleDef(x, false), 0f, false)); }
internal bool <> m__0(Thing t) { bool result; if (!this.$this.IsGoodPackableFoodFor(t, this.pawn) || t.IsForbidden(this.pawn) || !this.pawn.CanReserve(t, 1, -1, null, false) || !t.IsSociallyProper(this.pawn)) { result = false; } else { float num = this.invNutrition + t.GetStatValue(StatDefOf.Nutrition, true) * (float)t.stackCount; if (num < 0.8f) { result = false; } else { List <ThoughtDef> list = FoodUtility.ThoughtsFromIngesting(this.pawn, t, FoodUtility.GetFinalIngestibleDef(t, false)); for (int i = 0; i < list.Count; i++) { if (list[i].stages[0].baseMoodEffect < 0f) { return(false); } } result = true; } } return(result); }
public static bool TryFindBestFoodSourceFor(Pawn getter, Pawn eater, bool desperate, out Thing foodSource, out ThingDef foodDef, bool canRefillDispenser = true, bool canUseInventory = true, bool allowForbidden = false, bool allowCorpse = true, bool allowSociallyImproper = false, bool allowHarvest = false) { bool flag = getter.RaceProps.ToolUser && getter.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation); bool allowDrug = !eater.IsTeetotaler(); Thing thing = null; if (canUseInventory) { if (flag) { thing = FoodUtility.BestFoodInInventory(getter, null, FoodPreferability.MealAwful, FoodPreferability.MealLavish, 0f, false); } if (thing != null) { if (getter.Faction != Faction.OfPlayer) { foodSource = thing; foodDef = FoodUtility.GetFinalIngestibleDef(foodSource, false); return(true); } CompRottable compRottable = thing.TryGetComp <CompRottable>(); if (compRottable != null && compRottable.Stage == RotStage.Fresh && compRottable.TicksUntilRotAtCurrentTemp < 30000) { foodSource = thing; foodDef = FoodUtility.GetFinalIngestibleDef(foodSource, false); return(true); } } } bool allowPlant = getter == eater; ThingDef thingDef = default(ThingDef); Thing thing2 = FoodUtility.BestFoodSourceOnMap(getter, eater, desperate, out thingDef, FoodPreferability.MealLavish, allowPlant, allowDrug, allowCorpse, true, canRefillDispenser, allowForbidden, allowSociallyImproper, allowHarvest); if (thing == null && thing2 == null) { if (canUseInventory && flag) { thing = FoodUtility.BestFoodInInventory(getter, null, FoodPreferability.DesperateOnly, FoodPreferability.MealLavish, 0f, allowDrug); if (thing != null) { foodSource = thing; foodDef = FoodUtility.GetFinalIngestibleDef(foodSource, false); return(true); } } if (thing2 == null && getter == eater && (getter.RaceProps.predator || getter.IsWildMan())) { Pawn pawn = FoodUtility.BestPawnToHuntForPredator(getter); if (pawn != null) { foodSource = pawn; foodDef = FoodUtility.GetFinalIngestibleDef(foodSource, false); return(true); } } foodSource = null; foodDef = null; return(false); } if (thing == null && thing2 != null) { foodSource = thing2; foodDef = thingDef; return(true); } ThingDef finalIngestibleDef = FoodUtility.GetFinalIngestibleDef(thing, false); if (thing2 == null) { foodSource = thing; foodDef = finalIngestibleDef; return(true); } float num = FoodUtility.FoodOptimality(eater, thing2, thingDef, (float)(getter.Position - thing2.Position).LengthManhattan, false); float num2 = FoodUtility.FoodOptimality(eater, thing, finalIngestibleDef, 0f, false); num2 = (float)(num2 - 32.0); if (num > num2) { foodSource = thing2; foodDef = thingDef; return(true); } foodSource = thing; foodDef = FoodUtility.GetFinalIngestibleDef(foodSource, false); return(true); }
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); }