Exemple #1
0
        public static Job HopperFillFoodJob(Pawn pawn, ISlotGroupParent hopperSgp)
        {
            Building building = hopperSgp as Building;

            if (!pawn.CanReserveAndReach(building.Position, PathEndMode.Touch, pawn.NormalMaxDanger(), 1))
            {
                return(null);
            }
            ThingDef thingDef  = null;
            Thing    firstItem = building.Position.GetFirstItem();

            if (firstItem != null)
            {
                if (firstItem.def.IsNutritionSource)
                {
                    thingDef = firstItem.def;
                }
                else
                {
                    if (firstItem.IsForbidden(pawn.Faction))
                    {
                        return(null);
                    }
                    return(HaulAIUtility.HaulAsideJobFor(pawn, firstItem));
                }
            }
            List <Thing> list;

            if (thingDef == null)
            {
                list = Find.Map.listerThings.ThingsInGroup(ThingRequestGroup.FoodNotPlantOrTree);
            }
            else
            {
                list = Find.Map.listerThings.ThingsOfDef(thingDef);
            }
            for (int i = 0; i < list.Count; i++)
            {
                Thing thing = list[i];
                if (thing.def.ingestible.preferability == FoodPreferability.Raw)
                {
                    if (HaulAIUtility.PawnCanAutomaticallyHaul(pawn, thing))
                    {
                        if (Find.SlotGroupManager.SlotGroupAt(building.Position).Settings.AllowedToAccept(thing))
                        {
                            StoragePriority storagePriority = HaulAIUtility.StoragePriorityAtFor(thing.Position, thing);
                            if (storagePriority < hopperSgp.GetSlotGroup().Settings.Priority)
                            {
                                Job job = HaulAIUtility.HaulMaxNumToCellJob(pawn, thing, building.Position, true);
                                if (job != null)
                                {
                                    return(job);
                                }
                            }
                        }
                    }
                }
            }
            return(null);
        }
Exemple #2
0
        public static Job SmartBuild(Pawn p, Job job)
        {
            if (p.story.WorkTagIsDisabled(WorkTags.Hauling))
            {
                return(job);
            }
            var carryCapacity   = p.GetStatValue(StatDefOf.CarryingCapacity);
            var itemCount       = job.count;
            var thing           = job.targetA.Thing;
            var storagePriority = HaulAIUtility.StoragePriorityAtFor(thing.Position, thing);


            IntVec3 storePos;

            if (StoreUtility.TryFindBestBetterStoreCellFor(thing, p, thing.Map, storagePriority, p.Faction, out storePos) && carryCapacity >= itemCount)
            {
                var targetPos = thing.Position;
                var destPos   = job.targetB.Thing.Position;
                if ((targetPos - destPos).LengthHorizontalSquared > (targetPos - storePos).LengthHorizontalSquared)
                {
                    return(HaulAIUtility.HaulMaxNumToCellJob(p, thing, storePos, false));
                }
            }

            return(job);
        }
        public override Job JobOnThing(Pawn pawn, Thing thing, bool forced = false)
        {
            Logger.Debug($"{pawn.NameStringShort} is trying to merge {thing.Label}...");

            // standard hauling checks
            if (!HaulAIUtility.PawnCanAutomaticallyHaulFast(pawn, thing, forced))
            {
                return(null);
            }
            Logger.Debug($"{thing.LabelCap} can be hauled...");

            // find better place, and haul there
            IntVec3 target;

            if (pawn.Map.listerStackables().TryGetTargetCell(pawn, thing, out target))
            {
                if (pawn.Map.reservationManager.CanReserve(pawn, target, 1))
                {
                    Logger.Debug($"Hauling {thing.Label} to {target}...");
                    return(HaulAIUtility.HaulMaxNumToCellJob(pawn, thing, target, true));
                }

                Logger.Debug($"Couldn't reserve {target}...");
            }
            else
            {
                Logger.Debug($"Couldn't get target cell for {thing.Label}, removing from cache...");
                pawn.Map.listerStackables().TryRemove(thing);
            }

            return(null);
        }
Exemple #4
0
        public static Job HopperFillFoodJob(Pawn pawn, ISlotGroupParent hopperSgp)
        {
            Building building = hopperSgp as Building;

            if (!pawn.CanReserveAndReach(building.Position, PathEndMode.Touch, pawn.NormalMaxDanger(), 1, -1, null, false))
            {
                return(null);
            }
            ThingDef thingDef  = null;
            Thing    firstItem = building.Position.GetFirstItem(building.Map);

            if (firstItem != null)
            {
                if (!Building_NutrientPasteDispenser.IsAcceptableFeedstock(firstItem.def))
                {
                    if (firstItem.IsForbidden(pawn))
                    {
                        return(null);
                    }
                    return(HaulAIUtility.HaulAsideJobFor(pawn, firstItem));
                }
                thingDef = firstItem.def;
            }
            List <Thing> list = (thingDef != null) ? pawn.Map.listerThings.ThingsOfDef(thingDef) : pawn.Map.listerThings.ThingsInGroup(ThingRequestGroup.FoodSourceNotPlantOrTree);
            bool         flag = false;

            for (int i = 0; i < list.Count; i++)
            {
                Thing thing = list[i];
                if (thing.def.IsNutritionGivingIngestible && (thing.def.ingestible.preferability == FoodPreferability.RawBad || thing.def.ingestible.preferability == FoodPreferability.RawTasty) && HaulAIUtility.PawnCanAutomaticallyHaul(pawn, thing, false) && pawn.Map.slotGroupManager.SlotGroupAt(building.Position).Settings.AllowedToAccept(thing))
                {
                    StoragePriority storagePriority = HaulAIUtility.StoragePriorityAtFor(thing.Position, thing);
                    if ((int)storagePriority >= (int)hopperSgp.GetSlotGroup().Settings.Priority)
                    {
                        flag = true;
                        JobFailReason.Is(WorkGiver_CookFillHopper.TheOnlyAvailableFoodIsInStorageOfHigherPriorityTrans);
                    }
                    else
                    {
                        Job job = HaulAIUtility.HaulMaxNumToCellJob(pawn, thing, building.Position, true);
                        if (job != null)
                        {
                            return(job);
                        }
                    }
                }
            }
            if (!flag)
            {
                JobFailReason.Is(WorkGiver_CookFillHopper.NoFoodToFillHopperTrans);
            }
            return(null);
        }
Exemple #5
0
        private static Job                  HopperFillJob(Pawn pawn, ISlotGroupParent hopperSgp, Thing resource)
        {
            Building building = hopperSgp as Building;

            // Get a sorted list (by distance) of matching resources
            List <Thing> resources = null;

            if (resource != null)
            {
                resources = Find.Map.listerThings.ThingsOfDef(resource.def)
                            .Where(t => (
                                       (HaulAIUtility.PawnCanAutomaticallyHaul(pawn, t)) &&
                                       (hopperSgp.GetStoreSettings().AllowedToAccept(t)) &&
                                       (HaulAIUtility.StoragePriorityAtFor(t.Position, t) < hopperSgp.GetSlotGroup().Settings.Priority)
                                       )).ToList();
            }
            else
            {
                resources = Find.Map.listerThings.AllThings
                            .Where(t => (
                                       (HaulAIUtility.PawnCanAutomaticallyHaul(pawn, t)) &&
                                       (hopperSgp.GetStoreSettings().AllowedToAccept(t)) &&
                                       (HaulAIUtility.StoragePriorityAtFor(t.Position, t) < hopperSgp.GetSlotGroup().Settings.Priority)
                                       )).ToList();
            }

            if (resources.NullOrEmpty())
            {
                return((Job)null);
            }

            // Sort by distance (closest first)
            resources.Sort((Thing x, Thing y) => (Gen.ManhattanDistanceFlat(x.Position, building.Position) < Gen.ManhattanDistanceFlat(y.Position, building.Position)) ? -1 : 1);

            var grabResource = resources.First();

            if (grabResource != null)
            {
                // Try to haul the first (closest) resource found
                var job = HaulAIUtility.HaulMaxNumToCellJob(pawn, grabResource, building.Position, true);
                if (job != null)
                {
                    return(job);
                }
            }
            return((Job)null);
        }
        public override Job JobOnThing(Pawn pawn, Thing target)
        {
            Job job = GetCachedJob(pawn, target);

            // verify the job we found is hauling our target
            if (job != null)
            {
                if (job.targetA == target)
                {
                    return(job);
                }
                return(null);
            }

            if (!CanHaul(pawn, target))
            {
                return(null);
            }

            if (!IsThingCompactible(target))
            {
                return(null);
            }

            var destination = FindThingToStackOnto(pawn, target);

            if (destination == null)
            {
                return(null);
            }


            // should always be true, but it's good to safeguard against collisions
            if (!CanHaul(pawn, target, destination))
            {
                return(null);
            }


            job = HaulAIUtility.HaulMaxNumToCellJob(pawn, target, destination.Position, false);

            _haulingJobs.Add(pawn, job);

            LogMessage(() => $"{pawn} hauling {target.stackCount} of {target} to {destination.Position} in zone {target.Map.zoneManager.ZoneAt(target.Position) as Zone_Stockpile}, having {destination.stackCount}/{destination.def.stackLimit}");
            return(job);
        }
Exemple #7
0
        internal static Job HopperFillFoodJob(Pawn pawn, Building hopper, Thing parent)
        {
            var hopperSgp = hopper as ISlotGroupParent;

            if (
                (!pawn.CanReserveAndReach(
                     hopper.Position,
                     PathEndMode.Touch,
                     pawn.NormalMaxDanger(),
                     1)
                )
                )
            {
                return(null);
            }
            ThingDef resourceDef = null;
            var      firstItem   = hopper.Position.GetFirstItem();

            if (firstItem != null)
            {
                if (
                    (
                        (parent is Building_NutrientPasteDispenser) &&
                        (Building_NutrientPasteDispenser.IsAcceptableFeedstock(firstItem.def))
                    ) ||
                    (
                        (parent is Building_AutomatedFactory) &&
                        (((Building_AutomatedFactory)parent).CompHopperUser.ResourceSettings.AllowedToAccept(firstItem))
                    )
                    )
                {
                    resourceDef = firstItem.def;
                }
                else
                {
                    if (firstItem.IsForbidden(pawn))
                    {
                        return(( Job )null);
                    }
                    return(HaulAIUtility.HaulAsideJobFor(pawn, firstItem));
                }
            }
            List <Thing> list =
                resourceDef != null
                ? Find.Map.listerThings.ThingsOfDef(resourceDef)
                : Find.Map.listerThings.ThingsInGroup(ThingRequestGroup.FoodSourceNotPlantOrTree);

            for (int index = 0; index < list.Count; ++index)
            {
                Thing t = list[index];
                if (
                    (t.def.IsNutritionGivingIngestible) &&
                    (
                        (t.def.ingestible.preferability == FoodPreferability.RawBad) ||
                        (t.def.ingestible.preferability == FoodPreferability.RawTasty)
                    ) &&
                    (HaulAIUtility.PawnCanAutomaticallyHaul(pawn, t)) &&
                    (
                        (Find.SlotGroupManager.SlotGroupAt(hopper.Position).Settings.AllowedToAccept(t)) &&
                        (HaulAIUtility.StoragePriorityAtFor(t.Position, t) < hopperSgp.GetSlotGroup().Settings.Priority)
                    )
                    )
                {
                    Job job = HaulAIUtility.HaulMaxNumToCellJob(pawn, t, hopper.Position, true);
                    if (job != null)
                    {
                        return(job);
                    }
                }
            }
            return(null);
        }