internal static Job TakeFoodForAnimalInteractJob(this WorkGiver_InteractAnimal _this, Pawn pawn, Pawn tamee) { float reqNutrition = JobDriver_InteractAnimal.RequiredNutritionPerFeed(tamee) * 2f * 4f; Thing thing = FoodUtility.BestFoodSpawnedFor(pawn, tamee, false, FoodPreferability.Raw, false, false); if (thing == null) { return(null); } // Check for inventory space int numToCarry = Mathf.CeilToInt(reqNutrition / thing.def.ingestible.nutrition); CompInventory inventory = pawn.TryGetComp <CompInventory>(); if (inventory != null) { int maxCount; if (inventory.CanFitInInventory(thing, out maxCount)) { numToCarry = Mathf.Min(numToCarry, maxCount); } else { Messages.Message("CR_TamerInventoryFull".Translate(), pawn, MessageSound.RejectInput); return(null); } } return(new Job(JobDefOf.TakeInventory, thing) { maxNumToCarry = numToCarry }); }
internal static Thing _BestFoodSourceFor(Pawn getter, Pawn eater, bool fullDispensersOnly, out ThingDef foodDef) { var dispenserValidator = new DispenserValidator(); dispenserValidator.getter = getter; dispenserValidator.fullDispensersOnly = fullDispensersOnly; Thing bestFoodSpawnedFor = FoodUtility.BestFoodSpawnedFor(getter, eater, getter == eater); if ( (getter == eater) && (getter.RaceProps.predator) && (bestFoodSpawnedFor == null) ) { Pawn prey = BestPawnToHuntForPredator(getter); if (prey != null) { foodDef = prey.RaceProps.corpseDef; return((Thing)prey); } } if (getter.RaceProps.ToolUser) { // Try to find a working nutrient paste dispenser or food sythesizer var validatorPredicate = new Predicate <Thing>(dispenserValidator.Validate); var dispensers = Find.ListerThings.AllThings.Where(t => ( (t is Building_NutrientPasteDispenser) || ( (t is Building_AutomatedFactory) && (((Building_AutomatedFactory)t).CompAutomatedFactory.Properties.outputVector == FactoryOutputVector.DirectToPawn) ) )); if (dispensers.Any()) { // Check dispenses and synthesizers (automated factories) if (bestFoodSpawnedFor != null) { // Compare with best spawned meal float dist = (getter.Position - bestFoodSpawnedFor.Position).LengthManhattan; dispenserValidator.meal.thing = bestFoodSpawnedFor; dispenserValidator.meal.def = bestFoodSpawnedFor.def; dispenserValidator.meal.score = FoodOptimality(bestFoodSpawnedFor, dist); } else { // Nothing to compare to dispenserValidator.meal.thing = null; dispenserValidator.meal.def = null; dispenserValidator.meal.score = FoodOptimalityUnusable; } // Now find the best/closest dispenser var dispenser = GenClosest.ClosestThingReachable( getter.Position, ThingRequest.ForUndefined(), PathEndMode.InteractionCell, TraverseParms.For( dispenserValidator.getter, dispenserValidator.getter.NormalMaxDanger()), 9999f, validatorPredicate, dispensers, -1, true); if (dispenser != null) { // Found a dispenser/synthesizer and it's better than the spawned meal foodDef = dispenserValidator.meal.def; return(dispenser); } } } foodDef = bestFoodSpawnedFor == null ? null : bestFoodSpawnedFor.def; return(bestFoodSpawnedFor); }
internal static Job _TryGiveTerminalJob(this JobGiver_GetFood obj, Pawn pawn) { Thing foodInInventory = null; if (pawn.RaceProps.ToolUser) { foodInInventory = FoodUtility.FoodInInventory(pawn, (Pawn)null, FoodPreferability.Awful, FoodPreferability.Lavish, 0.0f); if (foodInInventory != null) { if (pawn.Faction != Faction.OfColony) { return(obj.IngestJob(pawn, foodInInventory)); } var comp = foodInInventory.TryGetComp <CompRottable>(); if ( (comp != null) && (comp.TicksUntilRotAtCurrentTemp < 30000) ) { return(obj.IngestJob(pawn, foodInInventory)); } } } ThingDef foodDef; var bestFoodSource = FoodUtility.BestFoodSourceFor(pawn, pawn, false, out foodDef); if ( (foodInInventory != null) && ( (bestFoodSource == null) || (!pawn.Position.InHorDistOf(bestFoodSource.Position, 50f))) ) { return(obj.IngestJob(pawn, foodInInventory)); } if (bestFoodSource == null) { return((Job)null); } if (bestFoodSource is Building) { Building hopper = null; bool needsFilling = false; if ( (bestFoodSource is Building_NutrientPasteDispenser) && (!((Building_NutrientPasteDispenser)bestFoodSource).HasEnoughFeedstockInHoppers()) ) { hopper = ((Building_NutrientPasteDispenser)bestFoodSource).AdjacentReachableHopper(pawn); needsFilling = true; } else if ( (bestFoodSource is Building_AutomatedFactory) && (((Building_AutomatedFactory)bestFoodSource).BestProduct(FoodSynthesis.IsMeal, FoodSynthesis.SortMeal) == null) ) { hopper = ((Building_AutomatedFactory)bestFoodSource).AdjacentReachableHopper(pawn); needsFilling = true; } if (needsFilling) { if (hopper == null) { bestFoodSource = FoodUtility.BestFoodSpawnedFor(pawn, pawn, true, FoodPreferability.Lavish, true); if (bestFoodSource == null) { return((Job)null); } } else { var hopperSgp = hopper as ISlotGroupParent; var job = HopperFillFoodJob(pawn, hopperSgp, bestFoodSource); if (job != null) { return(job); } bestFoodSource = FoodUtility.BestFoodSpawnedFor(pawn, pawn, true, FoodPreferability.Lavish, true); if (bestFoodSource == null) { return((Job)null); } foodDef = bestFoodSource.def; } } } var prey = bestFoodSource as Pawn; if (prey != null) { var predatorHunt = new Job(JobDefOf.PredatorHunt, prey); predatorHunt.killIncappedTarget = true; return(predatorHunt); } var ingestJob = new Job(JobDefOf.Ingest, bestFoodSource); ingestJob.maxNumToCarry = FoodUtility.WillEatStackCountOf(pawn, foodDef); return(ingestJob); }