Exemple #1
0
        protected override Job TryGiveJob(Pawn pawn)
        {
            Predicate <Thing> validator = delegate(Thing t)
            {
                if (t.IsForbidden(pawn))
                {
                    return(false);
                }
                if (!HaulAIUtility.PawnCanAutomaticallyHaulFast(pawn, t, forced: false))
                {
                    return(false);
                }
                if (pawn.carryTracker.MaxStackSpaceEver(t.def) <= 0)
                {
                    return(false);
                }
                if (!StoreUtility.TryFindBestBetterStoreCellFor(t, pawn, pawn.Map, StoreUtility.CurrentStoragePriorityOf(t), pawn.Faction, out IntVec3 _))
                {
                    return(false);
                }
                return(true);
            };
            Thing thing = GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map, pawn.Map.listerHaulables.ThingsPotentiallyNeedingHauling(), PathEndMode.OnCell, TraverseParms.For(pawn), 9999f, validator);

            if (thing != null)
            {
                return(HaulAIUtility.HaulToStorageJob(pawn, thing));
            }
            return(null);
        }
Exemple #2
0
 private Action RestoreRemainingThings(Thing t, int amount)
 {
     return(delegate
     {
         pawn.jobs.TryTakeOrderedJob(HaulAIUtility.HaulToStorageJob(pawn, t));
     });
 }
        /// <summary>
        /// the workgiver checks for encumbered, this is purely extra for CE
        /// </summary>
        /// <returns></returns>
        public Toil CheckForOverencumberedForCombatExtended()
        {
            Toil toil = new Toil();

            if (!ModCompatibilityCheck.CombatExtendedIsActive)
            {
                return(toil);
            }

            toil.initAction = delegate
            {
                Pawn  actor     = toil.actor;
                Job   curJob    = actor.jobs.curJob;
                Thing nextThing = curJob.targetA.Thing;

                var ceOverweight = CompatHelper.CeOverweight(pawn);

                if (!(MassUtility.EncumbrancePercent(actor) <= 0.9f && !ceOverweight))
                {
                    Job haul = HaulAIUtility.HaulToStorageJob(actor, nextThing);
                    if (haul?.TryMakePreToilReservations(actor, false) ?? false)
                    {
                        //note that HaulToStorageJob etc doesn't do opportunistic duplicate hauling for items in valid storage. REEEE
                        actor.jobs.jobQueue.EnqueueFirst(haul, JobTag.Misc);
                        EndJobWith(JobCondition.Succeeded);
                    }
                }
            };

            return(toil);
        }
 public override Job JobOnThing(Pawn pawn, Thing t, bool forced = false)
 {
     if (!HaulAIUtility.PawnCanAutomaticallyHaul(pawn, t, forced))
     {
         return(null);
     }
     return(HaulAIUtility.HaulToStorageJob(pawn, t));
 }
Exemple #5
0
 private void Haul()
 {
     if (HaulAIUtility.PawnCanAutomaticallyHaulFast(pawn, Silver, false))
     {
         pawn.jobs.StartJob(HaulAIUtility.HaulToStorageJob(pawn, Silver), JobCondition.Succeeded);
     }
     else
     {
         pawn.jobs.EndCurrentJob(JobCondition.Incompletable);
     }
 }
Exemple #6
0
 public static Job PutAwayTool(this Pawn pawn, ThingWithComps tool, bool bestLoc = true)
 {
     if (bestLoc)
     {
         return(HaulAIUtility.HaulToStorageJob(pawn, tool));
     }
     else
     {
         return(HaulAIUtility.HaulToStorageJob(pawn, tool));
     }
 }
Exemple #7
0
        public static Job TryGiveJob(this JobGiver_Haul @this, Pawn pawn)
        {
            Predicate <Thing> validator = t => !t.IsForbidden(pawn) && HaulAIUtility.PawnCanAutomaticallyHaulFast(pawn, t) && IsPlaceToPutThing(pawn, t);
            Thing             thing     = GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map, pawn.Map.listerHaulables.ThingsPotentiallyNeedingHauling(), PathEndMode.OnCell, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), 9999f, validator, null);

            if (thing != null)
            {
                return(HaulAIUtility.HaulToStorageJob(pawn, thing));
            }
            return(null);
        }
 protected override Job TryGiveJob(Pawn pawn)
 {
     if (pawn.Map == null)
     {
         return(null);
     }
     if (!pawn.story.WorkTagIsDisabled(WorkTags.Cleaning) && pawn.Map.listerFilthInHomeArea.FilthInHomeArea.Count > 0)
     {
         Thing closestFilth = pawn.Map.listerFilthInHomeArea.FilthInHomeArea.RandomElement();
         if (closestFilth != null && pawn.CanReserveAndReach(closestFilth, PathEndMode.Touch, Danger.Some))
         {
             Job job = new Job(JobDefOf.Clean);
             job.AddQueuedTarget(TargetIndex.A, closestFilth);
             int  num  = 15;
             Map  map  = closestFilth.Map;
             Room room = closestFilth.GetRoom(RegionType.Set_Passable);
             for (int i = 0; i < 100; i++)
             {
                 IntVec3 intVec = closestFilth.Position + GenRadial.RadialPattern[i];
                 if (intVec.InBounds(map) && intVec.GetRoom(map, RegionType.Set_Passable) == room)
                 {
                     List <Thing> thingList = intVec.GetThingList(map);
                     for (int j = 0; j < thingList.Count; j++)
                     {
                         Thing thing = thingList[j];
                         if (thing != closestFilth && IsValidFilth(pawn, thing))
                         {
                             job.AddQueuedTarget(TargetIndex.A, thing);
                         }
                     }
                     if (job.GetTargetQueue(TargetIndex.A).Count >= num)
                     {
                         break;
                     }
                 }
             }
             if (job.targetQueueA != null && job.targetQueueA.Count >= 5)
             {
                 job.targetQueueA.SortBy((LocalTargetInfo targ) => targ.Cell.DistanceToSquared(pawn.Position));
             }
             return(job);
         }
     }
     if (!pawn.story.WorkTagIsDisabled(WorkTags.Hauling) && pawn.Map.listerHaulables.ThingsPotentiallyNeedingHauling().Count > 0)
     {
         Thing thing = pawn.Map.listerHaulables.ThingsPotentiallyNeedingHauling().RandomElement();
         if (thing != null && HaulAIUtility.PawnCanAutomaticallyHaulFast(pawn, thing, true) && pawn.CanReserveAndReach(thing, PathEndMode.Touch, Danger.Some))
         {
             return(HaulAIUtility.HaulToStorageJob(pawn, thing));
         }
     }
     return(null);
 }
Exemple #9
0
        // drop tool and haul it to stockpile, if necessary
        public Job TryReturnTool(Pawn pawn)
        {
            ThingWithComps tool;

            // drops primary equipment (weapon) as forbidden
            pawn.equipment.TryDropEquipment(pawn.equipment.Primary, out tool, pawn.Position);
            // making it non forbidden
            tool.SetForbidden(false);

            // tr to haul to the stockpile
            return(HaulAIUtility.HaulToStorageJob(pawn, tool));
        }
Exemple #10
0
        public Job ReturnTool(Pawn pawn)
        {
            // NOTE: temporary solution using default jobs, need future improvement
            ThingWithComps tool;

            // drops primary equipment (weapon) as forbidden
            pawn.equipment.TryDropEquipment(pawn.equipment.Primary, out tool, pawn.Position);
            // making it non forbidden
            tool.SetForbidden(false);
            // vanilla haul to best stockpile job
            return(HaulAIUtility.HaulToStorageJob(pawn, tool));
        }
Exemple #11
0
        //pick up stuff until you can't anymore,
        //while you're up and about, pick up something and haul it
        //before you go out, empty your pockets

        public override Job JobOnThing(Pawn pawn, Thing thing, bool forced = false)
        {
            CompHauledToInventory takenToInventory = pawn.TryGetComp <CompHauledToInventory>();

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

            if (thing is Corpse)
            {
                return(null);
            }

            if (!HaulAIUtility.PawnCanAutomaticallyHaulFast(pawn, thing, forced))
            {
                return(null);
            }

            if (thing.IsForbidden(pawn) || StoreUtility.IsInValidBestStorage(thing))
            {
                return(null);
            }

            //bulky gear (power armor + minigun) so don't bother.
            if (MassUtility.GearMass(pawn) / MassUtility.Capacity(pawn) >= 0.8f)
            {
                return(null);
            }

            StoragePriority currentPriority = HaulAIUtility.StoragePriorityAtFor(thing.Position, thing);

            if (StoreUtility.TryFindBestBetterStoreCellFor(thing, pawn, pawn.Map, currentPriority, pawn.Faction, out IntVec3 storeCell, true))
            {
                //since we've gone through all the effort of getting the loc, might as well use it.
                //Don't multi-haul food to hoppers.
                if (thing.def.IsNutritionGivingIngestible)
                {
                    if (thing.def.ingestible.preferability == FoodPreferability.RawBad || thing.def.ingestible.preferability == FoodPreferability.RawTasty)
                    {
                        List <Thing> thingList = storeCell.GetThingList(thing.Map);
                        for (int i = 0; i < thingList.Count; i++)
                        {
                            Thing thingAtCell = thingList[i];
                            if (thingAtCell.def == ThingDefOf.Hopper)
                            {
                                return(HaulAIUtility.HaulToStorageJob(pawn, thing));
                            }
                        }
                    }
                }
            }
        public static bool TryGiveJob(ref Job __result, Pawn pawn)
        {
            int validationChecks        = 0;
            int validatorFalses1        = 0;
            int validatorFalses2        = 0;
            int validatorFalses3        = 0;
            int validatorFalses4        = 0;
            Predicate <Thing> validator = delegate(Thing t)
            {
                validationChecks++;
                if (t.IsForbidden(pawn))
                {
                    validatorFalses1++;
                    return(false);
                }

                if (!HaulAIUtility.PawnCanAutomaticallyHaulFast(pawn, t, forced: false))
                {
                    validatorFalses2++;
                    return(false);
                }

                if (pawn.carryTracker.MaxStackSpaceEver(t.def) <= 0)
                {
                    validatorFalses3++;
                    return(false);
                }

                IntVec3 foundCell;
                bool    tryFindBestBetterStoreCellFor = StoreUtility.TryFindBestBetterStoreCellFor(t, pawn, pawn.Map, StoreUtility.CurrentStoragePriorityOf(t), pawn.Faction, out foundCell) ? true : false;
                if (!tryFindBestBetterStoreCellFor)
                {
                    validatorFalses4++;
                }
                return(tryFindBestBetterStoreCellFor);
            };
            //Log.Error(pawn.Map.listerHaulables.ThingsPotentiallyNeedingHauling().Count.ToString());
            Thing thing = GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map, pawn.Map.listerHaulables.ThingsPotentiallyNeedingHauling(), PathEndMode.OnCell, TraverseParms.For(pawn), 9999f, validator);

            if (validationChecks > 10)
            {
                Log.Error("Validator Checks: " + validationChecks.ToString() + " " + validatorFalses1.ToString() + " " + validatorFalses2.ToString() + " " + validatorFalses3.ToString() + " " + validatorFalses4.ToString() + " ");
            }
            if (thing != null)
            {
                __result = HaulAIUtility.HaulToStorageJob(pawn, thing);
                return(false);
            }
            __result = null;
            return(false);
        }
        //pick up stuff until you can't anymore,
        //while you're up and about, pick up something and haul it
        //before you go out, empty your pockets

        public override Job JobOnThing(Pawn pawn, Thing thing, bool forced = false)
        {
            //bulky gear (power armor + minigun) so don't bother.
            if (MassUtility.GearMass(pawn) / MassUtility.Capacity(pawn) >= 0.8f)
            {
                return(null);
            }

            DesignationDef haulUrgentlyDesignation = DefDatabase <DesignationDef> .GetNamed("HaulUrgentlyDesignation", false);

            // Misc. Robots compatibility
            // See https://github.com/catgirlfighter/RimWorld_CommonSense/blob/master/Source/CommonSense11/CommonSense/OpportunisticTasks.cs#L129-L140
            if (pawn.TryGetComp <CompHauledToInventory>() == null)
            {
                return(null);
            }

            //This WorkGiver gets hijacked by AllowTool and expects us to urgently haul corpses.
            if (ModCompatibilityCheck.AllowToolIsActive && thing is Corpse &&
                pawn.Map.designationManager.DesignationOn(thing)?.def == haulUrgentlyDesignation && HaulAIUtility.PawnCanAutomaticallyHaulFast(pawn, thing, forced))
            {
                return(HaulAIUtility.HaulToStorageJob(pawn, thing));
            }

            if (!GoodThingToHaul(thing, pawn) || !HaulAIUtility.PawnCanAutomaticallyHaulFast(pawn, thing, forced))
            {
                return(null);
            }

            StoragePriority currentPriority = StoreUtility.CurrentStoragePriorityOf(thing);

            if (StoreUtility.TryFindBestBetterStoreCellFor(thing, pawn, pawn.Map, currentPriority, pawn.Faction, out IntVec3 storeCell, true))
            {
                //since we've gone through all the effort of getting the loc, might as well use it.
                //Don't multi-haul food to hoppers.
                if (thing.def.IsNutritionGivingIngestible)
                {
                    if (thing.def.ingestible.preferability == FoodPreferability.RawBad || thing.def.ingestible.preferability == FoodPreferability.RawTasty)
                    {
                        List <Thing> thingList = storeCell.GetThingList(thing.Map);

                        foreach (Thing t in thingList)
                        {
                            if (t.def == ThingDefOf.Hopper)
                            {
                                return(HaulAIUtility.HaulToStorageJob(pawn, thing));
                            }
                        }
                    }
                }
            }
        protected override Job TryGiveJob(Pawn pawn)
        {
            Predicate <Thing> validator = delegate(Thing t)
            {
                IntVec3 intVec;
                return(!t.IsForbidden(pawn) && HaulAIUtility.PawnCanAutomaticallyHaulFast(pawn, t, false) && pawn.carryTracker.MaxStackSpaceEver(t.def) > 0 && StoreUtility.TryFindBestBetterStoreCellFor(t, pawn, pawn.Map, HaulAIUtility.StoragePriorityAtFor(t.Position, t), pawn.Faction, out intVec, true));
            };
            Thing thing = GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map, pawn.Map.listerHaulables.ThingsPotentiallyNeedingHauling(), PathEndMode.OnCell, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), 9999f, validator, null);

            if (thing != null)
            {
                return(HaulAIUtility.HaulToStorageJob(pawn, thing));
            }
            return(null);
        }
        public static bool Prefix(Pawn pawn, Thing thing, ref Job __result)
        {
            StoragePriority currentPriority = StoreUtility.CurrentStoragePriorityOf(thing);

            if (StoreUtility.TryFindBestBetterStoreCellFor(thing, pawn, pawn.Map, currentPriority, pawn.Faction, out IntVec3 storeCell, true))
            {
                SlotGroup slotGroup = StoreUtility.GetSlotGroup(storeCell, thing.Map);
                if (Limits.HasLimit(slotGroup.Settings))
                {
                    __result = HaulAIUtility.HaulToStorageJob(pawn, thing);
                    return(false);
                }
            }

            return(true);
        }
Exemple #16
0
        // Token: 0x0600001D RID: 29 RVA: 0x00003124 File Offset: 0x00001324
        public static void AYWashHaulJob(Thing t)
        {
            if (!t.Spawned)
            {
                return;
            }

            var tub = t.Position.GetFirstBuilding(t.Map);

            if (tub == null || tub.def.defName != "AYApparelWashingTub")
            {
                return;
            }

            var p = tub.InteractionCell.GetFirstPawn(t.Map);

            if (p == null)
            {
                return;
            }

            var    jobs = p.jobs;
            JobDef jobDef;

            if (jobs == null)
            {
                jobDef = null;
            }
            else
            {
                var curJob = jobs.curJob;
                jobDef = curJob?.def;
            }

            if (jobDef != JobDefOf.DoBill)
            {
                return;
            }

            var newHaul = HaulAIUtility.HaulToStorageJob(p, t);

            if (newHaul != null)
            {
                p.jobs.jobQueue.EnqueueFirst(newHaul, JobTag.MiscWork);
            }
        }
Exemple #17
0
        public override Job JobOnThing(Pawn pawn, Thing t, bool forced = false)
        {
            Profiler.BeginSample("PawnCanAutomaticallyHaulFast");
            Job result;

            if (!HaulAIUtility.PawnCanAutomaticallyHaulFast(pawn, t, forced))
            {
                Profiler.EndSample();
                result = null;
            }
            else
            {
                Profiler.EndSample();
                result = HaulAIUtility.HaulToStorageJob(pawn, t);
            }
            return(result);
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnDespawnedNullOrForbidden(TargetIndex.A);
            this.FailOnDestroyedOrNull(TargetIndex.A);
            yield return(Toils_Reserve.Reserve(TargetIndex.A));

            yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell));

            yield return(Toils_General.WaitWith(TargetIndex.A, 200, true));

            yield return(new Toil()
            {
                initAction = delegate()
                {
                    Building_GrowerBase grower = TargetThingA as Building_GrowerBase;
                    if (grower != null)
                    {
                        Pawn actor = GetActor();
                        Thing product = grower.ExtractProduct(actor);
                        if (!product.Spawned)
                        {
                            GenPlace.TryPlaceThing(product, grower.InteractionCell, grower.Map, ThingPlaceMode.Near);
                        }

                        if (product is Pawn)
                        {
                            EndJobWith(JobCondition.Succeeded);
                        }
                        else
                        {
                            //job.SetTarget(TargetIndex.B, product);
                            IntVec3 storeCell;
                            IHaulDestination haulDestination;
                            if (StoreUtility.TryFindBestBetterStorageFor(product, actor, product.Map, StoragePriority.Unstored, actor.Faction, out storeCell, out haulDestination, false))
                            {
                                if (storeCell.IsValid || haulDestination != null)
                                {
                                    actor.jobs.StartJob(HaulAIUtility.HaulToStorageJob(actor, product), JobCondition.Succeeded);
                                }
                            }
                        }
                    }
                }
            });
        }
Exemple #19
0
        //pick up stuff until you can't anymore,
        //while you're up and about, pick up something and haul it
        //before you go out, empty your pockets

        public override Job JobOnThing(Pawn pawn, Thing thing, bool forced = false)
        {
            //bulky gear (power armor + minigun) so don't bother.
            if (MassUtility.GearMass(pawn) / MassUtility.Capacity(pawn) >= 0.8f)
            {
                return(null);
            }

            DesignationDef HaulUrgentlyDesignation = DefDatabase <DesignationDef> .GetNamed("HaulUrgentlyDesignation", false);

            //This WorkGiver gets hijacked by AllowTool and expects us to urgently haul corpses.
            if (ModCompatibilityCheck.AllowToolIsActive && thing is Corpse && pawn.Map.designationManager.DesignationOn(thing)?.def == HaulUrgentlyDesignation && HaulAIUtility.PawnCanAutomaticallyHaulFast(pawn, thing, forced))
            {
                return(HaulAIUtility.HaulToStorageJob(pawn, thing));
            }

            if (!GoodThingToHaul(thing, pawn) || !HaulAIUtility.PawnCanAutomaticallyHaulFast(pawn, thing, forced))
            {
                return(null);
            }

            StoragePriority currentPriority = StoreUtility.CurrentStoragePriorityOf(thing);

            if (StoreUtility.TryFindBestBetterStoreCellFor(thing, pawn, pawn.Map, currentPriority, pawn.Faction, out IntVec3 storeCell, true))
            {
                //since we've gone through all the effort of getting the loc, might as well use it.
                //Don't multi-haul food to hoppers.
                if (thing.def.IsNutritionGivingIngestible)
                {
                    if (thing.def.ingestible.preferability == FoodPreferability.RawBad || thing.def.ingestible.preferability == FoodPreferability.RawTasty)
                    {
                        List <Thing> thingList = storeCell.GetThingList(thing.Map);
                        for (int i = 0; i < thingList.Count; i++)
                        {
                            if (thingList[i].def == ThingDefOf.Hopper)
                            {
                                return(HaulAIUtility.HaulToStorageJob(pawn, thing));
                            }
                        }
                    }
                }
            }
 protected override Job TryGiveJob(Pawn pawn)
 {
     if (!pawn.story.WorkTagIsDisabled(WorkTags.Cleaning))
     {
         Thing closestFilth = pawn.Map.listerFilthInHomeArea.FilthInHomeArea.RandomElement();
         if (closestFilth != null && pawn.CanReserveAndReach(closestFilth, PathEndMode.Touch, Danger.Some))
         {
             return(new Job(JobDefOf.Clean, closestFilth));
         }
     }
     if (!pawn.story.WorkTagIsDisabled(WorkTags.Hauling))
     {
         Thing thing = pawn.Map.listerHaulables.ThingsPotentiallyNeedingHauling().RandomElement();
         if (thing != null && HaulAIUtility.PawnCanAutomaticallyHaulFast(pawn, thing) && pawn.CanReserveAndReach(thing, PathEndMode.Touch, Danger.Some))
         {
             return(HaulAIUtility.HaulToStorageJob(pawn, thing));
         }
     }
     return(null);
 }
        public Toil CheckForOverencumbered()
        {
            Toil toil = new Toil();

            toil.initAction = delegate
            {
                Pawn  actor     = toil.actor;
                Job   curJob    = actor.jobs.curJob;
                Thing nextThing = curJob.targetA.Thing;

                //float usedBulkByPct = 1f;
                //float usedWeightByPct = 1f;

                //try
                //{
                //    ((Action)(() =>
                //    {
                //        if (ModCompatibilityCheck.CombatExtendedIsActive)
                //        {
                //            CompInventory ceCompInventory = actor.GetComp<CompInventory>();
                //            usedWeightByPct = ceCompInventory.currentWeight / ceCompInventory.capacityWeight;
                //            usedBulkByPct = ceCompInventory.currentBulk / ceCompInventory.capacityBulk;
                //        }
                //    }))();
                //}
                //catch (TypeLoadException) { }


                if (!(MassUtility.EncumbrancePercent(actor) <= 0.9f /*|| usedBulkByPct >= 0.7f || usedWeightByPct >= 0.8f*/))
                {
                    Job haul = HaulAIUtility.HaulToStorageJob(actor, nextThing);
                    if (haul?.TryMakePreToilReservations(actor, false) ?? false)
                    {
                        //note that HaulToStorageJob etc doesn't do opportunistic duplicate hauling for items in valid storage. REEEE
                        actor.jobs.jobQueue.EnqueueFirst(haul, JobTag.Misc);
                        EndJobWith(JobCondition.Succeeded);
                    }
                }
            };
            return(toil);
        }
Exemple #22
0
        protected override Job TryGiveTerminalJob(Pawn pawn)
        {
            if (pawn.outfits == null)
            {
                Log.ErrorOnce(pawn + " tried to run JobGiver_OptimizeApparel without an OutfitTracker", 5643897);
                return(null);
            }
            if (pawn.Faction != Faction.OfColony)
            {
                Log.ErrorOnce("Non-colonist " + pawn + " tried to optimize apparel.", 764323);
                return(null);
            }

            if (Find.TickManager.TicksGame < pawn.mindState.nextApparelOptimizeTick)
            {
                return(null);
            }

            Saveable_Pawn configurarion = MapComponent_AutoEquip.Get.GetCache(pawn);
            Outfit        currentOutfit = pawn.outfits.CurrentOutfit;

            #region [  Wear Apparel  ]

            if (configurarion.toWearApparel.Count > 0)
            {
                List <Thing> list = Find.ListerThings.ThingsInGroup(ThingRequestGroup.Apparel);
                if (list.Count > 0)
                {
                    foreach (Apparel ap in list)
                    {
                        if (configurarion.toWearApparel.Contains(ap))
                        {
                            if (pawn.CanReserveAndReach(ap, PathEndMode.OnCell, pawn.NormalMaxDanger(), 1))
                            {
#if LOG && JOBS
                                Log.Message("Pawn " + pawn + " wear apparel: " + ap);
#endif
                                configurarion.toWearApparel.Remove(ap);
                                return(new Job(JobDefOf.Wear, ap));
                            }
                        }
                    }
                }
            }

            #endregion

            #region [  Drops unequiped  ]

            for (int i = configurarion.toDropApparel.Count - 1; i >= 0; i--)
            {
                Apparel a = configurarion.toDropApparel[i];
                configurarion.toDropApparel.Remove(a);

#if LOG && JOBS
                Log.Message("Pawn " + pawn + " drop apparel: " + a);
#endif

                if (pawn.apparel.WornApparel.Contains(a))
                {
                    Apparel t;
                    if (pawn.apparel.TryDrop(a, out t))
                    {
                        t.SetForbidden(false, true);

                        Job job = HaulAIUtility.HaulToStorageJob(pawn, t);

                        if (job != null)
                        {
                            return(job);
                        }
                        else
                        {
                            pawn.mindState.nextApparelOptimizeTick = Find.TickManager.TicksGame + 350;
                            return(null);
                        }
                    }
                }
            }

            #endregion

            pawn.mindState.nextApparelOptimizeTick = Find.TickManager.TicksGame + 350;
            return(null);
        }
        //reserve, goto, take, check for more. Branches off to "all over the place"
        protected override IEnumerable <Toil> MakeNewToils()
        {
            CompHauledToInventory takenToInventory        = pawn.TryGetComp <CompHauledToInventory>();
            HashSet <Thing>       carriedThings           = takenToInventory.GetHashSet();
            DesignationDef        HaulUrgentlyDesignation = DefDatabase <DesignationDef> .GetNamed("HaulUrgentlyDesignation", false);

            //Thanks to AlexTD for the more dynamic search range
            float searchForOthersRangeFraction = 0.5f;
            float distanceToOthers             = 0f;

            Toil wait           = Toils_General.Wait(2);
            Toil reserveTargetA = Toils_Reserve.Reserve(TargetIndex.A, 1, -1, null);

            Toil calculateExtraDistanceToGo = new Toil
            {
                initAction = () =>
                {
                    if (StoreUtility.TryFindStoreCellNearColonyDesperate(this.job.targetA.Thing, this.pawn, out IntVec3 storeLoc))
                    {
                        distanceToOthers = (storeLoc - job.targetA.Thing.Position).LengthHorizontal * searchForOthersRangeFraction;
                    }
                }
            };

            yield return(calculateExtraDistanceToGo);

            Toil checkForOtherItemsToHaulToInventory         = CheckForOtherItemsToHaulToInventory(reserveTargetA, TargetIndex.A, distanceToOthers, null);
            Toil checkForOtherItemsToUrgentlyHaulToInventory = CheckForOtherItemsToHaulToInventory(reserveTargetA, TargetIndex.A, distanceToOthers, (Thing x) => pawn.Map.designationManager.DesignationOn(x)?.def == HaulUrgentlyDesignation);

            yield return(reserveTargetA);

            Toil gotoThing = new Toil
            {
                initAction = () =>
                {
                    this.pawn.pather.StartPath(this.TargetThingA, PathEndMode.ClosestTouch);
                },
                defaultCompleteMode = ToilCompleteMode.PatherArrival,
            };

            gotoThing.FailOnDespawnedNullOrForbidden(TargetIndex.A);
            yield return(gotoThing);

            Toil takeThing = new Toil
            {
                initAction = () =>
                {
                    Pawn  actor = this.pawn;
                    Thing thing = actor.CurJob.GetTarget(TargetIndex.A).Thing;
                    Toils_Haul.ErrorCheckForCarry(actor, thing);

                    //get max we can pick up
                    int num = Mathf.Min(thing.stackCount, MassUtility.CountToPickUpUntilOverEncumbered(actor, thing));

                    // yo dawg, I heard you like delegates so I put delegates in your delegate, so you can delegate your delegates.
                    // because compilers don't respect IF statements in delegates and toils are fully iterated over as soon as the job starts.
                    try
                    {
                        ((Action)(() =>
                        {
                            if (ModCompatibilityCheck.CombatExtendedIsActive)
                            {
                                CombatExtended.CompInventory ceCompInventory = actor.GetComp <CombatExtended.CompInventory>();
                                ceCompInventory.CanFitInInventory(thing, out num, false, false);
                            }
                        }))();
                    }
                    catch (TypeLoadException) { }

                    //can't store more, so queue up hauling if we can + end the current job (smooth/instant transition)
                    if (num <= 0)
                    {
                        Job haul = HaulAIUtility.HaulToStorageJob(actor, thing);
                        if (haul?.TryMakePreToilReservations(actor) ?? false)
                        {
                            actor.jobs.jobQueue.EnqueueFirst(haul, new JobTag?(JobTag.Misc));
                        }
                        actor.jobs.curDriver.JumpToToil(wait);
                    }
                    else
                    {
                        bool isUrgent = false;
                        if (ModCompatibilityCheck.AllowToolIsActive)
                        {
                            //check BEFORE absorbing the thing, designation disappears when it's in inventory :^)
                            if (pawn.Map.designationManager.DesignationOn(thing)?.def == HaulUrgentlyDesignation)
                            {
                                isUrgent = true;
                            }
                        }

                        actor.inventory.GetDirectlyHeldThings().TryAdd(thing.SplitOff(num), true);
                        takenToInventory.RegisterHauledItem(thing);

                        try
                        {
                            ((Action)(() =>
                            {
                                if (ModCompatibilityCheck.CombatExtendedIsActive)
                                {
                                    CombatExtended.CompInventory ceCompInventory = actor.GetComp <CombatExtended.CompInventory>();
                                    ceCompInventory.UpdateInventory();
                                }
                            }))();
                        }
                        catch (TypeLoadException) { }

                        if (isUrgent)
                        {
                            actor.jobs.curDriver.JumpToToil(checkForOtherItemsToUrgentlyHaulToInventory);
                        }
                    }
                }
            };

            yield return(takeThing);

            yield return(checkForOtherItemsToHaulToInventory); //we end the job in there, so only one of the checks for duplicates gets called.

            yield return(checkForOtherItemsToUrgentlyHaulToInventory);

            yield return(wait);
        }
        protected override Job TryGiveJob(Pawn pawn)
        {
            Predicate <Thing> validator = (Thing t) => !t.IsForbidden(pawn) && HaulAIUtility.PawnCanAutomaticallyHaulFast(pawn, t);
            //Start my code
            Thing        thing     = null;
            List <Thing> things    = ListerHaulables.ThingsPotentiallyNeedingHauling();
            List <Thing> degrade   = new List <Thing>();
            List <Thing> undegrade = new List <Thing>();

            foreach (Thing t in things)
            {
                if (t.GetStatValue(StatDefOf.DeteriorationRate) > 0)
                {
                    degrade.Add(t);
                }
                else
                {
                    undegrade.Add(t);
                }
            }
            //Loop through all haul areas in order
            foreach (Area a in AreaFinder.getHaulAreas())
            {
                //Check if got degradable item
                thing = GenClosest.ClosestThing_Global_Reachable(pawn.Position, AreaFinder.searcher(a, degrade), PathEndMode.OnCell, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), 9999f, validator, null);
                if (thing != null)
                {
                    break;
                }

                //Check if got undegradable item
                thing = GenClosest.ClosestThing_Global_Reachable(pawn.Position, AreaFinder.searcher(a, undegrade), PathEndMode.OnCell, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), 9999f, validator, null);
                if (thing != null)
                {
                    break;
                }
            }
            if (thing == null)
            {
                thing = GenClosest.ClosestThing_Global_Reachable(pawn.Position, degrade, PathEndMode.OnCell, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), 9999f, validator, null);
                if (thing == null)
                {
                    thing = GenClosest.ClosestThing_Global_Reachable(pawn.Position, undegrade, PathEndMode.OnCell, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), 9999f, validator, null);
                }
            }

            /* old 50 cell code
             * Thing thing = GenClosest.ClosestThing_Global_Reachable(pawn.Position, degrade, PathEndMode.OnCell, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), 50f, validator, null);
             * if (thing == null)
             * {
             *  thing = GenClosest.ClosestThing_Global_Reachable(pawn.Position, undegrade, PathEndMode.OnCell, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), 50f, validator, null);
             *  if (thing == null)
             *  {
             *      thing = GenClosest.ClosestThing_Global_Reachable(pawn.Position, degrade, PathEndMode.OnCell, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), 9999f, validator, null);
             *      if (thing == null)
             *      {
             *          thing = GenClosest.ClosestThing_Global_Reachable(pawn.Position, undegrade, PathEndMode.OnCell, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), 9999f, validator, null);
             *      }
             *  }
             * }*/
            //End my code
            if (thing != null)
            {
                return(HaulAIUtility.HaulToStorageJob(pawn, thing));
            }
            return(null);
        }
 public override Job JobOnThing(Pawn pawn, Thing t, bool forced = false)
 {
     return(HaulAIUtility.HaulToStorageJob(pawn, t));
 }
Exemple #26
0
        /// <summary>
        /// Tries to give the pawn a job related to picking up or dropping an item from their inventory.
        /// </summary>
        /// <param name="pawn">Pawn to which the job is given.</param>
        /// <returns>Job that the pawn was instructed to do, be it hauling a dropped Thing or going and getting a Thing.</returns>
        protected override Job TryGiveJob(Pawn pawn)
        {
            // Get inventory
            CompInventory inventory = pawn.TryGetComp <CompInventory>();

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

            Loadout loadout = pawn.GetLoadout();

            if (loadout != null)
            {
                ThingWithComps dropEq;
                if (pawn.GetExcessEquipment(out dropEq))
                {
                    ThingWithComps droppedEq;
                    if (pawn.equipment.TryDropEquipment(pawn.equipment.Primary, out droppedEq, pawn.Position, false))
                    {
                        if (droppedEq != null)
                        {
                            return(HaulAIUtility.HaulToStorageJob(pawn, droppedEq));
                        }
                        Log.Error(string.Concat(pawn, " tried dropping ", dropEq, " from loadout but resulting thing is null"));
                    }
                }
                Thing dropThing;
                int   dropCount;
                if (pawn.GetExcessThing(out dropThing, out dropCount))
                {
                    Thing droppedThing;
                    if (inventory.container.TryDrop(dropThing, pawn.Position, pawn.Map, ThingPlaceMode.Near, dropCount, out droppedThing))
                    {
                        if (droppedThing != null)
                        {
                            return(HaulAIUtility.HaulToStorageJob(pawn, droppedThing));
                        }
                        Log.Error(string.Concat(pawn, " tried dropping ", dropThing, " from loadout but resulting thing is null"));
                    }
                }

                // Find missing items
                ItemPriority priority;
                Thing        closestThing;
                int          count;
                Pawn         carriedBy;
                bool         doEquip      = false;
                LoadoutSlot  prioritySlot = GetPrioritySlot(pawn, out priority, out closestThing, out count, out carriedBy);
                // moved logic to detect if should equip vs put in inventory here...
                if (closestThing != null)
                {
                    if (closestThing.TryGetComp <CompEquippable>() != null &&
                        !(pawn.story != null && pawn.WorkTagIsDisabled(WorkTags.Violent)) &&
                        (pawn.health != null && pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation)) &&
                        (pawn.equipment == null || pawn.equipment.Primary == null || !loadout.Slots.Any(s => s.thingDef == pawn.equipment.Primary.def ||
                                                                                                        (s.genericDef != null && s.countType == LoadoutCountType.pickupDrop &&
                                                                                                         s.genericDef.lambda(pawn.equipment.Primary.def)))))
                    {
                        doEquip = true;
                    }
                    if (carriedBy == null)
                    {
                        // Equip gun if unarmed or current gun is not in loadout
                        if (doEquip)
                        {
                            return(new Job(JobDefOf.Equip, closestThing));
                        }
                        return(new Job(JobDefOf.TakeInventory, closestThing)
                        {
                            count = Mathf.Min(closestThing.stackCount, count)
                        });
                    }
                    else
                    {
                        return(new Job(CE_JobDefOf.TakeFromOther, closestThing, carriedBy, doEquip ? pawn : null)
                        {
                            count = doEquip ? 1 : Mathf.Min(closestThing.stackCount, count)
                        });
                    }
                }
            }
            return(null);
        }
        //regular Toils_Haul.CheckForGetOpportunityDuplicate isn't going to work for our purposes, since we're not carrying anything.
        //Carrying something yields weird results with unspawning errors when transfering to inventory, so we copy-past-- I mean, implement our own.
        public Toil CheckForOtherItemsToHaulToInventory(Toil getHaulTargetToil, TargetIndex haulableInd, float distanceToOthers, Predicate <Thing> extraValidator = null)
        {
            Toil toil = new Toil();

            toil.initAction = delegate
            {
                Pawn    actor     = toil.actor;
                Job     curJob    = actor.jobs.curJob;
                IntVec3 storeCell = IntVec3.Invalid;

                Predicate <Thing> validator = (Thing t) => t.Spawned &&
                                              HaulAIUtility.PawnCanAutomaticallyHaulFast(actor, t, false) &&
                                              (!t.IsInValidBestStorage()) &&
                                              !t.IsForbidden(actor) &&
                                              !(t is Corpse) &&
                                              (StoreUtility.TryFindBestBetterStoreCellFor(t, pawn, pawn.Map, (HaulAIUtility.StoragePriorityAtFor(t.Position, t)), actor.Faction, out storeCell, true)) &&
                                              (extraValidator == null || extraValidator(t)) &&
                                              actor.CanReserve(t, 1, -1, null, false);

                Thing thing = GenClosest.ClosestThingReachable(actor.Position, actor.Map, ThingRequest.ForGroup(ThingRequestGroup.HaulableAlways), PathEndMode.ClosestTouch,
                                                               TraverseParms.For(actor, Danger.Deadly, TraverseMode.ByPawn, false), Math.Max(distanceToOthers, 12f), validator, null, 0, -1, false, RegionType.Set_Passable, false);

                float usedBulkByPct   = 1f;
                float usedWeightByPct = 1f;

                try
                {
                    ((Action)(() =>
                    {
                        if (ModCompatibilityCheck.CombatExtendedIsActive)
                        {
                            CombatExtended.CompInventory ceCompInventory = actor.GetComp <CombatExtended.CompInventory>();
                            usedWeightByPct = ceCompInventory.currentWeight / ceCompInventory.capacityWeight;
                            usedBulkByPct = ceCompInventory.currentBulk / ceCompInventory.capacityBulk;
                        }
                    }))();
                }
                catch (TypeLoadException) { }


                if (thing != null && (MassUtility.EncumbrancePercent(actor) <= 0.9f || usedBulkByPct >= 0.7f || usedWeightByPct >= 0.8f))
                {
                    curJob.SetTarget(haulableInd, thing);
                    actor.Reserve(storeCell, this.job, 1, -1, null);
                    actor.jobs.curDriver.JumpToToil(getHaulTargetToil);
                    return;
                }
                if (thing != null)
                {
                    Job haul = HaulAIUtility.HaulToStorageJob(actor, thing);
                    if (haul?.TryMakePreToilReservations(actor) ?? false)
                    {
                        actor.jobs.jobQueue.EnqueueFirst(haul, new JobTag?(JobTag.Misc));
                        this.EndJobWith(JobCondition.Succeeded);
                    }
                }
                if (thing == null)
                {
                    Job job = new Job(PickUpAndHaulJobDefOf.UnloadYourHauledInventory);
                    if (job.TryMakePreToilReservations(actor))
                    {
                        actor.jobs.jobQueue.EnqueueFirst(job, new JobTag?(JobTag.Misc));
                        this.EndJobWith(JobCondition.Succeeded);
                    }
                }
            };
            return(toil);
        }
Exemple #28
0
        protected override Job TryGiveJob(Pawn pawn)
        {
            // Get inventory
            CompInventory inventory = pawn.TryGetComp <CompInventory>();

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

            Loadout loadout = pawn.GetLoadout();

            if (loadout != null)
            {
                // Find and drop excess items
                foreach (LoadoutSlot slot in loadout.Slots)
                {
                    int numContained = inventory.container.TotalStackCountOfDef(slot.Def);

                    // Add currently equipped gun
                    if (pawn.equipment != null && pawn.equipment.Primary != null)
                    {
                        if (pawn.equipment.Primary.def == slot.Def)
                        {
                            numContained++;
                        }
                    }
                    // Drop excess items
                    if (numContained > slot.Count)
                    {
                        Thing thing = inventory.container.FirstOrDefault(x => x.def == slot.Def);
                        if (thing != null)
                        {
                            Thing droppedThing;
                            if (inventory.container.TryDrop(thing, pawn.Position, pawn.Map, ThingPlaceMode.Near, numContained - slot.Count, out droppedThing))
                            {
                                if (droppedThing != null)
                                {
                                    return(HaulAIUtility.HaulToStorageJob(pawn, droppedThing));
                                }
                                Log.Error(pawn + " tried dropping " + thing + " from loadout but resulting thing is null");
                            }
                        }
                    }
                }

                // Try drop currently equipped weapon
                if (pawn.equipment != null && pawn.equipment.Primary != null && !loadout.Slots.Any(slot => slot.Def == pawn.equipment.Primary.def && slot.Count >= 1))
                {
                    ThingWithComps droppedEq;
                    if (pawn.equipment.TryDropEquipment(pawn.equipment.Primary, out droppedEq, pawn.Position, false))
                    {
                        return(HaulAIUtility.HaulToStorageJob(pawn, droppedEq));
                    }
                }

                // Find excess items in inventory that are not part of our loadout
                bool  allowDropRaw  = Find.TickManager.TicksGame > pawn.mindState?.lastInventoryRawFoodUseTick + ticksBeforeDropRaw;
                Thing thingToRemove = inventory.container.FirstOrDefault(t =>
                                                                         (allowDropRaw || !t.def.IsNutritionGivingIngestible || t.def.ingestible.preferability > FoodPreferability.RawTasty) &&
                                                                         !loadout.Slots.Any(s => s.Def == t.def));
                if (thingToRemove != null)
                {
                    Thing droppedThing;
                    if (inventory.container.TryDrop(thingToRemove, pawn.Position, pawn.Map, ThingPlaceMode.Near, thingToRemove.stackCount, out droppedThing))
                    {
                        return(HaulAIUtility.HaulToStorageJob(pawn, droppedThing));
                    }
                    Log.Error(pawn + " tried dropping " + thingToRemove + " from inventory but resulting thing is null");
                }

                // Find missing items
                ItemPriority priority;
                Thing        closestThing;
                int          count;
                LoadoutSlot  prioritySlot = GetPrioritySlot(pawn, out priority, out closestThing, out count);
                if (closestThing != null)
                {
                    // Equip gun if unarmed or current gun is not in loadout
                    if (closestThing.TryGetComp <CompEquippable>() != null &&
                        (pawn.health != null && pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation)) &&
                        (pawn.equipment == null || pawn.equipment.Primary == null || !loadout.Slots.Any(s => s.Def == pawn.equipment.Primary.def)))
                    {
                        return(new Job(JobDefOf.Equip, closestThing));
                    }
                    // Take items into inventory if needed
                    int numContained = inventory.container.TotalStackCountOfDef(prioritySlot.Def);
                    return(new Job(JobDefOf.TakeInventory, closestThing)
                    {
                        count = Mathf.Min(closestThing.stackCount, prioritySlot.Count - numContained, count)
                    });
                }
            }
            return(null);
        }
        //get next, goto, take, check for more. Branches off to "all over the place"
        protected override IEnumerable <Toil> MakeNewToils()
        {
            CompHauledToInventory takenToInventory = pawn.TryGetComp <CompHauledToInventory>();

            Toil wait = Toils_General.Wait(2);

            Toil nextTarget = Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.A); //also does count

            yield return(nextTarget);

            //honestly the workgiver checks for encumbered, so until CE checks are in this is unnecessary
            //yield return CheckForOverencumbered();//Probably redundant without CE checks

            Toil gotoThing = new Toil
            {
                initAction = () =>
                {
                    pawn.pather.StartPath(TargetThingA, PathEndMode.ClosestTouch);
                },
                defaultCompleteMode = ToilCompleteMode.PatherArrival
            };

            gotoThing.FailOnDespawnedNullOrForbidden(TargetIndex.A);
            yield return(gotoThing);

            Toil takeThing = new Toil
            {
                initAction = () =>
                {
                    Pawn  actor = pawn;
                    Thing thing = actor.CurJob.GetTarget(TargetIndex.A).Thing;
                    Toils_Haul.ErrorCheckForCarry(actor, thing);

                    //get max we can pick up
                    int countToPickUp = Mathf.Min(job.count, MassUtility.CountToPickUpUntilOverEncumbered(actor, thing));
                    Log.Message($"{actor} is hauling to inventory {thing}:{countToPickUp}");

                    // yo dawg, I heard you like delegates so I put delegates in your delegate, so you can delegate your delegates.
                    // because compilers don't respect IF statements in delegates and toils are fully iterated over as soon as the job starts.
                    try
                    {
                        ((Action)(() =>
                        {
                            if (ModCompatibilityCheck.CombatExtendedIsActive)
                            {
                                //CombatExtended.CompInventory ceCompInventory = actor.GetComp<CombatExtended.CompInventory>();
                                //ceCompInventory.CanFitInInventory(thing, out countToPickUp);
                            }
                        }))();
                    }
                    catch (TypeLoadException) { }

                    if (countToPickUp > 0)
                    {
                        Thing splitThing  = thing.SplitOff(countToPickUp);
                        bool  shouldMerge = takenToInventory.GetHashSet().Any(x => x.def == thing.def);
                        actor.inventory.GetDirectlyHeldThings().TryAdd(splitThing, shouldMerge);
                        takenToInventory.RegisterHauledItem(splitThing);

                        try
                        {
                            ((Action)(() =>
                            {
                                if (ModCompatibilityCheck.CombatExtendedIsActive)
                                {
                                    //CombatExtended.CompInventory ceCompInventory = actor.GetComp<CombatExtended.CompInventory>();
                                    //ceCompInventory.UpdateInventory();
                                }
                            }))();
                        }
                        catch (TypeLoadException)
                        {
                        }
                    }

                    //thing still remains, so queue up hauling if we can + end the current job (smooth/instant transition)
                    //This will technically release the reservations in the queue, but what can you do
                    if (thing.Spawned)
                    {
                        Job haul = HaulAIUtility.HaulToStorageJob(actor, thing);
                        if (haul?.TryMakePreToilReservations(actor, false) ?? false)
                        {
                            actor.jobs.jobQueue.EnqueueFirst(haul, JobTag.Misc);
                        }
                        actor.jobs.curDriver.JumpToToil(wait);
                    }
                }
            };

            yield return(takeThing);

            yield return(Toils_Jump.JumpIf(nextTarget, () => !job.targetQueueA.NullOrEmpty()));

            //Find more to haul, in case things spawned while this was in progess
            yield return(new Toil
            {
                initAction = () =>
                {
                    List <Thing> haulables = pawn.Map.listerHaulables.ThingsPotentiallyNeedingHauling();
                    WorkGiver_HaulToInventory haulMoreWork = DefDatabase <WorkGiverDef> .AllDefsListForReading.First(wg => wg.Worker is WorkGiver_HaulToInventory).Worker as WorkGiver_HaulToInventory;

                    Thing haulMoreThing = GenClosest.ClosestThing_Global(pawn.Position, haulables, 12, t => haulMoreWork.HasJobOnThing(pawn, t));

                    //WorkGiver_HaulToInventory found more work nearby
                    if (haulMoreThing != null)
                    {
                        Log.Message($"{pawn} hauling again : {haulMoreThing}");
                        Job haulMoreJob = haulMoreWork.JobOnThing(pawn, haulMoreThing);

                        if (haulMoreJob.TryMakePreToilReservations(pawn, false))
                        {
                            pawn.jobs.jobQueue.EnqueueFirst(haulMoreJob, JobTag.Misc);
                            EndJobWith(JobCondition.Succeeded);
                        }
                    }
                }
            });

            //maintain cell reservations on the trip back
            //TODO: do that when we carry things
            //I guess that means TODO: implement carrying the rest of the items in this job instead of falling back on HaulToStorageJob
            yield return(Toils_Goto.GotoCell(TargetIndex.B, PathEndMode.ClosestTouch));

            yield return(new Toil //Queue next job
            {
                initAction = () =>
                {
                    Pawn actor = pawn;
                    Job curJob = actor.jobs.curJob;
                    LocalTargetInfo storeCell = curJob.targetB;

                    Job unloadJob = new Job(PickUpAndHaulJobDefOf.UnloadYourHauledInventory, storeCell);
                    if (unloadJob.TryMakePreToilReservations(actor, false))
                    {
                        actor.jobs.jobQueue.EnqueueFirst(unloadJob, JobTag.Misc);
                        EndJobWith(JobCondition.Succeeded);
                        //This will technically release the cell reservations in the queue, but what can you do
                    }
                }
            });

            yield return(wait);
        }
Exemple #30
0
 public override Job JobOnThing(Pawn pawn, Thing t, bool forced = false)
 {
     // give a vanilla haul job- it works just fine for our needs
     return(HaulAIUtility.HaulToStorageJob(pawn, t));
 }