private static Toil Toils_FillThingIntoConstructor(Pawn actor)
        {
            Thing carryThing = actor.jobs.curJob.GetTarget(IngredientInd).Thing;
            Building_NanoPrinter constructorThing = actor.jobs.curJob.GetTarget(BuildingInd).Thing as Building_NanoPrinter;

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

            Toil toil = new Toil();

            Action action = () =>
            {
                if (actor.carryTracker.TryDropCarriedThing(constructorThing.Position, ThingPlaceMode.Direct, out carryThing, null))
                {
                    constructorThing.Notify_ReceivedThing(carryThing);
                }
            };

            toil.finishActions = new List <Action>();
            toil.finishActions.Add(action);

            toil.defaultCompleteMode = ToilCompleteMode.Delay;
            toil.defaultDuration     = 30;

            return(toil);
        }
        private static Thing FindBestThing(Pawn pawn, Thing t, out int count)
        {
            Building_NanoPrinter building = (t as Building_NanoPrinter);

            count = 0;

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

            Dictionary <ThingDef, int> requiredMaterial = building.neededMaterial;

            foreach (ThingDef tDef in requiredMaterial.Keys)
            {
                Predicate <Thing> validator = delegate(Thing x)
                {
                    if (x.def == tDef)
                    {
                        if (!x.IsForbidden(pawn) && pawn.CanReserve(x, 1, -1, null, false))
                        {
                            return(true);
                        }
                    }

                    return(false);
                };
                IntVec3 position = pawn.Position;
                Map     map      = pawn.Map;

                ThingRequest bestThingRequest = ThingRequest.ForDef(tDef);

                PathEndMode   peMode         = PathEndMode.ClosestTouch;
                TraverseParms traverseParams = TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false);
                Thing         foundThing     = GenClosest.ClosestThingReachable(position, map, bestThingRequest, peMode, traverseParams, 9999f, validator, null, 0, -1, false, RegionType.Set_Passable, false);

                if (foundThing == null)
                {
                    continue;
                }

                count = requiredMaterial[tDef];

                return(foundThing);
            }
            return(null);
        }
        public static Job FillJob(Pawn pawn, Thing t, bool forced = false)
        {
            Building_NanoPrinter t1 = (t as Building_NanoPrinter);

            if (t1 == null)
            {
                return(null);
            }
            int   count;
            Thing t2 = FindBestThing(pawn, t, out count);

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

            IntVec3 p3 = (t as Building_NanoPrinter).collectorPos;
            Job     j  = new Job(DefDatabase <JobDef> .GetNamed(jobDefName), t2, t1, p3);

            j.targetQueueA = new List <LocalTargetInfo>();
            j.targetQueueA.Add(t2);
            j.count = count;
            return(j);
        }