public static void set_Forbidden(CompForbiddable __instance, bool value)
 {
     if (__instance.parent.Map != null)
     {
         HaulingCache.ReregisterHaulableItem(__instance.parent);
     }
 }
示例#2
0
        public static bool ReleaseAllClaimedBy(ReservationManager __instance, Pawn claimant)
        {
            Dictionary <Pawn, List <Reservation> > reservationClaimantDict = getReservationClaimantDict(__instance);

            lock (__instance)
            {
                Dictionary <LocalTargetInfo, List <Reservation> > reservationTargetDict = getReservationTargetDict(__instance);
                List <Reservation> reservationClaimantList = getReservationClaimantList(reservationClaimantDict, claimant);
                foreach (Reservation reservation in reservationClaimantList)
                {
                    List <Reservation> reservationTargetList    = getReservationTargetList(reservationTargetDict, reservation.Target);
                    List <Reservation> newReservationTargetList = new List <Reservation>();
                    for (int index = 0; index < reservationTargetList.Count; index++)
                    {
                        Reservation reservation2 = reservationTargetList[index];
                        if (reservation2.Claimant != claimant)
                        {
                            newReservationTargetList.Add(reservation2);
                        }
                    }

                    reservationTargetDict[reservation.Target] = newReservationTargetList;
                    //HaulingCache
                    if (reservation.Target.Thing != null && reservation.Target.Thing.def.EverHaulable && reservation.Target.Thing.Map != null)
                    {
                        HaulingCache.ReregisterHaulableItem(reservation.Target.Thing);
                    }
                }
                reservationClaimantDict[claimant] = new List <Reservation>();
            }
            return(false);
        }
示例#3
0
        public static void InitializeAllThreadStatics()
        {
            CellFinder_Patch.InitializeThreadStatics();
            ColoredText_Patch.InitializeThreadStatics();
            CompCauseGameCondition_Patch.InitializeThreadStatics();
            Dijkstra_Patch <IntVec3> .InitializeThreadStatics();

            Dijkstra_Patch <Region> .InitializeThreadStatics();

            Dijkstra_Patch <int> .InitializeThreadStatics();

            GenTemperature_Patch.InitializeThreadStatics();
            HaulingCache.InitializeThreadStatics();
            HediffSet_Patch.InitializeThreadStatics();
            PathFinder_Patch.InitializeThreadStatics();
            PawnPathPool_Patch.InitializeThreadStatics();
            Reachability_Patch.InitializeThreadStatics();
            ReachabilityCache_Patch.InitializeThreadStatics();
            Region_Patch.InitializeThreadStatics();
            //RegionAndRoomUpdater_Patch.InitializeThreadStatics();
            RegionDirtyer_Patch.InitializeThreadStatics();
            RegionTraverser_Patch.InitializeThreadStatics();
            SituationalThoughtHandler_Patch.InitializeThreadStatics();
            SustainerManager_Patch.InitializeThreadStatics();
            Toils_Ingest_Patch.InitializeThreadStatics();
            World_Patch.InitializeThreadStatics();
            WorldPawns_Patch.InitializeThreadStatics();
        }
示例#4
0
 public static void PostReleaseAllForTarget(ReservationManager __instance, LocalTargetInfo target, Pawn claimant, Job job)
 {
     if (target.Thing != null && target.Thing.def.EverHaulable && target.Thing.Map != null)
     {
         HaulingCache.ReregisterHaulableItem(target.Thing);
     }
 }
示例#5
0
        public static bool RegisterInCell(ThingGrid __instance, Thing t, IntVec3 c)
        {
            Map this_map = __instance.map;

            if (!c.InBounds(this_map))
            {
                Log.Warning(t.ToString() + " tried to register out of bounds at " + c + ". Destroying.");
                t.Destroy(DestroyMode.Vanish);
            }
            else
            {
                int index = this_map.cellIndices.CellToIndex(c);

                //int mapSizeX = this_map.Size.x;
                //int mapSizeZ = this_map.Size.z;

                lock (__instance)
                {
                    __instance.thingGrid[index].Add(t);
                }
                if (t.def.EverHaulable)
                {
                    HaulingCache.RegisterHaulableItem(t);
                }
                if (t is Building_PlantGrower building_PlantGrower)
                {
                    foreach (IntVec3 plantableLocation in building_PlantGrower.OccupiedRect())
                    {
                        PlantSowing_Cache.ReregisterObject(t.Map, plantableLocation, WorkGiver_Grower_Patch.awaitingPlantCellsMapDict);
                    }
                }

                /*
                 * if (!thingBillPoints.TryGetValue(t.def, out Dictionary<WorkGiver_Scanner, float> billPointsDict))
                 * {
                 *  billPointsDict = new Dictionary<WorkGiver_Scanner, float>();
                 *  thingBillPoints[t.def] = billPointsDict;
                 * }
                 * if (!mapIngredientDict.TryGetValue(this_map, out Dictionary<WorkGiver_Scanner, Dictionary<float, List<HashSet<Thing>[]>>> ingredientDict))
                 * {
                 *  ingredientDict = new Dictionary<WorkGiver_Scanner, Dictionary<float, List<HashSet<Thing>[]>>>();
                 *  mapIngredientDict[this_map] = ingredientDict;
                 * }
                 * foreach (KeyValuePair<WorkGiver_Scanner, float> billPoints in billPointsDict)
                 * {
                 *  int i = 0;
                 *  int power2;
                 *  do
                 *  {
                 *      power2 = power2array[i];
                 *      ingredientDict[billPoints.Key][billPoints.Value][i][CellToIndexCustom(c, mapSizeX, power2)].Add(t);
                 *      i++;
                 *  } while (power2 < mapSizeX || power2 < mapSizeZ);
                 * }
                 */
                //}
            }
            return(false);
        }
示例#6
0
        public static bool Release(ReservationManager __instance, LocalTargetInfo target, Pawn claimant, Job job)
        {
            if (target.ThingDestroyed)
            {
                Log.Warning("Releasing destroyed thing " + target + " for " + claimant);
            }
            Reservation        reservation1 = null;
            List <Reservation> reservationTargetListUnsafe = getReservationTargetList(__instance, target);

            foreach (Reservation reservation2 in reservationTargetListUnsafe)
            {
                if (reservation2.Claimant == claimant && reservation2.Job == job)
                {
                    reservation1 = reservation2;
                    break;
                }
            }
            if (reservation1 == null && !target.ThingDestroyed)
            {
                Log.Warning("Tried to release " + target + " that wasn't reserved by " + claimant + ".");
            }
            else
            {
                lock (__instance)
                {
                    Dictionary <Pawn, List <Reservation> > reservationClaimantDict = getReservationClaimantDict(__instance);
                    List <Reservation> reservationClaimantList    = getReservationClaimantList(reservationClaimantDict, claimant);
                    List <Reservation> newReservationClaimantList = new List <Reservation>();
                    foreach (Reservation reservation in reservationClaimantList)
                    {
                        if (reservation != reservation1)
                        {
                            newReservationClaimantList.Add(reservation);
                        }
                        reservationClaimantDict[claimant] = newReservationClaimantList;
                    }
                    Dictionary <LocalTargetInfo, List <Reservation> > reservationTargetDict = getReservationTargetDict(__instance);
                    List <Reservation> reservationTargetList    = getReservationTargetList(reservationTargetDict, target);
                    List <Reservation> newReservationTargetList = new List <Reservation>();
                    foreach (Reservation reservation2 in reservationTargetList)
                    {
                        if (reservation2 != reservation1)
                        {
                            newReservationTargetList.Add(reservation2);
                        }
                    }
                    reservationTargetDict[target] = newReservationTargetList;
                }
            }

            //Postfix
            if (target.Thing != null && target.Thing.def.EverHaulable && target.Thing.Map != null)
            {
                HaulingCache.ReregisterHaulableItem(target.Thing);
            }

            return(false);
        }
示例#7
0
        public static bool DeregisterInCell(ThingGrid __instance, Thing t, IntVec3 c)
        {
            Map this_map = __instance.map;

            if (!c.InBounds(this_map))
            {
                Log.Error(t.ToString() + " tried to de-register out of bounds at " + c);
                return(false);
            }

            int index = this_map.cellIndices.CellToIndex(c);

            List <Thing>[] thingGridInstance = __instance.thingGrid;
            List <Thing>   thingList         = thingGridInstance[index];
            List <Thing>   newThingList      = null;

            if (thingList.Contains(t))
            {
                bool found = false;
                lock (__instance)
                {
                    thingList = thingGridInstance[index];
                    if (thingList.Contains(t))
                    {
                        found        = true;
                        newThingList = new List <Thing>(thingList);
                        newThingList.Remove(t);
                        thingGridInstance[index] = newThingList;
                    }
                }
                if (found)
                {
                    if (t.def.EverHaulable)
                    {
                        HaulingCache.DeregisterHaulableItem(t);
                    }

                    if (c.GetZone(__instance.map) is Zone_Growing zone)
                    {
                        PlantSowing_Cache.ReregisterObject(zone.Map, c, WorkGiver_Grower_Patch.awaitingPlantCellsMapDict);
                    }

                    for (int i = newThingList.Count - 1; i >= 0; i--)
                    {
                        Thing thing2 = newThingList[i];
                        if (thing2 is Building_PlantGrower building_PlantGrower)
                        {
                            foreach (IntVec3 plantableLocation in building_PlantGrower.OccupiedRect())
                            {
                                PlantSowing_Cache.ReregisterObject(building_PlantGrower.Map, plantableLocation, WorkGiver_Grower_Patch.awaitingPlantCellsMapDict);
                            }
                        }
                    }
                }

                /*
                 * int mapSizeX = this_map.Size.x;
                 * int mapSizeZ = this_map.Size.z;
                 *
                 * if (!thingBillPoints.TryGetValue(t.def, out Dictionary<WorkGiver_Scanner, float> billPointsDict))
                 * {
                 *  billPointsDict = new Dictionary<WorkGiver_Scanner, float>();
                 *  thingBillPoints[t.def] = billPointsDict;
                 * }
                 * if (!mapIngredientDict.TryGetValue(this_map, out Dictionary<WorkGiver_Scanner, Dictionary<float, List<HashSet<Thing>[]>>> ingredientDict))
                 * {
                 *  ingredientDict = new Dictionary<WorkGiver_Scanner, Dictionary<float, List<HashSet<Thing>[]>>>();
                 *  mapIngredientDict[this_map] = ingredientDict;
                 * }
                 * foreach (KeyValuePair<WorkGiver_Scanner, float> billPoints in billPointsDict)
                 * {
                 *  int i = 0;
                 *  int power2;
                 *  do
                 *  {
                 *      power2 = power2array[i];
                 *      HashSet<Thing> newHashSet = new HashSet<Thing>(ingredientDict[billPoints.Key][billPoints.Value][i][CellToIndexCustom(c, mapSizeX, power2)]);
                 *      newHashSet.Remove(t);
                 *      ingredientDict[billPoints.Key][billPoints.Value][i][CellToIndexCustom(c, mapSizeX, power2)] = newHashSet;
                 *      i++;
                 *  } while (power2 < mapSizeX || power2 < mapSizeZ);
                 * }
                 */
                //}
                //}
            }

            return(false);
        }
 public static void DesignateThing(Designator_Haul __instance, Thing t)
 {
     HaulingCache.ReregisterHaulableItem(t);
 }
示例#9
0
        public static bool Reserve(ReservationManager __instance, ref bool __result,
                                   Pawn claimant,
                                   Job job,
                                   LocalTargetInfo target,
                                   int maxPawns              = 1,
                                   int stackCount            = -1,
                                   ReservationLayerDef layer = null,
                                   bool errorOnFailed        = true)
        {
            lock (__instance)
            {
                if (maxPawns > 1 && stackCount == -1)
                {
                    Log.ErrorOnce("Reserving with maxPawns > 1 and stackCount = All; this will not have a useful effect (suppressing future warnings)", 83269);
                }

                if (job == null)
                {
                    Log.Warning(claimant.ToStringSafe() + " tried to reserve thing " + target.ToStringSafe() + " without a valid job");
                    __result = false;
                    return(false);
                }
                int num1 = (!target.HasThing) ? 1 : target.Thing.stackCount;
                int num2 = stackCount == -1 ? num1 : stackCount;

                List <Reservation> reservationTargetList = getReservationTargetList(__instance, target);
                foreach (Reservation reservation1 in reservationTargetList)
                {
                    if (reservation1.Claimant == claimant && reservation1.Job == job && reservation1.Layer == layer)
                    {
                        if (reservation1.StackCount == -1 || reservation1.StackCount >= num2)
                        {
                            __result = true;
                            return(false);
                        }
                        Log.Warning("Debug reservation");
                    }
                }
                if (!target.IsValid || target.ThingDestroyed)                 //TODO reservation should be removed when thing is destroyed
                {
                    __result = false;
                    return(false);
                }
                bool        canReserveResult = __instance.CanReserve(claimant, target, maxPawns, stackCount, layer);
                Reservation reservation;
                Dictionary <LocalTargetInfo, List <Reservation> > reservationTargetDict;
                Dictionary <Pawn, List <Reservation> >            reservationClaimantDict;
                Thing haulableThing;
                if (!canReserveResult)
                {
                    if (job.playerForced && __instance.CanReserve(claimant, target, maxPawns, stackCount, layer, true))
                    {
                        reservation = new Reservation(claimant, job, maxPawns, stackCount, target, layer);
                        List <Reservation> claimantReservations;

                        reservationTargetDict = getReservationTargetDict(__instance);
                        //newReservationTargetList = new List<Reservation>(getReservationTargetList(reservationTargetDict, target))
                        //{
                        //    reservation
                        //};
                        getReservationTargetList(reservationTargetDict, target).Add(reservation);
                        reservationClaimantDict = getReservationClaimantDict(__instance);
                        //newReservationClaimantList =
                        //    new List<Reservation>(getReservationClaimantList(reservationClaimantDict, claimant))
                        //    {
                        //        reservation
                        //    };
                        claimantReservations = getReservationClaimantList(reservationClaimantDict, claimant);
                        claimantReservations.Add(reservation);

                        foreach (Reservation reservation2 in claimantReservations)
                        {
                            if (reservation2.Claimant != claimant && (reservation2.Layer == layer && RespectsReservationsOf(claimant, reservation2.Claimant)))
                            {
                                reservation2.Claimant.jobs.EndCurrentOrQueuedJob(reservation2.Job, JobCondition.InterruptForced);
                            }
                        }
                        haulableThing = target.Thing;
                        if (haulableThing != null && haulableThing.def.EverHaulable && haulableThing.Map != null)
                        {
                            //Log.Message("DeregisterHaulableItem " + haulableThing.ToString());
                            HaulingCache.DeregisterHaulableItem(haulableThing);
                        }
                        __result = true;
                        return(false);
                    }

                    //HACK - Probably because Reserve is no longer valid after CanReserve time delay with multiple threads.
                    if (errorOnFailed)
                    {
                        //LogCouldNotReserveError(__instance, claimant, job, target, maxPawns, stackCount, layer);
                        Log.Warning("ReservationManager.Reserve cannot reserve. This is likely because reservation is no longer valid after CanReserve was called due to time delay with multiple threads.");
                    }
                    __result = false;
                    return(false);
                }
                reservation = new Reservation(claimant, job, maxPawns, stackCount, target, layer);

                reservationTargetDict = getReservationTargetDict(__instance);
                //newReservationTargetList = new List<Reservation>(getReservationTargetList(reservationTargetDict, target))
                //	{
                //		reservation
                //	};
                getReservationTargetList(reservationTargetDict, target).Add(reservation);
                reservationClaimantDict = getReservationClaimantDict(__instance);
                //newReservationClaimantList = new List<Reservation>(getReservationClaimantList(reservationClaimantDict, claimant))
                //	{
                //		reservation
                //	};
                getReservationClaimantList(reservationClaimantDict, claimant).Add(reservation);


                haulableThing = target.Thing;
                if (haulableThing != null && haulableThing.def.EverHaulable && haulableThing.Map != null)
                {
                    //Log.Message("DeregisterHaulableItem " + haulableThing.ToString());
                    HaulingCache.DeregisterHaulableItem(haulableThing);
                }
            }
            __result = true;
            return(false);
        }
示例#10
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);
        }