// this allow the work giver to be present in both drafted and undrafted float menus
 public static FloatMenuOption InjectThingFloatOptionIfNeeded(Thing target, Pawn selPawn)
 {
     if (Designator_FinishOff.IsValidDesignationTarget(target))
     {
         if (WorkGiverEnabled)
         {
             JobFailReason.Clear();
             var giver = new WorkGiver_FinishOff {
                 def = AllowToolDefOf.FinishOff
             };
             var job = giver.JobOnThing(selPawn, target, true);
             var opt = new FloatMenuOption("Finish_off_floatMenu".Translate(target.LabelShort), () => {
                 selPawn.jobs.TryTakeOrderedJobPrioritizedWork(job, giver, target.Position);
             });
             opt = FloatMenuUtility.DecoratePrioritizedTask(opt, selPawn, target);
             if (job == null)
             {
                 opt.Disabled = true;
                 if (JobFailReason.HaveReason)
                 {
                     opt.Label = "CannotGenericWork".Translate(giver.def.verb, target.LabelShort) + " (" + JobFailReason.Reason + ")";
                 }
             }
             return(opt);
         }
     }
     return(null);
 }
Example #2
0
        public static void DoBehaviorForPawn(JobDriver_Wait driver)
        {
            var hunter = driver.pawn;

            if (!AllowToolController.Instance.Handles.PartyHuntSetting || !WorldSettings.PawnIsPartyHunting(hunter))
            {
                return;
            }
            var verb = hunter.TryGetAttackVerb(null, !hunter.IsColonist);

            if (hunter.Faction != null &&
                driver.job.def == JobDefOf.Wait_Combat &&
                AllowToolUtility.PawnCapableOfViolence(hunter) &&
                !hunter.stances.FullBodyBusy)
            {
                // fire at target
                if (hunter.drafter.FireAtWill)
                {
                    // fudge melee range for easier target acquisition
                    var weaponRange = verb.verbProps.IsMeleeAttack ? 2 : verb.verbProps.range;
                    var target      = TryFindHuntingTarget(hunter, verb.verbProps.minRange, weaponRange, HuntingTargetAttackFilter);
                    if (target != null)
                    {
                        hunter.TryStartAttack(target);
                        ResetAutoUndraftTimer(hunter.drafter);
                        if (target.Dead && WorldSettings.UnforbidDrops)
                        {
                            target.Corpse?.SetForbidden(false, false);
                        }
                    }
                }

                // finish off targets. Wait for everyone to finish firing to avoid catching stray bullets
                if (!hunter.stances.FullBodyBusy && WorldSettings.AutoFinishOff &&
                    CanDoCommonerWork(hunter) && !AnyHuntingPartyMembersInCombat(hunter, MaxPartyMemberDistance))
                {
                    // try mark a downed animal
                    var target = TryFindHuntingTarget(hunter, 0, MaxFinishOffDistance, HuntingTargetFinishFilter);
                    if (target != null)
                    {
                        target.ToggleDesignation(AllowToolDefOf.FinishOffDesignation, true);
                    }
                    // query work giver for finish off job in range
                    var job = WorkGiver_FinishOff.CreateInstance().TryGetJobInRange(hunter, MaxFinishOffDistance);
                    if (job != null)
                    {
                        hunter.jobs.StartJob(job, JobCondition.Ongoing, null, true);
                        if (hunter.jobs.curDriver is JobDriver_FinishOff jdfo && WorldSettings.UnforbidDrops)
                        {
                            jdfo.UnforbidBody = true;
                        }
                        // return to starting position
                        hunter.jobs.jobQueue.EnqueueFirst(JobMaker.MakeJob(JobDefOf.Goto, hunter.Position));
                    }
                }
            }
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            if (job.playerForced)
            {
                TargetA.Thing.ToggleDesignation(AllowToolDefOf.FinishOffDesignation, true);
            }
            AddFailCondition(JobHasFailed);
            yield return(Toils_Misc.ThrowColonistAttackingMote(TargetIndex.A));

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

            Thing skullMote = null;

            yield return(new Toil {
                initAction = () => {
                    var victim = job.targetA.Thing as Pawn;
                    skullMote = TryMakeSkullMote(victim, VictimSkullMoteChance);
                    AllowToolDefOf.EffecterWeaponGlint.Spawn().Trigger(pawn, job.targetA.Thing);
                },
                defaultDuration = PrepareSwingDuration,
                defaultCompleteMode = ToilCompleteMode.Delay
            });

            yield return(new Toil {
                initAction = () => {
                    var victim = job.targetA.Thing as Pawn;
                    if (victim == null || job.verbToUse == null)
                    {
                        return;
                    }
                    job.verbToUse.TryStartCastOn(victim);
                    DoSocialImpact(victim);
                    DoExecution(pawn, victim);
                    if (skullMote != null && !skullMote.Destroyed)
                    {
                        skullMote.Destroy();
                    }
                    // look for a target of opportunity nearby before moving on
                    // needed by drafted hunters. Their finish off job was not work-related, so they need to be fed a new opportunity job manually
                    if (!job.playerForced)
                    {
                        var opportunityJob = WorkGiver_FinishOff.CreateInstance().TryGetJobInRange(pawn, OpportunityTargetMaxRange);
                        if (opportunityJob != null)
                        {
                            pawn.jobs.jobQueue.EnqueueFirst(opportunityJob);
                        }
                    }
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            });
        }