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
            });
        }
예제 #2
0
        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);
        }