Пример #1
0
        // Token: 0x06000095 RID: 149 RVA: 0x000059E9 File Offset: 0x00003BE9
        protected override IEnumerable <Toil> MakeNewToils()
        {
            var count = 0;

            this.FailOn(() => job.GetTarget(TargetIndex.A).Thing.DestroyedOrNull());
            this.FailOn(() => !HaywireData.IsHaywired(pawn));
            var count1 = count;

            this.FailOn(() => count1 > 4);
            yield return(Toils_Combat.TrySetJobToUseAttackVerb(TargetIndex.A));

            var gotoCastPos = Toils_Combat.GotoCastPosition(TargetIndex.A, TargetIndex.None, false, 0.95f);

            yield return(gotoCastPos);

            var count2 = count;

            count = count2 + 1;
            if (count > 8)
            {
                EndJobWith(JobCondition.Incompletable);
            }

            var jumpIfCannotHit = Toils_Jump.JumpIfTargetNotHittable(TargetIndex.A, gotoCastPos);

            yield return(jumpIfCannotHit);

            yield return(Toils_Combat.CastVerb(TargetIndex.A));

            yield return(Toils_Jump.Jump(jumpIfCannotHit));
        }
Пример #2
0
        // Token: 0x0600000A RID: 10 RVA: 0x000029D9 File Offset: 0x00000BD9
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOn(delegate
            {
                if (job.ignoreDesignations)
                {
                    return(false);
                }

                var victim = Victim;
                if (victim != null && !victim.Dead &&
                    Map.designationManager.DesignationOn(victim, DesignationDefOf.Hunt) == null)
                {
                    return(true);
                }

                return(false);
            });
            yield return(new Toil
            {
                initAction = delegate { jobStartTick = Find.TickManager.TicksGame; }
            });

            yield return(Toils_Combat.TrySetJobToUseAttackVerb(TargetIndex.A));

            var startCollectCorpse = StartCollectCorpseToil();
            var gotoCastPos        = MarvsGotoCastPosition(TargetIndex.A, true)
                                     .JumpIfDespawnedOrNull(TargetIndex.A, startCollectCorpse)
                                     .FailOn(() => Find.TickManager.TicksGame > jobStartTick + 5000);

            yield return(gotoCastPos);

            var moveIfCannotHit = MarvsJumpIfTargetNotHittable(TargetIndex.A, gotoCastPos);

            yield return(moveIfCannotHit);

            yield return(MarvsJumpIfTargetDownedDistant(TargetIndex.A, gotoCastPos));

            yield return(Toils_Combat.CastVerb(TargetIndex.A, false)
                         .JumpIfDespawnedOrNull(TargetIndex.A, startCollectCorpse)
                         .FailOn(() => Find.TickManager.TicksGame > jobStartTick + 5000));

            yield return(Toils_Jump.JumpIfTargetDespawnedOrNull(TargetIndex.A, startCollectCorpse));

            yield return(Toils_Jump.Jump(moveIfCannotHit));

            yield return(startCollectCorpse);

            yield return(Toils_Goto.GotoCell(TargetIndex.A, PathEndMode.ClosestTouch)
                         .FailOnDespawnedNullOrForbidden(TargetIndex.A).FailOnSomeonePhysicallyInteracting(TargetIndex.A));

            yield return(Toils_Haul.StartCarryThing(TargetIndex.A));

            var carryToCell = Toils_Haul.CarryHauledThingToCell(TargetIndex.B);

            yield return(carryToCell);

            yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.B, carryToCell, true));
        }
Пример #3
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            Toil waitLabel = Toils_General.Label();
            Toil endLabel  = Toils_General.Label();

            yield return(Toils_Combat.TrySetJobToUseAttackVerb(TargetIndex.A));

            Toil approach = new Toil();

            approach.initAction = delegate
            {
                Job curJob = pawn.jobs.curJob;

                if (pawn == Victim || Victim == null)
                {
                    pawn.pather.StopDead();
                    ReadyForNextToil();
                }
                else
                {
                    CastPositionRequest newReq = default(CastPositionRequest);
                    newReq.caster              = pawn;
                    newReq.target              = Victim;
                    newReq.verb                = curJob.verbToUse;
                    newReq.maxRangeFromTarget  = (!Victim.Downed ? Mathf.Max(curJob.verbToUse.verbProps.range * maxRangeFactor, 1.42f) : Mathf.Min(curJob.verbToUse.verbProps.range, Victim.RaceProps.executionRange));
                    newReq.wantCoverFromTarget = false;
                    if (CastPositionFinder.TryFindCastPosition(newReq, out var dest))
                    {
                        pawn.pather.StartPath(dest, PathEndMode.OnCell);
                        pawn.Map.pawnDestinationReservationManager.Reserve(pawn, curJob, dest);
                    }
                    //else if (pawn.PositionHeld.DistanceTo(Victim.PositionHeld) <= waitRange)
                    //{
                    //    pawn.pather.StopDead();
                    //    pawn.jobs.curDriver.JumpToToil(waitLabel);
                    //}
                    else
                    {
                        pawn.pather.StartPath(Victim, PathEndMode.Touch);
                    }
                }
            };
            approach.FailOnDespawnedOrNull(VictimIndex);
            approach.defaultCompleteMode = ToilCompleteMode.Delay;
            approach.defaultDuration     = 60;
            yield return(approach);

            yield return(Toils_Jump.Jump(endLabel));

            yield return(waitLabel);

            yield return(Toils_General.Wait(60));

            yield return(endLabel);
        }
Пример #4
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            ToilFailConditions.FailOnDespawnedOrNull(this, TargetIndex.A);
            Pawn prey = this.TargetA.Thing as Pawn;

            if (prey.Dead)
            {
                this.EndJobWith(JobCondition.Succeeded);
            }
            yield return(Toils_Combat.TrySetJobToUseAttackVerb(TargetIndex.A));

            yield return(Toils_Combat.GotoCastPosition(TargetIndex.A, true));

            yield return(Toils_Combat.CastVerb(TargetIndex.A));

            yield break;
        }
Пример #5
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOn(delegate
            {
                if (!job.ignoreDesignations)
                {
                    Pawn victim = Victim;
                    if (victim != null && !victim.Dead && Map.designationManager.DesignationOn(victim, DesignationDefOf.Hunt) == null)
                    {
                        return(true);
                    }
                }
                return(false);
            });

            yield return(Toils_Reserve.Reserve(VictimInd, 1));

            var init = new Toil();

            init.initAction = delegate
            {
                jobStartTick = Find.TickManager.TicksGame;
            };
            yield return(init);

            yield return(Toils_Combat.TrySetJobToUseAttackVerb(TargetIndex.A));

            var comp = (pawn.equipment != null && pawn.equipment.Primary != null) ? pawn.equipment.Primary.TryGetComp <CompAmmoUser>() : null;
            var startCollectCorpse = StartCollectCorpseToil();
            var gotoCastPos        = GotoCastPosition(VictimInd, true).JumpIfDespawnedOrNull(VictimInd, startCollectCorpse).FailOn(() => Find.TickManager.TicksGame > jobStartTick + MaxHuntTicks);

            yield return(gotoCastPos);

            //var moveIfCannotHit = Toils_Jump.JumpIfTargetNotHittable(VictimInd, gotoCastPos);
            var moveIfCannotHit = Toils_Jump.JumpIf(gotoCastPos, delegate
            {
                var verb         = pawn.CurJob.verbToUse;
                var optimalRange = HuntRangePerBodysize(Victim.RaceProps.baseBodySize, Victim.RaceProps.executionRange, verb.verbProps.range);
                if (pawn.Position.DistanceTo(Victim.Position) > optimalRange)
                {
                    return(true);
                }
                return(!verb.CanHitTarget(Victim));
            });

            yield return(moveIfCannotHit);

            yield return(Toils_Jump.JumpIfTargetDespawnedOrNull(VictimInd, startCollectCorpse));

            var startExecuteDowned = Toils_Goto.GotoThing(VictimInd, PathEndMode.Touch).JumpIfDespawnedOrNull(VictimInd, startCollectCorpse);

            yield return(Toils_Jump.JumpIf(startExecuteDowned, () => Victim.Downed && Victim.RaceProps.executionRange <= 2));

            yield return(Toils_Jump.JumpIfTargetDowned(VictimInd, gotoCastPos));

            yield return(Toils_Combat.CastVerb(VictimInd, false).JumpIfDespawnedOrNull(VictimInd, startCollectCorpse)
                         .FailOn(() =>
            {
                if (Find.TickManager.TicksGame <= jobStartTick + MaxHuntTicks)
                {
                    if (comp == null || comp.HasAndUsesAmmoOrMagazine)
                    {
                        return false;
                    }
                }
                return true;
            }));

            yield return(Toils_Jump.Jump(moveIfCannotHit));

            // Execute downed animal - adapted from JobDriver_Slaughter
            yield return(startExecuteDowned);

            yield return(Toils_General.WaitWith(VictimInd, 180, true).JumpIfDespawnedOrNull(VictimInd, startCollectCorpse));

            yield return(new Toil
            {
                initAction = delegate
                {
                    ExecutionUtility.DoExecutionByCut(pawn, Victim);
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            });

            // Haul corpse to stockpile
            yield return(startCollectCorpse);

            yield return(Toils_Goto.GotoCell(VictimInd, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(VictimInd).FailOnSomeonePhysicallyInteracting(VictimInd));

            yield return(Toils_Haul.StartCarryThing(VictimInd));

            var carryToCell = Toils_Haul.CarryHauledThingToCell(StoreCellInd);

            yield return(carryToCell);

            yield return(Toils_Haul.PlaceHauledThingInCell(StoreCellInd, carryToCell, true));
        }
Пример #6
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            AddFailCondition(() => pawn.WorkTagIsDisabled(WorkTags.Violent));

            this.FailOnSomeonePhysicallyInteracting(TargetIndex.A);
            this.FailOnDespawnedNullOrForbidden(TargetIndex.A);
            jobStartTick = Find.TickManager.TicksGame;

            startingEquippedWeapon = pawn.equipment.Primary;
            trainingWeapon         = null;
            if (startingEquippedWeapon == null || !startingEquippedWeapon.def.IsWithinCategory(CombatTrainingDefOf.TrainingWeapons))
            {
                trainingWeapon = GetNearestTrainingWeapon(startingEquippedWeapon);
                if (trainingWeapon != null && !trainingWeapon.IsForbidden(pawn))
                {
                    if (Map.reservationManager.CanReserve(pawn, trainingWeapon))
                    {
                        pawn.Reserve(trainingWeapon, job);
                        job.SetTarget(TargetIndex.B, trainingWeapon);
                        yield return(Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.B));

                        yield return(CreateEquipToil(TargetIndex.B));
                    }
                    if (Map.reservationManager.CanReserve(pawn, startingEquippedWeapon))
                    {
                        pawn.Reserve(startingEquippedWeapon, job);
                        job.SetTarget(TargetIndex.C, startingEquippedWeapon);
                    }
                }
            }
            Toil endOfTraining = Toils_General.Label();
            Toil gotoCastPos   = Toils_Combat.GotoCastPosition(TargetIndex.A, closeIfDowned: true, 0.95f).EndOnDespawnedOrNull(TargetIndex.A);
            Toil ifTrainingDoneJumpToReequip = Toils_Jump.JumpIf(endOfTraining, HasTrainingEnded);
            Toil castVerb = Toils_Combat.CastVerb(TargetIndex.A, canHitNonTargetPawns: false);

            castVerb.AddFinishAction(delegate
            {
                LearnAttackSkill();
            });
            Toil trainingRoomImpressivenessMoodBoost = Toils_General.Do(delegate
            {
                TryGainCombatTrainingRoomThought();
            });
            Toil dropTrainingWeapon = Toils_General.Do(delegate
            {
                pawn.equipment.TryDropEquipment(pawn.equipment.Primary, out _, pawn.Position, forbid: false);
            });
            Toil reequipSwappedStartingWeapon = Toils_General.Do(delegate
            {
                pawn.inventory.innerContainer.Remove(startingEquippedWeapon);
                pawn.equipment.AddEquipment(startingEquippedWeapon);
            });
            Toil jobEndedLabel = Toils_General.Label();


            yield return(Toils_Combat.TrySetJobToUseAttackVerb(TargetIndex.A));

            yield return(gotoCastPos);

            yield return(Toils_Jump.JumpIfTargetNotHittable(TargetIndex.A, gotoCastPos));

            yield return(trainingRoomImpressivenessMoodBoost);

            yield return(ifTrainingDoneJumpToReequip);

            yield return(castVerb);

            yield return(Toils_Jump.Jump(ifTrainingDoneJumpToReequip));

            yield return(endOfTraining);

            if (trainingWeapon != null)
            {
                yield return(dropTrainingWeapon);
            }

            yield return(Toils_Jump.JumpIf(reequipSwappedStartingWeapon, () => pawn.inventory.Contains(startingEquippedWeapon)));

            yield return(Toils_Goto.GotoThing(TargetIndex.C, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.C));

            yield return(CreateEquipToil(TargetIndex.C));

            yield return(Toils_Jump.Jump(jobEndedLabel));

            yield return(reequipSwappedStartingWeapon);

            yield return(jobEndedLabel);
        }
Пример #7
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            Bill bill = job.bill;

            AddEndCondition(delegate
            {
                Thing thing = 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 = job.GetTarget(TargetIndex.A).Thing as IBillGiver;
                if (billGiver != null)
                {
                    if (job.bill.DeletedOrDereferenced)
                    {
                        return(true);
                    }
                    if (!billGiver.CurrentlyUsableForBills())
                    {
                        return(true);
                    }
                }
                return(false);
            });
            AddFinishAction(delegate()
            {
                //Log.Message("LearnWeapon: finishing");
                ThingWithComps thingWithComps = (ThingWithComps)job.targetB.Thing;
                if (pawn.equipment.Primary != null)
                {
                    pawn.equipment.TryDropEquipment(thingWithComps, out thingWithComps, pawn.Position, false);
                }
            });
            Toil gotoBillGiver = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell);

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

            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);

            //temporary equip
            yield return(new Toil
            {
                initAction = delegate()
                {
                    ThingWithComps thingWithComps = (ThingWithComps)job.targetB.Thing;
                    ThingWithComps thingWithComps2;
                    if (thingWithComps.def.stackLimit > 1 && thingWithComps.stackCount > 1)
                    {
                        thingWithComps2 = (ThingWithComps)thingWithComps.SplitOff(1);
                    }
                    else
                    {
                        thingWithComps2 = thingWithComps;
                        thingWithComps2.DeSpawn(DestroyMode.Vanish);
                    }
                    pawn.equipment.MakeRoomFor(thingWithComps2);
                    pawn.equipment.AddEquipment(thingWithComps2);
                    if (thingWithComps.def.soundInteract != null)
                    {
                        thingWithComps.def.soundInteract.PlayOneShot(new TargetInfo(pawn.Position, pawn.Map, false));
                    }
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            });

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

            yield return(gotoBillGiver);

            yield return(Toils_Combat.TrySetJobToUseAttackVerb(TargetIndex.A));

            Toil train = new Toil();

            train.initAction = delegate()
            {
                Pawn     actor  = train.actor;
                Job      curJob = actor.jobs.curJob;
                ThingDef weapon = job.targetB.Thing.def;
                workLeft                  = curJob.bill.recipe.WorkAmountTotal(null);
                billStartTick             = Find.TickManager.TicksGame;
                ticksSpentDoingRecipeWork = 0;
                curJob.bill.Notify_DoBillStarted(actor);
                //sound:
                if (weapon.soundInteract != null)
                {
                    weapon.soundInteract.PlayOneShot(new TargetInfo(pawn.Position, pawn.Map, false));
                }
            };
            train.tickAction = delegate()
            {
                Pawn     actor  = train.actor;
                Job      curJob = actor.jobs.curJob;
                ThingDef weapon = job.targetB.Thing.def;
                ticksSpentDoingRecipeWork++;
                curJob.bill.Notify_PawnDidWork(actor);
                IBillGiverWithTickAction billGiverWithTickAction = train.actor.CurJob.GetTarget(TargetIndex.A).Thing as IBillGiverWithTickAction;
                if (billGiverWithTickAction != null)
                {
                    billGiverWithTickAction.UsedThisTick();
                }
                float num = (curJob.RecipeDef.workSpeedStat != null) ? actor.GetStatValue(curJob.RecipeDef.workSpeedStat, true) : 1f;
                if (curJob.RecipeDef.workTableSpeedStat != null)
                {
                    Building_WorkTable building_WorkTable = BillGiver as Building_WorkTable;
                    if (building_WorkTable != null)
                    {
                        num *= building_WorkTable.GetStatValue(curJob.RecipeDef.workTableSpeedStat, true);
                    }
                }
                if (DebugSettings.fastCrafting)
                {
                    num *= 30f;
                }
                workLeft -= num;
                actor.GainComfortFromCellIfPossible();
                if (workLeft <= 0f)
                {
                    ReadyForNextToil();
                }

                //pawn posture
                Verb            verbToUse = actor.jobs.curJob.verbToUse;
                LocalTargetInfo target    = actor.jobs.curJob.GetTarget(TargetIndex.A);
                pawn.stances.SetStance(new Stance_Warmup(1, target, verbToUse));

                //sound:
                if (verbToUse.verbProps != null && verbToUse.verbProps.warmupTime > 0)
                {
                    if ((ticksSpentDoingRecipeWork % verbToUse.verbProps.AdjustedFullCycleTime(verbToUse, actor).SecondsToTicks()) == 0)
                    {
                        if (verbToUse.verbProps.soundCast != null)
                        {
                            verbToUse.verbProps.soundCast.PlayOneShot(new TargetInfo(pawn.Position, pawn.Map, false));
                        }
                        if (verbToUse.verbProps.soundCastTail != null)
                        {
                            verbToUse.verbProps.soundCastTail.PlayOneShotOnCamera(pawn.Map);
                        }
                    }
                }
                if (job.RecipeDef.workSkill != null)
                {
                    //float xpDelta = techComp.proficientWeapons.Contains(job.targetB.Thing.def) ? 1f : 0.1f;
                    float xp = 0.1f * job.RecipeDef.workSkillLearnFactor;
                    actor.skills.GetSkill(job.RecipeDef.workSkill).Learn(xp, false);
                }
            };
            train.defaultCompleteMode = ToilCompleteMode.Never;
            train.WithEffect(() => train.actor.CurJob.bill.recipe.effectWorking, TargetIndex.A);
            train.PlaySustainerOrSound(() => train.actor.CurJob.bill.recipe.soundWorking);
            train.WithProgressBar(TargetIndex.A, delegate
            {
                Pawn actor = train.actor;
                Job curJob = actor.CurJob;
                //return 1f - ((JobDriver_DoBill)actor.jobs.curDriver).workLeft / curJob.bill.recipe.WorkAmountTotal(null);
                return(1f - (workLeft / curJob.bill.recipe.WorkAmountTotal(null)));
            }, false, -0.5f);
            train.FailOn(() => train.actor.CurJob.bill.suspended);
            train.activeSkill = () => train.actor.CurJob.bill.recipe.workSkill;
            yield return(train.FailOnDespawnedNullOrForbiddenPlacedThings().FailOnCannotTouch(TargetIndex.A, PathEndMode.InteractionCell));

            Toil finalizeTraining = new Toil();

            finalizeTraining.initAction = delegate
            {
                Pawn          actor    = finalizeTraining.actor;
                CompKnowledge techComp = actor.TryGetComp <CompKnowledge>();
                if (!techComp.proficientWeapons.Contains(job.targetB.Thing.def))
                {
                    techComp.proficientWeapons.Add(TargetThingB.def);
                }
                job.bill.Notify_IterationCompleted(actor, new List <Thing> {
                });
                actor.jobs.EndCurrentJob(JobCondition.Succeeded, false);
            };
            finalizeTraining.defaultCompleteMode = ToilCompleteMode.Instant;
            finalizeTraining.FailOnDespawnedOrNull(TargetIndex.A);
            yield return(finalizeTraining);

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

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

            yield return(findPlaceTarget);

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

            yield break;
        }
Пример #8
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            Bill bill = job.bill;

            AddEndCondition(delegate
            {
                Thing thing = 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 = job.GetTarget(TargetIndex.A).Thing as IBillGiver;
                if (billGiver != null)
                {
                    if (job.bill.DeletedOrDereferenced)
                    {
                        return(true);
                    }
                    if (!billGiver.CurrentlyUsableForBills())
                    {
                        return(true);
                    }
                }
                return(false);
            });
            AddFinishAction(delegate()
            {
                if (pawn.equipment.Primary != null && !practice)
                {
                    if (pawn.equipment.Primary == (ThingWithComps)job.targetB.Thing)
                    {
                        ThingWithComps thingWithComps = (ThingWithComps)job.targetB.Thing;
                        pawn.equipment.TryDropEquipment(thingWithComps, out thingWithComps, pawn.Position, false);
                    }
                    if (job.GetTarget(TargetIndex.C).IsValid)
                    {
                        Equip(TargetIndex.C, false);
                    }
                }
            });
            Toil gotoBillGiver = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell);

            if (!practice)
            {
                yield return(Toils_Jump.JumpIf(gotoBillGiver, () => job.GetTargetQueue(TargetIndex.B).NullOrEmpty <LocalTargetInfo>()));

                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(new Toil
                {
                    initAction = delegate()
                    {
                        Equip(TargetIndex.B, true);
                    },
                    defaultCompleteMode = ToilCompleteMode.Instant
                });

                yield return(Toils_Jump.JumpIfHaveTargetInQueue(TargetIndex.B, extract));
            }
            Thing currentWeapon = practice ? pawn.equipment.Primary : job.targetB.Thing;

            yield return(gotoBillGiver);

            yield return(Toils_Combat.TrySetJobToUseAttackVerb(TargetIndex.A));

            yield return(Train(currentWeapon).FailOnDespawnedNullOrForbiddenPlacedThings().FailOnCannotTouch(TargetIndex.A, PathEndMode.InteractionCell));

            yield return(FinalizeTraining());

            yield break;
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOn(delegate()
            {
                if (!this.job.ignoreDesignations)
                {
                    Pawn victim = this.Victim;
                    if (victim != null && !victim.Dead && base.Map.designationManager.DesignationOn(victim, DesignationDefOf.Hunt) == null)
                    {
                        return(true);
                    }
                }
                return(false);
            });
            yield return(new Toil
            {
                initAction = delegate()
                {
                    this.jobStartTick = Find.TickManager.TicksGame;
                }
            });

            yield return(Toils_Combat.TrySetJobToUseAttackVerb(TargetIndex.A));

            Toil startCollectCorpseLabel = Toils_General.Label();
            Toil slaughterLabel          = Toils_General.Label();
            Toil gotoCastPos             = Toils_Combat.GotoCastPosition(TargetIndex.A, true, 0.95f).JumpIfDespawnedOrNull(TargetIndex.A, startCollectCorpseLabel).FailOn(() => Find.TickManager.TicksGame > this.jobStartTick + 5000);

            yield return(gotoCastPos);

            Toil slaughterIfPossible = Toils_Jump.JumpIf(slaughterLabel, delegate
            {
                Pawn victim = this.Victim;
                return((victim.RaceProps.DeathActionWorker == null || !victim.RaceProps.DeathActionWorker.DangerousInMelee) && victim.Downed);
            });

            yield return(slaughterIfPossible);

            yield return(Toils_Jump.JumpIfTargetNotHittable(TargetIndex.A, gotoCastPos));

            yield return(Toils_Combat.CastVerb(TargetIndex.A, false).JumpIfDespawnedOrNull(TargetIndex.A, startCollectCorpseLabel).FailOn(() => Find.TickManager.TicksGame > this.jobStartTick + 5000));

            yield return(Toils_Jump.JumpIfTargetDespawnedOrNull(TargetIndex.A, startCollectCorpseLabel));

            yield return(Toils_Jump.Jump(slaughterIfPossible));

            yield return(slaughterLabel);

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

            yield return(Toils_General.WaitWith(TargetIndex.A, 180, true, false).FailOnMobile(TargetIndex.A));

            yield return(Toils_General.Do(delegate
            {
                if (this.Victim.Dead)
                {
                    return;
                }
                ExecutionUtility.DoExecutionByCut(this.pawn, this.Victim);
                this.pawn.records.Increment(RecordDefOf.AnimalsSlaughtered);
                if (this.pawn.InMentalState)
                {
                    this.pawn.MentalState.Notify_SlaughteredAnimal();
                }
            }));

            yield return(Toils_Jump.Jump(startCollectCorpseLabel));

            yield return(startCollectCorpseLabel);

            yield return(this.StartCollectCorpseToil());

            yield return(Toils_Goto.GotoCell(TargetIndex.A, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.A).FailOnSomeonePhysicallyInteracting(TargetIndex.A));

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

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

            yield return(carryToCell);

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

            yield break;
        }
            public bool MoveNext()
            {
                uint num = (uint)this.$PC;

                this.$PC = -1;
                switch (num)
                {
                case 0u:
                {
                    this.FailOn(delegate()
                        {
                            if (!this.job.ignoreDesignations)
                            {
                                Pawn victim = base.Victim;
                                if (victim != null && !victim.Dead && base.Map.designationManager.DesignationOn(victim, DesignationDefOf.Hunt) == null)
                                {
                                    return(true);
                                }
                            }
                            return(false);
                        });
                    Toil init = new Toil();
                    init.initAction = delegate()
                    {
                        this.jobStartTick = Find.TickManager.TicksGame;
                    };
                    this.$current = init;
                    if (!this.$disposing)
                    {
                        this.$PC = 1;
                    }
                    return(true);
                }

                case 1u:
                    this.$current = Toils_Combat.TrySetJobToUseAttackVerb(TargetIndex.A);
                    if (!this.$disposing)
                    {
                        this.$PC = 2;
                    }
                    return(true);

                case 2u:
                    startCollectCorpseLabel = Toils_General.Label();
                    slaughterLabel          = Toils_General.Label();
                    gotoCastPos             = Toils_Combat.GotoCastPosition(TargetIndex.A, true, 0.95f).JumpIfDespawnedOrNull(TargetIndex.A, startCollectCorpseLabel).FailOn(() => Find.TickManager.TicksGame > this.jobStartTick + 5000);
                    this.$current           = gotoCastPos;
                    if (!this.$disposing)
                    {
                        this.$PC = 3;
                    }
                    return(true);

                case 3u:
                    slaughterIfPossible = Toils_Jump.JumpIf(slaughterLabel, delegate
                    {
                        Pawn victim = base.Victim;
                        return((victim.RaceProps.DeathActionWorker == null || !victim.RaceProps.DeathActionWorker.DangerousInMelee) && victim.Downed);
                    });
                    this.$current = slaughterIfPossible;
                    if (!this.$disposing)
                    {
                        this.$PC = 4;
                    }
                    return(true);

                case 4u:
                    this.$current = Toils_Jump.JumpIfTargetNotHittable(TargetIndex.A, gotoCastPos);
                    if (!this.$disposing)
                    {
                        this.$PC = 5;
                    }
                    return(true);

                case 5u:
                    this.$current = Toils_Combat.CastVerb(TargetIndex.A, false).JumpIfDespawnedOrNull(TargetIndex.A, startCollectCorpseLabel).FailOn(() => Find.TickManager.TicksGame > this.jobStartTick + 5000);
                    if (!this.$disposing)
                    {
                        this.$PC = 6;
                    }
                    return(true);

                case 6u:
                    this.$current = Toils_Jump.JumpIfTargetDespawnedOrNull(TargetIndex.A, startCollectCorpseLabel);
                    if (!this.$disposing)
                    {
                        this.$PC = 7;
                    }
                    return(true);

                case 7u:
                    this.$current = Toils_Jump.Jump(slaughterIfPossible);
                    if (!this.$disposing)
                    {
                        this.$PC = 8;
                    }
                    return(true);

                case 8u:
                    this.$current = slaughterLabel;
                    if (!this.$disposing)
                    {
                        this.$PC = 9;
                    }
                    return(true);

                case 9u:
                    this.$current = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch).FailOnMobile(TargetIndex.A);
                    if (!this.$disposing)
                    {
                        this.$PC = 10;
                    }
                    return(true);

                case 10u:
                    this.$current = Toils_General.WaitWith(TargetIndex.A, 180, true, false).FailOnMobile(TargetIndex.A);
                    if (!this.$disposing)
                    {
                        this.$PC = 11;
                    }
                    return(true);

                case 11u:
                    this.$current = Toils_General.Do(delegate
                    {
                        if (base.Victim.Dead)
                        {
                            return;
                        }
                        ExecutionUtility.DoExecutionByCut(this.pawn, base.Victim);
                        this.pawn.records.Increment(RecordDefOf.AnimalsSlaughtered);
                        if (this.pawn.InMentalState)
                        {
                            this.pawn.MentalState.Notify_SlaughteredAnimal();
                        }
                    });
                    if (!this.$disposing)
                    {
                        this.$PC = 12;
                    }
                    return(true);

                case 12u:
                    this.$current = Toils_Jump.Jump(startCollectCorpseLabel);
                    if (!this.$disposing)
                    {
                        this.$PC = 13;
                    }
                    return(true);

                case 13u:
                    this.$current = startCollectCorpseLabel;
                    if (!this.$disposing)
                    {
                        this.$PC = 14;
                    }
                    return(true);

                case 14u:
                    this.$current = base.StartCollectCorpseToil();
                    if (!this.$disposing)
                    {
                        this.$PC = 15;
                    }
                    return(true);

                case 15u:
                    this.$current = Toils_Goto.GotoCell(TargetIndex.A, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.A).FailOnSomeonePhysicallyInteracting(TargetIndex.A);
                    if (!this.$disposing)
                    {
                        this.$PC = 16;
                    }
                    return(true);

                case 16u:
                    this.$current = Toils_Haul.StartCarryThing(TargetIndex.A, false, false, false);
                    if (!this.$disposing)
                    {
                        this.$PC = 17;
                    }
                    return(true);

                case 17u:
                    carryToCell   = Toils_Haul.CarryHauledThingToCell(TargetIndex.B);
                    this.$current = carryToCell;
                    if (!this.$disposing)
                    {
                        this.$PC = 18;
                    }
                    return(true);

                case 18u:
                    this.$current = Toils_Haul.PlaceHauledThingInCell(TargetIndex.B, carryToCell, true);
                    if (!this.$disposing)
                    {
                        this.$PC = 19;
                    }
                    return(true);

                case 19u:
                    this.$PC = -1;
                    break;
                }
                return(false);
            }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            //fail if can't do violence
            base.AddFailCondition(delegate
            {
                return(this.pawn.WorkTagIsDisabled(WorkTags.Violent));
            });

            this.jobStartTick = Find.TickManager.TicksGame;

            Func <bool> designationValidator = () => !(
                // Dummy must have the any designation
                TargetThingA.HasDesignation(CombatTrainingDefOf.TrainCombatDesignation)
                ||
                // Dummy must have the melee designation, and the pawn has a melee weapon held
                TargetThingA.HasDesignation(CombatTrainingDefOf.TrainCombatDesignationMeleeOnly) &&
                pawn.equipment.Primary.def.IsMeleeWeapon
                ||
                // Dummy must have the ranged designation, and the pawn has a ranged weapon held
                TargetThingA.HasDesignation(CombatTrainingDefOf.TrainCombatDesignationRangedOnly) &&
                pawn.equipment.Primary.def.IsRangedWeapon
                ||
                // Dummy must have any designation, and the pawn is unarmed.
                (TargetThingA.HasDesignation(CombatTrainingDefOf.TrainCombatDesignation) ||
                 TargetThingA.HasDesignation(CombatTrainingDefOf.TrainCombatDesignationMeleeOnly) ||
                 TargetThingA.HasDesignation(CombatTrainingDefOf.TrainCombatDesignationRangedOnly)) &&
                pawn.equipment.Primary == null);

            //make sure thing has train combat designation
            if (designationValidator())
            {
                yield break;
            }

            // Make sure our dummy isn't already in use
            this.FailOnSomeonePhysicallyInteracting(TargetIndex.A);

            //fail if dummy is despawned null or forbidden
            this.FailOnDespawnedNullOrForbidden(TargetIndex.A);

            /**** START SWITCH TO TRAINING WEAPON ****/
            //Pick up a training weapon if one is nearby. Remember previous weapon
            ThingWithComps startingEquippedWeapon = this.pawn.equipment.Primary;
            ThingWithComps trainingWeapon         = null;

            if (startingEquippedWeapon == null || !startingEquippedWeapon.def.IsWithinCategory(CombatTrainingDefOf.TrainingWeapons))
            {
                trainingWeapon = GetNearestTrainingWeapon(startingEquippedWeapon);
                if (trainingWeapon != null && !trainingWeapon.IsForbidden(pawn))
                {
                    //reserve training weapon, goto, and equip
                    if (this.Map.reservationManager.CanReserve(this.pawn, trainingWeapon, 1, -1, null, false))
                    {
                        this.pawn.Reserve(trainingWeapon, this.job, 1, -1, null, true);
                        this.job.SetTarget(TargetIndex.B, trainingWeapon);
                        yield return(Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.B));

                        yield return(CreateEquipToil(TargetIndex.B));
                    }

                    //reserve previous weapon and set as target c
                    if (this.Map.reservationManager.CanReserve(this.pawn, startingEquippedWeapon, 1, -1, null, false))
                    {
                        this.pawn.Reserve(startingEquippedWeapon, this.job, 1, -1, null, true);
                        this.job.SetTarget(TargetIndex.C, startingEquippedWeapon);
                    }
                }
            }
            Toil reequipStartingWeaponLabel = Toils_General.Label();

            /**** END SWITCH TO TRAINING WEAPON ****/

            //set the job's attack verb to melee or shooting - needed to gotoCastPosition or stack overflow occurs
            yield return(Toils_Combat.TrySetJobToUseAttackVerb(TargetIndex.A));

            //based on attack verb, go to cast position
            Toil gotoCastPos = Toils_Combat.GotoCastPosition(TargetIndex.A, true, 0.95f).EndOnDespawnedOrNull(TargetIndex.A);

            yield return(gotoCastPos);

            //try going to new cast position if the target can't be hit from current position
            yield return(Toils_Jump.JumpIfTargetNotHittable(TargetIndex.A, gotoCastPos));

            //training loop - jump if done training -> cast verb -> jump to done training
            //if done training jumnp to reequipStartingWeaponLabel
            Toil doneTraining = Toils_Jump.JumpIf(reequipStartingWeaponLabel, delegate
            {
                if (LearningSaturated())
                {
                    return(true);
                }
                else
                {
                    return(Dummy.Destroyed || Find.TickManager.TicksGame > this.jobStartTick + 5000 || designationValidator());
                }
            });

            yield return(doneTraining);

            Toil castVerb = Toils_Combat.CastVerb(TargetIndex.A, false);

            castVerb.AddFinishAction(delegate
            {
                LearnAttackSkill();
            });
            yield return(castVerb);

            yield return(Toils_Jump.Jump(doneTraining));

            yield return(reequipStartingWeaponLabel);

            //gain room buff
            yield return(Toils_General.Do(delegate
            {
                TryGainCombatTrainingRoomThought();
            }));

            //equip strating weapon
            if (trainingWeapon != null && startingEquippedWeapon != null)
            {
                yield return(Toils_Goto.GotoThing(TargetIndex.C, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.C));

                yield return(CreateEquipToil(TargetIndex.C));
            }
            yield break;
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            var checkIncaseJobWasCancelledPreviously = new Toil
            {
                initAction = () =>
                {
                    var curMap     = this.GetActor().MapHeld;
                    var lastCorpse = curMap.listerThings.AllThings.FirstOrDefault(x =>
                                                                                  x is Corpse c && c.InnerPawn.health.hediffSet.HasHediff(UvhashDefOf.Uvhash_TattooParalysis));
                    if (lastCorpse != null)
                    {
                        this.job.SetTarget(TargetIndex.A, lastCorpse);
                    }
                }
            };

            var prepareToTransformCorpse = new Toil();

            prepareToTransformCorpse.initAction = delegate
            {
                Pawn   actor  = prepareToTransformCorpse.actor;
                Corpse corpse = this.Corpse;
                if (corpse == null)
                {
                    Pawn prey = this.Prey;
                    if (prey == null)
                    {
                        actor.jobs.EndCurrentJob(JobCondition.Incompletable, true);
                        return;
                    }
                    corpse = prey.Corpse;
                    if (corpse == null || !corpse.Spawned)
                    {
                        actor.jobs.EndCurrentJob(JobCondition.Incompletable, true);
                        return;
                    }
                }
                corpse.SetForbidden(actor.Faction != Faction.OfPlayer, false);
                actor.CurJob.SetTarget(TargetIndex.A, corpse);
            };
            var goToCorpse      = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch);
            var goToPreyPos     = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch);
            var gotoCastPos     = Toils_Combat.GotoCastPosition(TargetIndex.A, true).JumpIfDespawnedOrNull(TargetIndex.A, prepareToTransformCorpse).FailOn(() => Find.TickManager.TicksGame > this.jobStartTick + 5000);
            var moveIfCannotHit = Toils_Jump.JumpIfTargetNotHittable(TargetIndex.A, goToPreyPos);
            var castSpell       = new Toil {
                defaultCompleteMode = ToilCompleteMode.Delay
            };

            castSpell.WithProgressBarToilDelay(TargetIndex.A);
            castSpell.defaultDuration = 1200;
            castSpell.AddPreInitAction(() =>
            {
                curReport  = "BloodMage_CastingOn".Translate(TargetA.Thing.Label);
                moteThrown = UvhashUtility.ThrowMagicMote(1f, this.GetActor());
                moteThrown.LifeSpanOffset += 99999f;
                moteTarget.LifeSpanOffset += 99999f;
                moteTarget = UvhashUtility.ThrowMagicMote(TargetA.Thing.def.race.baseBodySize, TargetA.Thing);
            });
            castSpell.tickAction = () =>
            {
                if (moteThrown != null)
                {
                    moteThrown.exactPosition = this.GetActor().DrawPos;
                }
                if (moteTarget != null)
                {
                    moteTarget.exactPosition = TargetA.Thing.DrawPos;
                }
                if (Find.TickManager.TicksGame % 15 == 0)
                {
                    MoteMaker.ThrowText(this.GetActor().DrawPos + new Vector3(new FloatRange(-1, 1).RandomInRange, 0, new FloatRange(-1, 1).RandomInRange), this.GetActor().MapHeld, cultMadText.RandomElement(), Color.red);
                    //MoteMaker.ThrowText(this.TargetA.Thing.DrawPos + new Vector3(new FloatRange(-1, 1).RandomInRange, 0, new FloatRange(-1, 1).RandomInRange), this.GetActor().MapHeld, cultMadText.RandomElement(), Color.red);
                }
            };
            castSpell.PlaySustainerOrSound(UvhashDefOf.Uvhash_BloodMagicCastingSustainer);
            castSpell.AddFinishAction(() =>
            {
                if (!Prey.Downed)
                {
                    HealthUtility.AdjustSeverity(Prey, UvhashDefOf.Uvhash_TattooParalysis, 1.0f);
                }
                curReport = "";
                if (moteThrown != null)
                {
                    moteThrown.LifeSpanOffset -= 999999f;
                }
                if (moteTarget != null)
                {
                    moteTarget.LifeSpanOffset -= 999999f;
                }
            });
            var executeTarget = new Toil {
                defaultCompleteMode = ToilCompleteMode.Delay
            };

            executeTarget.WithProgressBarToilDelay(TargetIndex.B);
            executeTarget.defaultDuration = 200;
            executeTarget.AddFinishAction(() =>
            {
                ExecutionUtility.DoExecutionByCut(this.GetActor(), Prey);
            });
            Toil transformCorpse = new Toil();

            transformCorpse.defaultCompleteMode = ToilCompleteMode.Delay;
            transformCorpse.WithEffect(() => EffecterDef.Named("ButcherFlesh"), TargetIndex.A);
            transformCorpse.WithProgressBarToilDelay(TargetIndex.A);
            transformCorpse.defaultDuration = 800;
            transformCorpse.AddPreInitAction(() =>
            {
                Messages.Message("BloodBookCreation_Message".Translate(new object[] { this.pawn.LabelCap, this.Prey.Label }), MessageTypeDefOf.NeutralEvent);
            });
            var destroyCorpseAndSpawnBook = new Toil();

            destroyCorpseAndSpawnBook.initAction = () =>
            {
                var corpsePos = Corpse.PositionHeld;
                var corpseMap = Corpse.MapHeld;
                Corpse.Destroy();
                FilthMaker.MakeFilth(corpsePos, corpseMap, ThingDefOf.FilthBlood, Rand.Range(1, 2));
                for (int i = 0; i < 10; i++)
                {
                    FilthMaker.MakeFilth(corpsePos.RandomAdjacentCell8Way(), corpseMap, ThingDefOf.FilthBlood, Rand.Range(1, 2));
                    this.GetActor().filth.GainFilth(ThingDefOf.FilthBlood);
                }
                var book = (ThingWithComps_LiberCruoris)ThingMaker.MakeThing(UvhashDefOf.Uvhash_LiberCruoris);
                GenPlace.TryPlaceThing(book, corpsePos, corpseMap, ThingPlaceMode.Near);

                Find.World.GetComponent <WorldComponent_Uvhash>().CurrentCrystalStage = CrystalStage.BookCreated;
                this.GetActor().MentalState.RecoverFromState();
                this.GetActor().TryGetComp <CompBloodMage>().BloodMageLevel = 1;
                UvhashUtility.ShowMessageBox("BloodBookCreatedDesc".Translate(this.GetActor()).AdjustedFor(this.GetActor()), "BloodBookCreated".Translate());
            };

            yield return(new Toil
            {
                initAction = delegate
                {
                    this.jobStartTick = Find.TickManager.TicksGame;
                }
            });

            yield return(checkIncaseJobWasCancelledPreviously);

            yield return(Toils_Jump.JumpIf(goToCorpse, () => Prey.Dead));

            yield return(Toils_Jump.JumpIf(goToPreyPos, () => Prey.Downed));

            yield return(Toils_Combat.TrySetJobToUseAttackVerb());

            yield return(gotoCastPos.FailOn(() => this.GetActor().IsFighting()));

            yield return(castSpell);

            yield return(goToPreyPos);

            yield return(executeTarget);

            yield return(prepareToTransformCorpse);

            yield return(goToCorpse);

            yield return(transformCorpse);

            yield return(destroyCorpseAndSpawnBook);

            this.AddFinishAction(() =>
            {
                if (moteThrown != null)
                {
                    moteThrown.LifeSpanOffset -= 999999f;
                }
                if (moteTarget != null)
                {
                    moteTarget.LifeSpanOffset -= 999999f;
                }
            });
            yield break;
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            Toil startJobToil = new Toil();

            startJobToil.initAction = delegate
            {
                jobStartTick = Find.TickManager.TicksGame;
            };
            yield return(startJobToil);

            yield return(Toils_Combat.TrySetJobToUseAttackVerb(TargetIndex.A));

            Toil startCollectCorpseLabel = Toils_General.Label();
            Toil slaughterLabel          = Toils_General.Label();
            Toil meleeLabel = Toils_General.Label();

            Toil checkTargetToil = new Toil();

            checkTargetToil.initAction = delegate
            {
                targetCheckTick = Find.TickManager.TicksGame;

                //if (pawn.equipment.Primary == null || pawn.equipment.Primary.def.IsMeleeWeapon)
                //    pawn.jobs.curDriver.JumpToToil(meleeLabel);
            };
            yield return(checkTargetToil);

            //Toil gotoCastPos = Toils_Combat.GotoCastPosition(TargetIndex.A, true, 0.95f).JumpIfDespawnedOrNull(TargetIndex.A, startCollectCorpseLabel).FailOn(() => Find.TickManager.TicksGame > jobStartTick + 5000);
            Toil gotoCastPos = Toils_Combat.GotoCastPosition(TargetIndex.A, true, 4.0f)
                               .JumpIfDespawnedOrNull(TargetIndex.A, startCollectCorpseLabel)
                               .JumpIf(() => Find.TickManager.TicksGame > targetCheckTick + targetCheckInterval, checkTargetToil);

            yield return(gotoCastPos);

            Toil selectAttack = new Toil();

            selectAttack.initAction = delegate
            {
                if (pawn.CanReachImmediate(TargetA, PathEndMode.Touch))
                {
                    pawn.jobs.curDriver.JumpToToil(meleeLabel);
                }
                else if (Victim.Downed)
                {
                    if (Victim.AnimalOrWildMan())
                    {
                        pawn.jobs.curDriver.JumpToToil(slaughterLabel);
                    }
                    else
                    {
                        pawn.jobs.curDriver.JumpToToil(meleeLabel);
                    }
                }
            };
            yield return(selectAttack);

            // Ranged attack
            yield return(Toils_Jump.JumpIfTargetNotHittable(TargetIndex.A, checkTargetToil));

            yield return(Toils_Combat.CastVerb(TargetIndex.A, canHitNonTargetPawns: false).JumpIfDespawnedOrNull(TargetIndex.A, startCollectCorpseLabel).FailOn(() => Find.TickManager.TicksGame > jobStartTick + 5000));

            yield return(Toils_Jump.JumpIfTargetDespawnedOrNull(TargetIndex.A, startCollectCorpseLabel));

            yield return(Toils_Jump.Jump(selectAttack));

            // Melee
            yield return(meleeLabel);

            yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch).JumpIf(() => Find.TickManager.TicksGame > targetCheckTick + targetCheckInterval, checkTargetToil));

            //yield return Toils_Goto.GotoCell(TargetIndex.A, PathEndMode.OnCell).JumpIf(() => Find.TickManager.TicksGame > targetCheckTick + targetCheckInterval, checkTargetToil);
            Toil meleeAttack = new Toil();

            meleeAttack.tickAction = delegate
            {
                if (Victim == null || !Victim.Spawned || Victim.IsForbidden(pawn) || !pawn.CanReachImmediate(TargetA, PathEndMode.Touch))
                {
                    pawn.jobs.curDriver.JumpToToil(checkTargetToil);
                }
                else if (Victim.Downed && Victim.AnimalOrWildMan())
                {
                    pawn.jobs.curDriver.JumpToToil(slaughterLabel);
                }

                pawn.pather.StopDead();
                pawn.meleeVerbs.TryMeleeAttack(Victim);
            };
            meleeAttack.activeSkill         = () => SkillDefOf.Melee;
            meleeAttack.defaultCompleteMode = ToilCompleteMode.Never;
            yield return(meleeAttack);

            yield return(Toils_Jump.JumpIfCannotTouch(TargetIndex.A, PathEndMode.Touch, checkTargetToil));

            // Slaughter target
            yield return(slaughterLabel);

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

            yield return(Toils_General.WaitWith(TargetIndex.A, 180, useProgressBar: true).FailOnMobile(TargetIndex.A));

            yield return(Toils_General.Do(delegate
            {
                if (!Victim.Dead)
                {
                    ExecutionUtility.DoExecutionByCut(pawn, Victim);
                    pawn.records.Increment(RecordDefOf.AnimalsSlaughtered);
                    if (pawn.InMentalState)
                    {
                        pawn.MentalState.Notify_SlaughteredAnimal();
                    }
                }
            }));

            yield return(Toils_Jump.Jump(startCollectCorpseLabel));

            yield return(startCollectCorpseLabel);

            //yield return Toils_Misc.ThrowColonistAttackingMote(TargetIndex.A);
            //yield return Toils_Combat.FollowAndMeleeAttack(TargetIndex.A, delegate
            //{
            //    Thing thing = job.GetTarget(TargetIndex.A).Thing;
            //    Pawn p;
            //    if (job.reactingToMeleeThreat && (p = thing as Pawn) != null && !p.Awake())
            //    {
            //        EndJobWith(JobCondition.InterruptForced);
            //    }
            //    else if (pawn.meleeVerbs.TryMeleeAttack(thing, job.verbToUse) && pawn.CurJob != null && pawn.jobs.curDriver == this)
            //    {
            //        numMeleeAttacksMade++;
            //        if (numMeleeAttacksMade >= job.maxNumMeleeAttacks)
            //        {
            //            EndJobWith(JobCondition.Succeeded);
            //        }
            //    }
            //}).FailOnDespawnedOrNull(TargetIndex.A);
        }