Example #1
0
        public override Job JobOnThing(Pawn pawn, Thing t, bool forced = false)
        {
            if (!CanGetThing(pawn, t, forced))
            {
                return(null);
            }

            //plan count and dests
            HaulExplicitlyPosting posting = HaulExplicitly.GetManager(t.Map).PostingWithItem(t);

            if (posting == null)
            {
                return(null);
            }
            int            space_request        = AmountPawnWantsToPickUp(pawn, t, posting);
            var            destInfo             = DeliverableDestinations.For(t, pawn, posting);
            List <IntVec3> dests                = destInfo.RequestSpaceForItemAmount(space_request);
            int            dest_space_available = destInfo.FreeSpaceInCells(dests);
            var            count                = Math.Min(space_request, dest_space_available);

            if (count < 1)
            {
                return(null);
            }

            //make job
            JobDef JobDefOfHaulExplicitly =
                (JobDef)(GenDefDatabase.GetDef(typeof(JobDef), "HaulExplicitlyHaul"));
            Job job = new Job(JobDefOfHaulExplicitly, t, dests.First());

            //((JobDriver_HaulExplicitly)job.GetCachedDriver(pawn)).init();
            job.count        = count;
            job.targetQueueA = new List <LocalTargetInfo>(
                new LocalTargetInfo[] { new IntVec3(posting.id, dest_space_available, 0) });
            job.targetQueueB = new List <LocalTargetInfo>(dests.Skip(1).Take(dests.Count - 1)
                                                          .Select(c => new LocalTargetInfo(c)));
            job.haulOpportunisticDuplicates = true;
            return(job);
        }
Example #2
0
        public static Toil PickUpThing(TargetIndex haulxItemInd, Toil nextToilIfBeingOpportunistic)
        {
            Toil toil = new Toil();

            toil.initAction = delegate
            {
                Pawn  actor  = toil.actor;
                Job   job    = actor.CurJob;
                Thing target = job.GetTarget(haulxItemInd).Thing;
                if (Toils_Haul.ErrorCheckForCarry(actor, target))
                {
                    return;
                }

                Thing carriedItem             = actor.carryTracker.CarriedThing;
                int   targetInitialStackcount = target.stackCount;
                int   countToPickUp           = Mathf.Min(
                    job.count - (carriedItem?.stackCount ?? 0),
                    actor.carryTracker.AvailableStackSpace(target.def),
                    targetInitialStackcount);
                if (countToPickUp <= 0)
                {
                    throw new Exception("PickUpThing countToPickUp = " + countToPickUp);
                }

                //pick up
                int countPickedUp = actor.carryTracker.TryStartCarry(target, countToPickUp);
                if (countPickedUp < targetInitialStackcount)
                {
                    actor.Map.reservationManager.Release(target, actor, job);
                }
                carriedItem = actor.carryTracker.CarriedThing;
                job.SetTarget(haulxItemInd, carriedItem);
                actor.records.Increment(RecordDefOf.ThingsHauled);

                //register the carried item (into the HaulExplicitly job)
                if (carriedItem.IsAHaulableSetToHaulable())
                {
                    carriedItem.ToggleHaulDesignation();
                }
                var driver = (JobDriver_HaulExplicitly)actor.jobs.curDriver;
                driver.posting.TryAddItemSplinter(carriedItem);

                //pick up next available item in job?
                if (actor.CurJob.haulOpportunisticDuplicates)
                {
                    Thing prospect  = null;
                    int   best_dist = 999;
                    foreach (Thing item in driver.record.items.Where(
                                 i => i.Spawned && WorkGiver_HaulExplicitly.CanGetThing(actor, i, false)))
                    {
                        IntVec3 offset = item.Position - actor.Position;
                        int     dist   = Math.Abs(offset.x) + Math.Abs(offset.z);
                        if (dist < best_dist && dist < 7)
                        {
                            prospect  = item;
                            best_dist = dist;
                        }
                    }
                    if (prospect == null)
                    {
                        return;
                    }
                    int space_request = WorkGiver_HaulExplicitly
                                        .AmountPawnWantsToPickUp(actor, prospect, driver.posting);
                    if (space_request == 0)
                    {
                        return;
                    }
                    var            destInfo = DeliverableDestinations.For(prospect, actor, driver.posting);
                    List <IntVec3> dests    = destInfo.RequestSpaceForItemAmount(
                        Math.Max(0, space_request - driver.dest_space_available));
                    int new_dest_space = destInfo.FreeSpaceInCells(dests);
                    var count          = Math.Min(space_request, driver.dest_space_available + new_dest_space);
                    if (count < 1)
                    {
                        return;
                    }

                    //commit to it
                    actor.Reserve(prospect, job);
                    job.SetTarget(haulxItemInd, prospect);
                    job.SetTarget(TargetIndex.C, prospect.Position);
                    foreach (var dest in dests)
                    {
                        actor.Reserve(dest, job);
                        job.targetQueueB.Add(dest);
                    }
                    job.count += count;
                    driver.JumpToToil(nextToilIfBeingOpportunistic);
                }
            };
            return(toil);
        }