Exemple #1
0
        private static Job GiverTryGiveJobPrioritized(JobGiver_Work __instance, Pawn pawn, WorkGiver giver, IntVec3 cell)
        {
            if (!__instance.PawnCanUseWorkGiver(pawn, giver))
            {
                return(null);
            }
            try
            {
                Job job = giver.NonScanJob(pawn);
                if (job != null)
                {
                    return(job);
                }
                WorkGiver_Scanner scanner = giver as WorkGiver_Scanner;
                if (scanner != null)
                {
                    if (giver.def.scanThings)
                    {
                        Predicate <Thing> predicate;
                        if (scanner is WorkGiver_DoBill workGiver_DoBill)
                        {
                            predicate = (Thing t) => !t.IsForbidden(pawn) && WorkGiver_Scanner_Patch.HasJobOnThing(workGiver_DoBill, pawn, t);
                        }
                        else
                        {
                            predicate = (Thing t) => !t.IsForbidden(pawn) && scanner.HasJobOnThing(pawn, t);
                        }

                        List <Thing> thingList = cell.GetThingList(pawn.Map);
                        for (int i = 0; i < thingList.Count; i++)
                        {
                            Thing thing = thingList[i];
                            if (scanner.PotentialWorkThingRequest.Accepts(thing) && predicate(thing))
                            {
                                Job job2 = scanner.JobOnThing(pawn, thing);
                                if (job2 != null)
                                {
                                    job2.workGiverDef = giver.def;
                                }
                                return(job2);
                            }
                        }
                    }
                    if (giver.def.scanCells && !cell.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, cell))
                    {
                        Job job3 = scanner.JobOnCell(pawn, cell);
                        if (job3 != null)
                        {
                            job3.workGiverDef = giver.def;
                        }
                        return(job3);
                    }
                }
            }
            catch (Exception ex)
            {
                Log.Error(string.Concat(pawn, " threw exception in GiverTryGiveJobTargeted on WorkGiver ", giver.def.defName, ": ", ex.ToString()));
            }
            return(null);
        }
Exemple #2
0
 private Job GiverTryGiveJobPrioritized(Pawn pawn, WorkGiver giver, IntVec3 cell)
 {
     if (!this.PawnCanUseWorkGiver(pawn, giver))
     {
         return(null);
     }
     try
     {
         Job job = giver.NonScanJob(pawn);
         if (job != null)
         {
             Job result = job;
             return(result);
         }
         WorkGiver_Scanner scanner = giver as WorkGiver_Scanner;
         if (scanner != null)
         {
             if (giver.def.scanThings)
             {
                 Predicate <Thing> predicate = (Thing t) => !t.IsForbidden(pawn) && scanner.HasJobOnThing(pawn, t, false);
                 List <Thing>      thingList = cell.GetThingList(pawn.Map);
                 for (int i = 0; i < thingList.Count; i++)
                 {
                     Thing thing = thingList[i];
                     if (scanner.PotentialWorkThingRequest.Accepts(thing) && predicate(thing))
                     {
                         //pawn.mindState.lastGivenWorkType = giver.def.workType;
                         Job result = scanner.JobOnThing(pawn, thing, false);
                         return(result);
                     }
                 }
             }
             if (giver.def.scanCells && !cell.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, cell, false))
             {
                 // pawn.mindState.lastGivenWorkType = giver.def.workType;
                 Job result = scanner.JobOnCell(pawn, cell, false);
                 return(result);
             }
         }
     }
     catch (Exception ex)
     {
         Log.Error(string.Concat(new object[]
         {
             pawn,
             " threw exception in GiverTryGiveJobTargeted on WorkGiver ",
             giver.def.defName,
             ": ",
             ex.ToString()
         }));
     }
     return(null);
 }
        private bool HasSameJobOnThing(Job job, WorkGiver_Scanner workGiverScanner, LocalTargetInfo targetInfo)
        {
            if (HasValidTarget(targetInfo) && targetInfo.HasThing)
            {
                Job getJob = workGiverScanner.JobOnThing(Meeseeks, targetInfo.Thing, true);
                if (getJob != null && getJob.def == job.def)
                {
                    return(true);
                }
            }

            return(false);
        }
Exemple #4
0
        private static ThinkResult Detour(JobGiver_Work __instance, Pawn pawn)
        {
            if (__instance.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;
                    int       refire = 0;
                    try
                    {
                        refire = refires[worker.def];
                    }
                    catch (Exception)
                    {
                        refires.Add(worker.def, 0);
                    }
                    if (refire > 0)
                    {
                        continue;
                    }


                    Job job = __instance.GiverTryGiveJobPrioritized(pawn, worker, pawn.mindState.priorityWork.Cell);
                    if (job != null)
                    {
                        job.playerForced = true;

                        return(new ThinkResult(job, __instance, workGiversByPriority[i].tagToGive));
                    }
                    refires[worker.def] = refireLength;
                }

                pawn.mindState.priorityWork.Clear();
            }

            List <WorkGiver> list = __instance.emergency ? pawn.workSettings.WorkGiversInOrderEmergency : pawn.workSettings.WorkGiversInOrderNormal;

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

            Profiler prof = null;

            for (int j = 0; j < coo; j++)
            {
                WorkGiver workGiver = list[j];
                int       refire    = 0;
                try
                {
                    refire = refires[workGiver.def];
                }
                catch (Exception)
                {
                    refires.Add(workGiver.def, 0);
                }
                if (refire > 0)
                {
                    continue;
                }

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

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

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

                    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))
                {
                    string 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
                    {
                        prof = ProfileController.Start(name, namer, workGiver.GetType(), workGiver.def, pawn, meth);
                        Job job2 = workGiver.NonScanJob(pawn);
                        prof.Stop();

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

                        if (workGiver is WorkGiver_Scanner scanner)
                        {
                            if (scanner.def.scanThings)
                            {
                                bool Predicate(Thing t)
                                {
                                    return(!t.IsForbidden(pawn) && scanner.HasJobOnThing(pawn, t));
                                }
                                prof = ProfileController.Start(name, namer, workGiver.GetType(), workGiver.def, pawn, meth);
                                IEnumerable <Thing> enumerable = scanner.PotentialWorkThingsGlobal(pawn)?.Where(x => scanner.HasJobOnThing(pawn, x));

                                //if (scanner is WorkGiver_Repair repair)
                                //{
                                //    foreach (var repairableBuilding in pawn.Map.listerBuildingsRepairable.RepairableBuildings(pawn.Faction))
                                //    {
                                //        Log.Warning($"repair scan on {repairableBuilding}");
                                //    }
                                //}

                                Thing thing;
                                if (scanner.Prioritized)
                                {
                                    IEnumerable <Thing> 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
                                    {
                                        TraverseParms 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, Predicate,
                                                                                         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, Predicate);
                                }
                                else
                                {
                                    giver = workGiver;
                                    key   = name;

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

                                prof.Stop();

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


                            if (scanner.def.scanCells)
                            {
                                prof = ProfileController.Start(name, namer, workGiver.GetType(), workGiver.def, pawn, meth);
                                float  closestDistSquared = 99999f;
                                float  bestPriority       = 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;
                                    int   num4 = (intVec - pawn.Position).LengthHorizontalSquared;
                                    float num5 = 0f;
                                    if (prioritized)
                                    {
                                        if (!intVec.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, intVec))
                                        {
                                            if (!allowUnreachable &&
                                                !pawn.CanReach(intVec, scanner.PathEndMode, maxDanger))
                                            {
                                                goto jamalam;
                                            }

                                            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))
                                        {
                                            goto jamalam;
                                        }

                                        flag = true;
                                    }

                                    if (flag)
                                    {
                                        bestTargetOfLastPriority = new TargetInfo(intVec, pawn.Map);
                                        scannerWhoProvidedTarget = scanner;
                                        closestDistSquared       = num4;
                                        bestPriority             = num5;
                                    }
                                }
                                prof.Stop();
                            }
                        }
                    }
                    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;
                        prof = ProfileController.Start(name, namer, workGiver.GetType(), workGiver.def, pawn, meth);
                        Job job3;
                        if (bestTargetOfLastPriority.HasThing)
                        {
                            job3 = scannerWhoProvidedTarget.JobOnThing(pawn, bestTargetOfLastPriority.Thing);
                        }
                        else
                        {
                            job3 = scannerWhoProvidedTarget.JobOnCell(pawn, bestTargetOfLastPriority.Cell);
                        }
                        prof.Stop();
                        if (job3 != null)
                        {
                            job3.workGiverDef = scannerWhoProvidedTarget.def;
                            return(new ThinkResult(job3, __instance, list[j].def.tagToGive));
                        }

                        Log.ErrorOnce(
                            string.Concat("Analyzer: ", 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;
                }

jamalam:
                refires[workGiver.def] = refireLength;
            }

            return(ThinkResult.NoJob);
        }
Exemple #5
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);
        }
        public override ThinkResult TryIssueJobPackage(Pawn pawn, JobIssueParams jobParams)
        {
            var need = pawn.needs.TryGetNeed <Need_Motivation>();

            if (pawn.timetable == null)
            {
                WorkSettings.InitWorkSettings(pawn);
            }
            if (HealthAIUtility.ShouldHaveSurgeryDoneNow(pawn))
            {
                return(ThinkResult.NoJob);
            }

            if (PrisonLaborPrefs.EnableFullHealRest && (HealthAIUtility.ShouldBeTendedNowByPlayer(pawn) || HealthAIUtility.ShouldSeekMedicalRest(pawn)))
            {
                return(ThinkResult.NoJob);
            }
            //Check medical assistance, fed, and rest if not override
            if (!PrisonLaborUtility.WorkTime(pawn))
            {
                Other.Tutorials.Timetable();
                if (need != null)
                {
                    need.IsPrisonerWorking = false;
                }
                return(ThinkResult.NoJob);
            }
            //Check motivation
            if (PrisonLaborPrefs.EnableMotivationMechanics && (need == null || need.IsLazy))
            {
                return(ThinkResult.NoJob);
            }
            //Work prisoners will do
            WorkSettings.InitWorkSettings(pawn);
            var workList = pawn.workSettings.WorkGiversInOrderNormal;

            //TODO check this
            //workList.RemoveAll(workGiver => workGiver.def.defName == "GrowerSow");
            if (need != null)
            {
                need.IsPrisonerWorking = false;
            }

            var num        = -999;
            var targetInfo = TargetInfo.Invalid;
            WorkGiver_Scanner workGiver_Scanner = null;

            for (var j = 0; j < workList.Count; j++)
            {
                var workGiver = workList[j];
                if (workGiver.def.priorityInType != num && targetInfo.IsValid)
                {
                    break;
                }
                if (PawnCanUseWorkGiver(pawn, workGiver))
                {
                    try
                    {
                        var job2 = workGiver.NonScanJob(pawn);
                        if (job2 != null)
                        {
                            if (need != null)
                            {
                                need.IsPrisonerWorking = true;
                            }
                            return(new ThinkResult(job2, this, workList[j].def.tagToGive));
                        }
                        var scanner = workGiver as WorkGiver_Scanner;
                        if (scanner != null)
                        {
                            if (workGiver.def.scanThings)
                            {
                                Predicate <Thing> predicate = t =>
                                                              !t.IsForbidden(pawn) && scanner.HasJobOnThing(pawn, t, false);
                                var   enumerable = scanner.PotentialWorkThingsGlobal(pawn);
                                Thing thing;
                                if (scanner.Prioritized)
                                {
                                    var enumerable2 = enumerable;
                                    if (enumerable2 == null)
                                    {
                                        enumerable2 =
                                            pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest);
                                    }
                                    var validator = predicate;
                                    thing = GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map,
                                                                                     enumerable2, scanner.PathEndMode,
                                                                                     TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), 9999f,
                                                                                     validator, x => scanner.GetPriority(pawn, x));
                                }
                                else
                                {
                                    var validator         = predicate;
                                    var 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.MaxRegionsToScanBeforeGlobalSearch, forceGlobalSearch,
                                                                             RegionType.Set_Passable, false);
                                }
                                if (thing != null)
                                {
                                    targetInfo        = thing;
                                    workGiver_Scanner = scanner;
                                }
                            }
                            if (workGiver.def.scanCells)
                            {
                                var position    = pawn.Position;
                                var num2        = 99999f;
                                var num3        = -3.40282347E+38f;
                                var prioritized = scanner.Prioritized;
                                foreach (var current in scanner.PotentialWorkCellsGlobal(pawn))
                                {
                                    var   flag = false;
                                    float num4 = (current - position).LengthHorizontalSquared;
                                    if (prioritized)
                                    {
                                        if (!current.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, current))
                                        {
                                            var 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(pawn, " threw exception in WorkGiver ", workGiver.def.defName, ": ",
                                                ex.ToString()));
                    }
                    finally
                    {
                    }
                    if (targetInfo.IsValid)
                    {
                        Job job3;
                        if (targetInfo.HasThing)
                        {
                            job3 = workGiver_Scanner.JobOnThing(pawn, targetInfo.Thing, false);
                        }
                        else
                        {
                            job3 = workGiver_Scanner.JobOnCell(pawn, targetInfo.Cell);
                        }
                        if (job3 != null)
                        {
                            job3.workGiverDef = workGiver.def;
                            if (need != null)
                            {
                                need.IsPrisonerWorking = true;
                            }
                            return(new ThinkResult(job3, this, workList[j].def.tagToGive));
                        }
                        Log.ErrorOnce(
                            string.Concat(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);
        }
        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);
        }
 public override Job JobOnThing(Pawn pawn, Thing t, bool forced = false)
 {
     return(wrappedScanner?.JobOnThing(pawn, t, forced) ?? base.JobOnThing(pawn, t, forced));
 }
        protected override Job TryGiveJob(Pawn pawn)
        {
            if (workGiverDef != null)
            {
                int               num               = -999;
                TargetInfo        targetInfo        = TargetInfo.Invalid;
                WorkGiver_Scanner workGiver_Scanner = null;

                WorkGiver workGiver = workGiverDef.Worker;
                if (workGiver != null)
                {
                    if (workGiver.def.priorityInType != num && targetInfo.IsValid)
                    {
                        return(null);
                    }
                    if (this.PawnCanUseWorkGiver(pawn, workGiver))
                    {
                        try
                        {
                            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;
                                    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;
                                        thing = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, scanner.PotentialWorkThingRequest, scanner.PathEndMode, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), 9999f, validator, enumerable, scanner.MaxRegionsToScanBeforeGlobalSearch);
                                    }
                                    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        = new TargetInfo(current, pawn.Map, false);
                                            workGiver_Scanner = scanner;
                                            num2 = lengthHorizontalSquared;
                                        }
                                    }
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            Log.Error($"{pawn} threw exception in WorkGiver {workGiver.def.defName}: {ex.ToString()}");
                        }
                        finally
                        {
                        }
                        if (targetInfo.IsValid)
                        {
                            //pawn.mindState. = 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($"{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);
        }
Exemple #10
0
        public override ThinkResult TryIssueJobPackage(Pawn pawn, JobIssueParams jobParams)
        {
            X2_AIRobot robot = pawn as X2_AIRobot;

            if (robot == null)
            {
                return(ThinkResult.NoJob);
            }

            //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;

            for (int j = 0; j < list.Count; j++)
            {
                WorkGiver workGiver = list[j];
                if (workGiver.def.priorityInType != num && targetInfo.IsValid)
                {
                    break;
                }
                if (this.PawnCanUseWorkGiver(pawn, workGiver))
                {
                    try
                    {
                        Job job2 = workGiver.NonScanJob(pawn);
                        if (job2 != null)
                        {
                            return(new ThinkResult(job2, this, 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 = null;
                                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;

                                        try
                                        {
                                            thing = GenClosest.ClosestThing_Global(position, 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
                                    {
                                        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;
                                        try
                                        {
                                            thing = GenClosest.ClosestThing_Global_Reachable(position, 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;
                                        }
                                    }
                                }
                                if (!scanner.Prioritized && 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;
                                    try {
                                        thing = GenClosest.ClosestThing_Global(position, 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;
                                    }
                                }
                                if (!scanner.AllowUnreachable || thing == null)
                                {
                                    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;

                                    try
                                    {
                                        thing = GenClosest.ClosestThingReachable(position, map, potentialWorkThingRequest, pathEndMode, traverseParams, 9999f, validator, enumerable, 0, scanner.LocalRegionsToScanFirst, forceGlobalSearch, RegionType.Set_Passable, false);
                                    }
                                    // Added try-catch for a try of error handling
                                    catch //(Exception ex)
                                    {
                                        Log.Warning(string.Concat(new object[]
                                        {
                                            pawn,
                                            " threw exception in X2_JobGiver_Work ",
                                            workGiver.def.defName,
                                            " but we'll try again.. "
                                            //ex.ToString()
                                        }));
                                        if (enumerable != null)
                                        {
                                            try {
                                                thing = GenClosest.ClosestThing_Global(position, enumerable, 40f, validator, null);
                                            } catch {
                                                thing = null;
                                            }
                                        }
                                        else
                                        {
                                            thing = null;
                                        }
                                    }
                                }
                                if (thing != null)
                                {
                                    targetInfo        = thing;
                                    workGiver_Scanner = scanner;
                                }
                            }
                            if (scanner.def.scanCells)
                            {
                                IntVec3 position2        = 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 current in scanner.PotentialWorkCellsGlobal(pawn))
                                {
                                    bool  flag = false;
                                    float num4 = (float)(current - position2).LengthHorizontalSquared;
                                    float num5 = 0f;
                                    if (prioritized)
                                    {
                                        if (scanner.HasJobOnCell(pawn, current))
                                        {
                                            if (!allowUnreachable && !pawn.CanReach(current, scanner.PathEndMode, maxDanger, false, TraverseMode.ByPawn))
                                            {
                                                continue;
                                            }
                                            num5 = scanner.GetPriority(pawn, current);
                                            if (num5 > num3 || (num5 == num3 && num4 < num2))
                                            {
                                                flag = true;
                                            }
                                        }
                                    }
                                    else if (num4 < num2 && scanner.HasJobOnCell(pawn, current))
                                    {
                                        if (!allowUnreachable && !pawn.CanReach(current, scanner.PathEndMode, maxDanger, false, TraverseMode.ByPawn))
                                        {
                                            continue;
                                        }
                                        flag = true;
                                    }
                                    if (flag)
                                    {
                                        targetInfo        = new TargetInfo(current, 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, this, 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);
        }
        public static bool TryIssueJobPackage(JobGiver_Work __instance, ref ThinkResult __result, Pawn pawn, JobIssueParams jobParams)
        {
            if (__instance.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;
                            __result         = new ThinkResult(job, __instance, workGiversByPriority[i].tagToGive);
                            return(false);
                        }
                    }
                }
                pawn.mindState.priorityWork.Clear();
            }
            List <WorkGiver> list = (!__instance.emergency) ? pawn.workSettings.WorkGiversInOrderNormal : pawn.workSettings.WorkGiversInOrderEmergency;
            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)
                    {
                        __result = new ThinkResult(job2, __instance, workGiver.def.tagToGive);
                        return(false);
                    }
                    scanner = (workGiver as WorkGiver_Scanner);

                    if (scanner != null)
                    {
                        if (scanner.def.scanThings)
                        {
                            Predicate <Thing>   validator  = (Thing t) => !t.IsForbidden(pawn) && scanner.HasJobOnThing(pawn, t);                         //WorkGiver_CleanFilth_Patch.HasJobOnThing
                            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
                            {
                                //TODO: use better ThingRequest groups
                                if (
                                    workGiver.def.defName.Equals("DoctorFeedAnimals") ||
                                    workGiver.def.defName.Equals("DoctorFeedHumanlikes") ||
                                    workGiver.def.defName.Equals("DoctorTendToAnimals") ||
                                    workGiver.def.defName.Equals("DoctorTendToHumanlikes") ||
                                    workGiver.def.defName.Equals("DoBillsUseCraftingSpot") ||
                                    workGiver.def.defName.Equals("DoctorTendEmergency") ||
                                    workGiver.def.defName.Equals("HaulCorpses") ||
                                    workGiver.def.defName.Equals("FillFermentingBarrel") ||
                                    //workGiver.def.defName.Equals("HaulGeneral") ||
                                    workGiver.def.defName.Equals("HandlingFeedPatientAnimals") ||
                                    workGiver.def.defName.Equals("DoBillsButcherFlesh") ||
                                    workGiver.def.defName.Equals("DoBillsCook") ||
                                    workGiver.def.defName.Equals("DoBillsMakeApparel") ||
                                    workGiver.def.defName.Equals("Train") ||
                                    workGiver.def.defName.Equals("VisitSickPawn")
                                    )
                                {
                                    //ClosestThingReachable2 checks validator before CanReach
                                    DateTime startTime = DateTime.Now;

                                    //long
                                    thing = GenClosest_Patch.ClosestThingReachable2(pawn.Position, pawn.Map, scanner.PotentialWorkThingRequest, scanner.PathEndMode, TraverseParms.For(pawn, scanner.MaxPathDanger(pawn)), 9999f, validator, enumerable, 0, scanner.MaxRegionsToScanBeforeGlobalSearch, enumerable != null);

                                    if (DateTime.Now.Subtract(startTime).TotalMilliseconds > 200 && RimThreadedSettings.show200mswarning)
                                    {
                                        Log.Warning("ClosestThingReachable2 Took " + DateTime.Now.Subtract(startTime).TotalMilliseconds + "ms  for workGiver: " + workGiver.def.defName);
                                    }
                                }
                                else
                                {
                                    DateTime startTime = DateTime.Now;
                                    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 (DateTime.Now.Subtract(startTime).TotalMilliseconds > 200 && RimThreadedSettings.show200mswarning)
                                    {
                                        Log.Warning("ClosestThingReachable Took " + DateTime.Now.Subtract(startTime).TotalMilliseconds + "ms for workGiver: " + workGiver.def.defName);
                                    }
                                }
                            }
                            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;
                            if (scanner is WorkGiver_Grower workGiver_Grower)
                            {
                                RimThreaded.WorkGiver_GrowerSow_Patch_JobOnCell = 0;

                                enumerable4 = WorkGiver_Grower_Patch.PotentialWorkCellsGlobalWithoutCanReach(workGiver_Grower, pawn);
                                List <IntVec3> SortedList = enumerable4.OrderBy(o => (o - pawnPosition).LengthHorizontalSquared).ToList();
                                foreach (IntVec3 item in SortedList)
                                {
                                    ProcessCell(item);                                     //long
                                }

                                //Log.Message(RimThreaded.WorkGiver_GrowerSow_Patch_JobOnCell.ToString());
                            }
                            else
                            {
                                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)
                    {
                        float newDistanceSquared = (c - pawnPosition).LengthHorizontalSquared;
                        float newPriority        = 0f;

                        if (prioritized)
                        {
                            newPriority = scanner.GetPriority(pawn, c);
                            if (newPriority < bestPriority)
                            {
                                return;
                            }
                        }

                        if (newDistanceSquared < closestDistSquared && !c.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, c))
                        {
                            if (!allowUnreachable && !pawn.CanReach(c, scanner.PathEndMode, maxPathDanger))
                            {
                                return;
                            }

                            bestTargetOfLastPriority = new TargetInfo(c, pawn.Map);
                            scannerWhoProvidedTarget = scanner;
                            closestDistSquared       = newDistanceSquared;
                            bestPriority             = newPriority;
                        }
                    }
                }
                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;
                        __result          = new ThinkResult(job3, __instance, list[j].def.tagToGive);
                        return(false);
                    }
                    //HACK - I know. I'm awful.
                    //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);
                    Log.Warning(string.Concat(scannerWhoProvidedTarget, " provided target ", bestTargetOfLastPriority, " but yielded no actual job for pawn ", pawn, ". The CanGiveJob and JobOnX methods may not be synchronized."));
                }
                num = workGiver.def.priorityInType;
            }
            __result = ThinkResult.NoJob;
            return(false);
        }
Exemple #12
0
        public override ThinkResult TryIssueJobPackage(Pawn pawn, JobIssueParams jobParams)
        {
            Droid d = null;

            if (pawn is Droid)
            {
                d = pawn as Droid;
            }
            else
            {
                return(ThinkResult.NoJob);
            }
            List <WorkGiver> list               = emergency ? d.workManager.WorkGiversInOrderEmergency : d.workManager.WorkGiversInOrder;
            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))
                {
                    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;
                                        thing = GenClosest.ClosestThing_Global(intVec, searchSet, 99999f, validator, (Thing x) => scanner.GetPriority(pawn, x));
                                    }
                                    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;
                                        thing = GenClosest.ClosestThing_Global_Reachable(intVec, 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);
                                    }
                                    intVec = pawn.Position;
                                    IEnumerable <Thing> searchSet = enumerable3;
                                    Predicate <Thing>   validator = predicate;
                                    thing = GenClosest.ClosestThing_Global(intVec, searchSet, 99999f, validator, 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;
                                    thing = GenClosest.ClosestThingReachable(intVec, 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 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 (scanner.HasJobOnCell(pawn, item))
                                        {
                                            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 && scanner.HasJobOnCell(pawn, item))
                                    {
                                        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());
                    }
                    finally
                    {
                    }
                    if (targetInfo.IsValid)
                    {
                        pawn.mindState.lastGivenWorkType = workGiver.def.workType;
                        Job job3 = (!targetInfo.HasThing) ? workGiver_Scanner.JobOnCell(pawn, targetInfo.Cell) : workGiver_Scanner.JobOnThing(pawn, targetInfo.Thing, false);
                        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);
                    }
                    num = workGiver.def.priorityInType;
                }
            }
            return(ThinkResult.NoJob);
        }
Exemple #13
0
        public static bool TryIssueJobPackage(JobGiver_Work __instance, ref ThinkResult __result, Pawn pawn, JobIssueParams jobParams)
        {
            if (__instance.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;
                            __result         = new ThinkResult(job, __instance, workGiversByPriority[i].tagToGive);
                            return(false);
                        }
                    }
                }
                pawn.mindState.priorityWork.Clear();
            }
            List <WorkGiver> list = (!__instance.emergency) ? pawn.workSettings.WorkGiversInOrderNormal : pawn.workSettings.WorkGiversInOrderEmergency;
            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)
                    {
                        __result = new ThinkResult(job2, __instance, list[j].def.tagToGive);
                        return(false);
                    }
                    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;
                        __result          = new ThinkResult(job3, __instance, list[j].def.tagToGive);
                        return(false);
                    }
                    //HACK - I know. I'm awful.
                    //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);
                    Log.Warning(string.Concat(scannerWhoProvidedTarget, " provided target ", bestTargetOfLastPriority, " but yielded no actual job for pawn ", pawn, ". The CanGiveJob and JobOnX methods may not be synchronized."));
                }
                num = workGiver.def.priorityInType;
            }
            __result = ThinkResult.NoJob;
            return(false);
        }
        public void AddJobTarget(SavedTargetInfo target, bool firstTarget = false)
        {
            if (jobTargets.Contains(target))
            {
                return;
            }

            if (target.HasThing && savedJob.bill != null)
            {
                MeeseeksBillStorage billStorage = Current.Game.World.GetComponent <MeeseeksBillStorage>();

                if (firstTarget)
                {
                    billStorage.SaveBill(savedJob.bill);
                    savedJob.bill = billStorage.GetDuplicateBillFromOriginal(savedJob.bill);
                    savedJob.bill.billStack.billGiver = target.Thing as IBillGiver;
                }

                WorkGiver_Scanner workGiverScanner = savedJob.workGiverDef.Worker as WorkGiver_Scanner;
                if (workGiverScanner != null)
                {
                    Job job = workGiverScanner.JobOnThing(Meeseeks, target.Thing, true);
                    if (job != null && job.bill != null)
                    {
                        billStorage.SaveBill(job.bill);
                        target.bill = billStorage.GetDuplicateBillFromOriginal(job.bill);
                        target.bill.billStack.billGiver = target.Thing as IBillGiver;
                    }
                }
            }
            else if (target.HasThing && savedJob.IsConstruction)
            {
                ThingDef   thingDefToBuild   = null;
                TerrainDef terrainDefToBuild = null;
                ThingDef   stuffDefToUse     = null;

                Blueprint_Build blueprint = target.Thing as Blueprint_Build;
                Frame           frame     = target.Thing as Frame;

                if (blueprint != null)
                {
                    thingDefToBuild   = blueprint.def.entityDefToBuild as ThingDef;
                    terrainDefToBuild = blueprint.def.entityDefToBuild as TerrainDef;
                    stuffDefToUse     = blueprint.stuffToUse;
                }
                else if (frame != null)
                {
                    thingDefToBuild   = frame.def.entityDefToBuild as ThingDef;
                    terrainDefToBuild = frame.def.entityDefToBuild as TerrainDef;
                    stuffDefToUse     = frame.Stuff;
                }

                if (thingDefToBuild != null)
                {
                    target.blueprintThingDef = thingDefToBuild;
                }
                else if (terrainDefToBuild != null)
                {
                    target.blueprintTerrainDef = terrainDefToBuild;
                }

                target.blueprintStuff    = stuffDefToUse;
                target.blueprintRotation = target.Thing.Rotation;

                // Redirect job to the cell so that we can continue various construction phases and replace blueprint if needed
                target.target = target.Cell;
            }
            else if (target.HasThing && savedJob.IsTraining)
            {
                target.trainable = (target.Thing as Pawn).training.NextTrainableToTrain();
            }

            jobTargets.Add(target);
        }
Exemple #15
0
        protected override Job TryGiveJob(Pawn pawn)
        {
            ArcBaseRobot bot = pawn as ArcBaseRobot;

            Job result;

            if (bot == null)
            {
                result = null;
            }
            else
            {
                List <WorkGiver> workGivers         = bot.GetWorkGivers(false);
                int               num               = -999;
                TargetInfo        targetInfo        = TargetInfo.Invalid;
                WorkGiver_Scanner workGiver_Scanner = null;
                for (int i = 0; i < workGivers.Count; i++)
                {
                    WorkGiver workGiver = workGivers [i];
                    if (workGiver.def.priorityInType != num &&
                        targetInfo.IsValid)
                    {
                        break;
                    }
                    if (this.PawnCanUseWorkGiver(pawn, workGiver))
                    {
                        try {
                            Job job = workGiver.NonScanJob(pawn);
                            if (job != null)
                            {
                                result = job;
                                return(result);
                            }
                            WorkGiver_Scanner scanner = workGiver as WorkGiver_Scanner;

                            if (scanner != null)
                            {
                                if (workGiver.def.scanThings)
                                {
                                    Predicate <Thing>   predicate  = (Thing t) => !ForbidUtility.IsForbidden(t, 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> predicate2 = predicate;
                                        thing = GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map, enumerable2, scanner.PathEndMode, TraverseParms.For(pawn, Danger.Deadly, 0, false), 9999, predicate2, (Thing x) => scanner.GetPriority(pawn, x));
                                    }
                                    else
                                    {
                                        Predicate <Thing> predicate3 = predicate;
                                        bool flag7 = enumerable != null;
                                        thing = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, scanner.PotentialWorkThingRequest, scanner.PathEndMode, TraverseParms.For(pawn, Danger.Deadly, 0, false), 9999, predicate3, enumerable, 0, scanner.MaxRegionsToScanBeforeGlobalSearch, flag7, RegionType.Set_Passable, false);
                                    }
                                    if (thing != null)
                                    {
                                        targetInfo        = thing;
                                        workGiver_Scanner = scanner;
                                    }
                                }

                                if (workGiver.def.scanCells)
                                {
                                    IntVec3 position     = pawn.Position;
                                    float   num2         = 99999;
                                    float   num3         = float.MinValue;
                                    bool    prioritized2 = scanner.Prioritized;
                                    foreach (IntVec3 current in scanner.PotentialWorkCellsGlobal(pawn))
                                    {
                                        bool  flag9 = false;
                                        float num4  = (float)(current - position).LengthHorizontalSquared;
                                        if (prioritized2)
                                        {
                                            if (!ForbidUtility.IsForbidden(current, pawn) &&
                                                scanner.HasJobOnCell(pawn, current))
                                            {
                                                float priority = scanner.GetPriority(pawn, current);
                                                if (priority > num3 ||
                                                    (priority == num3 && num4 < num2))
                                                {
                                                    flag9 = true;
                                                    num3  = priority;
                                                }
                                            }
                                        }
                                        else
                                        {
                                            if (num4 < num2 &&
                                                !ForbidUtility.IsForbidden(current, pawn) &&
                                                scanner.HasJobOnCell(pawn, current))
                                            {
                                                flag9 = true;
                                            }
                                        }
                                        if (flag9)
                                        {
                                            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()
                            }));
                        }

                        if (targetInfo.IsValid)
                        {
                            //pawn.workSettings.lastGivenWorkType = workGiver.def.workType;
                            Job job2 = workGiver_Scanner.JobOnThing(pawn, targetInfo.Thing, false);

                            if (job2 != null)
                            {
                                result = job2;
                                return(result);
                            }
                            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;
                    }
                }
                result = null;
            }
            return(result);
        }
Exemple #16
0
 public override Job JobOnThing(Pawn pawn, Thing t, bool forced = false) => wrappedGiver.JobOnThing(pawn, t, forced);
Exemple #17
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);
        }
Exemple #18
0
        public override ThinkResult TryIssueJobPackage(Pawn pawn, JobIssueParams jobParams)
        {
            int               num               = -999;
            TargetInfo        targetInfo        = TargetInfo.Invalid;
            WorkGiver_Scanner workGiver_Scanner = null;

            WorkGiver workGiver = DefDatabase <WorkGiverDef> .GetNamed("Mine", true).Worker;

            if (workGiver.def.priorityInType != num && targetInfo.IsValid)
            {
                // break;
            }
            else
            {
                if (this.PawnCanUseWorkGiver(pawn, workGiver))
                {
                    try
                    {
                        Job job2 = workGiver.NonScanJob(pawn);
                        if (job2 != null)
                        {
                            return(new ThinkResult(job2, this, new JobTag?(workGiver.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.MaxRegionsToScanBeforeGlobalSearch, 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             = -3.40282347E+38f;
                                bool    prioritized      = scanner.Prioritized;
                                bool    allowUnreachable = scanner.AllowUnreachable;
                                Danger  maxDanger        = scanner.MaxPathDanger(pawn);
                                foreach (IntVec3 current in scanner.PotentialWorkCellsGlobal(pawn))
                                {
                                    bool  flag = false;
                                    float num4 = (float)(current - position2).LengthHorizontalSquared;
                                    float num5 = 0f;
                                    if (prioritized)
                                    {
                                        if (!current.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, current, false))
                                        {
                                            if (!allowUnreachable && !pawn.CanReach(current, scanner.PathEndMode, maxDanger, false, false, TraverseMode.ByPawn))
                                            {
                                                continue;
                                            }
                                            num5 = scanner.GetPriority(pawn, current);
                                            if (num5 > num3 || (num5 == num3 && num4 < num2))
                                            {
                                                flag = true;
                                            }
                                        }
                                    }
                                    else if (num4 < num2 && !current.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, current, false))
                                    {
                                        if (!allowUnreachable && !pawn.CanReach(current, scanner.PathEndMode, maxDanger, false, false, TraverseMode.ByPawn))
                                        {
                                            continue;
                                        }
                                        flag = true;
                                    }
                                    if (flag)
                                    {
                                        targetInfo        = new TargetInfo(current, 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)
                    {
                        Job job3;
                        if (targetInfo.HasThing)
                        {
                            job3 = workGiver_Scanner.JobOnThing(pawn, targetInfo.Thing, false);
                        }
                        else
                        {
                            job3 = workGiver_Scanner.JobOnCell(pawn, targetInfo.Cell, false);
                        }
                        if (job3 != null)
                        {
                            return(new ThinkResult(job3, this, new JobTag?(workGiver.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);
        }
        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;
            }
        }
        // Token: 0x06000005 RID: 5 RVA: 0x000027F0 File Offset: 0x000009F0
        private Job GiverTryGiveJobPrioritized(Pawn pawn, WorkGiver giver, IntVec3 cell)
        {
            bool flag = !this.PawnCanUseWorkGiver(pawn, giver);
            Job  result;

            if (flag)
            {
                result = null;
            }
            else
            {
                try
                {
                    Job  job   = giver.NonScanJob(pawn);
                    bool flag2 = job != null;
                    if (flag2)
                    {
                        return(job);
                    }
                    WorkGiver_Scanner scanner = giver as WorkGiver_Scanner;
                    bool flag3 = scanner != null;
                    if (flag3)
                    {
                        bool scanThings = giver.def.scanThings;
                        if (scanThings)
                        {
                            Predicate <Thing> predicate = (Thing t) => !t.IsForbidden(pawn) && scanner.HasJobOnThing(pawn, t, false);
                            List <Thing>      thingList = cell.GetThingList(pawn.Map);
                            for (int i = 0; i < thingList.Count; i++)
                            {
                                Thing thing = thingList[i];
                                bool  flag4 = scanner.PotentialWorkThingRequest.Accepts(thing) && predicate(thing);
                                if (flag4)
                                {
                                    Job  job2  = scanner.JobOnThing(pawn, thing, false);
                                    bool flag5 = job2 != null;
                                    if (flag5)
                                    {
                                        job2.workGiverDef = giver.def;
                                    }
                                    return(job2);
                                }
                            }
                        }
                        bool flag6 = giver.def.scanCells && !cell.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, cell, false);
                        if (flag6)
                        {
                            Job  job3  = scanner.JobOnCell(pawn, cell, false);
                            bool flag7 = job3 != null;
                            if (flag7)
                            {
                                job3.workGiverDef = giver.def;
                            }
                            return(job3);
                        }
                    }
                }
                catch (Exception ex)
                {
                    Log.Error(string.Concat(new object[]
                    {
                        pawn,
                        " threw exception in GiverTryGiveJobTargeted on WorkGiver ",
                        giver.def.defName,
                        ": ",
                        ex.ToString()
                    }), false);
                }
                result = null;
            }
            return(result);
        }
        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);
        }
        // Token: 0x06000003 RID: 3 RVA: 0x0000212C File Offset: 0x0000032C
        public override ThinkResult TryIssueJobPackage(Pawn pawn, JobIssueParams jobParams)
        {
            bool isPrioritized = pawn.mindState.priorityWork.IsPrioritized;

            if (isPrioritized)
            {
                List <WorkGiverDef> workGiversByPriority = pawn.mindState.priorityWork.WorkGiver.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);
                    bool      flag   = job != null;
                    if (flag)
                    {
                        job.playerForced = true;
                        return(new ThinkResult(job, this, new JobTag?(workGiversByPriority[i].tagToGive), false));
                    }
                }
                pawn.mindState.priorityWork.Clear();
            }
            int               num               = -999;
            TargetInfo        targetInfo        = TargetInfo.Invalid;
            WorkGiver_Scanner workGiver_Scanner = null;
            bool              flag2             = this.workGiverDef != null;

            if (flag2)
            {
                WorkGiver worker2 = this.workGiverDef.Worker;
                bool      flag3   = worker2.def.priorityInType != num && targetInfo.IsValid;
                if (flag3)
                {
                    return(ThinkResult.NoJob);
                }
                bool flag4 = this.PawnCanUseWorkGiver(pawn, worker2);
                if (flag4)
                {
                    try
                    {
                        Job  job2  = worker2.NonScanJob(pawn);
                        bool flag5 = job2 != null;
                        if (flag5)
                        {
                            return(new ThinkResult(job2, this, new JobTag?(this.workGiverDef.tagToGive), false));
                        }
                        WorkGiver_Scanner scanner = worker2 as WorkGiver_Scanner;
                        bool flag6 = scanner != null;
                        if (flag6)
                        {
                            bool scanThings = worker2.def.scanThings;
                            if (scanThings)
                            {
                                Predicate <Thing>   predicate  = (Thing t) => !t.IsForbidden(pawn) && scanner.HasJobOnThing(pawn, t, false);
                                IEnumerable <Thing> enumerable = scanner.PotentialWorkThingsGlobal(pawn);
                                bool  prioritized = scanner.Prioritized;
                                Thing thing;
                                if (prioritized)
                                {
                                    IEnumerable <Thing> enumerable2 = enumerable;
                                    bool flag7 = enumerable2 == null;
                                    if (flag7)
                                    {
                                        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> validator2 = predicate;
                                    bool forceAllowGlobalSearch  = enumerable != null;
                                    thing = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, scanner.PotentialWorkThingRequest, scanner.PathEndMode, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), 9999f, validator2, enumerable, 0, scanner.MaxRegionsToScanBeforeGlobalSearch, forceAllowGlobalSearch, RegionType.Set_Passable, false);
                                }
                                bool flag8 = thing != null;
                                if (flag8)
                                {
                                    targetInfo        = thing;
                                    workGiver_Scanner = scanner;
                                }
                            }
                            bool scanCells = worker2.def.scanCells;
                            if (scanCells)
                            {
                                IntVec3 position     = pawn.Position;
                                float   num2         = 99999f;
                                float   num3         = float.MinValue;
                                bool    prioritized2 = scanner.Prioritized;
                                foreach (IntVec3 intVec in scanner.PotentialWorkCellsGlobal(pawn))
                                {
                                    bool  flag9  = false;
                                    float num4   = (float)(intVec - position).LengthHorizontalSquared;
                                    bool  flag10 = prioritized2;
                                    if (flag10)
                                    {
                                        bool flag11 = !intVec.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, intVec, false);
                                        if (flag11)
                                        {
                                            float priority = scanner.GetPriority(pawn, intVec);
                                            bool  flag12   = priority > num3 || (priority == num3 && num4 < num2);
                                            if (flag12)
                                            {
                                                flag9 = true;
                                                num3  = priority;
                                            }
                                        }
                                    }
                                    else
                                    {
                                        bool flag13 = num4 < num2 && !intVec.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, intVec, false);
                                        if (flag13)
                                        {
                                            flag9 = true;
                                        }
                                    }
                                    bool flag14 = flag9;
                                    if (flag14)
                                    {
                                        targetInfo        = new TargetInfo(intVec, pawn.Map, false);
                                        workGiver_Scanner = scanner;
                                        num2 = num4;
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Log.Message(string.Concat(new object[]
                        {
                            pawn,
                            " threw exception DONT WANT LAH in WorkGiver ",
                            worker2.def.defName,
                            ": ",
                            ex.ToString()
                        }), false);
                    }
                    finally
                    {
                    }
                    bool isValid = targetInfo.IsValid;
                    if (isValid)
                    {
                        bool hasThing = targetInfo.HasThing;
                        Job  job3;
                        if (hasThing)
                        {
                            job3 = workGiver_Scanner.JobOnThing(pawn, targetInfo.Thing, false);
                        }
                        else
                        {
                            job3 = workGiver_Scanner.JobOnCell(pawn, targetInfo.Cell, false);
                        }
                        bool flag15 = job3 != null;
                        if (flag15)
                        {
                            return(new ThinkResult(job3, this, new JobTag?(this.workGiverDef.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, false);
                    }
                    num = worker2.def.priorityInType;
                }
            }
            return(ThinkResult.NoJob);
        }
            private static void Postfix(Vector3 clickPos, Pawn pawn, List <FloatMenuOption> opts, bool drafted, FloatMenuOption[] ___equivalenceGroupTempStorage)
            {
                if (pawn.thinker.TryGetMainTreeThinkNode <JobGiver_Work>() != null)
                {
                    IntVec3             clickCell           = IntVec3.FromVector3(clickPos);
                    TargetingParameters targetingParameters = new TargetingParameters();
                    targetingParameters.canTargetPawns     = true;
                    targetingParameters.canTargetBuildings = true;
                    targetingParameters.canTargetItems     = true;
                    targetingParameters.mapObjectTargetsMustBeAutoAttackable = false;
                    var ZTracker = ZUtils.ZTracker;
                    foreach (Thing item in GenUI.ThingsUnderMouse(clickPos, 1f, targetingParameters))
                    {
                        bool flag = false;
                        foreach (WorkTypeDef item2 in DefDatabase <WorkTypeDef> .AllDefsListForReading)
                        {
                            for (int i = 0; i < item2.workGiversByPriority.Count; i++)
                            {
                                WorkGiverDef workGiver2 = item2.workGiversByPriority[i];
                                if (!drafted || workGiver2.canBeDoneWhileDrafted)
                                {
                                    WorkGiver_Scanner workGiver_Scanner = workGiver2.Worker as WorkGiver_Scanner;
                                    if (workGiver_Scanner != null && workGiver_Scanner.def.directOrderable)
                                    {
                                        JobFailReason.Clear();
                                        if ((workGiver_Scanner.PotentialWorkThingRequest.Accepts(item) || (workGiver_Scanner.PotentialWorkThingsGlobal(pawn) != null && workGiver_Scanner.PotentialWorkThingsGlobal(pawn).Contains(item))) && !workGiver_Scanner.ShouldSkip(pawn, forced: true))
                                        {
                                            string          text            = null;
                                            Action          action          = null;
                                            PawnCapacityDef pawnCapacityDef = workGiver_Scanner.MissingRequiredCapacity(pawn);
                                            if (pawnCapacityDef != null)
                                            {
                                                text = "CannotMissingHealthActivities".Translate(pawnCapacityDef.label);
                                            }
                                            else
                                            {
                                                Map oldMap = pawn.Map;
                                                Job job    = null;
                                                Map dest   = null;
                                                foreach (var otherMap in ZTracker.GetAllMapsInClosestOrder(oldMap))
                                                {
                                                    if (workGiver_Scanner is WorkGiver_Refuel scanner1)
                                                    {
                                                        job = JobPatches.TryIssueJobPackagePatch.JobOnThing(
                                                            scanner1, pawn, item, true);
                                                    }
                                                    else if (workGiver_Scanner.def.defName == "HaulGeneral" ||
                                                             workGiver_Scanner.def.defName == "HaulCorpses")
                                                    {
                                                        job = JobPatches.TryIssueJobPackagePatch.JobOnThing(pawn,
                                                                                                            item, ref dest);
                                                    }
                                                    else if (workGiver_Scanner is WorkGiver_DoBill scanner2)
                                                    {
                                                        job = JobPatches.TryIssueJobPackagePatch.JobOnThing(
                                                            scanner2, pawn, item);
                                                    }
                                                    else if (workGiver_Scanner is
                                                             WorkGiver_ConstructDeliverResourcesToBlueprints scanner3)
                                                    {
                                                        job = JobPatches.TryIssueJobPackagePatch.JobOnThing(
                                                            scanner3, pawn, item);
                                                    }
                                                    else if (workGiver_Scanner is
                                                             WorkGiver_ConstructDeliverResourcesToFrames scanner4)
                                                    {
                                                        job = JobPatches.TryIssueJobPackagePatch.JobOnThing(
                                                            scanner4, pawn, item);
                                                    }
                                                    else
                                                    {
                                                        job = workGiver_Scanner.HasJobOnThing(pawn, item,
                                                                                              forced: true)
                                                            ? workGiver_Scanner.JobOnThing(pawn, item, forced: true)
                                                            : null;
                                                    }

                                                    if (job != null)
                                                    {
                                                        break;
                                                    }
                                                }
                                                if (job == null)
                                                {
                                                    if (JobFailReason.HaveReason)
                                                    {
                                                        text = (JobFailReason.CustomJobString.NullOrEmpty() ? ((string)"CannotGenericWork".Translate(workGiver_Scanner.def.verb, item.LabelShort, item)) : ((string)"CannotGenericWorkCustom".Translate(JobFailReason.CustomJobString)));
                                                        text = text + ": " + JobFailReason.Reason.CapitalizeFirst();
                                                    }
                                                    else
                                                    {
                                                        if (!item.IsForbidden(pawn))
                                                        {
                                                            continue;
                                                        }
                                                        text = (item.Position.InAllowedArea(pawn) ? ((string)"CannotPrioritizeForbidden".Translate(item.Label, item)) : ((string)("CannotPrioritizeForbiddenOutsideAllowedArea".Translate() + ": " + pawn.playerSettings.EffectiveAreaRestriction.Label)));
                                                    }
                                                }
                                                else
                                                {
                                                    WorkTypeDef workType = workGiver_Scanner.def.workType;
                                                    if (pawn.WorkTagIsDisabled(workGiver_Scanner.def.workTags))
                                                    {
                                                        text = "CannotPrioritizeWorkGiverDisabled".Translate(workGiver_Scanner.def.label);
                                                    }
                                                    else if (pawn.jobs.curJob != null && pawn.jobs.curJob.JobIsSameAs(job))
                                                    {
                                                        text = "CannotGenericAlreadyAm".Translate(workGiver_Scanner.PostProcessedGerund(job), item.LabelShort, item);
                                                    }
                                                    else if (pawn.workSettings.GetPriority(workType) == 0)
                                                    {
                                                        text = (pawn.WorkTypeIsDisabled(workType) ? ((string)"CannotPrioritizeWorkTypeDisabled".Translate(workType.gerundLabel)) : ((!"CannotPrioritizeNotAssignedToWorkType".CanTranslate()) ? ((string)"CannotPrioritizeWorkTypeDisabled".Translate(workType.pawnLabel)) : ((string)"CannotPrioritizeNotAssignedToWorkType".Translate(workType.gerundLabel))));
                                                    }
                                                    else if (job.def == JobDefOf.Research && item is Building_ResearchBench)
                                                    {
                                                        text = "CannotPrioritizeResearch".Translate();
                                                    }
                                                    else if (item.IsForbidden(pawn))
                                                    {
                                                        text = (item.Position.InAllowedArea(pawn) ? ((string)"CannotPrioritizeForbidden".Translate(item.Label, item)) : ((string)("CannotPrioritizeForbiddenOutsideAllowedArea".Translate() + ": " + pawn.playerSettings.EffectiveAreaRestriction.Label)));
                                                    }
                                                    else if (!pawn.CanReach(item, workGiver_Scanner.PathEndMode, Danger.Deadly))
                                                    {
                                                        text = (item.Label + ": " + "NoPath".Translate().CapitalizeFirst()).CapitalizeFirst();
                                                    }
                                                    else
                                                    {
                                                        text = "PrioritizeGeneric".Translate(workGiver_Scanner.PostProcessedGerund(job), item.Label);
                                                        Job localJob2 = job;
                                                        WorkGiver_Scanner localScanner2 = workGiver_Scanner;
                                                        job.workGiverDef = workGiver_Scanner.def;
                                                        action           = delegate
                                                        {
                                                            if (!ZTracker.jobTracker.ContainsKey(pawn))
                                                            {
                                                                ZTracker.jobTracker[pawn] = new JobTracker();
                                                            }
                                                            if (dest != null)
                                                            {
                                                                ZTracker.BuildJobListFor(pawn, dest, job);
                                                            }
                                                            else
                                                            {
                                                                ZTracker.BuildJobListFor(pawn, oldMap, job);
                                                            }
                                                            pawn.jobs.EndCurrentJob(JobCondition.InterruptForced);
                                                            if (workGiver2.forceMote != null)
                                                            {
                                                                MoteMaker.MakeStaticMote(clickCell, pawn.Map,
                                                                                         workGiver2.forceMote);
                                                            }
                                                        };
                                                    }
                                                }
                                            }
                                            if (DebugViewSettings.showFloatMenuWorkGivers)
                                            {
                                                text += $" (from {workGiver2.defName})";
                                            }
                                            FloatMenuOption menuOption = FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption(text, action), pawn, item);
                                            if (drafted && workGiver2.autoTakeablePriorityDrafted != -1)
                                            {
                                                menuOption.autoTakeable         = true;
                                                menuOption.autoTakeablePriority = workGiver2.autoTakeablePriorityDrafted;
                                            }
                                            if (!opts.Any((FloatMenuOption op) => op.Label == menuOption.Label))
                                            {
                                                if (workGiver2.equivalenceGroup != null)
                                                {
                                                    if (___equivalenceGroupTempStorage[workGiver2.equivalenceGroup.index] == null ||
                                                        (___equivalenceGroupTempStorage[workGiver2.equivalenceGroup.index].Disabled && !menuOption.Disabled))
                                                    {
                                                        ___equivalenceGroupTempStorage[workGiver2.equivalenceGroup.index] = menuOption;
                                                        flag = true;
                                                    }
                                                }
                                                else
                                                {
                                                    opts.Add(menuOption);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        if (flag)
                        {
                            for (int j = 0; j < ___equivalenceGroupTempStorage.Length; j++)
                            {
                                if (___equivalenceGroupTempStorage[j] != null)
                                {
                                    opts.Add(___equivalenceGroupTempStorage[j]);
                                    ___equivalenceGroupTempStorage[j] = null;
                                }
                            }
                        }
                    }
                    foreach (WorkTypeDef item3 in DefDatabase <WorkTypeDef> .AllDefsListForReading)
                    {
                        for (int k = 0; k < item3.workGiversByPriority.Count; k++)
                        {
                            WorkGiverDef workGiver = item3.workGiversByPriority[k];
                            if (!drafted || workGiver.canBeDoneWhileDrafted)
                            {
                                WorkGiver_Scanner workGiver_Scanner2 = workGiver.Worker as WorkGiver_Scanner;
                                if (workGiver_Scanner2 != null && workGiver_Scanner2.def.directOrderable)
                                {
                                    JobFailReason.Clear();
                                    if (workGiver_Scanner2.PotentialWorkCellsGlobal(pawn).Contains(clickCell) && !workGiver_Scanner2.ShouldSkip(pawn, forced: true))
                                    {
                                        Action          action2          = null;
                                        string          label            = null;
                                        PawnCapacityDef pawnCapacityDef2 = workGiver_Scanner2.MissingRequiredCapacity(pawn);
                                        if (pawnCapacityDef2 != null)
                                        {
                                            label = "CannotMissingHealthActivities".Translate(pawnCapacityDef2.label);
                                        }
                                        else
                                        {
                                            Job job2 = workGiver_Scanner2.HasJobOnCell(pawn, clickCell, forced: true) ? workGiver_Scanner2.JobOnCell(pawn, clickCell, forced: true) : null;
                                            if (job2 == null)
                                            {
                                                if (JobFailReason.HaveReason)
                                                {
                                                    if (!JobFailReason.CustomJobString.NullOrEmpty())
                                                    {
                                                        label = "CannotGenericWorkCustom".Translate(JobFailReason.CustomJobString);
                                                    }
                                                    else
                                                    {
                                                        label = "CannotGenericWork".Translate(workGiver_Scanner2.def.verb, "AreaLower".Translate());
                                                    }
                                                    label = label + ": " + JobFailReason.Reason.CapitalizeFirst();
                                                }
                                                else
                                                {
                                                    if (!clickCell.IsForbidden(pawn))
                                                    {
                                                        continue;
                                                    }
                                                    if (!clickCell.InAllowedArea(pawn))
                                                    {
                                                        label = "CannotPrioritizeForbiddenOutsideAllowedArea".Translate() + ": " + pawn.playerSettings.EffectiveAreaRestriction.Label;
                                                    }
                                                    else
                                                    {
                                                        label = "CannotPrioritizeCellForbidden".Translate();
                                                    }
                                                }
                                            }
                                            else
                                            {
                                                WorkTypeDef workType2 = workGiver_Scanner2.def.workType;
                                                if (pawn.jobs.curJob != null && pawn.jobs.curJob.JobIsSameAs(job2))
                                                {
                                                    label = "CannotGenericAlreadyAmCustom".Translate(workGiver_Scanner2.PostProcessedGerund(job2));
                                                }
                                                else if (pawn.workSettings.GetPriority(workType2) == 0)
                                                {
                                                    if (pawn.WorkTypeIsDisabled(workType2))
                                                    {
                                                        label = "CannotPrioritizeWorkTypeDisabled".Translate(workType2.gerundLabel);
                                                    }
                                                    else if ("CannotPrioritizeNotAssignedToWorkType".CanTranslate())
                                                    {
                                                        label = "CannotPrioritizeNotAssignedToWorkType".Translate(workType2.gerundLabel);
                                                    }
                                                    else
                                                    {
                                                        label = "CannotPrioritizeWorkTypeDisabled".Translate(workType2.pawnLabel);
                                                    }
                                                }
                                                else if (clickCell.IsForbidden(pawn))
                                                {
                                                    if (!clickCell.InAllowedArea(pawn))
                                                    {
                                                        label = "CannotPrioritizeForbiddenOutsideAllowedArea".Translate() + ": " + pawn.playerSettings.EffectiveAreaRestriction.Label;
                                                    }
                                                    else
                                                    {
                                                        label = "CannotPrioritizeCellForbidden".Translate();
                                                    }
                                                }
                                                else if (!pawn.CanReach(clickCell, PathEndMode.Touch, Danger.Deadly))
                                                {
                                                    label = "AreaLower".Translate().CapitalizeFirst() + ": " + "NoPath".Translate().CapitalizeFirst();
                                                }
                                                else
                                                {
                                                    label = "PrioritizeGeneric".Translate(workGiver_Scanner2.PostProcessedGerund(job2), "AreaLower".Translate());
                                                    Job localJob = job2;
                                                    WorkGiver_Scanner localScanner = workGiver_Scanner2;
                                                    job2.workGiverDef = workGiver_Scanner2.def;
                                                    action2           = delegate
                                                    {
                                                        if (pawn.jobs.TryTakeOrderedJobPrioritizedWork(localJob, localScanner, clickCell) && workGiver.forceMote != null)
                                                        {
                                                            MoteMaker.MakeStaticMote(clickCell, pawn.Map, workGiver.forceMote);
                                                        }
                                                    };
                                                }
                                            }
                                        }
                                        if (!opts.Any((FloatMenuOption op) => op.Label == label.TrimEnd()))
                                        {
                                            FloatMenuOption floatMenuOption = FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption(label, action2), pawn, clickCell);
                                            if (drafted && workGiver.autoTakeablePriorityDrafted != -1)
                                            {
                                                floatMenuOption.autoTakeable         = true;
                                                floatMenuOption.autoTakeablePriority = workGiver.autoTakeablePriorityDrafted;
                                            }
                                            opts.Add(floatMenuOption);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
Exemple #24
0
        protected Job GetJobOnTarget(Pawn meeseeks, SavedTargetInfo targetInfo, WorkGiver_Scanner workGiverScanner, bool scanAllThingsOnCell = false)
        {
            Job job = null;

            try
            {
                DesignatorUtility.ForceAllDesignationsOnCell(targetInfo.Cell, meeseeks.MapHeld);

                if (targetInfo.HasThing && !targetInfo.ThingDestroyed)
                {
                    // Special case for uninstall, the workgiver doesn't check to see if its already uninstalled
                    if (workGiverScanner as WorkGiver_Uninstall != null && !targetInfo.Thing.Spawned)
                    {
                        Logger.WarningFormat(this, "Target is inside {0}", targetInfo.Thing.ParentHolder);
                        DesignatorUtility.RestoreDesignationsOnCell(targetInfo.Cell, meeseeks.MapHeld);
                        return(null);
                    }

                    // Have to try-catch all these damn things because other mods arent't doing null checks :(
                    try
                    {
                        //Logger.MessageFormat(this, "Checking {0} for job on {1}", workGiverScanner, targetInfo.Thing);
                        if (workGiverScanner.HasJobOnThing(meeseeks, targetInfo.Thing, true))
                        {
                            //Logger.MessageFormat(this, "Getting {0} for job on {1}", workGiverScanner, targetInfo.Thing);
                            job = workGiverScanner.JobOnThing(meeseeks, targetInfo.Thing, true);
                        }
                    }
                    catch (Exception e)
                    {
                    }
                    finally
                    {
                    }
                }
                else
                {
                    // Have to try-catch all these damn things because other mods arent't doing null checks :(
                    try
                    {
                        //Logger.MessageFormat(this, "Checking {0} for job on {1}", workGiverScanner, targetInfo.Cell);
                        if (job == null && workGiverScanner.HasJobOnCell(meeseeks, targetInfo.Cell, true))
                        {
                            job = workGiverScanner.JobOnCell(meeseeks, targetInfo.Cell, true);
                        }
                    }
                    catch (Exception e)
                    {
                    }
                    finally
                    {
                    }
                }

                if (job == null && scanAllThingsOnCell)
                {
                    var thingsAtCell = meeseeks.MapHeld.thingGrid.ThingsAt(targetInfo.Cell);
                    foreach (Thing thing in thingsAtCell)
                    {
                        //Logger.MessageFormat(this, "Checking {0} for {1}.", thing, workGiverScanner.def.defName);

                        // Have to try-catch all these damn things because other mods arent't doing null checks :(
                        try
                        {
                            Logger.MessageFormat(this, "Checking {0} for job on {1}", workGiverScanner, thing);
                            if (workGiverScanner.HasJobOnThing(meeseeks, thing, true))
                            {
                                job = workGiverScanner.JobOnThing(meeseeks, thing, true);
                            }
                        }
                        catch (Exception e)
                        {
                        }
                        finally
                        {
                        }

                        if (job != null)
                        {
                            break;
                        }
                    }
                }
            }
            finally
            {
                DesignatorUtility.RestoreDesignationsOnCell(targetInfo.Cell, meeseeks.MapHeld);
            }

            return(job);
        }
        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);
        }
        //public bool emergency;

        protected override Job TryGiveTerminalJob(Pawn pawn)
        {
            if (!(pawn is Droid))
            {
                return(null);
            }
            Droid droid = pawn as Droid;

            if (!droid.Active)
            {
                return(null);
            }

            List <WorkGiver> list = this.emergency ? droid.work.WorkGiversInOrderEmergency : droid.work.WorkGiversInOrder;

            int               num               = -999;
            TargetInfo        targetInfo        = TargetInfo.Invalid;
            WorkGiver_Scanner workGiver_Scanner = null;

            for (int i = 0; i < list.Count; i++)
            {
                WorkGiver workGiver = list[i];
                if (workGiver.def.priorityInType != num && targetInfo.IsValid)
                {
                    break;
                }
                if (workGiver.MissingRequiredCapacity(pawn) == null)
                {
                    if (!workGiver.ShouldSkip(pawn))
                    {
                        try
                        {
                            Job job = workGiver.NonScanJob(pawn);
                            if (job != null)
                            {
                                Job result = job;
                                return(result);
                            }
                            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);
                                    Predicate <Thing>   validator  = predicate;
                                    Thing thing = GenClosest.ClosestThingReachable(pawn.Position, scanner.PotentialWorkThingRequest, scanner.PathEndMode, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), 9999f, validator, enumerable, scanner.LocalRegionsToScanFirst, enumerable != null);
                                    if (thing != null)
                                    {
                                        targetInfo        = thing;
                                        workGiver_Scanner = scanner;
                                    }
                                }
                                if (workGiver.def.scanCells)
                                {
                                    IntVec3 position = pawn.Position;
                                    float   num2     = 99999f;
                                    foreach (IntVec3 current in scanner.PotentialWorkCellsGlobal(pawn))
                                    {
                                        float lengthHorizontalSquared = (current - position).LengthHorizontalSquared;
                                        if (lengthHorizontalSquared < num2 && !current.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, current))
                                        {
                                            targetInfo        = current;
                                            workGiver_Scanner = scanner;
                                            num2 = lengthHorizontalSquared;
                                        }
                                    }
                                }
                                num = workGiver.def.priorityInType;
                            }
                        }
                        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;
                            if (targetInfo.HasThing)
                            {
                                return(workGiver_Scanner.JobOnThing(pawn, targetInfo.Thing));
                            }
                            return(workGiver_Scanner.JobOnCell(pawn, targetInfo.Cell));
                        }
                    }
                }
            }
            return(null);
        }
        // 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);
        }
Exemple #28
0
        public static bool TryIssueJobPackage(JobGiver_Work __instance, ref ThinkResult __result, Pawn pawn, JobIssueParams jobParams)
        {
#if DEBUG
            DateTime startTime = DateTime.Now;
#endif
            if (__instance.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 (__instance.WorkGiversRelated(pawn.mindState.priorityWork.WorkGiver, worker.def))
                    {
                        Job job = GiverTryGiveJobPrioritized(__instance, pawn, worker, pawn.mindState.priorityWork.Cell);
                        if (job != null)
                        {
                            job.playerForced = true;
                            __result         = new ThinkResult(job, __instance, workGiversByPriority[i].tagToGive);
                            return(false);
                        }
                    }
                }
                pawn.mindState.priorityWork.Clear();
            }
            List <WorkGiver> list = (!__instance.emergency) ? pawn.workSettings.WorkGiversInOrderNormal : pawn.workSettings.WorkGiversInOrderEmergency;
            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 (!__instance.PawnCanUseWorkGiver(pawn, workGiver))
                {
                    continue;
                }
                try
                {
                    Job job2 = workGiver.NonScanJob(pawn);
                    if (job2 != null)
                    {
                        __result = new ThinkResult(job2, __instance, workGiver.def.tagToGive);
                        return(false);
                    }
                    scanner = (workGiver as WorkGiver_Scanner);

                    if (scanner != null)
                    {
                        if (scanner.def.scanThings)
                        {
//----------------------THERE HAVE BEEN NO CHANGES ABOVE THIS---------------------------------

                            Predicate <Thing> validator;
                            if (scanner is WorkGiver_DoBill workGiver_DoBill)
                            {
                                validator = (Thing t) => !t.IsForbidden(pawn) && WorkGiver_Scanner_Patch.HasJobOnThing(workGiver_DoBill, pawn, t);
                            }
                            else
                            {
                                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
                            {
                                //TODO: use better ThingRequest groups
                                if (
                                    workGiver.def.defName.Equals("DoctorFeedAnimals") ||
                                    workGiver.def.defName.Equals("DoctorFeedHumanlikes") ||
                                    workGiver.def.defName.Equals("DoctorTendToAnimals") ||
                                    workGiver.def.defName.Equals("DoctorTendToHumanlikes") ||
                                    workGiver.def.defName.Equals("DoBillsUseCraftingSpot") ||
                                    workGiver.def.defName.Equals("DoctorTendEmergency") ||
                                    workGiver.def.defName.Equals("HaulCorpses") ||
                                    workGiver.def.defName.Equals("FillFermentingBarrel") ||
                                    workGiver.def.defName.Equals("HandlingFeedPatientAnimals") ||
                                    workGiver.def.defName.Equals("Train") ||
                                    workGiver.def.defName.Equals("VisitSickPawn") ||
                                    workGiver.def.defName.Equals("DoBillsButcherFlesh") ||
                                    workGiver.def.defName.Equals("DoBillsCook") ||
                                    workGiver.def.defName.Equals("DoBillsMakeApparel")
                                    )
                                {
                                    //long
                                    thing = GenClosest_Patch.ClosestThingReachable2(pawn.Position, pawn.Map, scanner.PotentialWorkThingRequest, scanner.PathEndMode, TraverseParms.For(pawn, scanner.MaxPathDanger(pawn)), 9999f, validator, enumerable, 0, scanner.MaxRegionsToScanBeforeGlobalSearch, enumerable != null);
                                }
                                else if (
                                    workGiver.def.defName.Equals("HaulGeneral")
                                    )
                                {
                                    //long
                                    thing = HaulingCache.ClosestThingReachable(pawn, scanner, pawn.Map, scanner.PotentialWorkThingRequest, scanner.PathEndMode, TraverseParms.For(pawn, scanner.MaxPathDanger(pawn)), 9999f, validator, enumerable, 0, scanner.MaxRegionsToScanBeforeGlobalSearch, enumerable != null);
                                }

                                /*
                                 * else if(
                                 *              workGiver.def.defName.Equals("DoBillsButcherFlesh") ||
                                 *              workGiver.def.defName.Equals("DoBillsCook") ||
                                 *              workGiver.def.defName.Equals("DoBillsMakeApparel"))
                                 * {
                                 *
                                 *      thing = null;
                                 *      //ThingGrid_Patch
                                 *      int mapSizeX = pawn.Map.Size.x;
                                 *      int mapSizeZ = pawn.Map.Size.z;
                                 *      int index = pawn.Map.cellIndices.CellToIndex(pawn.Position);
                                 *      //Dictionary<Bill, float> billPointsDict = ThingGrid_Patch.thingBillPoints[t.def];
                                 *      Dictionary<WorkGiver_Scanner, Dictionary<float, List<HashSet<Thing>[]>>> ingredientDict = ThingGrid_Patch.mapIngredientDict[pawn.Map];
                                 *      ThingRequest thingReq = scanner.PotentialWorkThingRequest;
                                 *      if(!ingredientDict.TryGetValue(scanner, out Dictionary<float, List<HashSet<Thing>[]>> scoreToJumboCellsList)) {
                                 *              scoreToJumboCellsList = new Dictionary<float, List<HashSet<Thing>[]>>();
                                 *              List<Thing> thingsMatchingRequest = pawn.Map.listerThings.ThingsMatching(thingReq);
                                 *      }
                                 *
                                 * }
                                 */
                                else
                                {
                                    //long
                                    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;
                            if (scanner is WorkGiver_GrowerSow workGiver_Grower)
                            {
                                //RimThreaded.WorkGiver_GrowerSow_Patch_JobOnCell = 0;

                                //thing = HaulingCache.ClosestThingReachable(pawn, scanner, pawn.Map, scanner.PotentialWorkThingRequest, scanner.PathEndMode, TraverseParms.For(pawn, scanner.MaxPathDanger(pawn)), 9999f, validator, enumerable, 0, scanner.MaxRegionsToScanBeforeGlobalSearch, enumerable != null);
                                IntVec3 bestCell = WorkGiver_Grower_Patch.ClosestLocationReachable(workGiver_Grower, pawn);
                                //Log.Message(bestCell.ToString());
                                if (bestCell.IsValid)
                                {
                                    bestTargetOfLastPriority = new TargetInfo(bestCell, pawn.Map);
                                    scannerWhoProvidedTarget = scanner;
                                }
                                //Log.Message(RimThreaded.WorkGiver_GrowerSow_Patch_JobOnCell.ToString());
                            }
                            else if (scanner is WorkGiver_GrowerHarvest workGiver_GrowerHarvest)
                            {
                                IntVec3 bestCell = WorkGiver_GrowerHarvest_Patch.ClosestLocationReachable(workGiver_GrowerHarvest, pawn);
                                if (bestCell.IsValid)
                                {
                                    bestTargetOfLastPriority = new TargetInfo(bestCell, pawn.Map);
                                    scannerWhoProvidedTarget = scanner;
                                }

                                /*
                                 * enumerable4 = workGiver_GrowerHarvest.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);
                                 *      }
                                 * }
                                 */
                            }
                            else
                            {
                                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)
                    {
                        float newDistanceSquared = (c - pawnPosition).LengthHorizontalSquared;
                        float newPriority        = 0f;

                        if (prioritized)
                        {
                            newPriority = scanner.GetPriority(pawn, c);
                            if (newPriority < bestPriority)
                            {
                                return;
                            }
                        }

                        if (newDistanceSquared < closestDistSquared && !c.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, c))
                        {
                            if (!allowUnreachable && !pawn.CanReach(c, scanner.PathEndMode, maxPathDanger))
                            {
                                return;
                            }

                            bestTargetOfLastPriority = new TargetInfo(c, pawn.Map);
                            scannerWhoProvidedTarget = scanner;
                            closestDistSquared       = newDistanceSquared;
                            bestPriority             = newPriority;
                        }
                    }
                }
                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;
                        __result          = new ThinkResult(job3, __instance, list[j].def.tagToGive);
                        return(false);
                    }

                    //If this was a cached plant job, deregister it
                    if (scannerWhoProvidedTarget is WorkGiver_GrowerSow)
                    {
                        Map          map       = pawn.Map;
                        IntVec3      cell      = bestTargetOfLastPriority.Cell;
                        List <Thing> thingList = cell.GetThingList(map);
                        foreach (Thing thing in thingList)
                        {
                            if (thing is Building_PlantGrower buildingPlantGrower)
                            {
                                PlantSowing_Cache.ReregisterObject(map, cell,
                                                                   WorkGiver_Grower_Patch.awaitingPlantCellsMapDict);
                            }
                        }
                        PlantSowing_Cache.ReregisterObject(map, cell, WorkGiver_Grower_Patch.awaitingPlantCellsMapDict);
                    }
                    //HACK - I know. I'm awful.
                    //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);
                    Log.Warning(string.Concat(scannerWhoProvidedTarget, " provided target ", bestTargetOfLastPriority, " but yielded no actual job for pawn ", pawn, ". The CanGiveJob and JobOnX methods may not be synchronized."));
                }
                num = workGiver.def.priorityInType;

#if DEBUG
                int milli99 = (int)DateTime.Now.Subtract(startTime).TotalMilliseconds;
                if (milli99 > 300)
                {
                    Log.Warning("99 JobGiver_Work.TryIssueJobPackage Took over " + milli99.ToString() + "ms for workGiver: " + workGiver.def.defName);
                    //Log.Warning(scanner.PotentialWorkThingRequest.ToString());
                    //Log.Warning(validator.ToString());
                }
#endif
            }
            __result = ThinkResult.NoJob;
            return(false);
        }