Ejemplo n.º 1
0
        public Toil BashIt()
        {
            Toil bashIt = new Toil();

            bashIt.tickAction = delegate()
            {
                Pawn  actor  = bashIt.actor;
                Job   curJob = actor.jobs.curJob;
                Thing thing  = curJob.GetTarget(TargetIndex.B).Thing;
                bool  flag   = actor.meleeVerbs.TryMeleeAttack(thing, null, false);
                bool  flag2  = flag;
                if (flag2)
                {
                    this.numMeleeAttacksMade++;
                    bool flag3 = this.numMeleeAttacksMade >= curJob.maxNumMeleeAttacks;
                    bool flag4 = flag3;
                    if (flag4)
                    {
                        this.EndJobWith(JobCondition.Succeeded);
                    }
                }
            };
            bashIt.defaultCompleteMode = ToilCompleteMode.Never;
            ToilFailConditions.EndOnDespawnedOrNull <Toil>(bashIt, TargetIndex.B, JobCondition.Succeeded);
            ToilFailConditions.FailOn <Toil>(bashIt, new Func <bool>(this.hunterIsKilled));
            return(bashIt);
        }
Ejemplo n.º 2
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            if (this.job.targetA.HasThing)
            {
                // ターゲットがThing=水アイテムを摂取する場合
                // 水が使用不可能になったらFail
                ToilFailConditions.FailOnDestroyedNullOrForbidden <JobDriver_DrinkWater>(this, WaterIndex);

                // 水を取得
                if (this.drinkingFromInventory)
                {
                    // 所持品から取り出す
                    yield return(Toils_Mizu.StartCarryFromInventory(WaterIndex));
                }
                else
                {
                    // 水の場所まで行く
                    yield return(Toils_Goto.Goto(WaterIndex, PathEndMode.OnCell));

                    // 水を拾う
                    yield return(Toils_Ingest.PickupIngestible(WaterIndex, this.pawn));
                }

                // 飲む場所を決めてそこへ移動
                yield return(Toils_Mizu.StartPathToDrinkSpot(WaterIndex));

                // 水を摂取
                yield return(Toils_Mizu.Drink(WaterIndex));

                // 水の摂取終了(心情、水分、アイテム個数の処理)
                yield return(Toils_Mizu.FinishDrink(WaterIndex));

                if (this.drinkingFromInventory && !this.TargetA.ThingDestroyed)
                {
                    // 所持品から取り出した&まだ残っている場合は所持品に戻す
                    yield return(Toils_Mizu.AddCarriedThingToInventory());
                }
            }
            else
            {
                // ターゲットがThingではない=水アイテムを摂取しない場合=水地形を利用する場合

                // 選んだ水地形が使用不可能or到達不可能になったらFail
                ToilFailConditions.FailOn <JobDriver_DrinkWater>(this, () =>
                {
                    return(this.job.targetA.Cell.IsForbidden(pawn) || !pawn.CanReach(this.job.targetA.Cell, PathEndMode.ClosestTouch, Danger.Deadly));
                });

                // 水地形まで移動
                yield return(Toils_Goto.GotoCell(WaterIndex, PathEndMode.OnCell));

                // 水地形から水分を摂取
                yield return(Toils_Mizu.DrinkTerrain(WaterIndex, BaseDrinkTicksFromTerrain));

                // 終了
                //yield return Toils_Mizu.FinishDrinkTerrain(WaterIndex);
            }
        }
Ejemplo n.º 3
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            Toil followAndAttack = new Toil();

            followAndAttack.tickAction = delegate()
            {
                Pawn  actor  = followAndAttack.actor;
                Job   curJob = actor.jobs.curJob;
                Thing thing  = curJob.GetTarget(TargetIndex.A).Thing;
                Pawn  pawn   = thing as Pawn;
                bool  flag   = this.pawn.Faction != Faction.OfPlayer;
                bool  flag2  = flag;
                if (flag2)
                {
                    actor.mindState.mentalStateHandler.TryStartMentalState(DefDatabase <MentalStateDef> .GetNamed("MurderousRage", true), null, false, false, null);
                }
                bool flag3 = thing != actor.pather.Destination.Thing || (!this.pawn.pather.Moving && !GenAdj.AdjacentTo8WayOrInside(this.pawn.Position, thing));
                bool flag4 = flag3;
                if (flag4)
                {
                    actor.pather.StartPath(thing, PathEndMode.Touch);
                }
                else
                {
                    bool flag5 = GenAdj.AdjacentTo8WayOrInside(this.pawn.Position, thing);
                    bool flag6 = flag5;
                    if (flag6)
                    {
                        bool flag7 = thing is Pawn && pawn.Downed && !curJob.killIncappedTarget;
                        bool flag8 = flag7;
                        if (flag8)
                        {
                            this.EndJobWith(JobCondition.Succeeded);
                        }
                        bool flag9  = actor.meleeVerbs.TryMeleeAttack(thing, null, false);
                        bool flag10 = flag9;
                        if (flag10)
                        {
                            this.numMeleeAttacksLanded += 1;
                            bool flag11 = this.numMeleeAttacksLanded >= curJob.maxNumMeleeAttacks;
                            bool flag12 = flag11;
                            if (flag12)
                            {
                                this.EndJobWith(JobCondition.Succeeded);
                            }
                        }
                    }
                }
            };
            followAndAttack.defaultCompleteMode = ToilCompleteMode.Never;
            ToilFailConditions.EndOnDespawnedOrNull <Toil>(followAndAttack, TargetIndex.A, JobCondition.Succeeded);
            ToilFailConditions.FailOn <Toil>(followAndAttack, new Func <bool>(this.hunterIsKilled));
            yield return(followAndAttack);

            yield break;
        }
Ejemplo n.º 4
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            ToilFailConditions.FailOnDestroyedOrNull <JobDriver_Segmentation>(this, TargetIndex.A);
            ToilFailConditions.FailOnDespawnedOrNull <JobDriver_Segmentation>(this, TargetIndex.A);
            ToilFailConditions.FailOn <JobDriver_Segmentation>(this, new Func <bool>(this.eaterIsKilled));
            Toil resCorpse = new Toil();

            resCorpse.initAction = delegate()
            {
                Pawn  actor = resCorpse.actor;
                Thing thing = resCorpse.actor.CurJob.GetTarget(TargetIndex.A).Thing;
                bool  flag  = !thing.Spawned || !this.Map.reservationManager.CanReserve(actor, thing, 1);
                bool  flag2 = flag;
                if (flag2)
                {
                    actor.jobs.EndCurrentJob(JobCondition.Incompletable, true);
                }
                else
                {
                    this.Map.reservationManager.Reserve(actor, actor.CurJob, thing, 1);
                }
            };
            resCorpse.defaultCompleteMode = ToilCompleteMode.Instant;
            yield return(resCorpse);

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

            yield return(Toils_General.Wait(400));

            Toil toil = new Toil
            {
                defaultCompleteMode = ToilCompleteMode.Instant
            };

            toil.initAction = new Action(this.doStripCorpse);
            yield return(toil);

            yield return(Toils_General.Wait(60));

            Toil toil2 = new Toil
            {
                defaultCompleteMode = ToilCompleteMode.Instant
            };

            toil2.initAction = new Action(this.doChewCorpse);
            ToilEffects.WithEffect(toil2, EffecterDefOf.EatMeat, TargetIndex.A);
            ToilFailConditions.EndOnDespawnedOrNull <Toil>(toil2, TargetIndex.A, JobCondition.Incompletable);
            yield return(toil2);

            yield break;
        }
        // Token: 0x06000030 RID: 48 RVA: 0x00002C83 File Offset: 0x00000E83
        protected override IEnumerable <Toil> MakeNewToils()
        {
            CompUniversalFermenter comp = ThingCompUtility.TryGetComp <CompUniversalFermenter>(this.Fermenter);

            ToilFailConditions.FailOn <JobDriver_TakeProductOutOfUniversalFermenter>(this, () => !comp.Fermented);
            ToilFailConditions.FailOnDestroyedNullOrForbidden <JobDriver_TakeProductOutOfUniversalFermenter>(this, (TargetIndex)1);
            yield return(Toils_Reserve.Reserve((TargetIndex)1, 1, -1, null));

            yield return(Toils_Goto.GotoThing((TargetIndex)1, (PathEndMode)3));

            yield return(ToilEffects.WithProgressBarToilDelay(ToilFailConditions.FailOnDestroyedNullOrForbidden <Toil>(Toils_General.Wait(200, 0), (TargetIndex)1), (TargetIndex)1, false, -0.5f));

            yield return(new Toil
            {
                initAction = delegate()
                {
                    Thing thing = comp.TakeOutProduct();
                    GenPlace.TryPlaceThing(thing, this.pawn.Position, this.Map, (ThingPlaceMode)1, null, null);
                    StoragePriority storagePriority = StoreUtility.CurrentStoragePriorityOf(thing);
                    IntVec3 intVec;
                    if (StoreUtility.TryFindBestBetterStoreCellFor(thing, this.pawn, this.Map, storagePriority, this.pawn.Faction, out intVec, true))
                    {
                        this.job.SetTarget((TargetIndex)2, thing);
                        this.job.count = thing.stackCount;
                        this.job.SetTarget((TargetIndex)3, intVec);
                        return;
                    }
                    this.EndJobWith((JobCondition)3);
                },
                defaultCompleteMode = (ToilCompleteMode)1
            });

            yield return(Toils_Reserve.Reserve((TargetIndex)2, 1, -1, null));

            yield return(Toils_Reserve.Reserve((TargetIndex)3, 1, -1, null));

            yield return(Toils_Goto.GotoThing((TargetIndex)2, (PathEndMode)3));

            yield return(Toils_Haul.StartCarryThing((TargetIndex)2, false, false, false));

            Toil carry = Toils_Haul.CarryHauledThingToCell((TargetIndex)3);

            yield return(carry);

            yield return(Toils_Haul.PlaceHauledThingInCell((TargetIndex)3, carry, true));

            yield break;
        }
        // Token: 0x0600002B RID: 43 RVA: 0x00002C03 File Offset: 0x00000E03
        protected override IEnumerable <Toil> MakeNewToils()
        {
            CompUniversalFermenter comp = ThingCompUtility.TryGetComp <CompUniversalFermenter>(this.Fermenter);

            ToilFailConditions.FailOn <JobDriver_FillUniversalFermenter>(this, () => comp.SpaceLeftForIngredient <= 0);
            ToilFailConditions.FailOnDestroyedNullOrForbidden <JobDriver_FillUniversalFermenter>(this, (TargetIndex)1);
            ToilFailConditions.FailOnDestroyedNullOrForbidden <JobDriver_FillUniversalFermenter>(this, (TargetIndex)2);
            Toil ingrToil = Toils_Reserve.Reserve((TargetIndex)2, 1, -1, null);

            yield return(ingrToil);

            yield return(Toils_Reserve.Reserve((TargetIndex)1, 1, -1, null));

            yield return(ToilFailConditions.FailOnDestroyedNullOrForbidden <Toil>(ToilFailConditions.FailOnSomeonePhysicallyInteracting <Toil>(Toils_Goto.GotoThing((TargetIndex)2, (PathEndMode)3), (TargetIndex)2), (TargetIndex)2));

            yield return(ToilFailConditions.FailOnDestroyedNullOrForbidden <Toil>(Toils_Haul.StartCarryThing((TargetIndex)2, false, true, false), (TargetIndex)2));

            yield return(Toils_Haul.CheckForGetOpportunityDuplicate(ingrToil, (TargetIndex)2, 0, true, null));

            yield return(Toils_Haul.CarryHauledThingToCell((TargetIndex)1));

            yield return(ToilEffects.WithProgressBarToilDelay(ToilFailConditions.FailOnDestroyedNullOrForbidden <Toil>(Toils_General.Wait(200, 0), (TargetIndex)1), (TargetIndex)1, false, -0.5f));

            yield return(new Toil
            {
                initAction = delegate()
                {
                    if (!comp.AddIngredient(this.Ingredient))
                    {
                        this.EndJobWith((JobCondition)3);
                        Log.Message("JobCondition.Incompletable", false);
                    }
                },
                defaultCompleteMode = (ToilCompleteMode)1
            });

            yield break;
        }
Ejemplo n.º 7
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            yield return(Toils_Reserve.Reserve((TargetIndex)1, 1, -1, null));

            yield return(ToilFailConditions.FailOn(Toils_Goto.GotoCell((TargetIndex)1, (PathEndMode)4), delegate(Toil to)
            {
                Building_SignalFire building_SignalFire = (Building_SignalFire)to.actor.jobs.curJob.GetTarget((TargetIndex)1).Thing;
                return !building_SignalFire.CanUseSignalFireNow;
            }));

            yield return(new Toil
            {
                initAction = () =>
                {
                    Pawn pawn = this.pawn;
                    Building_SignalFire building_SignalFire = (Building_SignalFire)pawn.jobs.curJob.GetTarget((TargetIndex)1).Thing;
                    bool canUseSignalFireNow = building_SignalFire.CanUseSignalFireNow;
                    if (canUseSignalFireNow)
                    {
                        pawn.jobs.curJob.commTarget.TryOpenComms(pawn);
                    }
                }
            });
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            // ターゲットがThing=水アイテムを摂取する場合

            // 水(食事)が使用不可能になったらFail
            ToilFailConditions.FailOnDestroyedNullOrForbidden(this, WaterIndex);
            ToilFailConditions.FailOn(this, () =>
            {
                if (this.Patient == null)
                {
                    return(true);
                }

                // 患者がベッドに入ってなかったらFail
                if (!this.Patient.InBed())
                {
                    return(true);
                }

                // 到達不能になっていたらFail
                if (!this.pawn.CanReach(this.Patient, PathEndMode.ClosestTouch, Danger.Deadly))
                {
                    return(true);
                }

                return(false);
            });

            // 水が予約出来ない状態なら中断
            if (!ReservationUtility.CanReserveAndReach(this.pawn, this.TargetA, PathEndMode.Touch, Danger.Deadly, 1, this.job.count, null, false))
            {
                this.GetActor().jobs.EndCurrentJob(JobCondition.Incompletable);
                yield break;
            }

            // 水を予約する
            if (!this.pawn.Map.reservationManager.ReservedBy(this.TargetA.Thing, pawn))
            {
                yield return(Toils_Reserve.Reserve(WaterIndex, 1, this.job.count, null));
            }

            if (this.getItemFromInventory)
            {
                // 水を持ち物から取り出す
                yield return(Toils_Mizu.StartCarryFromInventory(WaterIndex));
            }
            else
            {
                // 水の場所まで行く
                yield return(Toils_Goto.Goto(WaterIndex, PathEndMode.OnCell));

                // 水を拾う
                yield return(Toils_Ingest.PickupIngestible(WaterIndex, this.pawn));
            }

            // 患者のもとへ移動
            yield return(Toils_Goto.Goto(PatientIndex, PathEndMode.Touch));

            // 水を飲ませる
            yield return(Toils_Mizu.FeedToPatient(WaterIndex, PatientIndex));

            // 水の摂取終了(心情、食事の処理)
            yield return(Toils_Mizu.FinishDrinkPatient(WaterIndex, PatientIndex));

            if (this.getItemFromInventory && !this.TargetA.ThingDestroyed)
            {
                // 所持品から取り出した&まだ残っている場合は所持品に戻す
                yield return(Toils_Mizu.AddCarriedThingToInventory());
            }
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            base.AddEndCondition(delegate()
            {
                var thing = base.GetActor().jobs.curJob.GetTarget(TargetIndex.A).Thing;
                if (thing is Building && !thing.Spawned)
                {
                    return(JobCondition.Incompletable);
                }
                return(JobCondition.Ongoing);
            });
            this.FailOnBurningImmobile <JobDriver_DoBill>(TargetIndex.A);
            this.FailOn <JobDriver_DoBill>(delegate()
            {
                if (!(this.job.GetTarget(TargetIndex.A).Thing is IBillGiver billGiver))
                {
                    return(false);
                }
                if (this.job.bill.DeletedOrDereferenced)
                {
                    return(true);
                }
                if (!billGiver.CurrentlyUsableForBills())
                {
                    return(true);
                }
                return(false);
            });
            yield return(Toils_Reserve.Reserve(TargetIndex.A, 1, -1, null));

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

            var            tableThing     = this.job.GetTarget(TargetIndex.A).Thing as Building_СontainmentBreach;
            CompRefuelable refuelableComp = tableThing.GetComp <CompRefuelable>();
            Toil           toil           = new Toil();

            toil.initAction = delegate()
            {
                this.job.bill.Notify_DoBillStarted(this.pawn);
                this.workCycleProgress = this.job.bill.recipe.workAmount;
            };
            toil.tickAction = delegate()
            {
                this.workCycleProgress -= StatExtension.GetStatValue(this.pawn, StatDefOf.WorkToMake, true);
                tableThing.UsedThisTick();
                if (!tableThing.CurrentlyUsableForBills() || (refuelableComp != null && !refuelableComp.HasFuel))
                {
                    this.pawn.jobs.EndCurrentJob(JobCondition.Incompletable, true, true);
                }
                if (this.workCycleProgress <= 0f)
                {
                    SkillDef workSkill = this.job.bill.recipe.workSkill;
                    if (workSkill != null)
                    {
                        SkillRecord skill = this.pawn.skills.GetSkill(workSkill);
                        if (skill != null)
                        {
                            skill.Learn(0.11f * this.job.bill.recipe.workSkillLearnFactor, false);
                        }
                    }
                    GenSpawn.Spawn(tableThing.GetKorsolianToxin(this.job.bill.recipe),
                                   tableThing.InteractionCell, tableThing.Map, 0);
                    Toils_Reserve.Release(TargetIndex.A);
                    PawnUtility.GainComfortFromCellIfPossible(this.pawn, false);
                    this.job.bill.Notify_IterationCompleted(this.pawn, null);
                    this.ReadyForNextToil();
                }
            };
            toil.defaultCompleteMode = ToilCompleteMode.Never;
            ToilEffects.WithEffect(toil, () => this.job.bill.recipe.effectWorking, TargetIndex.A);
            ToilEffects.PlaySustainerOrSound(toil, () => toil.actor.CurJob.bill.recipe.soundWorking);
            ToilEffects.WithProgressBar(toil, TargetIndex.A, delegate()
            {
                return(PurpleIvyUtils.GetPercentageFromPartWhole
                           (this.job.bill.recipe.workAmount - this.workCycleProgress,
                           (int)this.job.bill.recipe.workAmount) / 100f);
            }, false, 0.5f);
            ToilFailConditions.FailOn <Toil>(toil, delegate()
            {
                IBillGiver billGiver = this.job.GetTarget(TargetIndex.A).Thing as IBillGiver;
                return(this.job.bill.suspended || this.job.bill.DeletedOrDereferenced || (billGiver != null && !billGiver.CurrentlyUsableForBills()));
            });
            yield return(toil);

            yield break;
        }
Ejemplo n.º 10
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            // Just on the off-chance the rock is on fire...
            this.FailOnBurningImmobile(TargetIndex.A);
            // Reserve the target
            yield return(Toils_Reserve.Reserve(TargetIndex.A));

            // Go to the target
            Toil toilGoto = Toils_Goto.GotoCell(TargetIndex.A, PathEndMode.Touch);

            // Fail going to the target if it becomes unreachable
            ToilFailConditions.FailOn <Toil>(toilGoto, (Func <bool>)(() =>
            {
                if (Reachability.CanReach(pawn, (TargetInfo)TargetLocA, PathEndMode.Touch, pawn.NormalMaxDanger()))
                {
                    return(false);
                }
                return(true);
            }));
            yield return(toilGoto);

            // Now the work toil itself
            Toil toilWork = new Toil
            {
                // Continue until done
                defaultCompleteMode = ToilCompleteMode.Never,
                // When the job starts...
                initAction = new Action(() =>
                {
                    smoothTicks = 0;
                }),
                // The work tick
                tickAction = new Action(() =>
                {
                    if (pawn.skills != null)
                    {
                        const float constructionXP = 0.11f / 5f;
                        const float miningXP       = 0.11f / 5f;
                        const float artisticXP     = 0.11f / 5f;
                        pawn.skills.Learn(SkillDefOf.Construction, constructionXP);
                        pawn.skills.Learn(SkillDefOf.Mining, miningXP);
                        pawn.skills.Learn(SkillDefOf.Artistic, artisticXP);
                    }
                    smoothTicks += 1;
                    if (smoothTicks < nextSmoothStrike)
                    {
                        return;
                    }
                    // Reset counter, damage rock
                    smoothTicks         = 0;
                    mineable.HitPoints -= DamagePerStrike;
                })
            };

            // When should we stop?
            toilWork.endConditions.Add((Func <JobCondition>)(() =>
            {
                // Go until the rock is fully damaged
                if (mineable.HitPoints > 0)
                {
                    return(JobCondition.Ongoing);
                }
                return(JobCondition.Succeeded);
            }));
            // Do something when done
            toilWork.AddFinishAction(new Action(() =>
            {
                // If the job failed, abort
                if (mineable.HitPoints > 0)
                {
                    return;
                }
                // Clear the designation at this cell
                Common.RemoveDesignationDefOfAt(SmoothWall.designationDef, TargetA.Cell);
                // Better have associated stone blocks...
                string blocksDef     = "Blocks" + mineable.def.defName;
                ThingDef stoneBlocks = DefDatabase <ThingDef> .GetNamed(blocksDef, true);
                // Replace the rock with a stone wall
                var wallThing = ThingMaker.MakeThing(SmoothWall.thingDef, stoneBlocks);
                if (wallThing != null)
                {
                    var wall = GenSpawn.Spawn(wallThing, TargetA.Cell);
                    if (wall != null)
                    {
                        wall.SetFaction(Faction.OfColony);
                    }
                }
            }));
            // Some fun sounds while working
            ToilEffects.WithSustainer(toilWork, (Func <SoundDef>)(() =>
            {
                return(SmoothWall.soundDef);
            }));
            // Some fun effects while working
            ToilEffects.WithEffect(toilWork, "Mine", TargetIndex.A);
            yield return(toilWork);

            // And we're done.
            yield break;
        }
Ejemplo n.º 11
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            base.AddEndCondition(delegate()
            {
                var thing = base.GetActor().jobs.curJob.GetTarget(TargetIndex.A).Thing;
                if (thing is Building && !thing.Spawned)
                {
                    return(JobCondition.Incompletable);
                }
                return(JobCondition.Ongoing);
            });
            this.FailOnBurningImmobile <JobDriver_DoBill>(TargetIndex.A);
            this.FailOn <JobDriver_DoBill>(delegate()
            {
                if (!(this.job.GetTarget(TargetIndex.A).Thing is IBillGiver billGiver))
                {
                    return(false);
                }
                if (this.job.bill.DeletedOrDereferenced)
                {
                    return(true);
                }
                if (!billGiver.CurrentlyUsableForBills())
                {
                    return(true);
                }
                return(false);
            });
            yield return(Toils_Reserve.Reserve(TargetIndex.A, 1, -1, null));

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

            var            tableThing     = this.job.GetTarget(TargetIndex.A).Thing as Building_СontainmentBreach;
            CompRefuelable refuelableComp = tableThing.GetComp <CompRefuelable>();
            Toil           toil           = new Toil();

            toil.initAction = delegate()
            {
                this.job.bill.Notify_DoBillStarted(this.pawn);
                this.workCycleProgress = this.job.bill.recipe.workAmount;
            };
            toil.tickAction = delegate()
            {
                this.workCycleProgress -= StatExtension.GetStatValue(this.pawn, StatDefOf.WorkToMake, true);
                tableThing.UsedThisTick();
                if (!tableThing.CurrentlyUsableForBills() || (refuelableComp != null && !refuelableComp.HasFuel))
                {
                    this.pawn.jobs.EndCurrentJob(JobCondition.Incompletable, true, true);
                }
                if (this.workCycleProgress <= 0f)
                {
                    SkillDef workSkill = this.job.bill.recipe.workSkill;
                    if (workSkill != null)
                    {
                        SkillRecord skill = this.pawn.skills.GetSkill(workSkill);
                        if (skill != null)
                        {
                            skill.Learn(0.11f * this.job.bill.recipe.workSkillLearnFactor, false);
                        }
                    }
                    var research = PurpleIvyData.AlienStudy.Where(x => x.TechprintsApplied == 0 &&
                                                                  GetActor().Map.listerThings.ThingsOfDef
                                                                      (ThingDef.Named("Techprint_" + x.defName)).Count == 0).RandomElement();
                    if (research != null)
                    {
                        GenSpawn.Spawn(ThingDef.Named("Techprint_" + research.defName),
                                       GetActor().Position, GetActor().Map);
                    }
                    job.bill.Notify_PawnDidWork(GetActor());
                    Bill_Production bill_Production = this.pawn.jobs.curJob.bill as Bill_Production;
                    if (bill_Production != null && bill_Production.repeatMode == BillRepeatModeDefOf.TargetCount)
                    {
                        this.Map.resourceCounter.UpdateResourceCounts();
                    }
                    Toils_Recipe.FinishRecipeAndStartStoringProduct();
                    job.bill.Notify_IterationCompleted(GetActor(), null);
                    Toils_Reserve.Release(TargetIndex.A);
                    PawnUtility.GainComfortFromCellIfPossible(this.pawn, false);
                    this.ReadyForNextToil();
                }
            };
            toil.defaultCompleteMode = ToilCompleteMode.Never;
            ToilEffects.WithEffect(toil, () => this.job.bill.recipe.effectWorking, TargetIndex.A);
            ToilEffects.PlaySustainerOrSound(toil, () => toil.actor.CurJob.bill.recipe.soundWorking);
            ToilEffects.WithProgressBar(toil, TargetIndex.A, delegate()
            {
                return(PurpleIvyUtils.GetPercentageFromPartWhole
                           (this.job.bill.recipe.workAmount - this.workCycleProgress,
                           (int)this.job.bill.recipe.workAmount) / 100f);
            }, false, 0.5f);
            ToilFailConditions.FailOn <Toil>(toil, delegate()
            {
                IBillGiver billGiver = this.job.GetTarget(TargetIndex.A).Thing as IBillGiver;
                return(this.job.bill.suspended || this.job.bill.DeletedOrDereferenced || (billGiver != null && !billGiver.CurrentlyUsableForBills()));
            });
            yield return(toil);

            yield break;
        }