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