Example #1
0
 private bool PawnCanUseWorkGiver(Pawn pawn, WorkGiver giver)
 {
     if (giver.ShouldSkip(pawn))
     {
         return(false);
     }
     if (pawn.story != null && pawn.story.WorkTagIsDisabled(giver.def.workTags))
     {
         return(false);
     }
     if (giver.MissingRequiredCapacity(pawn) != null)
     {
         return(false);
     }
     return(true);
 }
Example #2
0
        public static Profiler Start(WorkGiver giver)
        {
            if (!Active)
            {
                return(null);
            }

            wg = giver;

            CurrentKey = string.Empty;

            if (ByWorkType)
            {
                CurrentKey = giver.def.workType.defName;
            }
            else
            {
                CurrentKey = giver.def.defName;
            }
            if (PerPawn)
            {
                CurrentKey = string.Intern(CurrentKey + pawnname);
            }

            if (!meths.TryGetValue(giver, out var meth))
            {
                if (giver is WorkGiver_Scanner)
                {
                    if (giver.def.scanThings)
                    {
                        meth = AccessTools.Method(giver.GetType(), "PotentialWorkThingsGlobal");
                    }
                    else
                    {
                        meth = AccessTools.Method(giver.GetType(), "PotentialWorkCellsGlobal");
                    }
                }
                else
                {
                    meth = AccessTools.Method(giver.GetType(), "NonScanJob");
                }
                meths.Add(giver, meth);
            }


            return(ProfileController.Start(CurrentKey, namer, null, null, null, meth));
        }
Example #3
0
 private Job GiverTryGiveJobPrioritized(Pawn pawn, WorkGiver giver, IntVec3 cell)
 {
     if (!PawnCanUseWorkGiver(pawn, giver))
     {
         return(null);
     }
     try
     {
         var job = giver.NonScanJob(pawn);
         if (job != null)
         {
             var result = job;
             return(result);
         }
         var scanner = giver as WorkGiver_Scanner;
         if (scanner != null)
         {
             if (giver.def.scanThings)
             {
                 Predicate <Thing> predicate = t => !t.IsForbidden(pawn) && scanner.HasJobOnThing(pawn, t, false);
                 var thingList = cell.GetThingList(pawn.Map);
                 for (var i = 0; i < thingList.Count; i++)
                 {
                     var thing = thingList[i];
                     if (scanner.PotentialWorkThingRequest.Accepts(thing) && predicate(thing))
                     {
                         pawn.mindState.lastGivenWorkType = giver.def.workType;
                         var result = scanner.JobOnThing(pawn, thing, false);
                         return(result);
                     }
                 }
             }
             if (giver.def.scanCells && !cell.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, cell))
             {
                 pawn.mindState.lastGivenWorkType = giver.def.workType;
                 var result = scanner.JobOnCell(pawn, cell);
                 return(result);
             }
         }
     }
     catch (Exception ex)
     {
         Log.Error(string.Concat(pawn, " threw exception in GiverTryGiveJobTargeted on WorkGiver ",
                                 giver.def.defName, ": ", ex.ToString()));
     }
     return(null);
 }
Example #4
0
    public static bool PawnCanUseWorkGiver_PreFix(Pawn pawn, WorkGiver giver)
    {
        var tenantComp = pawn.GetTenantComponent();

        if (tenantComp == null || !tenantComp.IsTenant || !pawn.IsColonist)
        {
            return(true);
        }

        if (pawn.needs.mood.CurLevel > SettingsHelper.LatestVersion.LevelOfHappinessToWork / 100f ||
            Utility.UpdateEmergencyWork(giver))
        {
            return(true);
        }

        return(false);
    }
        public bool TryTakeOrderedJobPrioritizedWork(Job job, WorkGiver giver, IntVec3 cell)
        {
            bool result;

            if (this.TryTakeOrderedJob(job, giver.def.tagToGive))
            {
                this.pawn.mindState.lastGivenWorkType = giver.def.workType;
                if (giver.def.prioritizeSustains)
                {
                    this.pawn.mindState.priorityWork.Set(cell, giver.def.workType);
                }
                result = true;
            }
            else
            {
                result = false;
            }
            return(result);
        }
 private static bool PawnCanUseWorkGiver(Pawn pawn, WorkGiver giver)
 {
     if (!giver.def.nonColonistsCanDo && !pawn.IsColonist)
     {
         return(false);
     }
     if (pawn.WorkTagIsDisabled(giver.def.workTags))
     {
         return(false);
     }
     if (giver.ShouldSkip(pawn))
     {
         return(false);
     }
     if (giver.MissingRequiredCapacity(pawn) != null)
     {
         return(false);
     }
     return(true);
 }
Example #7
0
        internal ThinkResult PrioritizedJob(Pawn pawn)
        {
            if (emergency && pawn.mindState.priorityWork.IsPrioritized)
            {
                List <WorkGiverDef> workGiversByPriority = pawn.mindState.priorityWork.WorkType.workGiversByPriority;
                for (int i = 0; i < workGiversByPriority.Count; i++)
                {
                    WorkGiver worker = workGiversByPriority[i].Worker;
                    Job       job    = GiverTryGiveJobPrioritized(pawn, worker, pawn.mindState.priorityWork.Cell);
                    if (job != null)
                    {
                        job.playerForced = true;
                        return(new ThinkResult(job, this, workGiversByPriority[i].tagToGive));
                    }
                }
                pawn.mindState.priorityWork.Clear();
            }

            return(ThinkResult.NoJob);
        }
Example #8
0
            public static bool Prefix(ref bool __result, Pawn pawn, WorkGiver giver)
            {
                if (!pawn.IsGuest())
                {
                    return(true);
                }

                var canDo = !giver.ShouldSkip(pawn) && giver.MissingRequiredCapacity(pawn) == null && IsSkilledEnough(pawn, giver.def.workType);

                if (!canDo)
                {
                    return(false);
                }

                if (Settings.disableArtAndCraft.Value && IsArtOrCraft(giver.def.workType.workTags))
                {
                    return(false);
                }


                float score;

                if (!pawn.GetVisitScore(out score))
                {
                    return(false);
                }

                var   passion      = pawn.skills.MaxPassionOfRelevantSkillsFor(giver.def.workType);
                float passionBonus = passion == Passion.Major ? 40 : passion == Passion.Minor ? 20 : 0;

                var desireToHelp = pawn.Faction.GoodwillWith(Faction.OfPlayer) + passionBonus + score * 100 + (giver.def.emergency ? 75 : 0);

                //Log.Message(pawn.NameStringShort + ": help with "+giver.def.gerund+"? " + Mathf.RoundToInt(desireToHelp) + " >= " + Mathf.RoundToInt(100+Rand.ValueSeeded(pawn.thingIDNumber ^ 3436436)*100));
                if (desireToHelp < 100 + Rand.ValueSeeded(pawn.thingIDNumber ^ 3436436) * 100)
                {
                    return(false);
                }

                __result = true;
                return(false);
            }
Example #9
0
 public bool TryTakeOrderedJobPrioritizedWork(CaravanJob job, WorkGiver giver, IntVec3 cell)
 {
     return(TryTakeOrderedJob(job, giver.def.tagToGive));
 }
        public override ThinkResult TryIssueJobPackage(Pawn pawn, JobIssueParams jobParams)
        {
            X2_AIRobot robot = pawn as X2_AIRobot;

            if (robot == null || !robot.Spawned || robot.Destroyed || robot.GetWorkGivers(false) == null)
            {
                return(ThinkResult.NoJob);
            }

            //Profiler.BeginSample("JobGiver_Work");

            //if (this.emergency && pawn.mindState.priorityWork.IsPrioritized)
            //{
            //    List<WorkGiverDef> workGiversByPriority = pawn.mindState.priorityWork.WorkType.workGiversByPriority;
            //    for (int i = 0; i < workGiversByPriority.Count; i++)
            //    {
            //        WorkGiver worker = workGiversByPriority[i].Worker;
            //        Job job = this.GiverTryGiveJobPrioritized(pawn, worker, pawn.mindState.priorityWork.Cell);
            //        if (job != null)
            //        {
            //            job.playerForced = true;
            //            return new ThinkResult(job, this, new JobTag?(workGiversByPriority[i].tagToGive), false);
            //        }
            //    }
            //    pawn.mindState.priorityWork.Clear();
            //}


            List <WorkGiver> list               = robot.GetWorkGivers(false); // Get Non-Emergency WorkGivers
            int               num               = -999;
            TargetInfo        targetInfo        = TargetInfo.Invalid;
            WorkGiver_Scanner workGiver_Scanner = null;
            WorkGiver_Scanner scanner;

            for (int j = 0; j < list.Count; j++)
            {
                WorkGiver workGiver = list[j];
                if (workGiver.def.priorityInType != num && targetInfo.IsValid)
                {
                    break;
                }
                if (PawnCanUseWorkGiver(pawn, workGiver))
                {
                    //Profiler.BeginSample("WorkGiver: " + workGiver.def.defName);
                    try
                    {
                        Job job2 = workGiver.NonScanJob(pawn);
                        if (job2 != null)
                        {
                            return(new ThinkResult(job2, this, list[j].def.tagToGive, false));
                        }
                        scanner = (workGiver as WorkGiver_Scanner);
                        if (scanner != null)
                        {
                            IntVec3 intVec;
                            if (scanner.def.scanThings)
                            {
                                Predicate <Thing>   predicate  = (Thing t) => !t.IsForbidden(pawn) && scanner.HasJobOnThing(pawn, t, false);
                                IEnumerable <Thing> enumerable = scanner.PotentialWorkThingsGlobal(pawn);
                                Thing thing;
                                if (scanner.Prioritized)
                                {
                                    IEnumerable <Thing> enumerable2 = enumerable;
                                    if (enumerable2 == null)
                                    {
                                        enumerable2 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest);
                                    }
                                    if (scanner.AllowUnreachable)
                                    {
                                        intVec = pawn.Position;
                                        IEnumerable <Thing> searchSet = enumerable2;
                                        Predicate <Thing>   validator = predicate;
                                        try
                                        {
                                            thing = GenClosest.ClosestThing_Global(intVec, searchSet, 99999f, validator, (Thing x) => scanner.GetPriority(pawn, x));
                                        }
                                        catch //(Exception ex)
                                        {
                                            //Log.Warning(string.Concat(new object[]
                                            //{
                                            //    pawn,
                                            //    " threw exception in WorkGiver ",
                                            //    workGiver.def.defName,
                                            //    ": ",
                                            //    ex.ToString()
                                            //}));

                                            thing = null;
                                        }
                                    }
                                    else
                                    {
                                        intVec = pawn.Position;
                                        Map map = pawn.Map;
                                        IEnumerable <Thing> searchSet      = enumerable2;
                                        PathEndMode         pathEndMode    = scanner.PathEndMode;
                                        TraverseParms       traverseParams = TraverseParms.For(pawn, scanner.MaxPathDanger(pawn), TraverseMode.ByPawn, false);
                                        Predicate <Thing>   validator      = predicate;
                                        try
                                        {
                                            thing = GenClosest.ClosestThing_Global_Reachable(intVec, map, searchSet, pathEndMode, traverseParams, 9999f, validator, (Thing x) => scanner.GetPriority(pawn, x));
                                        }
                                        catch //(Exception ex)
                                        {
                                            //Log.Warning(string.Concat(new object[]
                                            //{
                                            //    pawn,
                                            //    " threw exception in WorkGiver ",
                                            //    workGiver.def.defName,
                                            //    ": ",
                                            //    ex.ToString()
                                            //}));

                                            thing = null;
                                        }
                                    }
                                }
                                else if (scanner.AllowUnreachable)
                                {
                                    IEnumerable <Thing> enumerable3 = enumerable;
                                    if (enumerable3 == null)
                                    {
                                        enumerable3 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest);
                                    }
                                    intVec = pawn.Position;
                                    IEnumerable <Thing> searchSet = enumerable3;
                                    Predicate <Thing>   validator = predicate;
                                    try
                                    {
                                        thing = GenClosest.ClosestThing_Global(intVec, searchSet, 99999f, validator, null);
                                    }
                                    catch //(Exception ex)
                                    {
                                        //Log.Warning(string.Concat(new object[]
                                        //{
                                        //    pawn,
                                        //    " threw exception in WorkGiver ",
                                        //    workGiver.def.defName,
                                        //    ": ",
                                        //    ex.ToString()
                                        //}));

                                        thing = null;
                                    }
                                }
                                else
                                {
                                    intVec = pawn.Position;
                                    Map               map = pawn.Map;
                                    ThingRequest      potentialWorkThingRequest = scanner.PotentialWorkThingRequest;
                                    PathEndMode       pathEndMode       = scanner.PathEndMode;
                                    TraverseParms     traverseParams    = TraverseParms.For(pawn, scanner.MaxPathDanger(pawn), TraverseMode.ByPawn, false);
                                    Predicate <Thing> validator         = predicate;
                                    bool              forceGlobalSearch = enumerable != null;
                                    try
                                    {
                                        thing = GenClosest.ClosestThingReachable(intVec, map, potentialWorkThingRequest, pathEndMode, traverseParams, 9999f, validator, enumerable, 0, scanner.MaxRegionsToScanBeforeGlobalSearch, forceGlobalSearch, RegionType.Set_Passable, false);
                                    }
                                    catch //(Exception ex)
                                    {
                                        //Log.Warning(string.Concat(new object[]
                                        //{
                                        //    pawn,
                                        //    " threw exception in WorkGiver ",
                                        //    workGiver.def.defName,
                                        //    ": ",
                                        //    ex.ToString()
                                        //}));

                                        thing = null;
                                    }
                                }
                                if (thing != null)
                                {
                                    targetInfo        = thing;
                                    workGiver_Scanner = scanner;
                                }
                            }
                            if (scanner.def.scanCells)
                            {
                                IntVec3 position         = pawn.Position;
                                float   num2             = 99999f;
                                float   num3             = -3.40282347E+38f;
                                bool    prioritized      = scanner.Prioritized;
                                bool    allowUnreachable = scanner.AllowUnreachable;
                                Danger  maxDanger        = scanner.MaxPathDanger(pawn);
                                foreach (IntVec3 item in scanner.PotentialWorkCellsGlobal(pawn))
                                {
                                    bool flag = false;
                                    intVec = item - position;
                                    float num4 = (float)intVec.LengthHorizontalSquared;
                                    float num5 = 0f;
                                    if (prioritized)
                                    {
                                        if (!item.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, item, false))
                                        {
                                            if (!allowUnreachable && !pawn.CanReach(item, scanner.PathEndMode, maxDanger, false, TraverseMode.ByPawn))
                                            {
                                                continue;
                                            }
                                            num5 = scanner.GetPriority(pawn, item);
                                            if (num5 > num3 || (num5 == num3 && num4 < num2))
                                            {
                                                flag = true;
                                            }
                                        }
                                    }
                                    else if (num4 < num2 && !item.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, item, false))
                                    {
                                        if (!allowUnreachable && !pawn.CanReach(item, scanner.PathEndMode, maxDanger, false, TraverseMode.ByPawn))
                                        {
                                            continue;
                                        }
                                        flag = true;
                                    }
                                    if (flag)
                                    {
                                        targetInfo        = new TargetInfo(item, pawn.Map, false);
                                        workGiver_Scanner = scanner;
                                        num2 = num4;
                                        num3 = num5;
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Log.Error(pawn + " threw exception in WorkGiver " + workGiver.def.defName + ": " + ex.ToString(), false);
                    }
                    finally
                    {
                        //Profiler.EndSample();
                    }
                    if (targetInfo.IsValid)
                    {
                        //Profiler.EndSample();
                        Job job3 = null;
                        try
                        {
                            //pawn.mindState.lastGivenWorkType = workGiver.def.workType;
                            job3 = (!targetInfo.HasThing) ? workGiver_Scanner.JobOnCell(pawn, targetInfo.Cell, false) : workGiver_Scanner.JobOnThing(pawn, targetInfo.Thing, false);
                        }
                        catch //(Exception ex)
                        {
                            //Log.Warning(string.Concat(new object[]
                            //{
                            //    pawn,
                            //    " threw exception in WorkGiver ",
                            //    workGiver.def.defName,
                            //    " in JobOnX: ",
                            //    ex.ToString()
                            //}));

                            // Error --> Force NoJob
                            return(ThinkResult.NoJob);
                        }
                        if (job3 != null)
                        {
                            return(new ThinkResult(job3, this, list[j].def.tagToGive, false));
                        }
                        Log.ErrorOnce(workGiver_Scanner + " provided target " + targetInfo + " but yielded no actual job for pawn " + pawn + ". The CanGiveJob and JobOnX methods may not be synchronized.", 6112651, false);
                    }
                    num = workGiver.def.priorityInType;
                }
            }
            return(ThinkResult.NoJob);
        }
 private static bool IsMedical(WorkGiver workGiver)
 {
     return(workGiver is WorkGiver_Tend);
 }
 private static bool IsOperation(WorkGiver workGiver)
 {
     return(workGiver is WorkGiver_DoBill && (workGiver.def.billGiversAllHumanlikes || workGiver.def.billGiversAllAnimals));
 }
Example #13
0
 private bool GiverCanGiveJobToPawn(Pawn pawn, WorkGiver giver)
 {
     return((giver.def.canBeDoneByNonColonists || pawn.IsColonist) && giver.MissingRequiredCapacity(pawn) == null && !giver.ShouldSkip(pawn));
 }
        public void HeaderInteractions(Rect rect, PawnTable table)
        {
            if (!Mouse.IsOver(rect))
            {
                return;
            }

            // handle interactions
            if (Event.current.shift)
            {
                // deal with clicks and scrolls
                if (Find.PlaySettings.useWorkPriorities)
                {
                    if (ScrolledUp(rect, true) || RightClicked(rect))
                    {
                        WorkGiver.IncrementPriority(CapablePawns, VisibleHour, SelectedHours);
                    }
                    if (ScrolledDown(rect, true) || LeftClicked(rect))
                    {
                        WorkGiver.DecrementPriority(CapablePawns, VisibleHour, SelectedHours);
                    }
                }
                else
                {
                    // this gets slightly more complicated
                    var pawns = CapablePawns;
                    if (ScrolledUp(rect, true) || RightClicked(rect))
                    {
                        if (pawns.Any(p => p.GetPriority(WorkGiver, VisibleHour) != 0))
                        {
                            if (Settings.playSounds)
                            {
                                SoundDefOf.CheckboxTurnedOff.PlayOneShotOnCamera();
                            }
                            foreach (Pawn pawn in pawns)
                            {
                                pawn.SetPriority(WorkGiver, 0, SelectedHours);
                            }
                        }
                    }

                    if (ScrolledDown(rect, true) || LeftClicked(rect))
                    {
                        if (pawns.Any(p => p.GetPriority(WorkGiver, VisibleHour) == 0))
                        {
                            if (Settings.playSounds)
                            {
                                SoundDefOf.CheckboxTurnedOn.PlayOneShotOnCamera();
                            }
                            foreach (Pawn pawn in pawns)
                            {
                                pawn.SetPriority(WorkGiver, 3, SelectedHours);
                            }
                        }
                    }
                }
            }
            else if (def.sortable)
            {
                if (LeftClicked(rect))
                {
                    Sort(table);
                }
                if (RightClicked(rect))
                {
                    Sort(table, false);
                }
            }
        }
Example #15
0
        public static bool CacheWorkGiversInOrder(Pawn_WorkSettings __instance)
        {
            //Pawn_WorkSettings.wtsByPrio.Clear();
            List <WorkTypeDef> wtsByPrio          = new List <WorkTypeDef>();
            List <WorkTypeDef> defsListForReading = DefDatabase <WorkTypeDef> .AllDefsListForReading;
            int num1 = 999;

            for (int index = 0; index < defsListForReading.Count; ++index)
            {
                WorkTypeDef w        = defsListForReading[index];
                int         priority = __instance.GetPriority(w);
                if (priority > 0)
                {
                    if (priority < num1 && w.workGiversByPriority.Any <WorkGiverDef>((Predicate <WorkGiverDef>)(wg => !wg.emergency)))
                    {
                        num1 = priority;
                    }
                    wtsByPrio.Add(w);
                }
            }
            wtsByPrio.InsertionSort <WorkTypeDef>((Comparison <WorkTypeDef>)((a, b) =>
            {
                float num2 = (float)(a.naturalPriority + (4 - __instance.GetPriority(a)) * 100000);
                return(((float)(b.naturalPriority + (4 - __instance.GetPriority(b)) * 100000)).CompareTo(num2));
            }));
            //this.workGiversInOrderEmerg.Clear();
            List <WorkGiver> workGiversInOrderEmerg = new List <WorkGiver>();

            for (int index1 = 0; index1 < wtsByPrio.Count; ++index1)
            {
                WorkTypeDef workTypeDef = wtsByPrio[index1];
                for (int index2 = 0; index2 < workTypeDef.workGiversByPriority.Count; ++index2)
                {
                    WorkGiver worker = workTypeDef.workGiversByPriority[index2].Worker;
                    if (worker.def.emergency && __instance.GetPriority(worker.def.workType) <= num1)
                    {
                        workGiversInOrderEmerg.Add(worker);
                    }
                }
            }
            lock (workGiversInOrderNormal(__instance))
            {
                workGiversInOrderNormal(__instance).Clear();
            }
            for (int index1 = 0; index1 < wtsByPrio.Count; ++index1)
            {
                WorkTypeDef workTypeDef = wtsByPrio[index1];
                for (int index2 = 0; index2 < workTypeDef.workGiversByPriority.Count; ++index2)
                {
                    WorkGiver worker = workTypeDef.workGiversByPriority[index2].Worker;
                    if (!worker.def.emergency || __instance.GetPriority(worker.def.workType) > num1)
                    {
                        lock (workGiversInOrderNormal(__instance))
                        {
                            workGiversInOrderNormal(__instance).Add(worker);
                        }
                    }
                }
            }
            workGiversDirty(__instance) = false;
            return(false);
        }
        public static void GetJobFor(Pawn pawn, List <WorkGiverDef> workGiverDefs)
        {
            if (pawn.Dead || !pawn.Spawned)
            {
                return;
            }
            List <WorkGiver> list = AllowedWorkGiversFor(pawn, workGiverDefs).Select(x => x.Worker).ToList();
            int               num = -999;
            TargetInfo        bestTargetOfLastPriority = TargetInfo.Invalid;
            WorkGiver_Scanner scannerWhoProvidedTarget = null;
            WorkGiver_Scanner scanner;
            IntVec3           pawnPosition;
            float             closestDistSquared;
            float             bestPriority;
            bool              prioritized;
            bool              allowUnreachable;
            Danger            maxPathDanger;

            for (int j = 0; j < list.Count; j++)
            {
                WorkGiver workGiver = list[j];
                if (workGiver.def.priorityInType != num && bestTargetOfLastPriority.IsValid)
                {
                    break;
                }
                if (!PawnCanUseWorkGiver(pawn, workGiver))
                {
                    continue;
                }
                try
                {
                    Job job2 = workGiver.NonScanJob(pawn);
                    if (job2 != null)
                    {
                        GiveJob(pawn, job2, workGiver);
                        return;
                    }
                    scanner = (workGiver as WorkGiver_Scanner);
                    if (scanner != null)
                    {
                        if (scanner.def.scanThings)
                        {
                            Predicate <Thing>   validator  = (Thing t) => !t.IsForbidden(pawn) && scanner.HasJobOnThing(pawn, t);
                            IEnumerable <Thing> enumerable = scanner.PotentialWorkThingsGlobal(pawn);
                            Thing thing;
                            if (scanner.Prioritized)
                            {
                                IEnumerable <Thing> enumerable2 = enumerable;
                                if (enumerable2 == null)
                                {
                                    enumerable2 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest);
                                }
                                thing = ((!scanner.AllowUnreachable) ? GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map, enumerable2, scanner.PathEndMode, TraverseParms.For(pawn, scanner.MaxPathDanger(pawn)), 9999f, validator, (Thing x) => scanner.GetPriority(pawn, x)) : GenClosest.ClosestThing_Global(pawn.Position, enumerable2, 99999f, validator, (Thing x) => scanner.GetPriority(pawn, x)));
                            }
                            else if (scanner.AllowUnreachable)
                            {
                                IEnumerable <Thing> enumerable3 = enumerable;
                                if (enumerable3 == null)
                                {
                                    enumerable3 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest);
                                }
                                thing = GenClosest.ClosestThing_Global(pawn.Position, enumerable3, 99999f, validator);
                            }
                            else
                            {
                                thing = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, scanner.PotentialWorkThingRequest, scanner.PathEndMode, TraverseParms.For(pawn, scanner.MaxPathDanger(pawn)), 9999f, validator, enumerable, 0, scanner.MaxRegionsToScanBeforeGlobalSearch, enumerable != null);
                            }
                            if (thing != null)
                            {
                                bestTargetOfLastPriority = thing;
                                scannerWhoProvidedTarget = scanner;
                            }
                        }
                        if (scanner.def.scanCells)
                        {
                            pawnPosition       = pawn.Position;
                            closestDistSquared = 99999f;
                            bestPriority       = float.MinValue;
                            prioritized        = scanner.Prioritized;
                            allowUnreachable   = scanner.AllowUnreachable;
                            maxPathDanger      = scanner.MaxPathDanger(pawn);
                            IEnumerable <IntVec3> enumerable4 = scanner.PotentialWorkCellsGlobal(pawn);
                            IList <IntVec3>       list2;
                            if ((list2 = (enumerable4 as IList <IntVec3>)) != null)
                            {
                                for (int k = 0; k < list2.Count; k++)
                                {
                                    ProcessCell(list2[k]);
                                }
                            }
                            else
                            {
                                foreach (IntVec3 item in enumerable4)
                                {
                                    ProcessCell(item);
                                }
                            }
                        }
                    }
                    void ProcessCell(IntVec3 c)
                    {
                        bool  flag = false;
                        float num2 = (c - pawnPosition).LengthHorizontalSquared;
                        float num3 = 0f;

                        if (prioritized)
                        {
                            if (!c.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, c))
                            {
                                if (!allowUnreachable && !pawn.CanReach(c, scanner.PathEndMode, maxPathDanger))
                                {
                                    return;
                                }
                                num3 = scanner.GetPriority(pawn, c);
                                if (num3 > bestPriority || (num3 == bestPriority && num2 < closestDistSquared))
                                {
                                    flag = true;
                                }
                            }
                        }
                        else if (num2 < closestDistSquared && !c.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, c))
                        {
                            if (!allowUnreachable && !pawn.CanReach(c, scanner.PathEndMode, maxPathDanger))
                            {
                                return;
                            }
                            flag = true;
                        }
                        if (flag)
                        {
                            bestTargetOfLastPriority = new TargetInfo(c, pawn.Map);
                            scannerWhoProvidedTarget = scanner;
                            closestDistSquared       = num2;
                            bestPriority             = num3;
                        }
                    }
                }
                catch (Exception ex)
                {
                    Log.Error(string.Concat(pawn, " threw exception in WorkGiver ", workGiver.def.defName, ": ", ex.ToString()));
                }
                finally
                {
                }
                if (bestTargetOfLastPriority.IsValid)
                {
                    Job job3 = (!bestTargetOfLastPriority.HasThing) ? scannerWhoProvidedTarget.JobOnCell(pawn, bestTargetOfLastPriority.Cell) : scannerWhoProvidedTarget.JobOnThing(pawn, bestTargetOfLastPriority.Thing);
                    if (job3 != null)
                    {
                        job3.workGiverDef = scannerWhoProvidedTarget.def;
                        GiveJob(pawn, job3, scannerWhoProvidedTarget);
                        return;
                    }
                }
                num = workGiver.def.priorityInType;
            }
        }
Example #17
0
 public static List <WorkGiverDef> GetCombinedDefs(WorkGiver baseWorkGiver)
 {
     return(GetCombinedDefs(baseWorkGiver.def));
 }
        public List <WorkGiver> GetWorkGivers(bool emergency)
        {
            List <WorkGiver> result;

            if (emergency && this.workGiversEmergencyCache != null)
            {
                result = this.workGiversEmergencyCache;
            }
            else
            {
                if (!emergency &&
                    this.workGiversNonEmergencyCache != null)
                {
                    result = this.workGiversNonEmergencyCache;
                }
                else
                {
                    List <WorkTypeDef> list = new List <WorkTypeDef> ();
                    List <WorkTypeDef> allDefsListForReading = DefDatabase <WorkTypeDef> .AllDefsListForReading;
                    int num = 999;
                    Predicate <WorkGiverDef> dummy = null;

                    for (int i = 0; i < allDefsListForReading.Count; i++)
                    {
                        WorkTypeDef workTypeDef = allDefsListForReading [i];
                        int         priority    = this.GetPriority(workTypeDef);

                        if (priority > 0)
                        {
                            if (priority < num)
                            {
                                List <WorkGiverDef>      arg_C8_0 = workTypeDef.workGiversByPriority;
                                Predicate <WorkGiverDef> arg_C8_1;
                                if ((arg_C8_1 = dummy) == null)
                                {
                                    arg_C8_1 = (dummy = ((WorkGiverDef wg) => wg.emergency == emergency));
                                }
                                if (GenCollection.Any <WorkGiverDef> (arg_C8_0, arg_C8_1))
                                {
                                    num = priority;
                                }
                            }
                            list.Add(workTypeDef);
                        }
                    }
                    GenList.InsertionSort <WorkTypeDef> (list, delegate(WorkTypeDef a, WorkTypeDef b) {
                        float value = (float)(a.naturalPriority + (4 - this.GetPriority(a)) * 100000);
                        return(((float)(b.naturalPriority + (4 - this.GetPriority(b)) * 100000)).CompareTo(value));
                    });
                    List <WorkGiver> list2 = new List <WorkGiver> ();
                    for (int j = 0; j < list.Count; j++)
                    {
                        WorkTypeDef workTypeDef2 = list [j];
                        for (int k = 0; k < workTypeDef2.workGiversByPriority.Count; k++)
                        {
                            WorkGiver worker = workTypeDef2.workGiversByPriority [k].Worker;
                            list2.Add(worker);
                        }
                    }
                    if (emergency)
                    {
                        this.workGiversEmergencyCache = list2;
                    }
                    else
                    {
                        this.workGiversNonEmergencyCache = list2;
                    }
                    result = list2;
                }
            }
            return(result);
        }
Example #19
0
 static bool IsConstruction(WorkGiver w) => w.def.workType == WorkTypeDefOf.Construction;
        public override ThinkResult TryIssueJobPackage(Pawn pawn, JobIssueParams jobParams)
        {
            int               num               = -999;
            TargetInfo        targetInfo        = TargetInfo.Invalid;
            WorkGiver_Scanner workGiver_Scanner = null;

            if (workGiverDef != null)
            {
                WorkGiver workGiver = workGiverDef.Worker;
                if (workGiver.def.priorityInType != num && targetInfo.IsValid)
                {
                    return(ThinkResult.NoJob);
                }

                if (this.PawnCanUseWorkGiver(pawn, workGiver))
                {
                    try
                    {
                        Job job2 = workGiver.NonScanJob(pawn);
                        if (job2 != null)
                        {
                            return(new ThinkResult(job2, this, new JobTag?(workGiverDef.tagToGive)));
                        }
                        WorkGiver_Scanner scanner = workGiver as WorkGiver_Scanner;
                        if (scanner != null)
                        {
                            if (workGiver.def.scanThings)
                            {
                                Predicate <Thing>   predicate  = (Thing t) => !t.IsForbidden(pawn) && scanner.HasJobOnThing(pawn, t, false);
                                IEnumerable <Thing> enumerable = scanner.PotentialWorkThingsGlobal(pawn);
                                Thing thing;
                                if (scanner.Prioritized)
                                {
                                    IEnumerable <Thing> enumerable2 = enumerable;
                                    if (enumerable2 == null)
                                    {
                                        enumerable2 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest);
                                    }
                                    Predicate <Thing> validator = predicate;
                                    thing = GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map, enumerable2, scanner.PathEndMode, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), 9999f, validator, (Thing x) => scanner.GetPriority(pawn, x));
                                }
                                else
                                {
                                    Predicate <Thing> validator = predicate;
                                    bool forceGlobalSearch      = enumerable != null;
                                    thing = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, scanner.PotentialWorkThingRequest, scanner.PathEndMode, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), 9999f, validator, enumerable, 0, scanner.LocalRegionsToScanFirst, forceGlobalSearch, RegionType.Set_Passable, false);
                                }
                                if (thing != null)
                                {
                                    targetInfo        = thing;
                                    workGiver_Scanner = scanner;
                                }
                            }
                            if (workGiver.def.scanCells)
                            {
                                IntVec3 position    = pawn.Position;
                                float   num2        = 99999f;
                                float   num3        = -3.40282347E+38f;
                                bool    prioritized = scanner.Prioritized;
                                foreach (IntVec3 current in scanner.PotentialWorkCellsGlobal(pawn))
                                {
                                    bool  flag = false;
                                    float num4 = (float)(current - position).LengthHorizontalSquared;
                                    if (prioritized)
                                    {
                                        if (!current.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, current))
                                        {
                                            float priority = scanner.GetPriority(pawn, current);
                                            if (priority > num3 || (priority == num3 && num4 < num2))
                                            {
                                                flag = true;
                                                num3 = priority;
                                            }
                                        }
                                    }
                                    else if (num4 < num2 && !current.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, current))
                                    {
                                        flag = true;
                                    }
                                    if (flag)
                                    {
                                        targetInfo        = new TargetInfo(current, pawn.Map, false);
                                        workGiver_Scanner = scanner;
                                        num2 = num4;
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Log.Error(string.Concat(new object[]
                        {
                            pawn,
                            " threw exception in WorkGiver ",
                            workGiver.def.defName,
                            ": ",
                            ex.ToString()
                        }));
                    }
                    finally
                    {
                    }
                    if (targetInfo.IsValid)
                    {
                        pawn.mindState.lastGivenWorkType = workGiver.def.workType;
                        Job job3;
                        if (targetInfo.HasThing)
                        {
                            job3 = workGiver_Scanner.JobOnThing(pawn, targetInfo.Thing, false);
                        }
                        else
                        {
                            job3 = workGiver_Scanner.JobOnCell(pawn, targetInfo.Cell);
                        }
                        if (job3 != null)
                        {
                            return(new ThinkResult(job3, this, new JobTag?(workGiverDef.tagToGive)));
                        }
                        Log.ErrorOnce(string.Concat(new object[]
                        {
                            workGiver_Scanner,
                            " provided target ",
                            targetInfo,
                            " but yielded no actual job for pawn ",
                            pawn,
                            ". The CanGiveJob and JobOnX methods may not be synchronized."
                        }), 6112651);
                    }
                    num = workGiver.def.priorityInType;
                }
            }

            return(ThinkResult.NoJob);
        }
Example #21
0
 private bool PawnCanUseWorkGiver(Pawn pawn, WorkGiver giver)
 {
     return((pawn.story == null || !pawn.WorkTagIsDisabled(giver.def.workTags)) &&
            !giver.ShouldSkip(pawn) && (giver.def.nonColonistsCanDo || pawn.IsPrisoner) &&
            giver.MissingRequiredCapacity(pawn) == null);
 }
Example #22
0
        private static ThinkResult Detour(JobGiver_Work __instance, Pawn pawn)
        {
            if (__instance.emergency && pawn.mindState.priorityWork.IsPrioritized)

            {
                var workGiversByPriority = pawn.mindState.priorityWork.WorkGiver.workType.workGiversByPriority;
                for (var i = 0; i < workGiversByPriority.Count; i++)
                {
                    var worker = workGiversByPriority[i].Worker;
                    var job    = __instance.GiverTryGiveJobPrioritized(pawn, worker, pawn.mindState.priorityWork.Cell);
                    if (job != null)
                    {
                        job.playerForced = true;
                        return(new ThinkResult(job, __instance, workGiversByPriority[i].tagToGive));
                    }
                }

                pawn.mindState.priorityWork.Clear();
            }

            var list = __instance.emergency
                ? pawn.workSettings.WorkGiversInOrderEmergency
                : pawn.workSettings.WorkGiversInOrderNormal;

            var num = -999;
            var bestTargetOfLastPriority = TargetInfo.Invalid;
            WorkGiver_Scanner scannerWhoProvidedTarget = null;
            var coo = list.Count;

            for (var j = 0; j < coo; j++)
            {
                var workGiver = list[j];

                string namer()
                {
                    var daffy = string.Empty;

                    if (ByWorkType)
                    {
                        daffy = workGiver.def?.workType?.defName;
                    }
                    else
                    {
                        daffy =
                            $"{workGiver.def?.defName} - {workGiver.def?.workType.defName} - {workGiver.def?.modContentPack?.Name}";
                    }

                    //if (true)
                    //{
                    //    daffy += $" - { TraverseParms.For(pawn, scanner.MaxPathDanger(pawn)).ToString()} - {pawn.Name.ToStringShort}";
                    //}

                    if (RequestTypes && workGiver is WorkGiver_Scanner scan)
                    {
                        daffy += $" - {scan.PotentialWorkThingRequest}";
                        if (scan.PotentialWorkThingRequest.group ==
                            ThingRequestGroup.BuildingArtificial)
                        {
                            daffy += " VERY BAD!";
                        }
                    }

                    return(daffy);
                }

                if (workGiver.def.priorityInType != num && bestTargetOfLastPriority.IsValid)
                {
                    break;
                }

                if (__instance.PawnCanUseWorkGiver(pawn, workGiver))
                {
                    var name = string.Empty;

                    if (ByWorkType)
                    {
                        name = workGiver.def.workType.defName;
                    }
                    else
                    {
                        name = workGiver.def.defName;
                    }

                    //if (true)
                    //{
                    //    name = string.Intern(name + pawn.Name.ToStringShort);
                    //}
                    if (workGiver is WorkGiver_Scanner scanny)
                    {
                        name += $"{scanny.PotentialWorkThingRequest}";
                    }


                    try
                    {
                        var job2 = workGiver.NonScanJob(pawn);
                        if (job2 != null)
                        {
                            return(new ThinkResult(job2, __instance, list[j].def.tagToGive));
                        }



                        if (workGiver is WorkGiver_Scanner scanner)
                        {
                            Analyzer.Start(name, namer, workGiver.GetType(), workGiver.def, pawn);

                            if (scanner.def.scanThings)
                            {
                                bool Predicate(Thing t)
                                {
                                    return(!t.IsForbidden(pawn) && scanner.HasJobOnThing(pawn, t));
                                }

                                var   enumerable = scanner.PotentialWorkThingsGlobal(pawn);
                                Thing thing;
                                if (scanner.Prioritized)
                                {
                                    var enumerable2 = enumerable;
                                    if (enumerable2 == null)
                                    {
                                        enumerable2 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest);
                                    }

                                    if (scanner.AllowUnreachable)
                                    {
                                        thing = GenClosest.ClosestThing_Global(pawn.Position, enumerable2, 99999f, Predicate, x => scanner.GetPriority(pawn, x));
                                    }
                                    else
                                    {
                                        var traverseParams = TraverseParms.For(pawn, scanner.MaxPathDanger(pawn));
                                        var validator      = (Predicate <Thing>)Predicate;
                                        thing = GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map,
                                                                                         enumerable2,
                                                                                         scanner.PathEndMode, traverseParams, 9999f, validator,
                                                                                         x => scanner.GetPriority(pawn, x));
                                    }
                                }
                                else if (scanner.AllowUnreachable)
                                {
                                    var enumerable3 = enumerable;
                                    if (enumerable3 == null)
                                    {
                                        enumerable3 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest);
                                    }

                                    thing = GenClosest.ClosestThing_Global(pawn.Position, enumerable3, 99999f, Predicate);
                                }
                                else
                                {
                                    giver = workGiver;
                                    key   = name;
                                    Analyzer.Start(name, namer, workGiver.GetType(), workGiver.def, pawn);
                                    thing = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map,
                                                                             scanner.PotentialWorkThingRequest,
                                                                             scanner.PathEndMode, TraverseParms.For(pawn, scanner.MaxPathDanger(pawn)),
                                                                             9999f, Predicate, enumerable, 0,
                                                                             scanner.MaxRegionsToScanBeforeGlobalSearch, enumerable != null);

                                    giver = null;
                                }

                                if (thing != null)
                                {
                                    bestTargetOfLastPriority = thing;
                                    scannerWhoProvidedTarget = scanner;
                                }
                            }



                            if (scanner.def.scanCells)
                            {
                                var closestDistSquared = 99999f;
                                var bestPriority       = float.MinValue;
                                var prioritized        = scanner.Prioritized;
                                var allowUnreachable   = scanner.AllowUnreachable;
                                var maxDanger          = scanner.MaxPathDanger(pawn);
                                foreach (var intVec in scanner.PotentialWorkCellsGlobal(pawn))
                                {
                                    var flag = false;
                                    var num4 = (intVec - pawn.Position).LengthHorizontalSquared;
                                    var num5 = 0f;
                                    if (prioritized)
                                    {
                                        if (!intVec.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, intVec))
                                        {
                                            if (!allowUnreachable &&
                                                !pawn.CanReach(intVec, scanner.PathEndMode, maxDanger))
                                            {
                                                continue;
                                            }

                                            num5 = scanner.GetPriority(pawn, intVec);
                                            if (num5 > bestPriority || num5 == bestPriority && num4 < closestDistSquared)
                                            {
                                                flag = true;
                                            }
                                        }
                                    }
                                    else if (num4 < closestDistSquared && !intVec.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, intVec))
                                    {
                                        if (!allowUnreachable && !pawn.CanReach(intVec, scanner.PathEndMode, maxDanger))
                                        {
                                            continue;
                                        }

                                        flag = true;
                                    }

                                    if (flag)
                                    {
                                        bestTargetOfLastPriority = new TargetInfo(intVec, pawn.Map);
                                        scannerWhoProvidedTarget = scanner;
                                        closestDistSquared       = num4;
                                        bestPriority             = num5;
                                    }
                                }
                            }


                            Analyzer.Stop(name);
                        }
                    }
                    catch (Exception ex)
                    {
                        Log.Error(string.Concat(pawn, " threw exception in WorkGiver ", workGiver.def.defName, ": ",
                                                ex.ToString()));
                    }

                    if (bestTargetOfLastPriority.IsValid)
                    {
                        //  pawn.mindState.lastGivenWorkType = workGiver.def.workType;
                        Job job3;
                        if (bestTargetOfLastPriority.HasThing)
                        {
                            job3 = scannerWhoProvidedTarget.JobOnThing(pawn, bestTargetOfLastPriority.Thing);
                        }
                        else
                        {
                            job3 = scannerWhoProvidedTarget.JobOnCell(pawn, bestTargetOfLastPriority.Cell);
                        }

                        if (job3 != null)
                        {
                            job3.workGiverDef = scannerWhoProvidedTarget.def;
                            return(new ThinkResult(job3, __instance, list[j].def.tagToGive));
                        }

                        Log.ErrorOnce(
                            string.Concat(scannerWhoProvidedTarget, " provided target ", bestTargetOfLastPriority,
                                          " but yielded no actual job for pawn ", pawn,
                                          ". The CanGiveJob and JobOnX methods may not be synchronized."), 6112651);
                    }

                    num = workGiver.def.priorityInType;
                }
            }

            return(ThinkResult.NoJob);
        }
Example #23
0
        public void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
        {
            WorkGiver wg = (WorkGiver)obj;

            info.AddValue("workgiverdef", wg.def);
        }
Example #24
0
 private bool PawnCanUseWorkGiver(Pawn pawn, WorkGiver giver)
 {
     return(giver.MissingRequiredCapacity(pawn) == null && !giver.ShouldSkip(pawn));
 }
 public static void GiveJob(Pawn pawn, Job job, WorkGiver giver)
 {
     job.workGiverDef = giver.def;
     pawn.jobs.TryTakeOrderedJobPrioritizedWork(job, giver, pawn.Position);
 }
Example #26
0
        protected override Job TryGiveJob(Pawn pawn)
        {
            //Player forced? or fire?
            if (this.emergency && pawn.mindState.priorityWork.IsPrioritized)
            {
                List <WorkGiverDef> workGiversByPriority = pawn.mindState.priorityWork.WorkType.workGiversByPriority;
                for (int i = 0; i < workGiversByPriority.Count; i++)
                {
                    WorkGiver worker = workGiversByPriority[i].Worker;
                    Job       job    = this.GiverTryGiveJobTargeted(pawn, worker, pawn.mindState.priorityWork.Cell);
                    if (job != null)
                    {
                        job.playerForced = true;
                        return(job);
                    }
                }
                pawn.mindState.priorityWork.Clear();
            }
            List <WorkGiver> list               = this.emergency ? pawn.workSettings.WorkGiversInOrderEmergency : pawn.workSettings.WorkGiversInOrderNormal;
            int               num               = -999;
            TargetInfo        targetInfo        = TargetInfo.Invalid;
            WorkGiver_Scanner workGiver_Scanner = null;

            for (int j = 0; j < list.Count; j++)
            {
                WorkGiver workGiver = list[j];
                //If pawn cannot do job
                if (workGiver.def.priorityInType != num && targetInfo.IsValid)
                {
                    break;
                }
                if (this.GiverCanGiveJobToPawn(pawn, workGiver))
                {
                    try
                    {
                        //If needs to go to bed? Resting?
                        Job job2 = workGiver.NonScanJob(pawn);
                        if (job2 != null)
                        {
                            return(job2);
                        }
                        WorkGiver_Scanner scanner = workGiver as WorkGiver_Scanner;
                        if (scanner != null)
                        {
                            if (workGiver.def.scanThings)
                            {
                                Predicate <Thing>   predicate  = (Thing t) => !t.IsForbidden(pawn) && scanner.HasJobOnThing(pawn, t);
                                IEnumerable <Thing> enumerable = scanner.PotentialWorkThingsGlobal(pawn);
                                Thing thing;
                                //Always false unless roof or researcher
                                if (scanner.Prioritized)
                                {
                                    IEnumerable <Thing> enumerable2 = enumerable;
                                    if (enumerable2 == null)
                                    {
                                        enumerable2 = Find.ListerThings.ThingsMatching(scanner.PotentialWorkThingRequest);
                                    }
                                    Predicate <Thing> validator = predicate;
                                    thing = GenClosest.ClosestThing_Global_Reachable(pawn.Position, enumerable2, scanner.PathEndMode, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), 9999f, validator, (Thing x) => scanner.GetPriority(pawn, x));
                                }
                                else
                                {
                                    Predicate <Thing> validator = predicate;
                                    //Start of my code
                                    if (scanner is WorkGiver_HaulGeneral)
                                    {
                                        thing = GenClosest_JT.ClosestThingReachable_JT(pawn.Position, scanner.PotentialWorkThingRequest, scanner.PathEndMode, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), 9999f, validator, enumerable, scanner.LocalRegionsToScanFirst, enumerable != null);
                                    }
                                    else
                                    {
                                        thing = GenClosest.ClosestThingReachable(pawn.Position, scanner.PotentialWorkThingRequest, scanner.PathEndMode, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), 9999f, validator, enumerable, scanner.LocalRegionsToScanFirst, enumerable != null);
                                    }
                                    //End of my code
                                }
                                if (thing != null)
                                {
                                    targetInfo        = thing;
                                    workGiver_Scanner = scanner;
                                }
                            }
                            if (workGiver.def.scanCells)
                            {
                                IntVec3 position    = pawn.Position;
                                float   num2        = 99999f;
                                float   num3        = -3.40282347E+38f;
                                bool    prioritized = scanner.Prioritized;
                                foreach (IntVec3 current in scanner.PotentialWorkCellsGlobal(pawn))
                                {
                                    bool  flag = false;
                                    float lengthHorizontalSquared = (current - position).LengthHorizontalSquared;
                                    if (prioritized)
                                    {
                                        if (!current.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, current))
                                        {
                                            float priority = scanner.GetPriority(pawn, current);
                                            if (priority > num3 || (priority == num3 && lengthHorizontalSquared < num2))
                                            {
                                                flag = true;
                                                num3 = priority;
                                            }
                                        }
                                    }
                                    else if (lengthHorizontalSquared < num2 && !current.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, current))
                                    {
                                        flag = true;
                                    }
                                    if (flag)
                                    {
                                        targetInfo        = current;
                                        workGiver_Scanner = scanner;
                                        num2 = lengthHorizontalSquared;
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Log.Error(string.Concat(new object[]
                        {
                            pawn,
                            " threw exception in WorkGiver ",
                            workGiver.def.defName,
                            ": ",
                            ex.ToString()
                        }));
                    }
                    finally
                    {
                    }
                    if (targetInfo.IsValid)
                    {
                        pawn.mindState.lastGivenWorkType = workGiver.def.workType;
                        Job job3;
                        if (targetInfo.HasThing)
                        {
                            job3 = workGiver_Scanner.JobOnThing(pawn, targetInfo.Thing);
                        }
                        else
                        {
                            job3 = workGiver_Scanner.JobOnCell(pawn, targetInfo.Cell);
                        }
                        if (job3 != null)
                        {
                            return(job3);
                        }
                        Log.ErrorOnce(string.Concat(new object[]
                        {
                            workGiver_Scanner,
                            " provided target ",
                            targetInfo,
                            " but yielded no actual job for pawn ",
                            pawn,
                            ". The CanGiveJob and JobOnX methods may not be synchronized."
                        }), 6112651);
                    }
                    num = workGiver.def.priorityInType;
                }
            }
            return(null);
        }
        public override ThinkResult TryIssueJobPackage(Pawn pawn, JobIssueParams jobParams)
        {
            X2_AIRobot robot = pawn as X2_AIRobot;

            if (robot == null || !robot.Spawned || robot.Destroyed || robot.GetWorkGivers(false) == null)
            {
                return(ThinkResult.NoJob);
            }

            //Profiler.BeginSample("JobGiver_Work");

            //if (emergency && pawn.mindState.priorityWork.IsPrioritized)
            //{
            //	List<WorkGiverDef> workGiversByPriority = pawn.mindState.priorityWork.WorkGiver.workType.workGiversByPriority;
            //	for (int i = 0; i < workGiversByPriority.Count; i++)
            //	{
            //		WorkGiver worker = workGiversByPriority[i].Worker;
            //		if (WorkGiversRelated(pawn.mindState.priorityWork.WorkGiver, worker.def))
            //		{
            //			Job job = GiverTryGiveJobPrioritized(pawn, worker, pawn.mindState.priorityWork.Cell);
            //			if (job != null)
            //			{
            //				job.playerForced = true;
            //				return new ThinkResult(job, this, workGiversByPriority[i].tagToGive);
            //			}
            //		}
            //	}
            //	pawn.mindState.priorityWork.Clear();
            //}



            List <WorkGiver> list = robot.GetWorkGivers(false); // Get Non-Emergency WorkGivers
            int               num = -999;
            TargetInfo        bestTargetOfLastPriority = TargetInfo.Invalid;
            WorkGiver_Scanner scannerWhoProvidedTarget = null;
            WorkGiver_Scanner scanner;
            IntVec3           pawnPosition;
            bool              prioritized;
            bool              allowUnreachable;
            Danger            maxPathDanger;

            for (int j = 0; j < list.Count; j++)
            {
                WorkGiver workGiver = list[j];
                if (workGiver.def.priorityInType != num && bestTargetOfLastPriority.IsValid)
                {
                    break;
                }
                if (!PawnCanUseWorkGiver(pawn, workGiver))
                {
                    continue;
                }
                try
                {
                    Job job2 = workGiver.NonScanJob(pawn);
                    if (job2 != null)
                    {
                        return(new ThinkResult(job2, this, list[j].def.tagToGive));
                    }
                    scanner = (workGiver as WorkGiver_Scanner);
                    float closestDistSquared;
                    float bestPriority;
                    if (scanner != null)
                    {
                        if (scanner.def.scanThings)
                        {
                            Predicate <Thing>   validator  = (Thing t) => !t.IsForbidden(pawn) && scanner.HasJobOnThing(pawn, t);
                            IEnumerable <Thing> enumerable = scanner.PotentialWorkThingsGlobal(pawn);
                            Thing thing;
                            try
                            {
                                if (scanner.Prioritized)
                                {
                                    IEnumerable <Thing> enumerable2 = enumerable;
                                    if (enumerable2 == null)
                                    {
                                        enumerable2 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest);
                                    }
                                    thing = ((!scanner.AllowUnreachable) ? GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map, enumerable2, scanner.PathEndMode, TraverseParms.For(pawn, scanner.MaxPathDanger(pawn)), 9999f, validator, (Thing x) => scanner.GetPriority(pawn, x)) : GenClosest.ClosestThing_Global(pawn.Position, enumerable2, 99999f, validator, (Thing x) => scanner.GetPriority(pawn, x)));
                                }
                                else if (scanner.AllowUnreachable)
                                {
                                    IEnumerable <Thing> enumerable3 = enumerable;
                                    if (enumerable3 == null)
                                    {
                                        enumerable3 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest);
                                    }
                                    thing = GenClosest.ClosestThing_Global(pawn.Position, enumerable3, 99999f, validator);
                                }
                                else
                                {
                                    thing = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, scanner.PotentialWorkThingRequest, scanner.PathEndMode, TraverseParms.For(pawn, scanner.MaxPathDanger(pawn)), 9999f, validator, enumerable, 0, scanner.MaxRegionsToScanBeforeGlobalSearch, enumerable != null);
                                }
                            }
                            catch (Exception ex)
                            {
                                Log.Error("Error in WorkGiver: " + ex.Message);

                                thing = null;
                            }
                            if (thing != null)
                            {
                                bestTargetOfLastPriority = thing;
                                scannerWhoProvidedTarget = scanner;
                            }
                        }

                        if (scanner.def.scanCells)
                        {
                            pawnPosition       = pawn.Position;
                            closestDistSquared = 99999f;
                            bestPriority       = float.MinValue;
                            prioritized        = scanner.Prioritized;
                            allowUnreachable   = scanner.AllowUnreachable;
                            maxPathDanger      = scanner.MaxPathDanger(pawn);
                            IEnumerable <IntVec3> enumerable4 = scanner.PotentialWorkCellsGlobal(pawn);
                            IList <IntVec3>       list2;
                            if ((list2 = (enumerable4 as IList <IntVec3>)) != null)
                            {
                                for (int k = 0; k < list2.Count; k++)
                                {
                                    ProcessCell(list2[k]);
                                }
                            }
                            else
                            {
                                foreach (IntVec3 item in enumerable4)
                                {
                                    ProcessCell(item);
                                }
                            }
                        }
                    }
                    void ProcessCell(IntVec3 c)
                    {
                        bool  flag = false;
                        float num2 = (c - pawnPosition).LengthHorizontalSquared;
                        float num3 = 0f;

                        if (prioritized)
                        {
                            if (!c.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, c))
                            {
                                if (!allowUnreachable && !pawn.CanReach(c, scanner.PathEndMode, maxPathDanger))
                                {
                                    return;
                                }
                                num3 = scanner.GetPriority(pawn, c);
                                if (num3 > bestPriority || (num3 == bestPriority && num2 < closestDistSquared))
                                {
                                    flag = true;
                                }
                            }
                        }
                        else if (num2 < closestDistSquared && !c.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, c))
                        {
                            if (!allowUnreachable && !pawn.CanReach(c, scanner.PathEndMode, maxPathDanger))
                            {
                                return;
                            }
                            flag = true;
                        }
                        if (flag)
                        {
                            bestTargetOfLastPriority = new TargetInfo(c, pawn.Map);
                            scannerWhoProvidedTarget = scanner;
                            closestDistSquared       = num2;
                            bestPriority             = num3;
                        }
                    }
                }
                catch (Exception ex)
                {
                    Log.Error(pawn + " threw exception in WorkGiver " + workGiver.def.defName + ": " + ex.ToString());
                }
                finally
                {
                }
                if (bestTargetOfLastPriority.IsValid)
                {
                    Job job3 = (!bestTargetOfLastPriority.HasThing) ? scannerWhoProvidedTarget.JobOnCell(pawn, bestTargetOfLastPriority.Cell) : scannerWhoProvidedTarget.JobOnThing(pawn, bestTargetOfLastPriority.Thing);
                    if (job3 != null)
                    {
                        job3.workGiverDef = scannerWhoProvidedTarget.def;
                        return(new ThinkResult(job3, this, list[j].def.tagToGive));
                    }
                    Log.ErrorOnce(scannerWhoProvidedTarget + " provided target " + bestTargetOfLastPriority + " but yielded no actual job for pawn " + pawn + ". The CanGiveJob and JobOnX methods may not be synchronized.", 6112651);
                }
                num = workGiver.def.priorityInType;
            }
            return(ThinkResult.NoJob);
        }
 private static bool IsFeeding(WorkGiver workGiver)
 {
     return(workGiver is WorkGiver_FeedPatient || workGiver is WorkGiver_Warden_Feed);
 }
        // Method from RimWorld.JobGiver_Work.TryIssueJobPackage(Pawn pawn, JobIssueParams jobParams)
        // I modified the line if (!workGiver.ShouldSkip(pawn))
#pragma warning disable
        public ThinkResult TryIssueJobPackageDrone(Pawn pawn, bool emergency)
        {
            List <WorkGiver> list               = emergency ? pawn.workSettings.WorkGiversInOrderEmergency : pawn.workSettings.WorkGiversInOrderNormal;
            int               num               = -999;
            TargetInfo        targetInfo        = TargetInfo.Invalid;
            WorkGiver_Scanner workGiver_Scanner = null;

            for (int j = 0; j < list.Count; j++)
            {
                WorkGiver workGiver = list[j];
                if (workGiver.def.priorityInType != num && targetInfo.IsValid)
                {
                    break;
                }
                if (!workGiver.ShouldSkip(pawn))
                {
                    try
                    {
                        Job job2 = workGiver.NonScanJob(pawn);
                        if (job2 != null)
                        {
                            return(new ThinkResult(job2, null, new JobTag?(list[j].def.tagToGive), false));
                        }
                        WorkGiver_Scanner scanner = workGiver as WorkGiver_Scanner;
                        if (scanner != null)
                        {
                            if (scanner.def.scanThings)
                            {
                                Predicate <Thing>   predicate  = (Thing t) => !t.IsForbidden(pawn) && scanner.HasJobOnThing(pawn, t, false);
                                IEnumerable <Thing> enumerable = scanner.PotentialWorkThingsGlobal(pawn);
                                Thing thing;
                                if (scanner.Prioritized)
                                {
                                    IEnumerable <Thing> enumerable2 = enumerable;
                                    if (enumerable2 == null)
                                    {
                                        enumerable2 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest);
                                    }
                                    if (scanner.AllowUnreachable)
                                    {
                                        IntVec3             position  = pawn.Position;
                                        IEnumerable <Thing> searchSet = enumerable2;
                                        Predicate <Thing>   validator = predicate;
                                        thing = GenClosest.ClosestThing_Global(position, searchSet, 99999f, validator, (Thing x) => scanner.GetPriority(pawn, x));
                                    }
                                    else
                                    {
                                        IntVec3             position       = pawn.Position;
                                        Map                 map            = pawn.Map;
                                        IEnumerable <Thing> searchSet      = enumerable2;
                                        PathEndMode         pathEndMode    = scanner.PathEndMode;
                                        TraverseParms       traverseParams = TraverseParms.For(pawn, scanner.MaxPathDanger(pawn), TraverseMode.ByPawn, false);
                                        Predicate <Thing>   validator      = predicate;
                                        thing = GenClosest.ClosestThing_Global_Reachable(position, map, searchSet, pathEndMode, traverseParams, 9999f, validator, (Thing x) => scanner.GetPriority(pawn, x));
                                    }
                                }
                                else if (scanner.AllowUnreachable)
                                {
                                    IEnumerable <Thing> enumerable3 = enumerable;
                                    if (enumerable3 == null)
                                    {
                                        enumerable3 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest);
                                    }
                                    IntVec3             position  = pawn.Position;
                                    IEnumerable <Thing> searchSet = enumerable3;
                                    Predicate <Thing>   validator = predicate;
                                    thing = GenClosest.ClosestThing_Global(position, searchSet, 99999f, validator, null);
                                }
                                else
                                {
                                    IntVec3           position = pawn.Position;
                                    Map               map      = pawn.Map;
                                    ThingRequest      potentialWorkThingRequest = scanner.PotentialWorkThingRequest;
                                    PathEndMode       pathEndMode       = scanner.PathEndMode;
                                    TraverseParms     traverseParams    = TraverseParms.For(pawn, scanner.MaxPathDanger(pawn), TraverseMode.ByPawn, false);
                                    Predicate <Thing> validator         = predicate;
                                    bool              forceGlobalSearch = enumerable != null;
                                    thing = GenClosest.ClosestThingReachable(position, map, potentialWorkThingRequest, pathEndMode, traverseParams, 9999f, validator, enumerable, 0, scanner.LocalRegionsToScanFirst, forceGlobalSearch, RegionType.Set_Passable, false);
                                }
                                if (thing != null)
                                {
                                    targetInfo        = thing;
                                    workGiver_Scanner = scanner;
                                }
                            }
                            if (scanner.def.scanCells)
                            {
                                IntVec3 position2        = pawn.Position;
                                float   num2             = 99999f;
                                float   num3             = float.MinValue;
                                bool    prioritized      = scanner.Prioritized;
                                bool    allowUnreachable = scanner.AllowUnreachable;
                                Danger  maxDanger        = scanner.MaxPathDanger(pawn);
                                foreach (IntVec3 intVec in scanner.PotentialWorkCellsGlobal(pawn))
                                {
                                    bool  flag = false;
                                    float num4 = (float)(intVec - position2).LengthHorizontalSquared;
                                    float num5 = 0f;
                                    if (prioritized)
                                    {
                                        if (scanner.HasJobOnCell(pawn, intVec))
                                        {
                                            if (!allowUnreachable && !pawn.CanReach(intVec, scanner.PathEndMode, maxDanger, false, TraverseMode.ByPawn))
                                            {
                                                continue;
                                            }
                                            num5 = scanner.GetPriority(pawn, intVec);
                                            if (num5 > num3 || (num5 == num3 && num4 < num2))
                                            {
                                                flag = true;
                                            }
                                        }
                                    }
                                    else if (num4 < num2 && scanner.HasJobOnCell(pawn, intVec))
                                    {
                                        if (!allowUnreachable && !pawn.CanReach(intVec, scanner.PathEndMode, maxDanger, false, TraverseMode.ByPawn))
                                        {
                                            continue;
                                        }
                                        flag = true;
                                    }
                                    if (flag)
                                    {
                                        targetInfo        = new TargetInfo(intVec, pawn.Map, false);
                                        workGiver_Scanner = scanner;
                                        num2 = num4;
                                        num3 = num5;
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Log.Error(string.Concat(new object[]
                        {
                            pawn,
                            " threw exception in WorkGiver ",
                            workGiver.def.defName,
                            ": ",
                            ex.ToString()
                        }));
                    }
                    finally
                    {
                    }
                    if (targetInfo.IsValid)
                    {
                        pawn.mindState.lastGivenWorkType = workGiver.def.workType;
                        Job job3;
                        if (targetInfo.HasThing)
                        {
                            job3 = workGiver_Scanner.JobOnThing(pawn, targetInfo.Thing, false);
                        }
                        else
                        {
                            job3 = workGiver_Scanner.JobOnCell(pawn, targetInfo.Cell);
                        }
                        if (job3 != null)
                        {
                            return(new ThinkResult(job3, null, new JobTag?(list[j].def.tagToGive), false));
                        }
                        Log.ErrorOnce(string.Concat(new object[]
                        {
                            workGiver_Scanner,
                            " provided target ",
                            targetInfo,
                            " but yielded no actual job for pawn ",
                            pawn,
                            ". The CanGiveJob and JobOnX methods may not be synchronized."
                        }), 6112651);
                    }
                    num = workGiver.def.priorityInType;
                }
            }
            return(ThinkResult.NoJob);
        }
 private static bool IsNegotiating(WorkGiver giver)
 {
     return(giver is WorkGiver_Diplomat || giver is WorkGiver_Recruiter);
 }