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