Пример #1
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));
        }