示例#1
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnDestroyedOrNull(TargetIndex.A);
            this.FailOnBurningImmobile(TargetIndex.B);
            //this.FailOnForbidden(TargetIndex.A);

            Toil gotoThing = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.ClosestTouch);

            gotoThing.FailOnSomeonePhysicallyInteracting(TargetIndex.A);
            gotoThing.FailOn(delegate(Toil toil)
            {
                Job job      = toil.actor.CurJob;
                Thing thing  = job.GetTarget(TargetIndex.A).Thing;
                IntVec3 cell = job.GetTarget(TargetIndex.B).Cell;
                List <Thing> items_in_cell = HaulExplicitlyPosting.GetItemsIfValidItemSpot(
                    toil.actor.Map, cell);
                if (items_in_cell == null)
                {
                    return(true);
                }
                if (items_in_cell.Count == 0)
                {
                    return(false);
                }
                if (items_in_cell.Count == 1 && thing.CanStackWith(items_in_cell.First()))
                {
                    return(false);
                }
                return(true);
            });
            yield return(gotoThing);

            yield return(Toils_HaulExplicitly.PickUpThing(TargetIndex.A, gotoThing));

            Toil carryToDest = Toils_Haul.CarryHauledThingToCell(TargetIndex.B);

            yield return(carryToDest);

            yield return(Toils_HaulExplicitly.PlaceHauledThingAtDest(TargetIndex.B, carryToDest));
        }
示例#2
0
        private DeliverableDestinations(Thing item, Pawn carrier, HaulExplicitlyPosting posting, Func <IntVec3, float> grader)
        {
            this.grader  = grader;
            this.posting = posting;
            record       = posting.RecordWithItem(item);
            Map map = posting.map;

            thing = item;
            IntVec3 item_pos      = (!item.SpawnedOrAnyParentSpawned) ? carrier.PositionHeld : item.PositionHeld;
            var     traverseparms = TraverseParms.For(carrier, Danger.Deadly, TraverseMode.ByPawn, false);

            foreach (IntVec3 cell in posting.destinations)
            {
                List <Thing> items_in_cell     = HaulExplicitlyPosting.GetItemsIfValidItemSpot(map, cell);
                bool         valid_destination = items_in_cell != null;

                //see if this cell already has, or will have, an item of our item's stack type
                // (tests items in the cell, as well as reservations on the cell)
                bool cell_is_same_stack_type = false;
                if (valid_destination)
                {
                    foreach (Thing i in items_in_cell)
                    {
                        if (record.CanMixWith(i))
                        {
                            cell_is_same_stack_type = true;
                        }
                    }
                }
                Pawn claimant = map.reservationManager.FirstRespectedReserver(cell, carrier);
                if (claimant != null)
                {
                    List <Job> jobs = new List <Job>(claimant.jobs.jobQueue.Select(x => x.job));
                    jobs.Add(claimant.jobs.curJob);
                    foreach (Job job in jobs)
                    {
                        if (job.def.driverClass == typeof(JobDriver_HaulExplicitly) &&
                            (job.targetB == cell || job.targetQueueB.Contains(cell)) &&
                            (record.CanMixWith(job.targetA.Thing)))
                        {
                            cell_is_same_stack_type = true;
                            break;
                        }
                    }
                }
                //finally, increment our counter of cells with our item's stack type
                if (cell_is_same_stack_type)
                {
                    dests_with_this_stack_type++;
                }

                //check if cell is valid, reachable from item, unreserved, and pawn is allowed to go there
                bool reachable = map.reachability.CanReach(item_pos, cell,
                                                           PathEndMode.ClosestTouch, traverseparms);
                if (!valid_destination || !reachable || claimant != null || cell.IsForbidden(carrier))
                {
                    continue;
                }

                // oh, just item things
                if (items_in_cell.Count == 0)
                {
                    free_cells.Add(cell);
                }
                try
                {
                    Thing item_in_cell = items_in_cell.Single();
                    int   space_avail  = item_in_cell.def.stackLimit - item_in_cell.stackCount;
                    if (cell_is_same_stack_type && space_avail > 0)
                    {
                        partial_cells.Add(cell);
                        partialCellSpaceAvailable.Add(space_avail);
                    }
                }
                catch { }
            }
        }