// 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));
        }
Esempio n. 2
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOn(delegate
            {
                if (!this.$this.job.ignoreDesignations)
                {
                    Pawn victim = this.$this.Victim;
                    if (victim != null && !victim.Dead && this.$this.Map.designationManager.DesignationOn(victim, DesignationDefOf.Hunt) == null)
                    {
                        return(true);
                    }
                }
                return(false);
            });
            yield return(new Toil
            {
                initAction = delegate
                {
                    this.$this.jobStartTick = Find.TickManager.TicksGame;
                }
            });

            yield return(Toils_Combat.TrySetJobToUseAttackVerb());

            Toil startCollectCorpse = this.StartCollectCorpseToil();
            Toil gotoCastPos        = Toils_Combat.GotoCastPosition(TargetIndex.A, true).JumpIfDespawnedOrNull(TargetIndex.A, startCollectCorpse).FailOn(() => Find.TickManager.TicksGame > this.$this.jobStartTick + 5000);

            yield return(gotoCastPos);

            Toil moveIfCannotHit = Toils_Jump.JumpIfTargetNotHittable(TargetIndex.A, gotoCastPos);

            yield return(moveIfCannotHit);

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

            yield return(Toils_Combat.CastVerb(TargetIndex.A, false).JumpIfDespawnedOrNull(TargetIndex.A, startCollectCorpse).FailOn(() => Find.TickManager.TicksGame > this.$this.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, false, false, false));

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

            yield return(carryToCell);

            yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.B, carryToCell, true));
        }
Esempio n. 3
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);
        }
        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);
        }