private Job GiverTryGiveJobPrioritized(Pawn pawn, WorkGiver giver, IntVec3 cell) { Job result; if (!this.PawnCanUseWorkGiver(pawn, giver)) { result = null; } else { 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 = (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; return(scanner.JobOnThing(pawn, thing, false)); } } } if (giver.def.scanCells) { if (!cell.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, cell, false)) { pawn.mindState.lastGivenWorkType = giver.def.workType; return(scanner.JobOnCell(pawn, cell, false)); } } } } 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); }
private Job GiverTryGiveJobPrioritized(Pawn pawn, WorkGiver giver, IntVec3 cell) { if (!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 = (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); }
public override ThinkResult TryIssueJobPackage(Pawn pawn, JobIssueParams jobParams) { 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 = 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 (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; 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 = -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, 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, 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() }), false); } 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, false); } 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, false); } num = workGiver.def.priorityInType; } } return(ThinkResult.NoJob); }
public override ThinkResult TryIssueJobPackage(Pawn pawn, JobIssueParams jobParams) { if (emergency && pawn.mindState.priorityWork.IsPrioritized) { List <WorkGiverDef> workGiversByPriority = pawn.mindState.priorityWork.WorkGiver.workType.workGiversByPriority; for (int i = 0; i < workGiversByPriority.Count; i++) { WorkGiver worker = workGiversByPriority[i].Worker; if (WorkGiversRelated(pawn.mindState.priorityWork.WorkGiver, worker.def)) { Job job = GiverTryGiveJobPrioritized(pawn, worker, pawn.mindState.priorityWork.Cell); if (job != null) { job.playerForced = true; return(new ThinkResult(job, this, workGiversByPriority[i].tagToGive)); } } } pawn.mindState.priorityWork.Clear(); } List <WorkGiver> list = ((!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) { return(new ThinkResult(job2, this, list[j].def.tagToGive)); } 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; return(new ThinkResult(job3, this, 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); }
private static void AddUndraftedOrders(Vector3 clickPos, Pawn pawn, List <FloatMenuOption> opts) { IntVec3 clickCell = IntVec3.FromVector3(clickPos); bool flag = false; bool flag2 = false; foreach (Thing item in pawn.Map.thingGrid.ThingsAt(clickCell)) { flag2 = true; if (pawn.CanReach(item, PathEndMode.Touch, Danger.Deadly, false, TraverseMode.ByPawn)) { flag = true; break; } } if (flag2 && !flag) { opts.Add(new FloatMenuOption("(" + "NoPath".Translate() + ")", null, MenuOptionPriority.Default, null, null, 0f, null, null)); } else { JobGiver_Work jobGiver_Work = pawn.thinker.TryGetMainTreeThinkNode <JobGiver_Work>(); if (jobGiver_Work != null) { foreach (Thing item2 in pawn.Map.thingGrid.ThingsAt(clickCell)) { foreach (WorkTypeDef item3 in DefDatabase <WorkTypeDef> .AllDefsListForReading) { for (int i = 0; i < item3.workGiversByPriority.Count; i++) { WorkGiver_Scanner workGiver_Scanner = item3.workGiversByPriority[i].Worker as WorkGiver_Scanner; string label; Action action; if (workGiver_Scanner != null && workGiver_Scanner.def.directOrderable && !workGiver_Scanner.ShouldSkip(pawn)) { JobFailReason.Clear(); if (!workGiver_Scanner.PotentialWorkThingRequest.Accepts(item2) && (workGiver_Scanner.PotentialWorkThingsGlobal(pawn) == null || !workGiver_Scanner.PotentialWorkThingsGlobal(pawn).Contains(item2))) { continue; } label = null; action = null; PawnCapacityDef pawnCapacityDef = workGiver_Scanner.MissingRequiredCapacity(pawn); if (pawnCapacityDef != null) { label = "CannotMissingHealthActivities".Translate(pawnCapacityDef.label); } else { Job job = workGiver_Scanner.HasJobOnThing(pawn, item2, true) ? workGiver_Scanner.JobOnThing(pawn, item2, true) : null; if (job == null) { if (JobFailReason.HaveReason) { label = "CannotGenericWork".Translate(workGiver_Scanner.def.verb, item2.LabelShort) + " (" + JobFailReason.Reason + ")"; goto IL_0589; } continue; } WorkTypeDef workType = workGiver_Scanner.def.workType; if (pawn.story != null && pawn.story.WorkTagIsDisabled(workGiver_Scanner.def.workTags)) { label = "CannotPrioritizeWorkGiverDisabled".Translate(workGiver_Scanner.def.label); } else if (pawn.jobs.curJob != null && pawn.jobs.curJob.JobIsSameAs(job)) { label = "CannotGenericAlreadyAm".Translate(workType.gerundLabel, item2.LabelShort); } else if (pawn.workSettings.GetPriority(workType) == 0) { if (pawn.story.WorkTypeIsDisabled(workType)) { label = "CannotPrioritizeWorkTypeDisabled".Translate(workType.gerundLabel); } else if ("CannotPrioritizeNotAssignedToWorkType".CanTranslate()) { label = "CannotPrioritizeNotAssignedToWorkType".Translate(workType.gerundLabel); } else { label = "CannotPrioritizeIsNotA".Translate(pawn.NameStringShort, workType.pawnLabel); } } else if (job.def == JobDefOf.Research && item2 is Building_ResearchBench) { label = "CannotPrioritizeResearch".Translate(); } else if (item2.IsForbidden(pawn)) { if (!item2.Position.InAllowedArea(pawn)) { label = "CannotPrioritizeForbiddenOutsideAllowedArea".Translate(item2.Label); } else { label = "CannotPrioritizeForbidden".Translate(item2.Label); } } else if (!pawn.CanReach(item2, workGiver_Scanner.PathEndMode, Danger.Deadly, false, TraverseMode.ByPawn)) { label = (item2.Label + ": " + "NoPath".Translate()).CapitalizeFirst(); } else { label = "PrioritizeGeneric".Translate(workGiver_Scanner.def.gerund, item2.Label); Job localJob = job; WorkGiver_Scanner localScanner = workGiver_Scanner; action = delegate { pawn.jobs.TryTakeOrderedJobPrioritizedWork(localJob, localScanner, clickCell); }; } } goto IL_0589; } continue; IL_0589: if (!opts.Any((FloatMenuOption op) => op.Label == label.TrimEnd())) { opts.Add(FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption(label, action, MenuOptionPriority.Default, null, null, 0f, null, null), pawn, item2, "ReservedBy")); } } } } foreach (WorkTypeDef item4 in DefDatabase <WorkTypeDef> .AllDefsListForReading) { for (int j = 0; j < item4.workGiversByPriority.Count; j++) { WorkGiver_Scanner workGiver_Scanner2 = item4.workGiversByPriority[j].Worker as WorkGiver_Scanner; Action action2; string label2; if (workGiver_Scanner2 != null && workGiver_Scanner2.def.directOrderable && !workGiver_Scanner2.ShouldSkip(pawn)) { JobFailReason.Clear(); if (workGiver_Scanner2.PotentialWorkCellsGlobal(pawn).Contains(clickCell)) { action2 = null; label2 = null; PawnCapacityDef pawnCapacityDef2 = workGiver_Scanner2.MissingRequiredCapacity(pawn); if (pawnCapacityDef2 != null) { label2 = "CannotMissingHealthActivities".Translate(pawnCapacityDef2.label); } else { Job job2 = workGiver_Scanner2.HasJobOnCell(pawn, clickCell) ? workGiver_Scanner2.JobOnCell(pawn, clickCell) : null; if (job2 == null) { if (JobFailReason.HaveReason) { label2 = "CannotGenericWork".Translate(workGiver_Scanner2.def.verb, "AreaLower".Translate()) + " (" + JobFailReason.Reason + ")"; goto IL_098f; } continue; } WorkTypeDef workType2 = workGiver_Scanner2.def.workType; if (pawn.jobs.curJob != null && pawn.jobs.curJob.JobIsSameAs(job2)) { label2 = "CannotGenericAlreadyAm".Translate(workType2.gerundLabel, "AreaLower".Translate()); } else if (pawn.workSettings.GetPriority(workType2) == 0) { if (pawn.story.WorkTypeIsDisabled(workType2)) { label2 = "CannotPrioritizeWorkTypeDisabled".Translate(workType2.gerundLabel); } else if ("CannotPrioritizeNotAssignedToWorkType".CanTranslate()) { label2 = "CannotPrioritizeNotAssignedToWorkType".Translate(workType2.gerundLabel); } else { label2 = "CannotPrioritizeIsNotA".Translate(pawn.NameStringShort, workType2.pawnLabel); } } else if (!pawn.CanReach(clickCell, PathEndMode.Touch, Danger.Deadly, false, TraverseMode.ByPawn)) { label2 = "AreaLower".Translate().CapitalizeFirst() + ": " + "NoPath".Translate(); } else { label2 = "PrioritizeGeneric".Translate(workGiver_Scanner2.def.gerund, "AreaLower".Translate()); Job localJob2 = job2; WorkGiver_Scanner localScanner2 = workGiver_Scanner2; action2 = delegate { pawn.jobs.TryTakeOrderedJobPrioritizedWork(localJob2, localScanner2, clickCell); }; } } goto IL_098f; } } continue; IL_098f: if (!opts.Any((FloatMenuOption op) => op.Label == label2.TrimEnd())) { opts.Add(FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption(label2, action2, MenuOptionPriority.Default, null, null, 0f, null, null), pawn, clickCell, "ReservedBy")); } } } } } }