// 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 = CreateInstance();
                    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, target) + " (" + JobFailReason.Reason + ")";
                        }
                    }

                    return(opt);
                }
            }

            return(null);
        }
        private static void CleanupDesignations(Map map)
        {
            if (map.designationManager == null)
            {
                return;
            }
            var mapDesignations = map.designationManager.allDesignations;

            for (int i = 0; i < mapDesignations.Count; i++)
            {
                var des      = mapDesignations[i];
                var desThing = des.target.Thing;
                if (desThing != null &&
                    ((des.def == AllowToolDefOf.FinishOffDesignation && !Designator_FinishOff.IsValidDesignationTarget(des.target.Thing)) ||
                     (des.def == AllowToolDefOf.HaulUrgentlyDesignation && desThing.IsInValidBestStorage())
                    ))
                {
                    cleanupList.Enqueue(des);
                }
            }
            while (cleanupList.Count > 0)
            {
                var des = cleanupList.Dequeue();
                des.designationManager.RemoveDesignation(des);
            }
        }
        private static void CleanupFinishOffDesignations()
        {
            var maps = Find.Maps;
            List <Designation> cleanupList = null;

            for (int i = 0; i < maps.Count; i++)
            {
                var map = maps[i];
                if (map.designationManager == null)
                {
                    continue;
                }
                var mapDesignations = map.designationManager.allDesignations;
                for (int j = 0; j < mapDesignations.Count; j++)
                {
                    var des = mapDesignations[j];
                    if (des.def == AllowToolDefOf.FinishOffDesignation && !Designator_FinishOff.IsValidDesignationTarget(des.target.Thing))
                    {
                        if (cleanupList == null)
                        {
                            cleanupList = new List <Designation>();
                        }
                        cleanupList.Add(des);
                    }
                }
            }
            if (cleanupList != null)
            {
                foreach (var designation in cleanupList)
                {
                    designation.designationManager.RemoveDesignation(designation);
                }
            }
        }
        private IEnumerable <Thing> GetPotentialTargets(Pawn pawn)
        {
            // enumerate all downed pawns to allow forcing the job without a designation
            var pawns = pawn.Map.mapPawns.AllPawnsSpawned;

            for (var i = 0; i < pawns.Count; i++)
            {
                var target = pawns[i];
                if (Designator_FinishOff.IsValidDesignationTarget(target))
                {
                    yield return(target);
                }
            }
        }
 public override IEnumerable <Thing> PotentialWorkThingsGlobal(Pawn pawn)
 {
     // enumerate all downed pawns to allow forcing the job without a designation
     if (WorkGiverEnabled)
     {
         var pawns = pawn.Map.mapPawns.AllPawnsSpawned;
         for (int i = 0; i < pawns.Count; i++)
         {
             var target = pawns[i];
             if (Designator_FinishOff.IsValidDesignationTarget(target))
             {
                 yield return(target);
             }
         }
     }
 }
        public override Job JobOnThing(Pawn pawn, Thing t, bool forced = false)
        {
            if (Designator_FinishOff.IsValidDesignationTarget(t))
            {
                if (pawn.CanReserveAndReach(t, PathEndMode.Touch, Danger.Deadly))
                {
                    var friendlyReport = Designator_FinishOff.FriendlyPawnIsValidTarget(t);
                    if (forced && !friendlyReport.Accepted)
                    {
                        // ignore if not forced- only designated targets will be picked in this case
                        JobFailReason.Is(friendlyReport.Reason);
                    }
                    else
                    {
                        var skillReport = Designator_FinishOff.PawnMeetsSkillRequirement(pawn);
                        if (!skillReport.Accepted)
                        {
                            JobFailReason.Is(skillReport.Reason);
                        }
                        else
                        {
                            if (forced || t.HasDesignation(AllowToolDefOf.FinishOffDesignation))
                            {
                                // ignore designation if forced- driver will add the designation
                                var verb = pawn.meleeVerbs != null?pawn.meleeVerbs.TryGetMeleeVerb() : null;

                                if (verb != null)
                                {
                                    return(new Job(AllowToolDefOf.FinishOffPawn, t)
                                    {
                                        verbToUse = verb,
                                        killIncappedTarget = true
                                    });
                                }
                            }
                        }
                    }
                }
            }
            return(null);
        }