public static bool TryGiveJobFromJoyGiverDefDirect(JobGiver_Work __instance, ref Job __result, JoyGiverDef def, Pawn pawn) { pawnx = pawn; defx = def; __result = defx.Worker.TryGiveJob(pawnx); return(false); }
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 static bool Prefix(JobGiver_Work __instance, Pawn pawn, ref ThinkResult __result) { if (!Active) { return(true); } __result = Detour(__instance, pawn); return(false); }
public void Notify_WorkPriorityDisabled(WorkTypeDef wType) { JobGiver_Work jobGiver_Work = this.lastJobGiver as JobGiver_Work; if (jobGiver_Work != null && this.lastGivenWorkType == wType) { this.pawn.jobs.EndCurrentJob(JobCondition.InterruptForced, true); } }
private static ThinkResult Detour(JobGiver_Work __instance, Pawn pawn) { if (__instance.emergency && pawn.mindState.priorityWork.IsPrioritized) { var workGiversByPriority = pawn.mindState.priorityWork.WorkGiver.workType.workGiversByPriority; for (var i = 0; i < workGiversByPriority.Count; i++) { var worker = workGiversByPriority[i].Worker; var job = __instance.GiverTryGiveJobPrioritized(pawn, worker, pawn.mindState.priorityWork.Cell); if (job != null) { job.playerForced = true; return(new ThinkResult(job, __instance, workGiversByPriority[i].tagToGive)); } } pawn.mindState.priorityWork.Clear(); } var list = __instance.emergency ? pawn.workSettings.WorkGiversInOrderEmergency : pawn.workSettings.WorkGiversInOrderNormal; var num = -999; var bestTargetOfLastPriority = TargetInfo.Invalid; WorkGiver_Scanner scannerWhoProvidedTarget = null; var coo = list.Count; for (var j = 0; j < coo; j++) { var workGiver = list[j]; string namer() { var daffy = string.Empty; if (ByWorkType) { daffy = workGiver.def?.workType?.defName; } else { daffy = $"{workGiver.def?.defName} - {workGiver.def?.workType.defName} - {workGiver.def?.modContentPack?.Name}"; } //if (true) //{ // daffy += $" - { TraverseParms.For(pawn, scanner.MaxPathDanger(pawn)).ToString()} - {pawn.Name.ToStringShort}"; //} if (RequestTypes && workGiver is WorkGiver_Scanner scan) { daffy += $" - {scan.PotentialWorkThingRequest}"; if (scan.PotentialWorkThingRequest.group == ThingRequestGroup.BuildingArtificial) { daffy += " VERY BAD!"; } } return(daffy); } if (workGiver.def.priorityInType != num && bestTargetOfLastPriority.IsValid) { break; } if (__instance.PawnCanUseWorkGiver(pawn, workGiver)) { var name = string.Empty; if (ByWorkType) { name = workGiver.def.workType.defName; } else { name = workGiver.def.defName; } //if (true) //{ // name = string.Intern(name + pawn.Name.ToStringShort); //} if (workGiver is WorkGiver_Scanner scanny) { name += $"{scanny.PotentialWorkThingRequest}"; } try { var job2 = workGiver.NonScanJob(pawn); if (job2 != null) { return(new ThinkResult(job2, __instance, list[j].def.tagToGive)); } if (workGiver is WorkGiver_Scanner scanner) { Analyzer.Start(name, namer, workGiver.GetType(), workGiver.def, pawn); if (scanner.def.scanThings) { bool Predicate(Thing t) { return(!t.IsForbidden(pawn) && scanner.HasJobOnThing(pawn, t)); } var enumerable = scanner.PotentialWorkThingsGlobal(pawn); Thing thing; if (scanner.Prioritized) { var enumerable2 = enumerable; if (enumerable2 == null) { enumerable2 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest); } if (scanner.AllowUnreachable) { thing = GenClosest.ClosestThing_Global(pawn.Position, enumerable2, 99999f, Predicate, x => scanner.GetPriority(pawn, x)); } else { var traverseParams = TraverseParms.For(pawn, scanner.MaxPathDanger(pawn)); var validator = (Predicate <Thing>)Predicate; thing = GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map, enumerable2, scanner.PathEndMode, traverseParams, 9999f, validator, x => scanner.GetPriority(pawn, x)); } } else if (scanner.AllowUnreachable) { var enumerable3 = enumerable; if (enumerable3 == null) { enumerable3 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest); } thing = GenClosest.ClosestThing_Global(pawn.Position, enumerable3, 99999f, Predicate); } else { giver = workGiver; key = name; Analyzer.Start(name, namer, workGiver.GetType(), workGiver.def, pawn); thing = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, scanner.PotentialWorkThingRequest, scanner.PathEndMode, TraverseParms.For(pawn, scanner.MaxPathDanger(pawn)), 9999f, Predicate, enumerable, 0, scanner.MaxRegionsToScanBeforeGlobalSearch, enumerable != null); giver = null; } if (thing != null) { bestTargetOfLastPriority = thing; scannerWhoProvidedTarget = scanner; } } if (scanner.def.scanCells) { var closestDistSquared = 99999f; var bestPriority = float.MinValue; var prioritized = scanner.Prioritized; var allowUnreachable = scanner.AllowUnreachable; var maxDanger = scanner.MaxPathDanger(pawn); foreach (var intVec in scanner.PotentialWorkCellsGlobal(pawn)) { var flag = false; var num4 = (intVec - pawn.Position).LengthHorizontalSquared; var num5 = 0f; if (prioritized) { if (!intVec.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, intVec)) { if (!allowUnreachable && !pawn.CanReach(intVec, scanner.PathEndMode, maxDanger)) { continue; } num5 = scanner.GetPriority(pawn, intVec); if (num5 > bestPriority || num5 == bestPriority && num4 < closestDistSquared) { flag = true; } } } else if (num4 < closestDistSquared && !intVec.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, intVec)) { if (!allowUnreachable && !pawn.CanReach(intVec, scanner.PathEndMode, maxDanger)) { continue; } flag = true; } if (flag) { bestTargetOfLastPriority = new TargetInfo(intVec, pawn.Map); scannerWhoProvidedTarget = scanner; closestDistSquared = num4; bestPriority = num5; } } } Analyzer.Stop(name); } } catch (Exception ex) { Log.Error(string.Concat(pawn, " threw exception in WorkGiver ", workGiver.def.defName, ": ", ex.ToString())); } if (bestTargetOfLastPriority.IsValid) { // pawn.mindState.lastGivenWorkType = workGiver.def.workType; Job job3; if (bestTargetOfLastPriority.HasThing) { job3 = scannerWhoProvidedTarget.JobOnThing(pawn, bestTargetOfLastPriority.Thing); } else { job3 = scannerWhoProvidedTarget.JobOnCell(pawn, bestTargetOfLastPriority.Cell); } if (job3 != null) { job3.workGiverDef = scannerWhoProvidedTarget.def; return(new ThinkResult(job3, __instance, list[j].def.tagToGive)); } Log.ErrorOnce( string.Concat(scannerWhoProvidedTarget, " provided target ", bestTargetOfLastPriority, " but yielded no actual job for pawn ", pawn, ". The CanGiveJob and JobOnX methods may not be synchronized."), 6112651); } num = workGiver.def.priorityInType; } } return(ThinkResult.NoJob); }
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)); } } } } } } } } }
private static ThinkResult Detour(JobGiver_Work __instance, Pawn pawn) { if (__instance.emergency && pawn.mindState.priorityWork.IsPrioritized) { List <WorkGiverDef> workGiversByPriority = pawn.mindState.priorityWork.WorkGiver.workType.workGiversByPriority; for (int i = 0; i < workGiversByPriority.Count; i++) { WorkGiver worker = workGiversByPriority[i].Worker; int refire = 0; try { refire = refires[worker.def]; } catch (Exception) { refires.Add(worker.def, 0); } if (refire > 0) { continue; } Job job = __instance.GiverTryGiveJobPrioritized(pawn, worker, pawn.mindState.priorityWork.Cell); if (job != null) { job.playerForced = true; return(new ThinkResult(job, __instance, workGiversByPriority[i].tagToGive)); } refires[worker.def] = refireLength; } pawn.mindState.priorityWork.Clear(); } List <WorkGiver> list = __instance.emergency ? pawn.workSettings.WorkGiversInOrderEmergency : pawn.workSettings.WorkGiversInOrderNormal; int num = -999; TargetInfo bestTargetOfLastPriority = TargetInfo.Invalid; WorkGiver_Scanner scannerWhoProvidedTarget = null; int coo = list.Count; Profiler prof = null; for (int j = 0; j < coo; j++) { WorkGiver workGiver = list[j]; int refire = 0; try { refire = refires[workGiver.def]; } catch (Exception) { refires.Add(workGiver.def, 0); } if (refire > 0) { continue; } if (!H_TryIssueJobPackageTrans.meths.TryGetValue(workGiver, out var meth)) { if (workGiver is WorkGiver_Scanner) { if (workGiver.def.scanThings) { meth = AccessTools.Method(workGiver.GetType(), "PotentialWorkThingsGlobal"); } else { meth = AccessTools.Method(workGiver.GetType(), "PotentialWorkCellsGlobal"); } } else { meth = AccessTools.Method(workGiver.GetType(), "NonScanJob"); } H_TryIssueJobPackageTrans.meths.Add(workGiver, meth); } string namer() { string daffy = string.Empty; if (ByWorkType) { daffy = workGiver.def?.workType?.defName; } else { daffy = $"{workGiver.def?.defName} - {workGiver.def?.workType.defName} - {workGiver.def?.modContentPack?.Name}"; } if (RequestTypes && workGiver is WorkGiver_Scanner scan) { daffy += $" - {scan.PotentialWorkThingRequest}"; if (scan.PotentialWorkThingRequest.group == ThingRequestGroup.BuildingArtificial) { daffy += " VERY BAD!"; } } return(daffy); } if (workGiver.def.priorityInType != num && bestTargetOfLastPriority.IsValid) { break; } if (__instance.PawnCanUseWorkGiver(pawn, workGiver)) { string name = string.Empty; if (ByWorkType) { name = workGiver.def.workType.defName; } else { name = workGiver.def.defName; } //if (true) //{ // name = string.Intern(name + pawn.Name.ToStringShort); //} if (workGiver is WorkGiver_Scanner scanny) { name += $"{scanny.PotentialWorkThingRequest}"; } try { prof = ProfileController.Start(name, namer, workGiver.GetType(), workGiver.def, pawn, meth); Job job2 = workGiver.NonScanJob(pawn); prof.Stop(); if (job2 != null) { return(new ThinkResult(job2, __instance, list[j].def.tagToGive)); } if (workGiver is WorkGiver_Scanner scanner) { if (scanner.def.scanThings) { bool Predicate(Thing t) { return(!t.IsForbidden(pawn) && scanner.HasJobOnThing(pawn, t)); } prof = ProfileController.Start(name, namer, workGiver.GetType(), workGiver.def, pawn, meth); IEnumerable <Thing> enumerable = scanner.PotentialWorkThingsGlobal(pawn)?.Where(x => scanner.HasJobOnThing(pawn, x)); //if (scanner is WorkGiver_Repair repair) //{ // foreach (var repairableBuilding in pawn.Map.listerBuildingsRepairable.RepairableBuildings(pawn.Faction)) // { // Log.Warning($"repair scan on {repairableBuilding}"); // } //} Thing thing; if (scanner.Prioritized) { IEnumerable <Thing> enumerable2 = enumerable; if (enumerable2 == null) { enumerable2 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest); } if (scanner.AllowUnreachable) { thing = GenClosest.ClosestThing_Global(pawn.Position, enumerable2, 99999f, Predicate, x => scanner.GetPriority(pawn, x)); } else { TraverseParms traverseParams = TraverseParms.For(pawn, scanner.MaxPathDanger(pawn)); // var validator = (Predicate<Thing>)Predicate; thing = GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map, enumerable2, scanner.PathEndMode, traverseParams, 9999f, Predicate, x => scanner.GetPriority(pawn, x)); } } else if (scanner.AllowUnreachable) { IEnumerable <Thing> enumerable3 = enumerable; if (enumerable3 == null) { enumerable3 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest); } thing = GenClosest.ClosestThing_Global(pawn.Position, enumerable3, 99999f, Predicate); } else { giver = workGiver; key = name; thing = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, scanner.PotentialWorkThingRequest, scanner.PathEndMode, TraverseParms.For(pawn, scanner.MaxPathDanger(pawn)), 9999f, Predicate, enumerable, 0, scanner.MaxRegionsToScanBeforeGlobalSearch, enumerable != null); giver = null; } prof.Stop(); if (thing != null) { bestTargetOfLastPriority = thing; scannerWhoProvidedTarget = scanner; } } if (scanner.def.scanCells) { prof = ProfileController.Start(name, namer, workGiver.GetType(), workGiver.def, pawn, meth); float closestDistSquared = 99999f; float bestPriority = float.MinValue; bool prioritized = scanner.Prioritized; bool allowUnreachable = scanner.AllowUnreachable; Danger maxDanger = scanner.MaxPathDanger(pawn); foreach (IntVec3 intVec in scanner.PotentialWorkCellsGlobal(pawn)) { bool flag = false; int num4 = (intVec - pawn.Position).LengthHorizontalSquared; float num5 = 0f; if (prioritized) { if (!intVec.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, intVec)) { if (!allowUnreachable && !pawn.CanReach(intVec, scanner.PathEndMode, maxDanger)) { goto jamalam; } num5 = scanner.GetPriority(pawn, intVec); if (num5 > bestPriority || num5 == bestPriority && num4 < closestDistSquared) { flag = true; } } } else if (num4 < closestDistSquared && !intVec.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, intVec)) { if (!allowUnreachable && !pawn.CanReach(intVec, scanner.PathEndMode, maxDanger)) { goto jamalam; } flag = true; } if (flag) { bestTargetOfLastPriority = new TargetInfo(intVec, pawn.Map); scannerWhoProvidedTarget = scanner; closestDistSquared = num4; bestPriority = num5; } } prof.Stop(); } } } catch (Exception ex) { Log.Error(string.Concat(pawn, " threw exception in WorkGiver ", workGiver.def.defName, ": ", ex.ToString())); } if (bestTargetOfLastPriority.IsValid) { // pawn.mindState.lastGivenWorkType = workGiver.def.workType; prof = ProfileController.Start(name, namer, workGiver.GetType(), workGiver.def, pawn, meth); Job job3; if (bestTargetOfLastPriority.HasThing) { job3 = scannerWhoProvidedTarget.JobOnThing(pawn, bestTargetOfLastPriority.Thing); } else { job3 = scannerWhoProvidedTarget.JobOnCell(pawn, bestTargetOfLastPriority.Cell); } prof.Stop(); if (job3 != null) { job3.workGiverDef = scannerWhoProvidedTarget.def; return(new ThinkResult(job3, __instance, list[j].def.tagToGive)); } Log.ErrorOnce( string.Concat("Analyzer: ", scannerWhoProvidedTarget, " provided target ", bestTargetOfLastPriority, " but yielded no actual job for pawn ", pawn, ". The CanGiveJob and JobOnX methods may not be synchronized."), 6112651); } num = workGiver.def.priorityInType; } jamalam: refires[workGiver.def] = refireLength; } return(ThinkResult.NoJob); }
internal static List <FloatMenuOption> ChoicesAtFor(Vector3 clickPos, Pawn pawn) { IntVec3 clickCell = IntVec3.FromVector3(clickPos); DangerUtility.NotifyDirectOrderingThisFrame(pawn); List <FloatMenuOption> list = new List <FloatMenuOption>(); if (!clickCell.InBounds()) { return(list); } // ***** Beginning of drafted options ***** if (pawn.Drafted) { foreach (TargetInfo attackTarg in GenUI.TargetsAt(clickPos, TargetingParameters.ForAttackHostile(), true)) { // *** Fire at option *** if (pawn.equipment.Primary != null && !pawn.equipment.PrimaryEq.PrimaryVerb.verbProps.MeleeRange) { string str; Action rangedAct = FloatMenuUtility.GetRangedAttackAction(pawn, attackTarg, out str); string text = "FireAt".Translate(new object[] { attackTarg.Thing.LabelCap }); FloatMenuOption floatMenuOption = new FloatMenuOption(); floatMenuOption.priority = MenuOptionPriority.High; if (rangedAct == null) { text = text + " (" + str + ")"; } else { floatMenuOption.autoTakeable = true; floatMenuOption.action = new Action(delegate { MoteThrower.ThrowStatic(attackTarg.Thing.DrawPos, ThingDefOf.Mote_FeedbackAttack, 1f); rangedAct(); }); } floatMenuOption.label = text; list.Add(floatMenuOption); } // *** Melee attack option *** string str2; Action meleeAct = FloatMenuUtility.GetMeleeAttackAction(pawn, attackTarg, out str2); Pawn pawn2 = attackTarg.Thing as Pawn; string text2; if (pawn2 != null && pawn2.Downed) { text2 = "MeleeAttackToDeath".Translate(new object[] { attackTarg.Thing.LabelCap }); } else { text2 = "MeleeAttack".Translate(new object[] { attackTarg.Thing.LabelCap }); } Thing thing = attackTarg.Thing; FloatMenuOption floatMenuOption2 = new FloatMenuOption(string.Empty, null, MenuOptionPriority.High, null, thing); if (meleeAct == null) { text2 = text2 + " (" + str2 + ")"; } else { floatMenuOption2.action = new Action(delegate { MoteThrower.ThrowStatic(attackTarg.Thing.DrawPos, ThingDefOf.Mote_FeedbackAttack, 1f); meleeAct(); }); } floatMenuOption2.label = text2; list.Add(floatMenuOption2); } // *** Arrest option *** if (pawn.RaceProps.Humanlike && !pawn.Downed) { foreach (TargetInfo current2 in GenUI.TargetsAt(clickPos, TargetingParameters.ForArrest(pawn), true)) { TargetInfo dest = current2; if (!pawn.CanReach(dest, PathEndMode.OnCell, Danger.Deadly, false, TraverseMode.ByPawn)) { list.Add(new FloatMenuOption("CannotArrest".Translate() + " (" + "NoPath".Translate() + ")", null, MenuOptionPriority.Medium, null, null)); } else if (!pawn.CanReserve(dest.Thing, 1)) { list.Add(new FloatMenuOption("CannotArrest".Translate() + ": " + "Reserved".Translate(), null, MenuOptionPriority.Medium, null, null)); } else { Pawn pTarg = (Pawn)dest.Thing; Action action = new Action(delegate { Building_Bed building_Bed = RestUtility.FindBedFor(pTarg, pawn, true, false, false); if (building_Bed == null) { Messages.Message("CannotArrest".Translate() + ": " + "NoPrisonerBed".Translate(), pTarg, MessageSound.RejectInput); return; } Job job = new Job(JobDefOf.Arrest, pTarg, building_Bed); job.playerForced = true; job.maxNumToCarry = 1; pawn.drafter.TakeOrderedJob(job); TutorUtility.DoModalDialogIfNotKnown(ConceptDefOf.ArrestingCreatesEnemies); }); List <FloatMenuOption> arg_3F1_0 = list; Thing thing = dest.Thing; arg_3F1_0.Add(new FloatMenuOption("TryToArrest".Translate(new object[] { dest.Thing.LabelCap }), action, MenuOptionPriority.Medium, null, thing)); } } } // *** Goto option *** int num = GenRadial.NumCellsInRadius(2.9f); for (int i = 0; i < num; i++) { IntVec3 curLoc = GenRadial.RadialPattern[i] + clickCell; if (curLoc.Standable()) { if (curLoc != pawn.Position) { if (!pawn.CanReach(curLoc, PathEndMode.OnCell, Danger.Deadly, false, TraverseMode.ByPawn)) { FloatMenuOption item = new FloatMenuOption("CannotGoNoPath".Translate(), null, MenuOptionPriority.Low, null, null); list.Add(item); } else { Action action2 = new Action(delegate { IntVec3 dest = Pawn_DraftController.BestGotoDestNear(curLoc, pawn); Job job = new Job(JobDefOf.Goto, dest); job.playerForced = true; pawn.drafter.TakeOrderedJob(job); MoteThrower.ThrowStatic(dest, ThingDefOf.Mote_FeedbackGoto, 1f); }); list.Add(new FloatMenuOption("GoHere".Translate(), action2, MenuOptionPriority.Low, null, null) { autoTakeable = true }); } } break; } } } // *** End of drafted options *** // *** Beginning of humanlike options *** if (pawn.RaceProps.Humanlike) { int num2 = 0; if (pawn.story != null) { num2 = pawn.story.traits.DegreeOfTrait(TraitDefOf.DrugDesire); } // *** Consume option *** foreach (Thing current3 in clickCell.GetThingList()) { Thing t = current3; if (t.def.ingestible != null && pawn.RaceProps.CanEverEat(t) && t.IngestibleNow) { FloatMenuOption item2; if (t.def.ingestible.isPleasureDrug && num2 < 0) { item2 = new FloatMenuOption("ConsumeThing".Translate(new object[] { t.LabelBaseShort }) + " (" + "Teetotaler".Translate() + ")", null, MenuOptionPriority.Medium, null, null); } else if (!pawn.CanReach(t, PathEndMode.OnCell, Danger.Deadly, false, TraverseMode.ByPawn)) { item2 = new FloatMenuOption("ConsumeThing".Translate(new object[] { t.LabelBaseShort }) + " (" + "NoPath".Translate() + ")", null, MenuOptionPriority.Medium, null, null); } else if (!pawn.CanReserve(t, 1)) { item2 = new FloatMenuOption("ConsumeThing".Translate(new object[] { t.LabelBaseShort }) + " (" + "ReservedBy".Translate(new object[] { Find.Reservations.FirstReserverOf(t, pawn.Faction).LabelBaseShort }) + ")", null, MenuOptionPriority.Medium, null, null); } else { item2 = new FloatMenuOption("ConsumeThing".Translate(new object[] { t.LabelBaseShort }), new Action(delegate { t.SetForbidden(false, true); Job job = new Job(JobDefOf.Ingest, t); job.maxNumToCarry = t.def.ingestible.maxNumToIngestAtOnce; pawn.drafter.TakeOrderedJob(job); }), MenuOptionPriority.Medium, null, null); } list.Add(item2); } } // *** Rescue/Capture downed option *** foreach (TargetInfo current4 in GenUI.TargetsAt(clickPos, TargetingParameters.ForRescue(pawn), true)) { Pawn victim = (Pawn)current4.Thing; if (!victim.InBed() && pawn.CanReserveAndReach(victim, PathEndMode.OnCell, Danger.Deadly, 1) && !victim.IsPrisonerOfColony) { if ((victim.Faction == Faction.OfColony && victim.MentalStateDef == null) || (victim.Faction != Faction.OfColony && victim.MentalStateDef == null && !victim.IsPrisonerOfColony && (victim.Faction == null || !victim.Faction.HostileTo(Faction.OfColony)))) { List <FloatMenuOption> arg_8E1_0 = list; Pawn victim2 = victim; arg_8E1_0.Add(new FloatMenuOption("Rescue".Translate(new object[] { victim2.LabelCap }), new Action(delegate { Building_Bed building_Bed = RestUtility.FindBedFor(victim, pawn, false, false, false); if (building_Bed == null) { string str; if (victim.RaceProps.Animal) { str = "NoAnimalBed".Translate(); } else { str = "NoNonPrisonerBed".Translate(); } Messages.Message("CannotRescue".Translate() + ": " + str, victim, MessageSound.RejectInput); return; } Job job = new Job(JobDefOf.Rescue, victim, building_Bed); job.maxNumToCarry = 1; job.playerForced = true; pawn.drafter.TakeOrderedJob(job); ConceptDatabase.KnowledgeDemonstrated(ConceptDefOf.Rescuing, KnowledgeAmount.Total); }), MenuOptionPriority.Medium, null, victim2)); } if (victim.MentalStateDef != null || (victim.RaceProps.Humanlike && victim.Faction != Faction.OfColony)) { List <FloatMenuOption> arg_962_0 = list; Pawn victim2 = victim; arg_962_0.Add(new FloatMenuOption("Capture".Translate(new object[] { victim2.LabelCap }), new Action(delegate { Building_Bed building_Bed = RestUtility.FindBedFor(victim, pawn, true, false, false); if (building_Bed == null) { Messages.Message("CannotCapture".Translate() + ": " + "NoPrisonerBed".Translate(), victim, MessageSound.RejectInput); return; } Job job = new Job(JobDefOf.Capture, victim, building_Bed); job.maxNumToCarry = 1; job.playerForced = true; pawn.drafter.TakeOrderedJob(job); ConceptDatabase.KnowledgeDemonstrated(ConceptDefOf.Capturing, KnowledgeAmount.Total); }), MenuOptionPriority.Medium, null, victim2)); } } } // *** Carry to cryosleep option *** foreach (TargetInfo current5 in GenUI.TargetsAt(clickPos, TargetingParameters.ForRescue(pawn), true)) { TargetInfo targetInfo = current5; Pawn victim = (Pawn)targetInfo.Thing; if (victim.Downed && pawn.CanReserveAndReach(victim, PathEndMode.OnCell, Danger.Deadly, 1) && Building_CryptosleepCasket.FindCryptosleepCasketFor(victim, pawn) != null) { string label = "CarryToCryptosleepCasket".Translate(new object[] { targetInfo.Thing.LabelCap }); JobDef jDef = JobDefOf.CarryToCryptosleepCasket; Action action3 = new Action(delegate { Building_CryptosleepCasket building_CryptosleepCasket = Building_CryptosleepCasket.FindCryptosleepCasketFor(victim, pawn); if (building_CryptosleepCasket == null) { Messages.Message("CannotCarryToCryptosleepCasket".Translate() + ": " + "NoCryptosleepCasket".Translate(), victim, MessageSound.RejectInput); return; } Job job = new Job(jDef, victim, building_CryptosleepCasket); job.maxNumToCarry = 1; job.playerForced = true; pawn.drafter.TakeOrderedJob(job); }); List <FloatMenuOption> arg_A80_0 = list; Pawn victim2 = victim; arg_A80_0.Add(new FloatMenuOption(label, action3, MenuOptionPriority.Medium, null, victim2)); } } // *** Strip option *** foreach (TargetInfo current6 in GenUI.TargetsAt(clickPos, TargetingParameters.ForStrip(pawn), true)) { TargetInfo stripTarg = current6; FloatMenuOption item3; if (!pawn.CanReach(stripTarg, PathEndMode.ClosestTouch, Danger.Deadly, false, TraverseMode.ByPawn)) { item3 = new FloatMenuOption("CannotStrip".Translate(new object[] { stripTarg.Thing.LabelCap }) + " (" + "NoPath".Translate() + ")", null, MenuOptionPriority.Medium, null, null); } else if (!pawn.CanReserveAndReach(stripTarg, PathEndMode.ClosestTouch, Danger.Deadly, 1)) { item3 = new FloatMenuOption("CannotStrip".Translate(new object[] { stripTarg.Thing.LabelCap }) + " (" + "ReservedBy".Translate(new object[] { Find.Reservations.FirstReserverOf(stripTarg, pawn.Faction).LabelBaseShort }) + ")", null, MenuOptionPriority.Medium, null, null); } else { item3 = new FloatMenuOption("Strip".Translate(new object[] { stripTarg.Thing.LabelCap }), new Action(delegate { stripTarg.Thing.SetForbidden(false, false); Job job = new Job(JobDefOf.Strip, stripTarg); job.playerForced = true; pawn.drafter.TakeOrderedJob(job); }), MenuOptionPriority.Medium, null, null); } list.Add(item3); } // *** Equip option *** CompInventory compInventory = pawn.TryGetComp <CompInventory>(); // Need compInventory here for equip and wear options if (pawn.equipment != null) { ThingWithComps equipment = null; List <Thing> thingList = clickCell.GetThingList(); for (int j = 0; j < thingList.Count; j++) { if (thingList[j].TryGetComp <CompEquippable>() != null) { equipment = (ThingWithComps)thingList[j]; break; } } if (equipment != null) { string eqLabel = GenLabel.ThingLabel(equipment.def, equipment.Stuff, 1); FloatMenuOption equipOption; if (!pawn.CanReach(equipment, PathEndMode.ClosestTouch, Danger.Deadly, false, TraverseMode.ByPawn)) { equipOption = new FloatMenuOption("CannotEquip".Translate(new object[] { eqLabel }) + " (" + "NoPath".Translate() + ")", null, MenuOptionPriority.Medium, null, null); } else if (!pawn.CanReserve(equipment, 1)) { equipOption = new FloatMenuOption("CannotEquip".Translate(new object[] { eqLabel }) + " (" + "ReservedBy".Translate(new object[] { Find.Reservations.FirstReserverOf(equipment, pawn.Faction).LabelBaseShort }) + ")", null, MenuOptionPriority.Medium, null, null); } else if (!pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation)) { equipOption = new FloatMenuOption("CannotEquip".Translate(new object[] { eqLabel }) + " (" + "Incapable".Translate() + ")", null, MenuOptionPriority.Medium, null, null); } else { // Added check for inventory space here int count; if (compInventory != null && !compInventory.CanFitInInventory(equipment, out count, true)) { equipOption = new FloatMenuOption("CannotEquip".Translate(new object[] { eqLabel }) + " (" + "CR_InventoryFull".Translate() + ")", null); } else { string equipOptionLabel = "Equip".Translate(new object[] { eqLabel }); if (equipment.def.IsRangedWeapon && pawn.story != null && pawn.story.traits.HasTrait(TraitDefOf.Brawler)) { equipOptionLabel = equipOptionLabel + " " + "EquipWarningBrawler".Translate(); } equipOption = new FloatMenuOption(equipOptionLabel, new Action(delegate { equipment.SetForbidden(false, true); Job job = new Job(JobDefOf.Equip, equipment); job.playerForced = true; pawn.drafter.TakeOrderedJob(job); MoteThrower.ThrowStatic(equipment.DrawPos, ThingDefOf.Mote_FeedbackEquip, 1f); ConceptDatabase.KnowledgeDemonstrated(ConceptDefOf.EquippingWeapons, KnowledgeAmount.Total); }), MenuOptionPriority.Medium, null, null); } } list.Add(equipOption); } } // *** Wear option *** if (pawn.apparel != null) { Apparel apparel = Find.ThingGrid.ThingAt <Apparel>(clickCell); if (apparel != null) { FloatMenuOption wearOption; if (!pawn.CanReach(apparel, PathEndMode.ClosestTouch, Danger.Deadly, false, TraverseMode.ByPawn)) { wearOption = new FloatMenuOption("CannotWear".Translate(new object[] { apparel.Label }) + " (" + "NoPath".Translate() + ")", null, MenuOptionPriority.Medium, null, null); } else if (!pawn.CanReserve(apparel, 1)) { Pawn pawn3 = Find.Reservations.FirstReserverOf(apparel, pawn.Faction); wearOption = new FloatMenuOption("CannotWear".Translate(new object[] { apparel.Label }) + " (" + "ReservedBy".Translate(new object[] { pawn3.LabelBaseShort }) + ")", null, MenuOptionPriority.Medium, null, null); } else if (!ApparelUtility.HasPartsToWear(pawn, apparel.def)) { wearOption = new FloatMenuOption("CannotWear".Translate(new object[] { apparel.Label }) + " (" + "CannotWearBecauseOfMissingBodyParts".Translate() + ")", null, MenuOptionPriority.Medium, null, null); } else { // Added check for inventory capacity int count; if (compInventory != null && !compInventory.CanFitInInventory(apparel, out count, false, true)) { wearOption = new FloatMenuOption("CannotWear".Translate(new object[] { apparel.Label }) + " (" + "CR_InventoryFull".Translate() + ")", null); } else { wearOption = new FloatMenuOption("ForceWear".Translate(new object[] { apparel.LabelBaseShort }), new Action(delegate { apparel.SetForbidden(false, true); Job job = new Job(JobDefOf.Wear, apparel); job.playerForced = true; pawn.drafter.TakeOrderedJob(job); }), MenuOptionPriority.Medium, null, null); } } list.Add(wearOption); } } // *** NEW: Pick up option *** if (compInventory != null) { List <Thing> thingList = clickCell.GetThingList(); if (!thingList.NullOrEmpty <Thing>()) { Thing item = thingList.FirstOrDefault(thing => thing.def.alwaysHaulable && !(thing is Corpse)); if (item != null) { FloatMenuOption pickUpOption; int count = 0; if (!pawn.CanReach(item, PathEndMode.Touch, Danger.Deadly)) { pickUpOption = new FloatMenuOption("CR_CannotPickUp".Translate() + " " + item.LabelBaseShort + " (" + "NoPath".Translate() + ")", null); } else if (!pawn.CanReserve(item)) { pickUpOption = new FloatMenuOption("CR_CannotPickUp".Translate() + " " + item.LabelBaseShort + " (" + "ReservedBy".Translate(new object[] { Find.Reservations.FirstReserverOf(item, pawn.Faction) }), null); } else if (!compInventory.CanFitInInventory(item, out count)) { pickUpOption = new FloatMenuOption("CR_CannotPickUp".Translate() + " " + item.LabelBaseShort + " (" + "CR_InventoryFull".Translate() + ")", null); } else { pickUpOption = new FloatMenuOption("CR_PickUp".Translate() + " " + item.LabelBaseShort, new Action(delegate { item.SetForbidden(false); Job job = new Job(JobDefOf.TakeInventory, item) { maxNumToCarry = 1 }; job.playerForced = true; pawn.drafter.TakeOrderedJob(job); })); } list.Add(pickUpOption); if (count > 1 && item.stackCount > 1) { int numToCarry = Math.Min(count, item.stackCount); FloatMenuOption pickUpStackOption = new FloatMenuOption("CR_PickUp".Translate() + " " + item.LabelBaseShort + " x" + numToCarry.ToString(), new Action(delegate { item.SetForbidden(false); Job job = new Job(JobDefOf.TakeInventory, item) { maxNumToCarry = numToCarry }; job.playerForced = true; pawn.drafter.TakeOrderedJob(job); })); list.Add(pickUpStackOption); } } } } // *** Deposit/drop equipment options *** if (pawn.equipment != null && pawn.equipment.Primary != null) { Thing thing2 = Find.ThingGrid.ThingAt(clickCell, ThingDefOf.EquipmentRack); if (thing2 != null) { if (!pawn.CanReach(thing2, PathEndMode.ClosestTouch, Danger.Deadly, false, TraverseMode.ByPawn)) { list.Add(new FloatMenuOption("CannotDeposit".Translate(new object[] { pawn.equipment.Primary.LabelCap, thing2.def.label }) + " (" + "NoPath".Translate() + ")", null, MenuOptionPriority.Medium, null, null)); } else { using (IEnumerator <IntVec3> enumerator7 = GenAdj.CellsOccupiedBy(thing2).GetEnumerator()) { while (enumerator7.MoveNext()) { IntVec3 c = enumerator7.Current; if (c.GetStorable() == null && pawn.CanReserveAndReach(c, PathEndMode.ClosestTouch, Danger.Deadly, 1)) { Action action4 = new Action(delegate { ThingWithComps t; if (pawn.equipment.TryDropEquipment(pawn.equipment.Primary, out t, pawn.Position, true)) { t.SetForbidden(false, true); Job job = new Job(JobDefOf.HaulToCell, t, c); job.haulMode = HaulMode.ToCellStorage; job.maxNumToCarry = 1; job.playerForced = true; pawn.drafter.TakeOrderedJob(job); } }); list.Add(new FloatMenuOption("Deposit".Translate(new object[] { pawn.equipment.Primary.LabelCap, thing2.def.label }), action4, MenuOptionPriority.Medium, null, null)); break; } } } } } if (pawn.equipment != null && GenUI.TargetsAt(clickPos, TargetingParameters.ForSelf(pawn), true).Any <TargetInfo>()) { Action action5 = new Action(delegate { ThingWithComps thingWithComps; pawn.equipment.TryDropEquipment(pawn.equipment.Primary, out thingWithComps, pawn.Position, true); pawn.drafter.TakeOrderedJob(new Job(JobDefOf.Wait, 20, false)); } ); list.Add(new FloatMenuOption("Drop".Translate(new object[] { pawn.equipment.Primary.LabelCap }), action5, MenuOptionPriority.Medium, null, null)); } } // *** Trade with option *** foreach (TargetInfo current7 in GenUI.TargetsAt(clickPos, TargetingParameters.ForTrade(), true)) { TargetInfo dest2 = current7; if (!pawn.CanReach(dest2, PathEndMode.OnCell, Danger.Deadly, false, TraverseMode.ByPawn)) { list.Add(new FloatMenuOption("CannotTrade".Translate() + " (" + "NoPath".Translate() + ")", null, MenuOptionPriority.Medium, null, null)); } else if (!pawn.CanReserve(dest2.Thing, 1)) { list.Add(new FloatMenuOption("CannotTrade".Translate() + " (" + "Reserved".Translate() + ")", null, MenuOptionPriority.Medium, null, null)); } else { Pawn pTarg = (Pawn)dest2.Thing; Action action6 = new Action(delegate { Job job = new Job(JobDefOf.TradeWithPawn, pTarg); job.playerForced = true; pawn.drafter.TakeOrderedJob(job); ConceptDatabase.KnowledgeDemonstrated(ConceptDefOf.InteractingWithTraders, KnowledgeAmount.Total); }); string str3 = string.Empty; if (pTarg.Faction != null) { str3 = " (" + pTarg.Faction.name + ")"; } List <FloatMenuOption> arg_142E_0 = list; Thing thing = dest2.Thing; arg_142E_0.Add(new FloatMenuOption("TradeWith".Translate(new object[] { pTarg.LabelBaseShort }) + str3, action6, MenuOptionPriority.Medium, null, thing)); } } foreach (Thing current8 in Find.ThingGrid.ThingsAt(clickCell)) { foreach (FloatMenuOption current9 in current8.GetFloatMenuOptions(pawn)) { list.Add(current9); } } } // *** End of humanlike options *** // *** Beginning of non-drafted options *** if (!pawn.Drafted) { bool flag = false; bool flag2 = false; foreach (Thing current10 in Find.ThingGrid.ThingsAt(clickCell)) { flag2 = true; if (pawn.CanReach(current10, PathEndMode.Touch, Danger.Deadly, false, TraverseMode.ByPawn)) { flag = true; break; } } if (flag2 && !flag) { list.Add(new FloatMenuOption("(" + "NoPath".Translate() + ")", null, MenuOptionPriority.Medium, null, null)); return(list); } foreach (Thing current11 in Find.ThingGrid.ThingsAt(clickCell)) { Pawn pawn4 = Find.Reservations.FirstReserverOf(current11, pawn.Faction); if (pawn4 != null && pawn4 != pawn) { list.Add(new FloatMenuOption("IsReservedBy".Translate(new object[] { current11.LabelBaseShort.CapitalizeFirst(), pawn4.LabelBaseShort }), null, MenuOptionPriority.Medium, null, null)); } else { JobGiver_Work jobGiver_Work = pawn.thinker.TryGetMainTreeThinkNode <JobGiver_Work>(); if (jobGiver_Work != null) { foreach (WorkTypeDef current12 in DefDatabase <WorkTypeDef> .AllDefsListForReading) { for (int k = 0; k < current12.workGiversByPriority.Count; k++) { WorkGiver_Scanner workGiver_Scanner = current12.workGiversByPriority[k].Worker as WorkGiver_Scanner; if (workGiver_Scanner != null) { if (workGiver_Scanner.def.directOrderable) { if (!workGiver_Scanner.ShouldSkip(pawn)) { JobFailReason.Clear(); Job job; if (!workGiver_Scanner.HasJobOnThingForced(pawn, current11)) { job = null; } else { job = workGiver_Scanner.JobOnThingForced(pawn, current11); } if (workGiver_Scanner.PotentialWorkThingRequest.Accepts(current11) || (workGiver_Scanner.PotentialWorkThingsGlobal(pawn) != null && workGiver_Scanner.PotentialWorkThingsGlobal(pawn).Contains(current11))) { if (job == null) { if (JobFailReason.HaveReason) { string label2 = "CannotGenericWork".Translate(new object[] { workGiver_Scanner.def.verb, current11.LabelBaseShort }) + " (" + JobFailReason.Reason + ")"; list.Add(new FloatMenuOption(label2, null, MenuOptionPriority.Medium, null, null)); } } else { string label; WorkTypeDef workType = workGiver_Scanner.def.workType; Action action7 = null; PawnCapacityDef pawnCapacityDef = workGiver_Scanner.MissingRequiredCapacity(pawn); 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, current11.LabelBaseShort }); } else if (pawn.workSettings.GetPriority(workType) == 0) { label = "CannotPrioritizeIsNotA".Translate(new object[] { pawn.NameStringShort, workType.pawnLabel }); } else if (job.def == JobDefOf.Research && current11 is Building_ResearchBench) { label = "CannotPrioritizeResearch".Translate(); } else if (current11.IsForbidden(pawn)) { label = "CannotPrioritizeForbidden".Translate(new object[] { current11.Label }); } else if (!pawn.CanReach(current11, PathEndMode.Touch, Danger.Deadly, false, TraverseMode.ByPawn)) { label = current11.Label + ": " + "NoPath".Translate(); } else { label = "PrioritizeGeneric".Translate(new object[] { workGiver_Scanner.def.gerund, current11.Label }); Job localJob = job; WorkTypeDef localWorkTypeDef = workType; action7 = new Action(delegate { pawn.thinker.GetMainTreeThinkNode <JobGiver_Work>().TryStartPrioritizedWorkOn(pawn, localJob, localWorkTypeDef); }); } if (!list.Any(op => op.label == label)) { list.Add(new FloatMenuOption(label, action7, MenuOptionPriority.Medium, null, null)); } } } } } } } } } } } } // *** End of non-drafted options *** foreach (FloatMenuOption current13 in pawn.GetExtraFloatMenuOptionsFor(clickCell)) { list.Add(current13); } DangerUtility.DoneDirectOrdering(); return(list); }
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); }
public static bool TryIssueJobPackage(JobGiver_Work __instance, ref ThinkResult __result, Pawn pawn, JobIssueParams jobParams) { if (__instance.emergency && pawn.mindState.priorityWork.IsPrioritized) { List <WorkGiverDef> workGiversByPriority = pawn.mindState.priorityWork.WorkGiver.workType.workGiversByPriority; for (int i = 0; i < workGiversByPriority.Count; i++) { WorkGiver worker = workGiversByPriority[i].Worker; if (WorkGiversRelated(pawn.mindState.priorityWork.WorkGiver, worker.def)) { Job job = GiverTryGiveJobPrioritized(pawn, worker, pawn.mindState.priorityWork.Cell); if (job != null) { job.playerForced = true; __result = new ThinkResult(job, __instance, workGiversByPriority[i].tagToGive); return(false); } } } pawn.mindState.priorityWork.Clear(); } List <WorkGiver> list = (!__instance.emergency) ? pawn.workSettings.WorkGiversInOrderNormal : pawn.workSettings.WorkGiversInOrderEmergency; int num = -999; TargetInfo bestTargetOfLastPriority = TargetInfo.Invalid; WorkGiver_Scanner scannerWhoProvidedTarget = null; WorkGiver_Scanner scanner; IntVec3 pawnPosition; float closestDistSquared; float bestPriority; bool prioritized; bool allowUnreachable; Danger maxPathDanger; for (int j = 0; j < list.Count; j++) { WorkGiver workGiver = list[j]; if (workGiver.def.priorityInType != num && bestTargetOfLastPriority.IsValid) { break; } if (!PawnCanUseWorkGiver(pawn, workGiver)) { continue; } try { Job job2 = workGiver.NonScanJob(pawn); if (job2 != null) { __result = new ThinkResult(job2, __instance, list[j].def.tagToGive); return(false); } scanner = (workGiver as WorkGiver_Scanner); if (scanner != null) { if (scanner.def.scanThings) { Predicate <Thing> validator = (Thing t) => !t.IsForbidden(pawn) && scanner.HasJobOnThing(pawn, t); IEnumerable <Thing> enumerable = scanner.PotentialWorkThingsGlobal(pawn); Thing thing; if (scanner.Prioritized) { IEnumerable <Thing> enumerable2 = enumerable; if (enumerable2 == null) { enumerable2 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest); } thing = ((!scanner.AllowUnreachable) ? GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map, enumerable2, scanner.PathEndMode, TraverseParms.For(pawn, scanner.MaxPathDanger(pawn)), 9999f, validator, (Thing x) => scanner.GetPriority(pawn, x)) : GenClosest.ClosestThing_Global(pawn.Position, enumerable2, 99999f, validator, (Thing x) => scanner.GetPriority(pawn, x))); } else if (scanner.AllowUnreachable) { IEnumerable <Thing> enumerable3 = enumerable; if (enumerable3 == null) { enumerable3 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest); } thing = GenClosest.ClosestThing_Global(pawn.Position, enumerable3, 99999f, validator); } else { thing = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, scanner.PotentialWorkThingRequest, scanner.PathEndMode, TraverseParms.For(pawn, scanner.MaxPathDanger(pawn)), 9999f, validator, enumerable, 0, scanner.MaxRegionsToScanBeforeGlobalSearch, enumerable != null); } if (thing != null) { bestTargetOfLastPriority = thing; scannerWhoProvidedTarget = scanner; } } if (scanner.def.scanCells) { pawnPosition = pawn.Position; closestDistSquared = 99999f; bestPriority = float.MinValue; prioritized = scanner.Prioritized; allowUnreachable = scanner.AllowUnreachable; maxPathDanger = scanner.MaxPathDanger(pawn); IEnumerable <IntVec3> enumerable4 = scanner.PotentialWorkCellsGlobal(pawn); IList <IntVec3> list2; if ((list2 = (enumerable4 as IList <IntVec3>)) != null) { for (int k = 0; k < list2.Count; k++) { ProcessCell(list2[k]); } } else { foreach (IntVec3 item in enumerable4) { ProcessCell(item); } } } } void ProcessCell(IntVec3 c) { bool flag = false; float num2 = (c - pawnPosition).LengthHorizontalSquared; float num3 = 0f; if (prioritized) { if (!c.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, c)) { if (!allowUnreachable && !pawn.CanReach(c, scanner.PathEndMode, maxPathDanger)) { return; } num3 = scanner.GetPriority(pawn, c); if (num3 > bestPriority || (num3 == bestPriority && num2 < closestDistSquared)) { flag = true; } } } else if (num2 < closestDistSquared && !c.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, c)) { if (!allowUnreachable && !pawn.CanReach(c, scanner.PathEndMode, maxPathDanger)) { return; } flag = true; } if (flag) { bestTargetOfLastPriority = new TargetInfo(c, pawn.Map); scannerWhoProvidedTarget = scanner; closestDistSquared = num2; bestPriority = num3; } } } catch (Exception ex) { Log.Error(string.Concat(pawn, " threw exception in WorkGiver ", workGiver.def.defName, ": ", ex.ToString())); } finally { } if (bestTargetOfLastPriority.IsValid) { Job job3 = (!bestTargetOfLastPriority.HasThing) ? scannerWhoProvidedTarget.JobOnCell(pawn, bestTargetOfLastPriority.Cell) : scannerWhoProvidedTarget.JobOnThing(pawn, bestTargetOfLastPriority.Thing); if (job3 != null) { job3.workGiverDef = scannerWhoProvidedTarget.def; __result = new ThinkResult(job3, __instance, list[j].def.tagToGive); return(false); } //HACK - I know. I'm awful. //Log.ErrorOnce(string.Concat(scannerWhoProvidedTarget, " provided target ", bestTargetOfLastPriority, " but yielded no actual job for pawn ", pawn, ". The CanGiveJob and JobOnX methods may not be synchronized."), 6112651); Log.Warning(string.Concat(scannerWhoProvidedTarget, " provided target ", bestTargetOfLastPriority, " but yielded no actual job for pawn ", pawn, ". The CanGiveJob and JobOnX methods may not be synchronized.")); } num = workGiver.def.priorityInType; } __result = ThinkResult.NoJob; return(false); }
public 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); }