コード例 #1
0
        public static bool PawnCanAutomaticallyHaulFast(Pawn p, Thing t, bool forced)
        {
            UnfinishedThing unfinishedThing = t as UnfinishedThing;
            Building        building;

            if (unfinishedThing != null && unfinishedThing.BoundBill != null && ((building = unfinishedThing.BoundBill.billStack.billGiver as Building) == null || (building.Spawned && building.OccupiedRect().ExpandedBy(1).Contains(unfinishedThing.Position))))
            {
                return(false);
            }
            if (!p.CanReach(t, PathEndMode.ClosestTouch, p.NormalMaxDanger()))
            {
                return(false);
            }
            if (!p.CanReserve(t, 1, -1, null, forced))
            {
                return(false);
            }
            if (!p.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation))
            {
                return(false);
            }
            if (t.def.IsNutritionGivingIngestible && t.def.ingestible.HumanEdible && !t.IsSociallyProper(p, forPrisoner: false, animalsCare: true))
            {
                JobFailReason.Is(ReservedForPrisonersTrans);
                return(false);
            }
            if (t.IsBurning())
            {
                JobFailReason.Is(BurningLowerTrans);
                return(false);
            }
            return(true);
        }
コード例 #2
0
        public static bool PawnCanAutomaticallyHaulFast(Pawn p, Thing t, bool forced)
        {
            UnfinishedThing unfinishedThing = t as UnfinishedThing;

            if (unfinishedThing != null && unfinishedThing.BoundBill != null)
            {
                return(false);
            }
            if (!p.CanReach(t, PathEndMode.ClosestTouch, p.NormalMaxDanger(), false, TraverseMode.ByPawn))
            {
                return(false);
            }
            LocalTargetInfo target = t;

            if (!p.CanReserve(target, 1, -1, null, forced))
            {
                return(false);
            }
            if (t.def.IsNutritionGivingIngestible && t.def.ingestible.HumanEdible && !t.IsSociallyProper(p, false, true))
            {
                JobFailReason.Is(HaulAIUtility.ReservedForPrisonersTrans, null);
                return(false);
            }
            if (t.IsBurning())
            {
                JobFailReason.Is(HaulAIUtility.BurningLowerTrans, null);
                return(false);
            }
            return(true);
        }
コード例 #3
0
        private static Job FinishUftJob(Pawn pawn, UnfinishedThing uft, Bill_ProductionWithUft bill)
        {
            if (uft.Creator != pawn)
            {
                Log.Error(string.Concat(new object[]
                {
                    "Tried to get FinishUftJob for ",
                    pawn,
                    " finishing ",
                    uft,
                    " but its creator is ",
                    uft.Creator
                }), false);
                return(null);
            }
            Job job = WorkGiverUtility.HaulStuffOffBillGiverJob(pawn, bill.billStack.billGiver, uft);

            if (job != null && job.targetA.Thing != uft)
            {
                return(job);
            }
            return(new Job(JobDefOf.DoBill, (Thing)bill.billStack.billGiver)
            {
                bill = bill,
                targetQueueB = new List <LocalTargetInfo>
                {
                    uft
                },
                countQueue = new List <int>
                {
                    1
                },
                haulMode = HaulMode.ToCellNonStorage
            });
        }
コード例 #4
0
        private static List <Thing> CalculateIngredients(Job job, Pawn actor)
        {
            UnfinishedThing unfinishedThing = job.GetTarget(TargetIndex.B).Thing as UnfinishedThing;

            if (unfinishedThing != null)
            {
                List <Thing> ingredients = unfinishedThing.ingredients;
                job.RecipeDef.Worker.ConsumeIngredient(unfinishedThing, job.RecipeDef, actor.Map);
                job.placedThings = null;
                return(ingredients);
            }
            List <Thing> list = new List <Thing>();

            if (job.placedThings != null)
            {
                for (int i = 0; i < job.placedThings.Count; i++)
                {
                    if (job.placedThings[i].Count <= 0)
                    {
                        Log.Error(string.Concat(new object[]
                        {
                            "PlacedThing ",
                            job.placedThings[i],
                            " with count ",
                            job.placedThings[i].Count,
                            " for job ",
                            job
                        }));
                    }
                    else
                    {
                        Thing thing;
                        if (job.placedThings[i].Count < job.placedThings[i].thing.stackCount)
                        {
                            thing = job.placedThings[i].thing.SplitOff(job.placedThings[i].Count);
                        }
                        else
                        {
                            thing = job.placedThings[i].thing;
                        }
                        job.placedThings[i].Count = 0;
                        if (list.Contains(thing))
                        {
                            Log.Error("Tried to add ingredient from job placed targets twice: " + thing);
                        }
                        else
                        {
                            list.Add(thing);
                            IStrippable strippable = thing as IStrippable;
                            if (strippable != null)
                            {
                                strippable.Strip();
                            }
                        }
                    }
                }
            }
            job.placedThings = null;
            return(list);
        }
コード例 #5
0
        static Pawn Postfix(Pawn __result, Bill_ProductionWithUft __instance, UnfinishedThing __state)
        {
            if (__result == null && __state != null)
            {
                Pawn creator = __state.Creator;
                if (creator == null || creator.Downed || creator.Destroyed || !creator.Spawned)
                {
                    return(__result);
                }
                Thing thing = __instance.billStack.billGiver as Thing;
                if (thing != null)
                {
                    WorkTypeDef         workTypeDef           = null;
                    List <WorkGiverDef> allDefsListForReading = DefDatabase <WorkGiverDef> .AllDefsListForReading;
                    for (int i = 0; i < allDefsListForReading.Count; i++)
                    {
                        if (allDefsListForReading[i].fixedBillGiverDefs != null && allDefsListForReading[i].fixedBillGiverDefs.Contains(thing.def))
                        {
                            workTypeDef = allDefsListForReading[i].workType;
                            break;
                        }
                    }
                    if (workTypeDef != null && !creator.workSettings.WorkIsActive(workTypeDef))
                    {
                        return(__result);
                    }
                }
                Traverse.Create(__instance).Field("boundUftInt").SetValue(__state);
                DebugLogger.debug($"Returning creator {creator.LabelShort}, value override");
                return(creator);
            }

            return(__result);
        }
コード例 #6
0
ファイル: HaulAIUtility.cs プロジェクト: potsh/RimWorld
        public static bool PawnCanAutomaticallyHaulFast(Pawn p, Thing t, bool forced)
        {
            UnfinishedThing unfinishedThing = t as UnfinishedThing;

            if (unfinishedThing != null && unfinishedThing.BoundBill != null)
            {
                return(false);
            }
            if (!p.CanReach(t, PathEndMode.ClosestTouch, p.NormalMaxDanger()))
            {
                return(false);
            }
            LocalTargetInfo target = t;
            bool            ignoreOtherReservations = forced;

            if (!p.CanReserve(target, 1, -1, null, ignoreOtherReservations))
            {
                return(false);
            }
            if (t.def.IsNutritionGivingIngestible && t.def.ingestible.HumanEdible && !t.IsSociallyProper(p, forPrisoner: false, animalsCare: true))
            {
                JobFailReason.Is(ReservedForPrisonersTrans);
                return(false);
            }
            if (t.IsBurning())
            {
                JobFailReason.Is(BurningLowerTrans);
                return(false);
            }
            return(true);
        }
コード例 #7
0
        private static Thing CalculateDominantIngredient(Job job, List <Thing> ingredients)
        {
            UnfinishedThing uft = job.GetTarget(TargetIndex.B).Thing as UnfinishedThing;
            Thing           result;

            if (uft != null && uft.def.MadeFromStuff)
            {
                result = uft.ingredients.First((Thing ing) => ing.def == uft.Stuff);
            }
            else if (!ingredients.NullOrEmpty <Thing>())
            {
                if (job.RecipeDef.productHasIngredientStuff)
                {
                    result = ingredients[0];
                }
                else if (job.RecipeDef.products.Any((ThingDefCountClass x) => x.thingDef.MadeFromStuff))
                {
                    result = (from x in ingredients
                              where x.def.IsStuff
                              select x).RandomElementByWeight((Thing x) => (float)x.stackCount);
                }
                else
                {
                    result = ingredients.RandomElementByWeight((Thing x) => (float)x.stackCount);
                }
            }
            else
            {
                result = null;
            }
            return(result);
        }
コード例 #8
0
        private static Job FinishUftJob(Pawn pawn, UnfinishedThing uft, Bill_ProductionWithUft bill)
        {
            if (uft.Creator != pawn)
            {
                Log.Error("Tried to get FinishUftJob for " + pawn + " finishing " + uft + " but its creator is " + uft.Creator);
                return(null);
            }
            Job job = WorkGiverUtility.HaulStuffOffBillGiverJob(pawn, bill.billStack.billGiver, uft);

            if (job != null && job.targetA.Thing != uft)
            {
                return(job);
            }
            Job job2 = JobMaker.MakeJob(JobDefOf.DoBill, (Thing)bill.billStack.billGiver);

            job2.bill         = bill;
            job2.targetQueueB = new List <LocalTargetInfo>
            {
                uft
            };
            job2.countQueue = new List <int>
            {
                1
            };
            job2.haulMode = HaulMode.ToCellNonStorage;
            return(job2);
        }
コード例 #9
0
ファイル: Toils_Recipe.cs プロジェクト: woomy144/Rimworld
        /// <summary>
        /// Gets the dominant ingredient that determines the stuff, color, and possibly other properties of recipe products.
        /// </summary>
        private static Thing CalculateDominantIngredient(Job job, List <Thing> ingredients)
        {
            UnfinishedThing uft = job.GetTarget(JobDriver_DoBill.IngredientInd).Thing as UnfinishedThing;

            if (uft != null && uft.def.MadeFromStuff)
            {
                return(uft.ingredients.First(ing => ing.def == uft.Stuff));
            }

            if (!ingredients.NullOrEmpty())
            {
                // if the recipe uses stuff ingredient (from recipe maker), then the first ingredient is the dominant one (stuff)
                if (job.RecipeDef.productHasIngredientStuff)
                {
                    return(ingredients[0]);
                }

                if (job.RecipeDef.products.Any(x => x.thingDef.MadeFromStuff))
                {
                    return(ingredients.Where(x => x.def.IsStuff).RandomElementByWeight(x => x.stackCount));
                }
                else
                {
                    return(ingredients.RandomElementByWeight(x => x.stackCount));
                }
            }

            return(null);
        }
コード例 #10
0
ファイル: Main.cs プロジェクト: dninemfive/Some-Job-Authors
 public static void Creator(UnfinishedThing __instance)
 {
     if (__instance.def.HasModExtension <ModExtension_NoJobAuthor>())
     {
         _creatorName(__instance) = "Everyone";
     }
 }
コード例 #11
0
        private Toil MakeUnfinishedThingIfNeeded()
        {
            Toil toil = new Toil();

            toil.initAction = delegate()
            {
                Pawn actor  = toil.actor;
                Job  curJob = actor.jobs.curJob;
                if (!curJob.RecipeDef.UsesUnfinishedThing)
                {
                    return;
                }
                if (curJob.GetTarget(TargetIndex.B).Thing != null && curJob.GetTarget(TargetIndex.B).Thing is UnfinishedThing)
                {
                    return;
                }
                UnfinishedThing unfinishedThing = (UnfinishedThing)ThingMaker.MakeThing(curJob.RecipeDef.unfinishedThingDef, techStuff);
                unfinishedThing.Creator     = actor;
                unfinishedThing.BoundBill   = (Bill_ProductionWithUft)curJob.bill;               // <- when pawn is a prisoner, the recipe doesn't seem to register this.
                unfinishedThing.ingredients = new List <Thing>
                {
                    new Thing()
                    {
                        def        = unfinishedThing.Stuff,
                        stackCount = 0
                    }
                };
                GenSpawn.Spawn(unfinishedThing, curJob.GetTarget(TargetIndex.A).Cell, actor.Map, WipeMode.Vanish);
                curJob.SetTarget(TargetIndex.B, unfinishedThing);
                actor.Reserve(unfinishedThing, curJob, 1, -1, null, true);
            };
            return(toil);
        }
コード例 #12
0
 private Job StartOrResumeBillJob(Pawn pawn, IBillGiver giver)
 {
     for (int i = 0; i < giver.BillStack.Count; i++)
     {
         Bill bill = giver.BillStack[i];
         if ((bill.recipe.requiredGiverWorkType != null && bill.recipe.requiredGiverWorkType != def.workType) || (Find.TickManager.TicksGame < bill.lastIngredientSearchFailTicks + ReCheckFailedBillTicksRange.RandomInRange && FloatMenuMakerMap.makingFor != pawn))
         {
             continue;
         }
         bill.lastIngredientSearchFailTicks = 0;
         if (!bill.ShouldDoNow() || !bill.PawnAllowedToStartAnew(pawn))
         {
             continue;
         }
         SkillRequirement skillRequirement = bill.recipe.FirstSkillRequirementPawnDoesntSatisfy(pawn);
         if (skillRequirement != null)
         {
             JobFailReason.Is("UnderRequiredSkill".Translate(skillRequirement.minLevel), bill.Label);
             continue;
         }
         Bill_ProductionWithUft bill_ProductionWithUft = bill as Bill_ProductionWithUft;
         if (bill_ProductionWithUft != null)
         {
             if (bill_ProductionWithUft.BoundUft != null)
             {
                 if (bill_ProductionWithUft.BoundWorker == pawn && pawn.CanReserveAndReach(bill_ProductionWithUft.BoundUft, PathEndMode.Touch, Danger.Deadly) && !bill_ProductionWithUft.BoundUft.IsForbidden(pawn))
                 {
                     return(FinishUftJob(pawn, bill_ProductionWithUft.BoundUft, bill_ProductionWithUft));
                 }
                 continue;
             }
             UnfinishedThing unfinishedThing = ClosestUnfinishedThingForBill(pawn, bill_ProductionWithUft);
             if (unfinishedThing != null)
             {
                 return(FinishUftJob(pawn, unfinishedThing, bill_ProductionWithUft));
             }
         }
         if (!TryFindBestBillIngredients(bill, pawn, (Thing)giver, chosenIngThings))
         {
             if (FloatMenuMakerMap.makingFor != pawn)
             {
                 bill.lastIngredientSearchFailTicks = Find.TickManager.TicksGame;
             }
             else
             {
                 JobFailReason.Is(MissingMaterialsTranslated, bill.Label);
             }
             chosenIngThings.Clear();
             continue;
         }
         Job haulOffJob;
         Job result = TryStartNewDoBillJob(pawn, bill, giver, chosenIngThings, out haulOffJob);
         chosenIngThings.Clear();
         return(result);
     }
     chosenIngThings.Clear();
     return(null);
 }
コード例 #13
0
ファイル: Main.cs プロジェクト: dninemfive/Some-Job-Authors
 public static bool Creator(UnfinishedThing __instance, ref Pawn __result)
 {
     if (__instance.def.HasModExtension <ModExtension_NoJobAuthor>())
     {
         __result = null;
         return(false);
     }
     return(true);
 }
コード例 #14
0
 private Job StartOrResumeBillJob(Pawn pawn, IBillGiver giver, LocalTargetInfo target)
 {
     for (int i = 0; i < giver.BillStack.Count; i++)
     {
         Bill bill = giver.BillStack[i];
         if ((bill.recipe == TechDefOf.DocumentTech || bill.recipe == TechDefOf.DocumentTechDigital) && bill.ShouldDoNow() && bill.PawnAllowedToStartAnew(pawn))
         {
             SkillRequirement skillRequirement = bill.recipe.FirstSkillRequirementPawnDoesntSatisfy(pawn);
             if (skillRequirement != null)
             {
                 JobFailReason.Is("UnderRequiredSkill".Translate(skillRequirement.minLevel), bill.Label);
             }
             else
             {
                 if (bill.recipe.UsesUnfinishedThing)
                 {
                     Bill_ProductionWithUft bill_ProductionWithUft = bill as Bill_ProductionWithUft;
                     if (bill_ProductionWithUft != null)
                     {
                         if (bill_ProductionWithUft.BoundUft != null)
                         {
                             if (bill_ProductionWithUft.BoundWorker == pawn && pawn.CanReserveAndReach(bill_ProductionWithUft.BoundUft, PathEndMode.Touch, Danger.Deadly, 1, -1, null, false) && !bill_ProductionWithUft.BoundUft.IsForbidden(pawn))
                             {
                                 return(FinishUftJob(pawn, bill_ProductionWithUft.BoundUft, bill_ProductionWithUft));
                             }
                             return(null);
                         }
                         else
                         {
                             MethodInfo      ClosestUftInfo  = AccessTools.Method(typeof(WorkGiver_DoBill), "ClosestUnfinishedThingForBill");
                             UnfinishedThing unfinishedThing = (UnfinishedThing)ClosestUftInfo.Invoke(this, new object[] { pawn, bill_ProductionWithUft });
                             if (unfinishedThing != null)
                             {
                                 return(FinishUftJob(pawn, unfinishedThing, bill_ProductionWithUft));
                             }
                         }
                     }
                     return(new Job(TechJobDefOf.DocumentTech, target)
                     {
                         bill = bill
                     });
                 }
                 else
                 {
                     return(new Job(TechJobDefOf.DocumentTechDigital, target)
                     {
                         bill = bill
                     });
                 }
             }
         }
     }
     return(null);
 }
コード例 #15
0
        // prefix
        // - wants instance, result and count
        // - wants to change count
        // - returns a boolean that controls if original is executed (true) or not (false)
        public static Boolean CalculateIngredientsPrefix(Job job, Pawn actor, ref List <Thing> __result)
        {
            UnfinishedThing unfinishedThing = job.GetTarget(TargetIndex.B).Thing as UnfinishedThing;

            if (unfinishedThing != null)
            {
                List <Thing> ingredients = unfinishedThing.ingredients;
                job.RecipeDef.Worker.ConsumeIngredient(unfinishedThing, job.RecipeDef, actor.Map);
                job.placedThings = null;
                //return ingredients;
                __result = ingredients;
                return(false);
            }
            List <Thing> list = new List <Thing>();

            if (job.placedThings != null)
            {
                for (int i = 0; i < job.placedThings.Count; i++)
                {
                    if (job.placedThings[i].Count <= 0)
                    {
                        Log.Error("PlacedThing " + job.placedThings[i] + " with count " + job.placedThings[i].Count + " for job " + job);
                    }
                    else
                    {
                        Thing thing = (job.placedThings[i].Count >= job.placedThings[i].thing.stackCount) ? job.placedThings[i].thing : job.placedThings[i].thing.SplitOff(job.placedThings[i].Count);
                        job.placedThings[i].Count = 0;
                        if (list.Contains(thing))
                        {
                            Log.Error("Tried to add ingredient from job placed targets twice: " + thing);
                        }
                        else
                        {
                            list.Add(thing);

                            //Check if the Name of the Recipe is "CremateCorpse", if so do not strip.
                            if (!string.Equals(job.RecipeDef.defName, "CremateCorpse"))
                            {
                                IStrippable strippable = thing as IStrippable;
                                if (strippable != null)
                                {
                                    strippable.Strip();
                                }
                            }
                        }
                    }
                }
            }
            job.placedThings = null;

            // return list;
            __result = list;
            return(false);
        }
コード例 #16
0
        public new object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector)
        {
            Bill_ProductionWithUft _obj = (Bill_ProductionWithUft)base.SetObjectData(obj, info, context, selector);
            UnfinishedThing uft = (UnfinishedThing)info.GetValue("uft", typeof(UnfinishedThing));

            if (_obj != null)
            {
                _obj.SetBoundUft(uft, true);
            }

            return _obj;
        }
コード例 #17
0
        // Token: 0x0600002D RID: 45 RVA: 0x0000384C File Offset: 0x00001A4C
        public static Toil MakeUnfinishedThingIfNeeded()
        {
            Toil toil = new Toil();

            toil.initAction = delegate()
            {
                Pawn actor  = toil.actor;
                Job  curJob = actor.jobs.curJob;
                bool flag   = !curJob.RecipeDef.UsesUnfinishedThing;
                if (!flag)
                {
                    bool flag2 = curJob.GetTarget(TargetIndex.B).Thing is UnfinishedThing;
                    if (!flag2)
                    {
                        List <Thing> list  = Toils_WPRecipe.CalculateIngredients(curJob, actor);
                        string       str   = "ingredient list in toil_wprecipe";
                        List <Thing> list2 = list;
                        Log.Message(str + ((list2 != null) ? list2.ToString() : null), false);
                        Thing thing = Toils_WPRecipe.CalculateDominantIngredient(curJob, list);
                        for (int i = 0; i < list.Count; i++)
                        {
                            Thing  thing2 = list[i];
                            string str2   = "ingredient in toil_wprecipe";
                            Thing  thing3 = list[i];
                            Log.Message(str2 + ((thing3 != null) ? thing3.ToString() : null), false);
                            actor.Map.designationManager.RemoveAllDesignationsOn(thing2, false);
                            bool spawned = thing2.Spawned;
                            if (spawned)
                            {
                                thing2.DeSpawn(DestroyMode.Vanish);
                            }
                        }
                        ThingDef        stuff           = (!curJob.RecipeDef.unfinishedThingDef.MadeFromStuff) ? null : thing.def;
                        UnfinishedThing unfinishedThing = (UnfinishedThing)ThingMaker.MakeThing(curJob.RecipeDef.unfinishedThingDef, stuff);
                        unfinishedThing.Creator     = actor;
                        unfinishedThing.BoundBill   = (Bill_ProductionWithUft)curJob.bill;
                        unfinishedThing.ingredients = list;
                        CompColorable compColorable = unfinishedThing.TryGetComp <CompColorable>();
                        bool          flag3         = compColorable != null;
                        if (flag3)
                        {
                            compColorable.Color = thing.DrawColor;
                        }
                        GenSpawn.Spawn(unfinishedThing, curJob.GetTarget(TargetIndex.A).Cell, actor.Map, WipeMode.Vanish);
                        curJob.SetTarget(TargetIndex.B, unfinishedThing);
                        actor.Reserve(unfinishedThing, curJob, 1, -1, null, true);
                    }
                }
            };
            return(toil);
        }
コード例 #18
0
        static void Prefix(Bill_ProductionWithUft __instance, out UnfinishedThing __state)
        {
            UnfinishedThing unfinishedThing = Traverse.Create(__instance).Field("boundUftInt").GetValue <UnfinishedThing>();

            if (unfinishedThing != null && unfinishedThing.Creator != null && unfinishedThing.Creator.IsPrisonerOfColony)
            {
                DebugLogger.debug($"[PL] Saving unfinished thing to state pawn: {unfinishedThing.Creator.LabelShort}, bill: {unfinishedThing.LabelShort}");
                __state = unfinishedThing;
            }
            else
            {
                __state = null;
            }
        }
コード例 #19
0
ファイル: Main.cs プロジェクト: Jellypowered/no-job-authors
        public static bool ClosestUnfinishedThingForBill(ref UnfinishedThing __result, Pawn pawn, Bill_ProductionWithUft bill)
        {
            bool Validator(Thing t) => !t.IsForbidden(pawn) &&
            ((UnfinishedThing)t).Recipe == bill.recipe &&
            ((UnfinishedThing)t).ingredients.TrueForAll(x => bill.IsFixedOrAllowedIngredient(x.def)) &&
            pawn.CanReserve(t);

            ThingRequest  thingReq       = ThingRequest.ForDef(bill.recipe.unfinishedThingDef);
            TraverseParms traverseParams = TraverseParms.For(pawn, pawn.NormalMaxDanger());

            __result = (UnfinishedThing)GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, thingReq, PathEndMode.InteractionCell, traverseParams, validator: Validator);
            //Log.Message("This is closest unfinished thing for bill", false);
            return(false);
        }
コード例 #20
0
 private Job StartOrResumeBillJob(Pawn pawn, IBillGiver giver)
 {
     for (int i = 0; i < giver.BillStack.Count; i++)
     {
         Bill bill = giver.BillStack[i];
         if ((bill.recipe.requiredGiverWorkType == null || bill.recipe.requiredGiverWorkType == base.def.workType) && (Find.TickManager.TicksGame >= bill.lastIngredientSearchFailTicks + WorkGiver_DoBill.ReCheckFailedBillTicksRange.RandomInRange || FloatMenuMakerMap.makingFor == pawn))
         {
             bill.lastIngredientSearchFailTicks = 0;
             if (bill.ShouldDoNow() && bill.PawnAllowedToStartAnew(pawn))
             {
                 if (bill.recipe.PawnSatisfiesSkillRequirements(pawn))
                 {
                     Bill_ProductionWithUft bill_ProductionWithUft = bill as Bill_ProductionWithUft;
                     if (bill_ProductionWithUft != null)
                     {
                         if (bill_ProductionWithUft.BoundUft != null)
                         {
                             if (bill_ProductionWithUft.BoundWorker == pawn && pawn.CanReserveAndReach(bill_ProductionWithUft.BoundUft, PathEndMode.Touch, Danger.Deadly, 1, -1, null, false) && !bill_ProductionWithUft.BoundUft.IsForbidden(pawn))
                             {
                                 return(WorkGiver_DoBill.FinishUftJob(pawn, bill_ProductionWithUft.BoundUft, bill_ProductionWithUft));
                             }
                             continue;
                         }
                         UnfinishedThing unfinishedThing = WorkGiver_DoBill.ClosestUnfinishedThingForBill(pawn, bill_ProductionWithUft);
                         if (unfinishedThing != null)
                         {
                             return(WorkGiver_DoBill.FinishUftJob(pawn, unfinishedThing, bill_ProductionWithUft));
                         }
                     }
                     if (!WorkGiver_DoBill.TryFindBestBillIngredients(bill, pawn, (Thing)giver, this.chosenIngThings))
                     {
                         if (FloatMenuMakerMap.makingFor != pawn)
                         {
                             bill.lastIngredientSearchFailTicks = Find.TickManager.TicksGame;
                         }
                         else
                         {
                             JobFailReason.Is(WorkGiver_DoBill.MissingMaterialsTranslated);
                         }
                         continue;
                     }
                     return(this.TryStartNewDoBillJob(pawn, bill, giver));
                 }
                 JobFailReason.Is(WorkGiver_DoBill.MissingSkillTranslated);
             }
         }
     }
     return(null);
 }
コード例 #21
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            AddEndCondition(delegate
            {
                Thing thing = ((_003CMakeNewToils_003Ec__Iterator0) /*Error near IL_006b: stateMachine*/)._0024this.GetActor().jobs.curJob.GetTarget(TargetIndex.A).Thing;
                if (thing is Building && !thing.Spawned)
                {
                    return(JobCondition.Incompletable);
                }
                return(JobCondition.Ongoing);
            });
            this.FailOnBurningImmobile(TargetIndex.A);
            this.FailOn(delegate
            {
                IBillGiver billGiver = ((_003CMakeNewToils_003Ec__Iterator0) /*Error near IL_008f: stateMachine*/)._0024this.job.GetTarget(TargetIndex.A).Thing as IBillGiver;
                if (billGiver != null)
                {
                    if (((_003CMakeNewToils_003Ec__Iterator0) /*Error near IL_008f: stateMachine*/)._0024this.job.bill.DeletedOrDereferenced)
                    {
                        return(true);
                    }
                    if (!billGiver.CurrentlyUsableForBills())
                    {
                        return(true);
                    }
                }
                return(false);
            });
            Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell);
            yield return(new Toil
            {
                initAction = delegate
                {
                    if (((_003CMakeNewToils_003Ec__Iterator0) /*Error near IL_00bf: stateMachine*/)._0024this.job.targetQueueB != null && ((_003CMakeNewToils_003Ec__Iterator0) /*Error near IL_00bf: stateMachine*/)._0024this.job.targetQueueB.Count == 1)
                    {
                        UnfinishedThing unfinishedThing = ((_003CMakeNewToils_003Ec__Iterator0) /*Error near IL_00bf: stateMachine*/)._0024this.job.targetQueueB[0].Thing as UnfinishedThing;
                        if (unfinishedThing != null)
                        {
                            unfinishedThing.BoundBill = (Bill_ProductionWithUft)((_003CMakeNewToils_003Ec__Iterator0) /*Error near IL_00bf: stateMachine*/)._0024this.job.bill;
                        }
                    }
                }
            });

            /*Error: Unable to find new state assignment for yield return*/;
        }
        private bool TryGetValue(StatRequest req, out float value)
        {
            UnfinishedThing unfinishedThing = req.Thing as UnfinishedThing;

            if (unfinishedThing == null)
            {
                value = 0f;
                return(false);
            }
            float num = 0f;

            for (int i = 0; i < unfinishedThing.ingredients.Count; i++)
            {
                num += unfinishedThing.ingredients[i].GetStatValue(StatDefOf.Mass, true) * (float)unfinishedThing.ingredients[i].stackCount;
            }
            value = num;
            return(true);
        }
コード例 #23
0
        public static Toil MakeUnfinishedThingIfNeeded()
        {
            Toil toil = new Toil();

            toil.initAction = delegate
            {
                Pawn actor  = toil.actor;
                Job  curJob = actor.jobs.curJob;
                if (!curJob.RecipeDef.UsesUnfinishedThing)
                {
                    return;
                }
                if (curJob.GetTarget(TargetIndex.B).Thing is UnfinishedThing)
                {
                    return;
                }
                List <Thing> list  = Toils_Recipe.CalculateIngredients(curJob, actor);
                Thing        thing = Toils_Recipe.CalculateDominantIngredient(curJob, list);
                for (int i = 0; i < list.Count; i++)
                {
                    Thing thing2 = list[i];
                    actor.Map.designationManager.RemoveAllDesignationsOn(thing2, false);
                    if (thing2.Spawned)
                    {
                        thing2.DeSpawn(DestroyMode.Vanish);
                    }
                }
                ThingDef        stuff           = (!curJob.RecipeDef.unfinishedThingDef.MadeFromStuff) ? null : thing.def;
                UnfinishedThing unfinishedThing = (UnfinishedThing)ThingMaker.MakeThing(curJob.RecipeDef.unfinishedThingDef, stuff);
                unfinishedThing.Creator     = actor;
                unfinishedThing.BoundBill   = (Bill_ProductionWithUft)curJob.bill;
                unfinishedThing.ingredients = list;
                CompColorable compColorable = unfinishedThing.TryGetComp <CompColorable>();
                if (compColorable != null)
                {
                    compColorable.Color = thing.DrawColor;
                }
                GenSpawn.Spawn(unfinishedThing, curJob.GetTarget(TargetIndex.A).Cell, actor.Map, WipeMode.Vanish);
                curJob.SetTarget(TargetIndex.B, unfinishedThing);
                actor.Reserve(unfinishedThing, curJob, 1, -1, null, true);
            };
            return(toil);
        }
コード例 #24
0
        private static List <Thing> CalculateIngredients(Job job, Pawn actor)
        {
            UnfinishedThing unfinishedThing = job.GetTarget(TargetIndex.B).Thing as UnfinishedThing;

            if (unfinishedThing != null)
            {
                List <Thing> ingredients = unfinishedThing.ingredients;
                job.RecipeDef.Worker.ConsumeIngredient(unfinishedThing, job.RecipeDef, actor.Map);
                job.placedThings = null;
                return(ingredients);
            }
            List <Thing> list = new List <Thing>();

            if (job.placedThings != null)
            {
                for (int i = 0; i < job.placedThings.Count; i++)
                {
                    if (job.placedThings[i].Count <= 0)
                    {
                        Log.Error("PlacedThing " + job.placedThings[i] + " with count " + job.placedThings[i].Count + " for job " + job);
                    }
                    else
                    {
                        Thing thing = (job.placedThings[i].Count >= job.placedThings[i].thing.stackCount) ? job.placedThings[i].thing : job.placedThings[i].thing.SplitOff(job.placedThings[i].Count);
                        job.placedThings[i].Count = 0;
                        if (list.Contains(thing))
                        {
                            Log.Error("Tried to add ingredient from job placed targets twice: " + thing);
                        }
                        else
                        {
                            list.Add(thing);
                            if (job.RecipeDef.autoStripCorpses)
                            {
                                (thing as IStrippable)?.Strip();
                            }
                        }
                    }
                }
            }
            job.placedThings = null;
            return(list);
        }
コード例 #25
0
        public static bool CanGetThing(Pawn pawn, Thing t, bool forced)
        {
            //tests based on AI.HaulAIUtility.PawnCanAutomaticallyHaulFast
            UnfinishedThing unfinishedThing = t as UnfinishedThing;

            if ((unfinishedThing != null && unfinishedThing.BoundBill != null) ||
                !pawn.CanReach(t, PathEndMode.ClosestTouch, pawn.NormalMaxDanger(),
                               mode: TraverseMode.ByPawn) ||
                !pawn.CanReserve(t, 1, -1, null, forced))
            {
                return(false);
            }
            if (t.IsBurning())
            {
                JobFailReason.Is("BurningLower".Translate(), null);
                return(false);
            }
            return(true);
        }
コード例 #26
0
 public void SetBoundUft(UnfinishedThing value, bool setOtherLink = true)
 {
     if (value != this.boundUftInt)
     {
         UnfinishedThing unfinishedThing = this.boundUftInt;
         this.boundUftInt = value;
         if (setOtherLink)
         {
             if (unfinishedThing != null && unfinishedThing.BoundBill == this)
             {
                 unfinishedThing.BoundBill = null;
             }
             if (value != null && value.BoundBill != this)
             {
                 this.boundUftInt.BoundBill = this;
             }
         }
     }
 }
コード例 #27
0
        private static Thing CalculateDominantIngredient(Job job, List <Thing> ingredients)
        {
            UnfinishedThing uft = job.GetTarget(TargetIndex.B).Thing as UnfinishedThing;

            if (uft != null && uft.def.MadeFromStuff)
            {
                return(uft.ingredients.First((Thing ing) => ing.def == uft.Stuff));
            }
            if (!ingredients.NullOrEmpty())
            {
                if (job.RecipeDef.productHasIngredientStuff)
                {
                    return(ingredients[0]);
                }
                if (job.RecipeDef.products.Any((ThingDefCountClass x) => x.thingDef.MadeFromStuff))
                {
                    return(ingredients.Where((Thing x) => x.def.IsStuff).RandomElementByWeight((Thing x) => x.stackCount));
                }
                return(ingredients.RandomElementByWeight((Thing x) => x.stackCount));
            }
            return(null);
        }
コード例 #28
0
        public new static Job FinishUftJob(Pawn pawn, UnfinishedThing uft, Bill_ProductionWithUft bill)
        {
            if (pawn.TryGetComp <CompKnowledge>().expertise.Where(x => !x.Key.IsFinished && x.Value >= 1f && x.Key.LabelCap == uft.Stuff.stuffProps.stuffAdjective).Any() == false)
            {
                return(null);
            }
            Job job = WorkGiverUtility.HaulStuffOffBillGiverJob(pawn, bill.billStack.billGiver, uft);

            if (job != null && job.targetA.Thing != uft)
            {
                return(job);
            }
            Job job2 = JobMaker.MakeJob(TechJobDefOf.DocumentTech, (Thing)bill.billStack.billGiver);

            job2.bill         = bill;
            job2.targetQueueB = new List <LocalTargetInfo> {
                uft
            };
            job2.countQueue = new List <int> {
                1
            };
            job2.haulMode = HaulMode.ToCellNonStorage;
            return(job2);
        }
コード例 #29
0
        static IEnumerable <Toil> DoMakeToils(JobDriver_DoBill_Access __instance)
        {
            //normal scenario
            __instance.AddEndCondition(delegate
            {
                Thing thing = __instance.GetActor().jobs.curJob.GetTarget(TargetIndex.A).Thing;
                if (thing is Building && !thing.Spawned)
                {
                    return(JobCondition.Incompletable);
                }
                return(JobCondition.Ongoing);
            });
            __instance.FailOnBurningImmobile(TargetIndex.A);
            __instance.FailOn(delegate()
            {
                if (__instance.job.GetTarget(TargetIndex.A).Thing is Filth)
                {
                    return(false);
                }

                IBillGiver billGiver = __instance.job.GetTarget(TargetIndex.A).Thing as IBillGiver;
                if (billGiver != null)
                {
                    if (__instance.job.bill.DeletedOrDereferenced)
                    {
                        return(true);
                    }
                    if (!billGiver.CurrentlyUsableForBills())
                    {
                        return(true);
                    }
                }
                return(false);
            });

            Toil gotoBillGiver = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell);

            yield return(new Toil
            {
                initAction = delegate()
                {
                    if (__instance.job.targetQueueB != null && __instance.job.targetQueueB.Count == 1)
                    {
                        UnfinishedThing unfinishedThing = __instance.job.targetQueueB[0].Thing as UnfinishedThing;
                        if (unfinishedThing != null)
                        {
                            unfinishedThing.BoundBill = (Bill_ProductionWithUft)__instance.job.bill;
                        }
                    }
                }
            });

            yield return(Toils_Jump.JumpIf(gotoBillGiver, () => __instance.job.GetTargetQueue(TargetIndex.B).NullOrEmpty()));

            //hauling patch
            if (Settings.adv_haul_all_ings && __instance.pawn.Faction == Faction.OfPlayer)
            {
                Toil checklist = new Toil();
                checklist.initAction = delegate()
                {
                    Pawn actor  = checklist.actor;
                    Job  curJob = actor.jobs.curJob;
                    List <LocalTargetInfo> targetQueue = curJob.GetTargetQueue(TargetIndex.B);
                    if (targetQueue.NullOrEmpty())
                    {
                        actor.jobs.curDriver.EndJobWith(JobCondition.Incompletable);
                    }
                    else
                    {
                        foreach (var target in (targetQueue))
                        {
                            if (target == null || target.Thing.DestroyedOrNull())
                            {
                                actor.jobs.curDriver.EndJobWith(JobCondition.Incompletable);
                                break;
                            }
                        }
                    }
                };

                yield return(checklist);

                Toil extract = new Toil();
                extract.initAction = delegate()
                {
                    Pawn actor  = extract.actor;
                    Job  curJob = actor.jobs.curJob;
                    List <LocalTargetInfo> targetQueue = curJob.GetTargetQueue(TargetIndex.B);
                    if (!curJob.countQueue.NullOrEmpty())
                    {
                        if (curJob.countQueue[0] > targetQueue[0].Thing.stackCount)
                        {
                            actor.jobs.curDriver.EndJobWith(JobCondition.Incompletable);
                        }
                        else
                        {
                            curJob.SetTarget(TargetIndex.B, targetQueue[0]);
                            targetQueue.RemoveAt(0);
                            curJob.count = curJob.countQueue[0];
                            curJob.countQueue.RemoveAt(0);
                        }
                    }
                };

                Toil PickUpThing;
                List <LocalTargetInfo> L = __instance.job.GetTargetQueue(TargetIndex.B);
                if (L.Count < 2 && (L.Count == 0 || L[0].Thing.def.stackLimit < 2))
                {
                    PickUpThing = Toils_Haul.StartCarryThing(TargetIndex.B, true, false, true);
                }
                else
                {
                    PickUpThing            = new Toil();
                    PickUpThing.initAction = delegate()
                    {
                        Pawn  actor  = PickUpThing.actor;
                        Job   curJob = actor.jobs.curJob;
                        Thing thing  = curJob.GetTarget(TargetIndex.B).Thing;
                        List <LocalTargetInfo> targetQueue = curJob.GetTargetQueue(TargetIndex.B);
                        bool InventorySpawned = thing.ParentHolder == actor.inventory;
                        if (InventorySpawned || !Toils_Haul.ErrorCheckForCarry(actor, thing))
                        {
                            if (thing.stackCount < curJob.count)
                            {
                                actor.jobs.curDriver.EndJobWith(JobCondition.Incompletable);
                            }
                            else
                            {
                                Thing splitThing = thing.SplitOff(curJob.count);
                                if (splitThing.ParentHolder != actor.inventory && !actor.inventory.GetDirectlyHeldThings().TryAdd(splitThing, false))
                                {
                                    actor.jobs.curDriver.EndJobWith(JobCondition.Incompletable);
                                }


                                if (!splitThing.Destroyed && splitThing.stackCount != 0)
                                {
                                    targetQueue.Add(splitThing);

                                    if (!InventorySpawned)
                                    {
                                        CompUnloadChecker CUC = splitThing.TryGetComp <CompUnloadChecker>();
                                        if (CUC != null)
                                        {
                                            CUC.ShouldUnload = true;
                                        }
                                    }
                                }

                                if (splitThing != thing && actor.Map.reservationManager.ReservedBy(thing, actor, curJob))
                                {
                                    actor.Map.reservationManager.Release(thing, actor, curJob);
                                }
                            }
                        }
                    };
                }

                Toil TakeToHands = new Toil();
                TakeToHands.initAction = delegate()
                {
                    Pawn actor  = TakeToHands.actor;
                    Job  curJob = actor.jobs.curJob;
                    List <LocalTargetInfo> targetQueue = curJob.GetTargetQueue(TargetIndex.B);
                    if (!targetQueue.NullOrEmpty() && targetQueue[0].Thing.ParentHolder != actor.carryTracker)
                    {
                        actor.inventory.innerContainer.TryTransferToContainer(targetQueue[0].Thing, actor.carryTracker.innerContainer);
                        actor.Reserve(targetQueue[0], curJob);
                        curJob.SetTarget(TargetIndex.B, targetQueue[0]);
                        targetQueue.RemoveAt(0);
                    }
                };

                yield return(extract);

                Toil getToHaulTarget = Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.B).FailOnSomeonePhysicallyInteracting(TargetIndex.B);
                yield return(Toils_Jump.JumpIf(PickUpThing, () => __instance.job.GetTarget(TargetIndex.B).Thing.ParentHolder == __instance.pawn.inventory));

                yield return(getToHaulTarget);

                yield return(PickUpThing);

                yield return(Toils_Jump.JumpIf(extract, () => !__instance.job.countQueue.NullOrEmpty()));

                yield return(TakeToHands);

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

                Toil findPlaceTarget = Toils_JobTransforms.SetTargetToIngredientPlaceCell(TargetIndex.A, TargetIndex.B, TargetIndex.C);
                yield return(findPlaceTarget);

                yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.C, findPlaceTarget, false));

                yield return(Toils_Jump.JumpIfHaveTargetInQueue(TargetIndex.B, TakeToHands));
            }
            else
            {
                Toil extract = Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.B, true);
                yield return(extract);

                Toil getToHaulTarget = Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.B).FailOnSomeonePhysicallyInteracting(TargetIndex.B);
                yield return(getToHaulTarget);

                yield return(Toils_Haul.StartCarryThing(TargetIndex.B, true, false, true));

                yield return(JobDriver_DoBill_Access.JumpToCollectNextIntoHandsForBillCrutch(getToHaulTarget, TargetIndex.B));

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

                Toil findPlaceTarget = Toils_JobTransforms.SetTargetToIngredientPlaceCell(TargetIndex.A, TargetIndex.B, TargetIndex.C);
                yield return(findPlaceTarget);

                yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.C, findPlaceTarget, false));

                yield return(Toils_Jump.JumpIfHaveTargetInQueue(TargetIndex.B, extract));
            }

            yield return(gotoBillGiver); //one line from normal scenario

            //cleaning patch
            if (Settings.adv_cleaning && !Utility.IncapableOfCleaning(__instance.pawn))
            {
                Toil returnToBillGiver = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell);
                Toil FilthList         = new Toil();
                FilthList.initAction = delegate()
                {
                    Job curJob = FilthList.actor.jobs.curJob;
                    if (curJob.GetTargetQueue(TargetIndex.A).NullOrEmpty())
                    {
                        LocalTargetInfo A = curJob.GetTarget(TargetIndex.A);
                        DoCleanComp     comp;
                        if (!Settings.clean_gizmo || (comp = A.Thing?.TryGetComp <DoCleanComp>()) == null || comp.Active)
                        {
                            IEnumerable <Filth> l = Utility.SelectAllFilth(FilthList.actor, A, Settings.adv_clean_num);
                            Utility.AddFilthToQueue(curJob, TargetIndex.A, l, FilthList.actor);
                            FilthList.actor.ReserveAsManyAsPossible(curJob.GetTargetQueue(TargetIndex.A), curJob);
                        }
                        curJob.targetQueueA.Add(A);
                    }
                };
                yield return(FilthList);

                yield return(Toils_Jump.JumpIf(returnToBillGiver, () => __instance.job.GetTargetQueue(TargetIndex.A).NullOrEmpty()));

                Toil CleanFilthList = Toils_JobTransforms.ClearDespawnedNullOrForbiddenQueuedTargets(TargetIndex.A, null);
                yield return(CleanFilthList);

                yield return(Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.A, true));

                yield return(Toils_Jump.JumpIf(returnToBillGiver, () => __instance.job.GetTargetQueue(TargetIndex.A).NullOrEmpty()));

                yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch).JumpIfDespawnedOrNullOrForbidden(TargetIndex.A, CleanFilthList).JumpIfOutsideHomeArea(TargetIndex.A, CleanFilthList));

                Toil clean = new Toil();
                clean.initAction = delegate()
                {
                    Filth filth = clean.actor.jobs.curJob.GetTarget(TargetIndex.A).Thing as Filth;
                    __instance.billStartTick             = 0;
                    __instance.ticksSpentDoingRecipeWork = 0;
                    __instance.workLeft = filth.def.filth.cleaningWorkToReduceThickness * filth.thickness;
                };
                clean.tickAction = delegate()
                {
                    Filth filth = clean.actor.jobs.curJob.GetTarget(TargetIndex.A).Thing as Filth;
                    __instance.billStartTick             += 1;
                    __instance.ticksSpentDoingRecipeWork += 1;
                    if (__instance.billStartTick > filth.def.filth.cleaningWorkToReduceThickness)
                    {
                        filth.ThinFilth();
                        __instance.billStartTick = 0;
                        if (filth.Destroyed)
                        {
                            clean.actor.records.Increment(RecordDefOf.MessesCleaned);
                            __instance.ReadyForNextToil();
                            return;
                        }
                    }
                };
                clean.defaultCompleteMode = ToilCompleteMode.Never;
                clean.WithEffect(EffecterDefOf.Clean, TargetIndex.A);
                clean.WithProgressBar(TargetIndex.A, () => __instance.ticksSpentDoingRecipeWork / __instance.workLeft, true, -0.5f);
                clean.PlaySustainerOrSound(() => SoundDefOf.Interact_CleanFilth);
                clean.JumpIfDespawnedOrNullOrForbidden(TargetIndex.A, CleanFilthList);
                clean.JumpIfOutsideHomeArea(TargetIndex.A, CleanFilthList);
                yield return(clean);

                yield return(Toils_Jump.Jump(CleanFilthList));

                yield return(returnToBillGiver);
            }

            //continuation of normal scenario
            yield return(Toils_Recipe.MakeUnfinishedThingIfNeeded());

            yield return(Toils_Recipe.DoRecipeWork().FailOnDespawnedNullOrForbiddenPlacedThings().FailOnCannotTouch(TargetIndex.A, PathEndMode.InteractionCell));

            yield return(Toils_Recipe.FinishRecipeAndStartStoringProduct());

            if (!__instance.job.RecipeDef.products.NullOrEmpty() || !__instance.job.RecipeDef.specialProducts.NullOrEmpty())
            {
                yield return(Toils_Reserve.Reserve(TargetIndex.B, 1, -1, null));

                Toil carryToCell = Toils_Haul.CarryHauledThingToCell(TargetIndex.B);
                yield return(carryToCell);

                yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.B, carryToCell, true));

                Toil recount = new Toil();
                recount.initAction = delegate()
                {
                    Bill_Production bill_Production = recount.actor.jobs.curJob.bill as Bill_Production;
                    if (bill_Production != null && bill_Production.repeatMode == BillRepeatModeDefOf.TargetCount)
                    {
                        __instance.MapCrutch().resourceCounter.UpdateResourceCounts();
                    }
                };
                yield return(recount);
            }
            yield break;
        }
コード例 #30
0
        public static Toil DoRecipeWork()
        {
            Toil toil = new Toil();

            toil.initAction = delegate
            {
                Pawn             actor            = toil.actor;
                Job              curJob           = actor.jobs.curJob;
                JobDriver_DoBill jobDriver_DoBill = (JobDriver_DoBill)actor.jobs.curDriver;
                UnfinishedThing  unfinishedThing  = curJob.GetTarget(TargetIndex.B).Thing as UnfinishedThing;
                if (unfinishedThing != null && unfinishedThing.Initialized)
                {
                    jobDriver_DoBill.workLeft = unfinishedThing.workLeft;
                }
                else
                {
                    jobDriver_DoBill.workLeft = curJob.bill.recipe.WorkAmountTotal((unfinishedThing == null) ? null : unfinishedThing.Stuff);
                    if (unfinishedThing != null)
                    {
                        unfinishedThing.workLeft = jobDriver_DoBill.workLeft;
                    }
                }
                jobDriver_DoBill.billStartTick             = Find.TickManager.TicksGame;
                jobDriver_DoBill.ticksSpentDoingRecipeWork = 0;
                curJob.bill.Notify_DoBillStarted(actor);
            };
            toil.tickAction = delegate
            {
                Pawn             actor            = toil.actor;
                Job              curJob           = actor.jobs.curJob;
                JobDriver_DoBill jobDriver_DoBill = (JobDriver_DoBill)actor.jobs.curDriver;
                UnfinishedThing  unfinishedThing  = curJob.GetTarget(TargetIndex.B).Thing as UnfinishedThing;
                if (unfinishedThing != null && unfinishedThing.Destroyed)
                {
                    actor.jobs.EndCurrentJob(JobCondition.Incompletable, true);
                    return;
                }
                jobDriver_DoBill.ticksSpentDoingRecipeWork++;
                curJob.bill.Notify_PawnDidWork(actor);
                IBillGiverWithTickAction billGiverWithTickAction = toil.actor.CurJob.GetTarget(TargetIndex.A).Thing as IBillGiverWithTickAction;
                if (billGiverWithTickAction != null)
                {
                    billGiverWithTickAction.UsedThisTick();
                }
                if (curJob.RecipeDef.workSkill != null && curJob.RecipeDef.UsesUnfinishedThing)
                {
                    actor.skills.Learn(curJob.RecipeDef.workSkill, 0.1f * curJob.RecipeDef.workSkillLearnFactor, false);
                }
                float num = (curJob.RecipeDef.workSpeedStat != null) ? actor.GetStatValue(curJob.RecipeDef.workSpeedStat, true) : 1f;
                if (curJob.RecipeDef.workTableSpeedStat != null)
                {
                    Building_WorkTable building_WorkTable = jobDriver_DoBill.BillGiver as Building_WorkTable;
                    if (building_WorkTable != null)
                    {
                        num *= building_WorkTable.GetStatValue(curJob.RecipeDef.workTableSpeedStat, true);
                    }
                }
                if (DebugSettings.fastCrafting)
                {
                    num *= 30f;
                }
                jobDriver_DoBill.workLeft -= num;
                if (unfinishedThing != null)
                {
                    unfinishedThing.workLeft = jobDriver_DoBill.workLeft;
                }
                actor.GainComfortFromCellIfPossible();
                if (jobDriver_DoBill.workLeft <= 0f)
                {
                    jobDriver_DoBill.ReadyForNextToil();
                }
                if (curJob.bill.recipe.UsesUnfinishedThing)
                {
                    int num2 = Find.TickManager.TicksGame - jobDriver_DoBill.billStartTick;
                    if (num2 >= 3000 && num2 % 1000 == 0)
                    {
                        actor.jobs.CheckForJobOverride();
                    }
                }
            };
            toil.defaultCompleteMode = ToilCompleteMode.Never;
            toil.WithEffect(() => toil.actor.CurJob.bill.recipe.effectWorking, TargetIndex.A);
            toil.PlaySustainerOrSound(() => toil.actor.CurJob.bill.recipe.soundWorking);
            toil.WithProgressBar(TargetIndex.A, delegate
            {
                Pawn actor = toil.actor;
                Job curJob = actor.CurJob;
                UnfinishedThing unfinishedThing = curJob.GetTarget(TargetIndex.B).Thing as UnfinishedThing;
                return(1f - ((JobDriver_DoBill)actor.jobs.curDriver).workLeft / curJob.bill.recipe.WorkAmountTotal((unfinishedThing == null) ? null : unfinishedThing.Stuff));
            }, false, -0.5f);
            toil.FailOn(() => toil.actor.CurJob.bill.suspended);
            toil.activeSkill = (() => toil.actor.CurJob.bill.recipe.workSkill);
            return(toil);
        }