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); }
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 void ProcessCell(IntVec3 c, Pawn pawn, WorkGiver_Scanner scanner, IntVec3 pawnPosition, bool prioritized, bool allowUnreachable, Danger maxPathDanger, ref TargetInfo bestTargetOfLastPriority, ref WorkGiver_Scanner scannerWhoProvidedTarget, ref float closestDistSquared, ref float bestPriority) { bool found = false; float distSquared = (c - pawnPosition).LengthHorizontalSquared; float priority = 0f; if (prioritized) { if (!c.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, c)) { if (!allowUnreachable && !pawn.CanReach(c, scanner.PathEndMode, maxPathDanger)) { return; } priority = scanner.GetPriority(pawn, c); if (priority > bestPriority || (priority == bestPriority && distSquared < closestDistSquared)) { found = true; } } } else if (distSquared < closestDistSquared && !c.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, c)) { if (!allowUnreachable && !pawn.CanReach(c, scanner.PathEndMode, maxPathDanger)) { return; } found = true; } if (found) { bestTargetOfLastPriority = new TargetInfo(c, pawn.Map); scannerWhoProvidedTarget = scanner; closestDistSquared = distSquared; bestPriority = priority; } }
public override bool HasJobOnCell(Pawn pawn, IntVec3 c, bool forced = false) { return(wrappedScanner?.HasJobOnCell(pawn, c, forced) ?? base.HasJobOnCell(pawn, c, forced)); }
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); }
internal static void AddUndraftedOrders(Vector3 clickPos, Pawn pawn, List <FloatMenuOption> opts) { IntVec3 clickCell = IntVec3.FromVector3(clickPos); bool flag = false; bool flag2 = false; foreach (Thing current in Find.ThingGrid.ThingsAt(clickCell)) { flag2 = true; if (pawn.CanReach(current, PathEndMode.Touch, Danger.Deadly, false, TraverseMode.ByPawn)) { flag = true; break; } } if (flag2 && !flag) { opts.Add(new FloatMenuOption("(" + "NoPath".Translate() + ")", null, MenuOptionPriority.Medium, null, null, 0f, null)); return; } JobGiver_Work jobGiver_Work = pawn.thinker.TryGetMainTreeThinkNode <JobGiver_Work>(); if (jobGiver_Work != null) { foreach (Thing current2 in Find.ThingGrid.ThingsAt(clickCell)) { Pawn pawn2 = Find.Reservations.FirstReserverOf(current2, pawn.Faction, true); if (pawn2 != null && pawn2 != pawn) { opts.Add(new FloatMenuOption("IsReservedBy".Translate(new object[] { current2.LabelShort.CapitalizeFirst(), pawn2.LabelShort }), null, MenuOptionPriority.Medium, null, null, 0f, null)); } else { foreach (WorkTypeDef current3 in DefDatabase <WorkTypeDef> .AllDefsListForReading) { for (int i = 0; i < current3.workGiversByPriority.Count; i++) { WorkGiver_Scanner workGiver_Scanner = current3.workGiversByPriority[i].Worker as WorkGiver_Scanner; if (workGiver_Scanner != null && workGiver_Scanner.def.directOrderable && !workGiver_Scanner.ShouldSkip(pawn)) { JobFailReason.Clear(); if (workGiver_Scanner.PotentialWorkThingRequest.Accepts(current2) || (workGiver_Scanner.PotentialWorkThingsGlobal(pawn) != null && workGiver_Scanner.PotentialWorkThingsGlobal(pawn).Contains(current2))) { Job job; if (!workGiver_Scanner.HasJobOnThingForced(pawn, current2)) { job = null; } else { job = workGiver_Scanner.JobOnThingForced(pawn, current2); } if (job == null) { if (JobFailReason.HaveReason) { string label3 = "CannotGenericWork".Translate(new object[] { workGiver_Scanner.def.verb, current2.LabelShort }) + " (" + JobFailReason.Reason + ")"; opts.Add(new FloatMenuOption(label3, null, MenuOptionPriority.Medium, null, null, 0f, null)); } } else { WorkTypeDef workType = workGiver_Scanner.def.workType; Action action = null; PawnCapacityDef pawnCapacityDef = workGiver_Scanner.MissingRequiredCapacity(pawn); string label; if (pawnCapacityDef != null) { label = "CannotMissingHealthActivities".Translate(new object[] { pawnCapacityDef.label }); } else if (pawn.jobs.curJob != null && pawn.jobs.curJob.JobIsSameAs(job)) { label = "CannotGenericAlreadyAm".Translate(new object[] { workType.gerundLabel, current2.LabelShort }); } else if (pawn.workSettings.GetPriority(workType) == 0) { label = "CannotPrioritizeIsNotA".Translate(new object[] { pawn.NameStringShort, workType.pawnLabel }); } else if (job.def == JobDefOf.Research && current2 is Building_ResearchBench) { label = "CannotPrioritizeResearch".Translate(); } else if (current2.IsForbidden(pawn)) { if (!current2.Position.InAllowedArea(pawn)) { label = "CannotPrioritizeForbiddenOutsideAllowedArea".Translate(new object[] { current2.Label }); } else { label = "CannotPrioritizeForbidden".Translate(new object[] { current2.Label }); } } else if (!pawn.CanReach(current2, PathEndMode.Touch, Danger.Deadly, false, TraverseMode.ByPawn)) { label = current2.Label + ": " + "NoPath".Translate(); } else { label = "PrioritizeGeneric".Translate(new object[] { workGiver_Scanner.def.gerund, current2.Label }); Job localJob = job; WorkGiver_Scanner localScanner = workGiver_Scanner; action = delegate { pawn.thinker.GetMainTreeThinkNode <JobGiver_Work>().TryStartPrioritizedWorkOn(pawn, localJob, localScanner, clickCell); }; } if (!opts.Any((FloatMenuOption op) => op.Label == label.TrimEnd(new char[0]))) { opts.Add(new FloatMenuOption(label, action, MenuOptionPriority.Medium, null, null, 0f, null)); } } } } } } } } Pawn pawn3 = Find.Reservations.FirstReserverOf(clickCell, pawn.Faction, true); if (pawn3 != null && pawn3 != pawn) { opts.Add(new FloatMenuOption("IsReservedBy".Translate(new object[] { "AreaLower".Translate(), pawn3.LabelShort }).CapitalizeFirst(), null, MenuOptionPriority.Medium, null, null, 0f, null)); } else { foreach (WorkTypeDef current4 in DefDatabase <WorkTypeDef> .AllDefsListForReading) { for (int j = 0; j < current4.workGiversByPriority.Count; j++) { WorkGiver_Scanner workGiver_Scanner2 = current4.workGiversByPriority[j].Worker as WorkGiver_Scanner; if (workGiver_Scanner2 != null && workGiver_Scanner2.def.directOrderable && !workGiver_Scanner2.ShouldSkip(pawn)) { JobFailReason.Clear(); if (workGiver_Scanner2.PotentialWorkCellsGlobal(pawn).Contains(clickCell)) { Job job2; if (!workGiver_Scanner2.HasJobOnCell(pawn, clickCell)) { job2 = null; } else { job2 = workGiver_Scanner2.JobOnCell(pawn, clickCell); } if (job2 == null) { if (JobFailReason.HaveReason) { string label2 = "CannotGenericWork".Translate(new object[] { workGiver_Scanner2.def.verb, "AreaLower".Translate() }) + " (" + JobFailReason.Reason + ")"; opts.Add(new FloatMenuOption(label2, null, MenuOptionPriority.Medium, null, null, 0f, null)); } } else { WorkTypeDef workType2 = workGiver_Scanner2.def.workType; Action action2 = null; PawnCapacityDef pawnCapacityDef2 = workGiver_Scanner2.MissingRequiredCapacity(pawn); string label; if (pawnCapacityDef2 != null) { label = "CannotMissingHealthActivities".Translate(new object[] { pawnCapacityDef2.label }); } else if (pawn.jobs.curJob != null && pawn.jobs.curJob.JobIsSameAs(job2)) { label = "CannotGenericAlreadyAm".Translate(new object[] { workType2.gerundLabel, "AreaLower".Translate() }); } else if (pawn.workSettings.GetPriority(workType2) == 0) { label = "CannotPrioritizeIsNotA".Translate(new object[] { pawn.NameStringShort, workType2.pawnLabel }); } else if (!pawn.CanReach(clickCell, PathEndMode.Touch, Danger.Deadly, false, TraverseMode.ByPawn)) { label = "AreaLower".Translate().CapitalizeFirst() + ": " + "NoPath".Translate(); } else { label = "PrioritizeGeneric".Translate(new object[] { workGiver_Scanner2.def.gerund, "AreaLower".Translate() }); Job localJob = job2; WorkGiver_Scanner localScanner = workGiver_Scanner2; action2 = delegate { pawn.thinker.GetMainTreeThinkNode <JobGiver_Work>().TryStartPrioritizedWorkOn(pawn, localJob, localScanner, clickCell); }; } if (!opts.Any((FloatMenuOption op) => op.Label == label.TrimEnd(new char[0]))) { opts.Add(new FloatMenuOption(label, action2, MenuOptionPriority.Medium, null, null, 0f, null)); } } } } } } } } }
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); }
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); }
// 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); }
// 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; 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 override bool HasJobOnCell(Pawn pawn, IntVec3 c) { // if (prioritization.ShouldAvoid (c)) // return false; return(wrappedGiver.HasJobOnCell(pawn, c)); }
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); }
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 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); }
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); } } } } } } } }
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); }
// 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); }
//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); }