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 bool HasSameJobOnThing(Job job, WorkGiver_Scanner workGiverScanner, LocalTargetInfo targetInfo) { if (HasValidTarget(targetInfo) && targetInfo.HasThing) { Job getJob = workGiverScanner.JobOnThing(Meeseeks, targetInfo.Thing, true); if (getJob != null && getJob.def == job.def) { return(true); } } return(false); }
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); }
private static ThinkResult Detour(JobGiver_Work __instance, Pawn pawn) { if (__instance.emergency && pawn.mindState.priorityWork.IsPrioritized) { var workGiversByPriority = pawn.mindState.priorityWork.WorkGiver.workType.workGiversByPriority; for (var i = 0; i < workGiversByPriority.Count; i++) { var worker = workGiversByPriority[i].Worker; var job = __instance.GiverTryGiveJobPrioritized(pawn, worker, pawn.mindState.priorityWork.Cell); if (job != null) { job.playerForced = true; return(new ThinkResult(job, __instance, workGiversByPriority[i].tagToGive)); } } pawn.mindState.priorityWork.Clear(); } var list = __instance.emergency ? pawn.workSettings.WorkGiversInOrderEmergency : pawn.workSettings.WorkGiversInOrderNormal; var num = -999; var bestTargetOfLastPriority = TargetInfo.Invalid; WorkGiver_Scanner scannerWhoProvidedTarget = null; var coo = list.Count; for (var j = 0; j < coo; j++) { var workGiver = list[j]; string namer() { var daffy = string.Empty; if (ByWorkType) { daffy = workGiver.def?.workType?.defName; } else { daffy = $"{workGiver.def?.defName} - {workGiver.def?.workType.defName} - {workGiver.def?.modContentPack?.Name}"; } //if (true) //{ // daffy += $" - { TraverseParms.For(pawn, scanner.MaxPathDanger(pawn)).ToString()} - {pawn.Name.ToStringShort}"; //} if (RequestTypes && workGiver is WorkGiver_Scanner scan) { daffy += $" - {scan.PotentialWorkThingRequest}"; if (scan.PotentialWorkThingRequest.group == ThingRequestGroup.BuildingArtificial) { daffy += " VERY BAD!"; } } return(daffy); } if (workGiver.def.priorityInType != num && bestTargetOfLastPriority.IsValid) { break; } if (__instance.PawnCanUseWorkGiver(pawn, workGiver)) { var name = string.Empty; if (ByWorkType) { name = workGiver.def.workType.defName; } else { name = workGiver.def.defName; } //if (true) //{ // name = string.Intern(name + pawn.Name.ToStringShort); //} if (workGiver is WorkGiver_Scanner scanny) { name += $"{scanny.PotentialWorkThingRequest}"; } try { var job2 = workGiver.NonScanJob(pawn); if (job2 != null) { return(new ThinkResult(job2, __instance, list[j].def.tagToGive)); } if (workGiver is WorkGiver_Scanner scanner) { Analyzer.Start(name, namer, workGiver.GetType(), workGiver.def, pawn); if (scanner.def.scanThings) { bool Predicate(Thing t) { return(!t.IsForbidden(pawn) && scanner.HasJobOnThing(pawn, t)); } var enumerable = scanner.PotentialWorkThingsGlobal(pawn); Thing thing; if (scanner.Prioritized) { var enumerable2 = enumerable; if (enumerable2 == null) { enumerable2 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest); } if (scanner.AllowUnreachable) { thing = GenClosest.ClosestThing_Global(pawn.Position, enumerable2, 99999f, Predicate, x => scanner.GetPriority(pawn, x)); } else { var traverseParams = TraverseParms.For(pawn, scanner.MaxPathDanger(pawn)); var validator = (Predicate <Thing>)Predicate; thing = GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map, enumerable2, scanner.PathEndMode, traverseParams, 9999f, validator, x => scanner.GetPriority(pawn, x)); } } else if (scanner.AllowUnreachable) { var enumerable3 = enumerable; if (enumerable3 == null) { enumerable3 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest); } thing = GenClosest.ClosestThing_Global(pawn.Position, enumerable3, 99999f, Predicate); } else { giver = workGiver; key = name; Analyzer.Start(name, namer, workGiver.GetType(), workGiver.def, pawn); thing = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, scanner.PotentialWorkThingRequest, scanner.PathEndMode, TraverseParms.For(pawn, scanner.MaxPathDanger(pawn)), 9999f, Predicate, enumerable, 0, scanner.MaxRegionsToScanBeforeGlobalSearch, enumerable != null); giver = null; } if (thing != null) { bestTargetOfLastPriority = thing; scannerWhoProvidedTarget = scanner; } } if (scanner.def.scanCells) { var closestDistSquared = 99999f; var bestPriority = float.MinValue; var prioritized = scanner.Prioritized; var allowUnreachable = scanner.AllowUnreachable; var maxDanger = scanner.MaxPathDanger(pawn); foreach (var intVec in scanner.PotentialWorkCellsGlobal(pawn)) { var flag = false; var num4 = (intVec - pawn.Position).LengthHorizontalSquared; var num5 = 0f; if (prioritized) { if (!intVec.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, intVec)) { if (!allowUnreachable && !pawn.CanReach(intVec, scanner.PathEndMode, maxDanger)) { continue; } num5 = scanner.GetPriority(pawn, intVec); if (num5 > bestPriority || num5 == bestPriority && num4 < closestDistSquared) { flag = true; } } } else if (num4 < closestDistSquared && !intVec.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, intVec)) { if (!allowUnreachable && !pawn.CanReach(intVec, scanner.PathEndMode, maxDanger)) { continue; } flag = true; } if (flag) { bestTargetOfLastPriority = new TargetInfo(intVec, pawn.Map); scannerWhoProvidedTarget = scanner; closestDistSquared = num4; bestPriority = num5; } } } Analyzer.Stop(name); } } catch (Exception ex) { Log.Error(string.Concat(pawn, " threw exception in WorkGiver ", workGiver.def.defName, ": ", ex.ToString())); } if (bestTargetOfLastPriority.IsValid) { // pawn.mindState.lastGivenWorkType = workGiver.def.workType; Job job3; if (bestTargetOfLastPriority.HasThing) { job3 = scannerWhoProvidedTarget.JobOnThing(pawn, bestTargetOfLastPriority.Thing); } else { job3 = scannerWhoProvidedTarget.JobOnCell(pawn, bestTargetOfLastPriority.Cell); } if (job3 != null) { job3.workGiverDef = scannerWhoProvidedTarget.def; return(new ThinkResult(job3, __instance, list[j].def.tagToGive)); } Log.ErrorOnce( string.Concat(scannerWhoProvidedTarget, " provided target ", bestTargetOfLastPriority, " but yielded no actual job for pawn ", pawn, ". The CanGiveJob and JobOnX methods may not be synchronized."), 6112651); } num = workGiver.def.priorityInType; } } return(ThinkResult.NoJob); }
public override ThinkResult TryIssueJobPackage(Pawn pawn, JobIssueParams jobParams) { var need = pawn.needs.TryGetNeed <Need_Motivation>(); if (pawn.timetable == null) { WorkSettings.InitWorkSettings(pawn); } if (HealthAIUtility.ShouldHaveSurgeryDoneNow(pawn)) { return(ThinkResult.NoJob); } if (PrisonLaborPrefs.EnableFullHealRest && (HealthAIUtility.ShouldBeTendedNowByPlayer(pawn) || HealthAIUtility.ShouldSeekMedicalRest(pawn))) { return(ThinkResult.NoJob); } //Check medical assistance, fed, and rest if not override if (!PrisonLaborUtility.WorkTime(pawn)) { Other.Tutorials.Timetable(); if (need != null) { need.IsPrisonerWorking = false; } return(ThinkResult.NoJob); } //Check motivation if (PrisonLaborPrefs.EnableMotivationMechanics && (need == null || need.IsLazy)) { return(ThinkResult.NoJob); } //Work prisoners will do WorkSettings.InitWorkSettings(pawn); var workList = pawn.workSettings.WorkGiversInOrderNormal; //TODO check this //workList.RemoveAll(workGiver => workGiver.def.defName == "GrowerSow"); if (need != null) { need.IsPrisonerWorking = false; } var num = -999; var targetInfo = TargetInfo.Invalid; WorkGiver_Scanner workGiver_Scanner = null; for (var j = 0; j < workList.Count; j++) { var workGiver = workList[j]; if (workGiver.def.priorityInType != num && targetInfo.IsValid) { break; } if (PawnCanUseWorkGiver(pawn, workGiver)) { try { var job2 = workGiver.NonScanJob(pawn); if (job2 != null) { if (need != null) { need.IsPrisonerWorking = true; } return(new ThinkResult(job2, this, workList[j].def.tagToGive)); } var scanner = workGiver as WorkGiver_Scanner; if (scanner != null) { if (workGiver.def.scanThings) { Predicate <Thing> predicate = t => !t.IsForbidden(pawn) && scanner.HasJobOnThing(pawn, t, false); var enumerable = scanner.PotentialWorkThingsGlobal(pawn); Thing thing; if (scanner.Prioritized) { var enumerable2 = enumerable; if (enumerable2 == null) { enumerable2 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest); } var validator = predicate; thing = GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map, enumerable2, scanner.PathEndMode, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), 9999f, validator, x => scanner.GetPriority(pawn, x)); } else { var validator = predicate; var forceGlobalSearch = enumerable != null; thing = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, scanner.PotentialWorkThingRequest, scanner.PathEndMode, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), 9999f, validator, enumerable, 0, scanner.MaxRegionsToScanBeforeGlobalSearch, forceGlobalSearch, RegionType.Set_Passable, false); } if (thing != null) { targetInfo = thing; workGiver_Scanner = scanner; } } if (workGiver.def.scanCells) { var position = pawn.Position; var num2 = 99999f; var num3 = -3.40282347E+38f; var prioritized = scanner.Prioritized; foreach (var current in scanner.PotentialWorkCellsGlobal(pawn)) { var flag = false; float num4 = (current - position).LengthHorizontalSquared; if (prioritized) { if (!current.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, current)) { var priority = scanner.GetPriority(pawn, current); if (priority > num3 || priority == num3 && num4 < num2) { flag = true; num3 = priority; } } } else if (num4 < num2 && !current.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, current)) { flag = true; } if (flag) { targetInfo = new TargetInfo(current, pawn.Map, false); workGiver_Scanner = scanner; num2 = num4; } } } } } catch (Exception ex) { Log.Error(string.Concat(pawn, " threw exception in WorkGiver ", workGiver.def.defName, ": ", ex.ToString())); } finally { } if (targetInfo.IsValid) { Job job3; if (targetInfo.HasThing) { job3 = workGiver_Scanner.JobOnThing(pawn, targetInfo.Thing, false); } else { job3 = workGiver_Scanner.JobOnCell(pawn, targetInfo.Cell); } if (job3 != null) { job3.workGiverDef = workGiver.def; if (need != null) { need.IsPrisonerWorking = true; } return(new ThinkResult(job3, this, workList[j].def.tagToGive)); } Log.ErrorOnce( string.Concat(workGiver_Scanner, " provided target ", targetInfo, " but yielded no actual job for pawn ", pawn, ". The CanGiveJob and JobOnX methods may not be synchronized."), 6112651); } num = workGiver.def.priorityInType; } } return(ThinkResult.NoJob); }
public override ThinkResult TryIssueJobPackage(Pawn pawn, JobIssueParams jobParams) { X2_AIRobot robot = pawn as X2_AIRobot; if (robot == null || !robot.Spawned || robot.Destroyed || robot.GetWorkGivers(false) == null) { return(ThinkResult.NoJob); } //Profiler.BeginSample("JobGiver_Work"); //if (this.emergency && pawn.mindState.priorityWork.IsPrioritized) //{ // List<WorkGiverDef> workGiversByPriority = pawn.mindState.priorityWork.WorkType.workGiversByPriority; // for (int i = 0; i < workGiversByPriority.Count; i++) // { // WorkGiver worker = workGiversByPriority[i].Worker; // Job job = this.GiverTryGiveJobPrioritized(pawn, worker, pawn.mindState.priorityWork.Cell); // if (job != null) // { // job.playerForced = true; // return new ThinkResult(job, this, new JobTag?(workGiversByPriority[i].tagToGive), false); // } // } // pawn.mindState.priorityWork.Clear(); //} List <WorkGiver> list = robot.GetWorkGivers(false); // Get Non-Emergency WorkGivers int num = -999; TargetInfo targetInfo = TargetInfo.Invalid; WorkGiver_Scanner workGiver_Scanner = null; WorkGiver_Scanner scanner; for (int j = 0; j < list.Count; j++) { WorkGiver workGiver = list[j]; if (workGiver.def.priorityInType != num && targetInfo.IsValid) { break; } if (PawnCanUseWorkGiver(pawn, workGiver)) { //Profiler.BeginSample("WorkGiver: " + workGiver.def.defName); try { Job job2 = workGiver.NonScanJob(pawn); if (job2 != null) { return(new ThinkResult(job2, this, list[j].def.tagToGive, false)); } scanner = (workGiver as WorkGiver_Scanner); if (scanner != null) { IntVec3 intVec; if (scanner.def.scanThings) { Predicate <Thing> predicate = (Thing t) => !t.IsForbidden(pawn) && scanner.HasJobOnThing(pawn, t, false); IEnumerable <Thing> enumerable = scanner.PotentialWorkThingsGlobal(pawn); Thing thing; if (scanner.Prioritized) { IEnumerable <Thing> enumerable2 = enumerable; if (enumerable2 == null) { enumerable2 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest); } if (scanner.AllowUnreachable) { intVec = pawn.Position; IEnumerable <Thing> searchSet = enumerable2; Predicate <Thing> validator = predicate; try { thing = GenClosest.ClosestThing_Global(intVec, searchSet, 99999f, validator, (Thing x) => scanner.GetPriority(pawn, x)); } catch //(Exception ex) { //Log.Warning(string.Concat(new object[] //{ // pawn, // " threw exception in WorkGiver ", // workGiver.def.defName, // ": ", // ex.ToString() //})); thing = null; } } else { intVec = pawn.Position; Map map = pawn.Map; IEnumerable <Thing> searchSet = enumerable2; PathEndMode pathEndMode = scanner.PathEndMode; TraverseParms traverseParams = TraverseParms.For(pawn, scanner.MaxPathDanger(pawn), TraverseMode.ByPawn, false); Predicate <Thing> validator = predicate; try { thing = GenClosest.ClosestThing_Global_Reachable(intVec, map, searchSet, pathEndMode, traverseParams, 9999f, validator, (Thing x) => scanner.GetPriority(pawn, x)); } catch //(Exception ex) { //Log.Warning(string.Concat(new object[] //{ // pawn, // " threw exception in WorkGiver ", // workGiver.def.defName, // ": ", // ex.ToString() //})); thing = null; } } } else if (scanner.AllowUnreachable) { IEnumerable <Thing> enumerable3 = enumerable; if (enumerable3 == null) { enumerable3 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest); } intVec = pawn.Position; IEnumerable <Thing> searchSet = enumerable3; Predicate <Thing> validator = predicate; try { thing = GenClosest.ClosestThing_Global(intVec, searchSet, 99999f, validator, null); } catch //(Exception ex) { //Log.Warning(string.Concat(new object[] //{ // pawn, // " threw exception in WorkGiver ", // workGiver.def.defName, // ": ", // ex.ToString() //})); thing = null; } } else { intVec = pawn.Position; Map map = pawn.Map; ThingRequest potentialWorkThingRequest = scanner.PotentialWorkThingRequest; PathEndMode pathEndMode = scanner.PathEndMode; TraverseParms traverseParams = TraverseParms.For(pawn, scanner.MaxPathDanger(pawn), TraverseMode.ByPawn, false); Predicate <Thing> validator = predicate; bool forceGlobalSearch = enumerable != null; try { thing = GenClosest.ClosestThingReachable(intVec, map, potentialWorkThingRequest, pathEndMode, traverseParams, 9999f, validator, enumerable, 0, scanner.MaxRegionsToScanBeforeGlobalSearch, forceGlobalSearch, RegionType.Set_Passable, false); } catch //(Exception ex) { //Log.Warning(string.Concat(new object[] //{ // pawn, // " threw exception in WorkGiver ", // workGiver.def.defName, // ": ", // ex.ToString() //})); thing = null; } } if (thing != null) { targetInfo = thing; workGiver_Scanner = scanner; } } if (scanner.def.scanCells) { IntVec3 position = pawn.Position; float num2 = 99999f; float num3 = -3.40282347E+38f; bool prioritized = scanner.Prioritized; bool allowUnreachable = scanner.AllowUnreachable; Danger maxDanger = scanner.MaxPathDanger(pawn); foreach (IntVec3 item in scanner.PotentialWorkCellsGlobal(pawn)) { bool flag = false; intVec = item - position; float num4 = (float)intVec.LengthHorizontalSquared; float num5 = 0f; if (prioritized) { if (!item.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, item, false)) { if (!allowUnreachable && !pawn.CanReach(item, scanner.PathEndMode, maxDanger, false, TraverseMode.ByPawn)) { continue; } num5 = scanner.GetPriority(pawn, item); if (num5 > num3 || (num5 == num3 && num4 < num2)) { flag = true; } } } else if (num4 < num2 && !item.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, item, false)) { if (!allowUnreachable && !pawn.CanReach(item, scanner.PathEndMode, maxDanger, false, TraverseMode.ByPawn)) { continue; } flag = true; } if (flag) { targetInfo = new TargetInfo(item, pawn.Map, false); workGiver_Scanner = scanner; num2 = num4; num3 = num5; } } } } } catch (Exception ex) { Log.Error(pawn + " threw exception in WorkGiver " + workGiver.def.defName + ": " + ex.ToString(), false); } finally { //Profiler.EndSample(); } if (targetInfo.IsValid) { //Profiler.EndSample(); Job job3 = null; try { //pawn.mindState.lastGivenWorkType = workGiver.def.workType; job3 = (!targetInfo.HasThing) ? workGiver_Scanner.JobOnCell(pawn, targetInfo.Cell, false) : workGiver_Scanner.JobOnThing(pawn, targetInfo.Thing, false); } catch //(Exception ex) { //Log.Warning(string.Concat(new object[] //{ // pawn, // " threw exception in WorkGiver ", // workGiver.def.defName, // " in JobOnX: ", // ex.ToString() //})); // Error --> Force NoJob return(ThinkResult.NoJob); } if (job3 != null) { return(new ThinkResult(job3, this, list[j].def.tagToGive, false)); } Log.ErrorOnce(workGiver_Scanner + " provided target " + targetInfo + " but yielded no actual job for pawn " + pawn + ". The CanGiveJob and JobOnX methods may not be synchronized.", 6112651, false); } num = workGiver.def.priorityInType; } } return(ThinkResult.NoJob); }
public override Job JobOnThing(Pawn pawn, Thing t, bool forced = false) { return(wrappedScanner?.JobOnThing(pawn, t, forced) ?? base.JobOnThing(pawn, t, forced)); }
protected override Job TryGiveJob(Pawn pawn) { if (workGiverDef != null) { int num = -999; TargetInfo targetInfo = TargetInfo.Invalid; WorkGiver_Scanner workGiver_Scanner = null; WorkGiver workGiver = workGiverDef.Worker; if (workGiver != null) { if (workGiver.def.priorityInType != num && targetInfo.IsValid) { return(null); } if (this.PawnCanUseWorkGiver(pawn, workGiver)) { try { Job job2 = workGiver.NonScanJob(pawn); if (job2 != null) { return(job2); } WorkGiver_Scanner scanner = workGiver as WorkGiver_Scanner; if (scanner != null) { if (workGiver.def.scanThings) { Predicate <Thing> predicate = (Thing t) => !t.IsForbidden(pawn) && scanner.HasJobOnThing(pawn, t); IEnumerable <Thing> enumerable = scanner.PotentialWorkThingsGlobal(pawn); Thing thing; if (scanner.Prioritized) { IEnumerable <Thing> enumerable2 = enumerable; if (enumerable2 == null) { enumerable2 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest); } Predicate <Thing> validator = predicate; thing = GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map, enumerable2, scanner.PathEndMode, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), 9999f, validator, (Thing x) => scanner.GetPriority(pawn, x)); } else { Predicate <Thing> validator = predicate; thing = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, scanner.PotentialWorkThingRequest, scanner.PathEndMode, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), 9999f, validator, enumerable, scanner.MaxRegionsToScanBeforeGlobalSearch); } if (thing != null) { targetInfo = thing; workGiver_Scanner = scanner; } } if (workGiver.def.scanCells) { IntVec3 position = pawn.Position; float num2 = 99999f; float num3 = -3.40282347E+38f; bool prioritized = scanner.Prioritized; foreach (IntVec3 current in scanner.PotentialWorkCellsGlobal(pawn)) { bool flag = false; float lengthHorizontalSquared = (current - position).LengthHorizontalSquared; if (prioritized) { if (!current.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, current)) { float priority = scanner.GetPriority(pawn, current); if (priority > num3 || (priority == num3 && lengthHorizontalSquared < num2)) { flag = true; num3 = priority; } } } else if (lengthHorizontalSquared < num2 && !current.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, current)) { flag = true; } if (flag) { targetInfo = new TargetInfo(current, pawn.Map, false); workGiver_Scanner = scanner; num2 = lengthHorizontalSquared; } } } } } catch (Exception ex) { Log.Error($"{pawn} threw exception in WorkGiver {workGiver.def.defName}: {ex.ToString()}"); } finally { } if (targetInfo.IsValid) { //pawn.mindState. = workGiver.def.workType; Job job3; if (targetInfo.HasThing) { job3 = workGiver_Scanner.JobOnThing(pawn, targetInfo.Thing); } else { job3 = workGiver_Scanner.JobOnCell(pawn, targetInfo.Cell); } if (job3 != null) { return(job3); } Log.ErrorOnce($"{workGiver_Scanner} provided target {targetInfo} but yielded no actual job for pawn {pawn}. The CanGiveJob and JobOnX methods may not be synchronized.", 6112651); } num = workGiver.def.priorityInType; } } } return(null); }
public override ThinkResult TryIssueJobPackage(Pawn pawn, JobIssueParams jobParams) { X2_AIRobot robot = pawn as X2_AIRobot; if (robot == null) { return(ThinkResult.NoJob); } //if (this.emergency && pawn.mindState.priorityWork.IsPrioritized) //{ // List<WorkGiverDef> workGiversByPriority = pawn.mindState.priorityWork.WorkType.workGiversByPriority; // for (int i = 0; i < workGiversByPriority.Count; i++) // { // WorkGiver worker = workGiversByPriority[i].Worker; // Job job = this.GiverTryGiveJobPrioritized(pawn, worker, pawn.mindState.priorityWork.Cell); // if (job != null) // { // job.playerForced = true; // return new ThinkResult(job, this, new JobTag?(workGiversByPriority[i].tagToGive), false); // } // } // pawn.mindState.priorityWork.Clear(); //} List <WorkGiver> list = robot.GetWorkGivers(false); // Get Non-Emergency WorkGivers int num = -999; TargetInfo targetInfo = TargetInfo.Invalid; WorkGiver_Scanner workGiver_Scanner = null; for (int j = 0; j < list.Count; j++) { WorkGiver workGiver = list[j]; if (workGiver.def.priorityInType != num && targetInfo.IsValid) { break; } if (this.PawnCanUseWorkGiver(pawn, workGiver)) { try { Job job2 = workGiver.NonScanJob(pawn); if (job2 != null) { return(new ThinkResult(job2, this, new JobTag?(list[j].def.tagToGive), false)); } WorkGiver_Scanner scanner = workGiver as WorkGiver_Scanner; if (scanner != null) { if (scanner.def.scanThings) { Predicate <Thing> predicate = (Thing t) => !t.IsForbidden(pawn) && scanner.HasJobOnThing(pawn, t, false); IEnumerable <Thing> enumerable = scanner.PotentialWorkThingsGlobal(pawn); Thing thing = null; if (scanner.Prioritized) { IEnumerable <Thing> enumerable2 = enumerable; if (enumerable2 == null) { enumerable2 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest); } if (scanner.AllowUnreachable) { IntVec3 position = pawn.Position; IEnumerable <Thing> searchSet = enumerable2; Predicate <Thing> validator = predicate; try { thing = GenClosest.ClosestThing_Global(position, searchSet, 99999f, validator, (Thing x) => scanner.GetPriority(pawn, x)); } catch //(Exception ex) { //Log.Warning(string.Concat(new object[] //{ // pawn, // " threw exception in WorkGiver ", // workGiver.def.defName, // ": ", // ex.ToString() //})); thing = null; } } else { IntVec3 position = pawn.Position; Map map = pawn.Map; IEnumerable <Thing> searchSet = enumerable2; PathEndMode pathEndMode = scanner.PathEndMode; TraverseParms traverseParams = TraverseParms.For(pawn, scanner.MaxPathDanger(pawn), TraverseMode.ByPawn, false); Predicate <Thing> validator = predicate; try { thing = GenClosest.ClosestThing_Global_Reachable(position, map, searchSet, pathEndMode, traverseParams, 9999f, validator, (Thing x) => scanner.GetPriority(pawn, x)); } catch //(Exception ex) { //Log.Warning(string.Concat(new object[] //{ // pawn, // " threw exception in WorkGiver ", // workGiver.def.defName, // ": ", // ex.ToString() //})); thing = null; } } } if (!scanner.Prioritized && scanner.AllowUnreachable) { IEnumerable <Thing> enumerable3 = enumerable; if (enumerable3 == null) { enumerable3 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest); } IntVec3 position = pawn.Position; IEnumerable <Thing> searchSet = enumerable3; Predicate <Thing> validator = predicate; try { thing = GenClosest.ClosestThing_Global(position, searchSet, 99999f, validator, null); } catch //(Exception ex) { //Log.Warning(string.Concat(new object[] //{ // pawn, // " threw exception in WorkGiver ", // workGiver.def.defName, // ": ", // ex.ToString() //})); thing = null; } } if (!scanner.AllowUnreachable || thing == null) { IntVec3 position = pawn.Position; Map map = pawn.Map; ThingRequest potentialWorkThingRequest = scanner.PotentialWorkThingRequest; PathEndMode pathEndMode = scanner.PathEndMode; TraverseParms traverseParams = TraverseParms.For(pawn, scanner.MaxPathDanger(pawn), TraverseMode.ByPawn, false); Predicate <Thing> validator = predicate; bool forceGlobalSearch = enumerable != null; try { thing = GenClosest.ClosestThingReachable(position, map, potentialWorkThingRequest, pathEndMode, traverseParams, 9999f, validator, enumerable, 0, scanner.LocalRegionsToScanFirst, forceGlobalSearch, RegionType.Set_Passable, false); } // Added try-catch for a try of error handling catch //(Exception ex) { Log.Warning(string.Concat(new object[] { pawn, " threw exception in X2_JobGiver_Work ", workGiver.def.defName, " but we'll try again.. " //ex.ToString() })); if (enumerable != null) { try { thing = GenClosest.ClosestThing_Global(position, enumerable, 40f, validator, null); } catch { thing = null; } } else { thing = null; } } } if (thing != null) { targetInfo = thing; workGiver_Scanner = scanner; } } if (scanner.def.scanCells) { IntVec3 position2 = pawn.Position; float num2 = 99999f; float num3 = -3.40282347E+38f; bool prioritized = scanner.Prioritized; bool allowUnreachable = scanner.AllowUnreachable; Danger maxDanger = scanner.MaxPathDanger(pawn); foreach (IntVec3 current in scanner.PotentialWorkCellsGlobal(pawn)) { bool flag = false; float num4 = (float)(current - position2).LengthHorizontalSquared; float num5 = 0f; if (prioritized) { if (scanner.HasJobOnCell(pawn, current)) { if (!allowUnreachable && !pawn.CanReach(current, scanner.PathEndMode, maxDanger, false, TraverseMode.ByPawn)) { continue; } num5 = scanner.GetPriority(pawn, current); if (num5 > num3 || (num5 == num3 && num4 < num2)) { flag = true; } } } else if (num4 < num2 && scanner.HasJobOnCell(pawn, current)) { if (!allowUnreachable && !pawn.CanReach(current, scanner.PathEndMode, maxDanger, false, TraverseMode.ByPawn)) { continue; } flag = true; } if (flag) { targetInfo = new TargetInfo(current, pawn.Map, false); workGiver_Scanner = scanner; num2 = num4; num3 = num5; } } } } } catch (Exception ex) { Log.Error(string.Concat(new object[] { pawn, " threw exception in WorkGiver ", workGiver.def.defName, ": ", ex.ToString() })); } finally { } if (targetInfo.IsValid) { pawn.mindState.lastGivenWorkType = workGiver.def.workType; Job job3; if (targetInfo.HasThing) { job3 = workGiver_Scanner.JobOnThing(pawn, targetInfo.Thing, false); } else { job3 = workGiver_Scanner.JobOnCell(pawn, targetInfo.Cell); } if (job3 != null) { return(new ThinkResult(job3, this, new JobTag?(list[j].def.tagToGive), false)); } Log.ErrorOnce(string.Concat(new object[] { workGiver_Scanner, " provided target ", targetInfo, " but yielded no actual job for pawn ", pawn, ". The CanGiveJob and JobOnX methods may not be synchronized." }), 6112651); } num = workGiver.def.priorityInType; } } return(ThinkResult.NoJob); }
public static bool TryIssueJobPackage(JobGiver_Work __instance, ref ThinkResult __result, Pawn pawn, JobIssueParams jobParams) { if (__instance.emergency && pawn.mindState.priorityWork.IsPrioritized) { List <WorkGiverDef> workGiversByPriority = pawn.mindState.priorityWork.WorkGiver.workType.workGiversByPriority; for (int i = 0; i < workGiversByPriority.Count; i++) { WorkGiver worker = workGiversByPriority[i].Worker; if (WorkGiversRelated(pawn.mindState.priorityWork.WorkGiver, worker.def)) { Job job = GiverTryGiveJobPrioritized(pawn, worker, pawn.mindState.priorityWork.Cell); if (job != null) { job.playerForced = true; __result = new ThinkResult(job, __instance, workGiversByPriority[i].tagToGive); return(false); } } } pawn.mindState.priorityWork.Clear(); } List <WorkGiver> list = (!__instance.emergency) ? pawn.workSettings.WorkGiversInOrderNormal : pawn.workSettings.WorkGiversInOrderEmergency; int num = -999; TargetInfo bestTargetOfLastPriority = TargetInfo.Invalid; WorkGiver_Scanner scannerWhoProvidedTarget = null; //WorkGiver_Scanner scanner; IntVec3 pawnPosition; float closestDistSquared; float bestPriority; bool prioritized; bool allowUnreachable; Danger maxPathDanger; for (int j = 0; j < list.Count; j++) { WorkGiver workGiver = list[j]; if (workGiver.def.priorityInType != num && bestTargetOfLastPriority.IsValid) { break; } if (!PawnCanUseWorkGiver(pawn, workGiver)) { continue; } try { Job job2 = workGiver.NonScanJob(pawn); if (job2 != null) { __result = new ThinkResult(job2, __instance, workGiver.def.tagToGive); return(false); } scanner = (workGiver as WorkGiver_Scanner); if (scanner != null) { if (scanner.def.scanThings) { Predicate <Thing> validator = (Thing t) => !t.IsForbidden(pawn) && scanner.HasJobOnThing(pawn, t); //WorkGiver_CleanFilth_Patch.HasJobOnThing IEnumerable <Thing> enumerable = scanner.PotentialWorkThingsGlobal(pawn); Thing thing; if (scanner.Prioritized) { IEnumerable <Thing> enumerable2 = enumerable; if (enumerable2 == null) { enumerable2 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest); } thing = ((!scanner.AllowUnreachable) ? GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map, enumerable2, scanner.PathEndMode, TraverseParms.For(pawn, scanner.MaxPathDanger(pawn)), 9999f, validator, (Thing x) => scanner.GetPriority(pawn, x)) : GenClosest.ClosestThing_Global(pawn.Position, enumerable2, 99999f, validator, (Thing x) => scanner.GetPriority(pawn, x))); } else if (scanner.AllowUnreachable) { IEnumerable <Thing> enumerable3 = enumerable; if (enumerable3 == null) { enumerable3 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest); } thing = GenClosest.ClosestThing_Global(pawn.Position, enumerable3, 99999f, validator); } else { //TODO: use better ThingRequest groups if ( workGiver.def.defName.Equals("DoctorFeedAnimals") || workGiver.def.defName.Equals("DoctorFeedHumanlikes") || workGiver.def.defName.Equals("DoctorTendToAnimals") || workGiver.def.defName.Equals("DoctorTendToHumanlikes") || workGiver.def.defName.Equals("DoBillsUseCraftingSpot") || workGiver.def.defName.Equals("DoctorTendEmergency") || workGiver.def.defName.Equals("HaulCorpses") || workGiver.def.defName.Equals("FillFermentingBarrel") || //workGiver.def.defName.Equals("HaulGeneral") || workGiver.def.defName.Equals("HandlingFeedPatientAnimals") || workGiver.def.defName.Equals("DoBillsButcherFlesh") || workGiver.def.defName.Equals("DoBillsCook") || workGiver.def.defName.Equals("DoBillsMakeApparel") || workGiver.def.defName.Equals("Train") || workGiver.def.defName.Equals("VisitSickPawn") ) { //ClosestThingReachable2 checks validator before CanReach DateTime startTime = DateTime.Now; //long thing = GenClosest_Patch.ClosestThingReachable2(pawn.Position, pawn.Map, scanner.PotentialWorkThingRequest, scanner.PathEndMode, TraverseParms.For(pawn, scanner.MaxPathDanger(pawn)), 9999f, validator, enumerable, 0, scanner.MaxRegionsToScanBeforeGlobalSearch, enumerable != null); if (DateTime.Now.Subtract(startTime).TotalMilliseconds > 200 && RimThreadedSettings.show200mswarning) { Log.Warning("ClosestThingReachable2 Took " + DateTime.Now.Subtract(startTime).TotalMilliseconds + "ms for workGiver: " + workGiver.def.defName); } } else { DateTime startTime = DateTime.Now; thing = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, scanner.PotentialWorkThingRequest, scanner.PathEndMode, TraverseParms.For(pawn, scanner.MaxPathDanger(pawn)), 9999f, validator, enumerable, 0, scanner.MaxRegionsToScanBeforeGlobalSearch, enumerable != null); if (DateTime.Now.Subtract(startTime).TotalMilliseconds > 200 && RimThreadedSettings.show200mswarning) { Log.Warning("ClosestThingReachable Took " + DateTime.Now.Subtract(startTime).TotalMilliseconds + "ms for workGiver: " + workGiver.def.defName); } } } if (thing != null) { bestTargetOfLastPriority = thing; scannerWhoProvidedTarget = scanner; } } if (scanner.def.scanCells) { pawnPosition = pawn.Position; closestDistSquared = 99999f; bestPriority = float.MinValue; prioritized = scanner.Prioritized; allowUnreachable = scanner.AllowUnreachable; maxPathDanger = scanner.MaxPathDanger(pawn); IEnumerable <IntVec3> enumerable4; if (scanner is WorkGiver_Grower workGiver_Grower) { RimThreaded.WorkGiver_GrowerSow_Patch_JobOnCell = 0; enumerable4 = WorkGiver_Grower_Patch.PotentialWorkCellsGlobalWithoutCanReach(workGiver_Grower, pawn); List <IntVec3> SortedList = enumerable4.OrderBy(o => (o - pawnPosition).LengthHorizontalSquared).ToList(); foreach (IntVec3 item in SortedList) { ProcessCell(item); //long } //Log.Message(RimThreaded.WorkGiver_GrowerSow_Patch_JobOnCell.ToString()); } else { enumerable4 = scanner.PotentialWorkCellsGlobal(pawn); IList <IntVec3> list2; if ((list2 = (enumerable4 as IList <IntVec3>)) != null) { for (int k = 0; k < list2.Count; k++) { ProcessCell(list2[k]); } } else { foreach (IntVec3 item in enumerable4) { ProcessCell(item); } } } } } void ProcessCell(IntVec3 c) { float newDistanceSquared = (c - pawnPosition).LengthHorizontalSquared; float newPriority = 0f; if (prioritized) { newPriority = scanner.GetPriority(pawn, c); if (newPriority < bestPriority) { return; } } if (newDistanceSquared < closestDistSquared && !c.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, c)) { if (!allowUnreachable && !pawn.CanReach(c, scanner.PathEndMode, maxPathDanger)) { return; } bestTargetOfLastPriority = new TargetInfo(c, pawn.Map); scannerWhoProvidedTarget = scanner; closestDistSquared = newDistanceSquared; bestPriority = newPriority; } } } catch (Exception ex) { Log.Error(string.Concat(pawn, " threw exception in WorkGiver ", workGiver.def.defName, ": ", ex.ToString())); } finally { } if (bestTargetOfLastPriority.IsValid) { Job job3 = (!bestTargetOfLastPriority.HasThing) ? scannerWhoProvidedTarget.JobOnCell(pawn, bestTargetOfLastPriority.Cell) : scannerWhoProvidedTarget.JobOnThing(pawn, bestTargetOfLastPriority.Thing); if (job3 != null) { job3.workGiverDef = scannerWhoProvidedTarget.def; __result = new ThinkResult(job3, __instance, list[j].def.tagToGive); return(false); } //HACK - I know. I'm awful. //Log.ErrorOnce(string.Concat(scannerWhoProvidedTarget, " provided target ", bestTargetOfLastPriority, " but yielded no actual job for pawn ", pawn, ". The CanGiveJob and JobOnX methods may not be synchronized."), 6112651); Log.Warning(string.Concat(scannerWhoProvidedTarget, " provided target ", bestTargetOfLastPriority, " but yielded no actual job for pawn ", pawn, ". The CanGiveJob and JobOnX methods may not be synchronized.")); } num = workGiver.def.priorityInType; } __result = ThinkResult.NoJob; return(false); }
public override ThinkResult TryIssueJobPackage(Pawn pawn, JobIssueParams jobParams) { Droid d = null; if (pawn is Droid) { d = pawn as Droid; } else { return(ThinkResult.NoJob); } List <WorkGiver> list = emergency ? d.workManager.WorkGiversInOrderEmergency : d.workManager.WorkGiversInOrder; int num = -999; TargetInfo targetInfo = TargetInfo.Invalid; WorkGiver_Scanner workGiver_Scanner = null; WorkGiver_Scanner scanner; for (int j = 0; j < list.Count; j++) { WorkGiver workGiver = list[j]; if (workGiver.def.priorityInType != num && targetInfo.IsValid) { break; } if (PawnCanUseWorkGiver(pawn, workGiver)) { try { Job job2 = workGiver.NonScanJob(pawn); if (job2 != null) { return(new ThinkResult(job2, this, list[j].def.tagToGive, false)); } scanner = (workGiver as WorkGiver_Scanner); if (scanner != null) { IntVec3 intVec; if (scanner.def.scanThings) { Predicate <Thing> predicate = (Thing t) => !t.IsForbidden(pawn) && scanner.HasJobOnThing(pawn, t, false); IEnumerable <Thing> enumerable = scanner.PotentialWorkThingsGlobal(pawn); Thing thing; if (scanner.Prioritized) { IEnumerable <Thing> enumerable2 = enumerable; if (enumerable2 == null) { enumerable2 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest); } if (scanner.AllowUnreachable) { intVec = pawn.Position; IEnumerable <Thing> searchSet = enumerable2; Predicate <Thing> validator = predicate; thing = GenClosest.ClosestThing_Global(intVec, searchSet, 99999f, validator, (Thing x) => scanner.GetPriority(pawn, x)); } else { intVec = pawn.Position; Map map = pawn.Map; IEnumerable <Thing> searchSet = enumerable2; PathEndMode pathEndMode = scanner.PathEndMode; TraverseParms traverseParams = TraverseParms.For(pawn, scanner.MaxPathDanger(pawn), TraverseMode.ByPawn, false); Predicate <Thing> validator = predicate; thing = GenClosest.ClosestThing_Global_Reachable(intVec, map, searchSet, pathEndMode, traverseParams, 9999f, validator, (Thing x) => scanner.GetPriority(pawn, x)); } } else if (scanner.AllowUnreachable) { IEnumerable <Thing> enumerable3 = enumerable; if (enumerable3 == null) { enumerable3 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest); } intVec = pawn.Position; IEnumerable <Thing> searchSet = enumerable3; Predicate <Thing> validator = predicate; thing = GenClosest.ClosestThing_Global(intVec, searchSet, 99999f, validator, null); } else { intVec = pawn.Position; Map map = pawn.Map; ThingRequest potentialWorkThingRequest = scanner.PotentialWorkThingRequest; PathEndMode pathEndMode = scanner.PathEndMode; TraverseParms traverseParams = TraverseParms.For(pawn, scanner.MaxPathDanger(pawn), TraverseMode.ByPawn, false); Predicate <Thing> validator = predicate; bool forceGlobalSearch = enumerable != null; thing = GenClosest.ClosestThingReachable(intVec, map, potentialWorkThingRequest, pathEndMode, traverseParams, 9999f, validator, enumerable, 0, scanner.LocalRegionsToScanFirst, forceGlobalSearch, RegionType.Set_Passable, false); } if (thing != null) { targetInfo = thing; workGiver_Scanner = scanner; } } if (scanner.def.scanCells) { IntVec3 position = pawn.Position; float num2 = 99999f; float num3 = -3.40282347E+38f; bool prioritized = scanner.Prioritized; bool allowUnreachable = scanner.AllowUnreachable; Danger maxDanger = scanner.MaxPathDanger(pawn); foreach (IntVec3 item in scanner.PotentialWorkCellsGlobal(pawn)) { bool flag = false; intVec = item - position; float num4 = (float)intVec.LengthHorizontalSquared; float num5 = 0f; if (prioritized) { if (scanner.HasJobOnCell(pawn, item)) { if (!allowUnreachable && !pawn.CanReach(item, scanner.PathEndMode, maxDanger, false, TraverseMode.ByPawn)) { continue; } num5 = scanner.GetPriority(pawn, item); if (num5 > num3 || (num5 == num3 && num4 < num2)) { flag = true; } } } else if (num4 < num2 && scanner.HasJobOnCell(pawn, item)) { if (!allowUnreachable && !pawn.CanReach(item, scanner.PathEndMode, maxDanger, false, TraverseMode.ByPawn)) { continue; } flag = true; } if (flag) { targetInfo = new TargetInfo(item, pawn.Map, false); workGiver_Scanner = scanner; num2 = num4; num3 = num5; } } } } } catch (Exception ex) { Log.Error(pawn + " threw exception in WorkGiver " + workGiver.def.defName + ": " + ex.ToString()); } finally { } if (targetInfo.IsValid) { pawn.mindState.lastGivenWorkType = workGiver.def.workType; Job job3 = (!targetInfo.HasThing) ? workGiver_Scanner.JobOnCell(pawn, targetInfo.Cell) : workGiver_Scanner.JobOnThing(pawn, targetInfo.Thing, false); if (job3 != null) { return(new ThinkResult(job3, this, list[j].def.tagToGive, false)); } Log.ErrorOnce(workGiver_Scanner + " provided target " + targetInfo + " but yielded no actual job for pawn " + pawn + ". The CanGiveJob and JobOnX methods may not be synchronized.", 6112651); } num = workGiver.def.priorityInType; } } return(ThinkResult.NoJob); }
public static bool TryIssueJobPackage(JobGiver_Work __instance, ref ThinkResult __result, Pawn pawn, JobIssueParams jobParams) { if (__instance.emergency && pawn.mindState.priorityWork.IsPrioritized) { List <WorkGiverDef> workGiversByPriority = pawn.mindState.priorityWork.WorkGiver.workType.workGiversByPriority; for (int i = 0; i < workGiversByPriority.Count; i++) { WorkGiver worker = workGiversByPriority[i].Worker; if (WorkGiversRelated(pawn.mindState.priorityWork.WorkGiver, worker.def)) { Job job = GiverTryGiveJobPrioritized(pawn, worker, pawn.mindState.priorityWork.Cell); if (job != null) { job.playerForced = true; __result = new ThinkResult(job, __instance, workGiversByPriority[i].tagToGive); return(false); } } } pawn.mindState.priorityWork.Clear(); } List <WorkGiver> list = (!__instance.emergency) ? pawn.workSettings.WorkGiversInOrderNormal : pawn.workSettings.WorkGiversInOrderEmergency; int num = -999; TargetInfo bestTargetOfLastPriority = TargetInfo.Invalid; WorkGiver_Scanner scannerWhoProvidedTarget = null; WorkGiver_Scanner scanner; IntVec3 pawnPosition; float closestDistSquared; float bestPriority; bool prioritized; bool allowUnreachable; Danger maxPathDanger; for (int j = 0; j < list.Count; j++) { WorkGiver workGiver = list[j]; if (workGiver.def.priorityInType != num && bestTargetOfLastPriority.IsValid) { break; } if (!PawnCanUseWorkGiver(pawn, workGiver)) { continue; } try { Job job2 = workGiver.NonScanJob(pawn); if (job2 != null) { __result = new ThinkResult(job2, __instance, list[j].def.tagToGive); return(false); } scanner = (workGiver as WorkGiver_Scanner); if (scanner != null) { if (scanner.def.scanThings) { Predicate <Thing> validator = (Thing t) => !t.IsForbidden(pawn) && scanner.HasJobOnThing(pawn, t); IEnumerable <Thing> enumerable = scanner.PotentialWorkThingsGlobal(pawn); Thing thing; if (scanner.Prioritized) { IEnumerable <Thing> enumerable2 = enumerable; if (enumerable2 == null) { enumerable2 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest); } thing = ((!scanner.AllowUnreachable) ? GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map, enumerable2, scanner.PathEndMode, TraverseParms.For(pawn, scanner.MaxPathDanger(pawn)), 9999f, validator, (Thing x) => scanner.GetPriority(pawn, x)) : GenClosest.ClosestThing_Global(pawn.Position, enumerable2, 99999f, validator, (Thing x) => scanner.GetPriority(pawn, x))); } else if (scanner.AllowUnreachable) { IEnumerable <Thing> enumerable3 = enumerable; if (enumerable3 == null) { enumerable3 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest); } thing = GenClosest.ClosestThing_Global(pawn.Position, enumerable3, 99999f, validator); } else { thing = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, scanner.PotentialWorkThingRequest, scanner.PathEndMode, TraverseParms.For(pawn, scanner.MaxPathDanger(pawn)), 9999f, validator, enumerable, 0, scanner.MaxRegionsToScanBeforeGlobalSearch, enumerable != null); } if (thing != null) { bestTargetOfLastPriority = thing; scannerWhoProvidedTarget = scanner; } } if (scanner.def.scanCells) { pawnPosition = pawn.Position; closestDistSquared = 99999f; bestPriority = float.MinValue; prioritized = scanner.Prioritized; allowUnreachable = scanner.AllowUnreachable; maxPathDanger = scanner.MaxPathDanger(pawn); IEnumerable <IntVec3> enumerable4 = scanner.PotentialWorkCellsGlobal(pawn); IList <IntVec3> list2; if ((list2 = (enumerable4 as IList <IntVec3>)) != null) { for (int k = 0; k < list2.Count; k++) { ProcessCell(list2[k]); } } else { foreach (IntVec3 item in enumerable4) { ProcessCell(item); } } } } void ProcessCell(IntVec3 c) { bool flag = false; float num2 = (c - pawnPosition).LengthHorizontalSquared; float num3 = 0f; if (prioritized) { if (!c.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, c)) { if (!allowUnreachable && !pawn.CanReach(c, scanner.PathEndMode, maxPathDanger)) { return; } num3 = scanner.GetPriority(pawn, c); if (num3 > bestPriority || (num3 == bestPriority && num2 < closestDistSquared)) { flag = true; } } } else if (num2 < closestDistSquared && !c.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, c)) { if (!allowUnreachable && !pawn.CanReach(c, scanner.PathEndMode, maxPathDanger)) { return; } flag = true; } if (flag) { bestTargetOfLastPriority = new TargetInfo(c, pawn.Map); scannerWhoProvidedTarget = scanner; closestDistSquared = num2; bestPriority = num3; } } } catch (Exception ex) { Log.Error(string.Concat(pawn, " threw exception in WorkGiver ", workGiver.def.defName, ": ", ex.ToString())); } finally { } if (bestTargetOfLastPriority.IsValid) { Job job3 = (!bestTargetOfLastPriority.HasThing) ? scannerWhoProvidedTarget.JobOnCell(pawn, bestTargetOfLastPriority.Cell) : scannerWhoProvidedTarget.JobOnThing(pawn, bestTargetOfLastPriority.Thing); if (job3 != null) { job3.workGiverDef = scannerWhoProvidedTarget.def; __result = new ThinkResult(job3, __instance, list[j].def.tagToGive); return(false); } //HACK - I know. I'm awful. //Log.ErrorOnce(string.Concat(scannerWhoProvidedTarget, " provided target ", bestTargetOfLastPriority, " but yielded no actual job for pawn ", pawn, ". The CanGiveJob and JobOnX methods may not be synchronized."), 6112651); Log.Warning(string.Concat(scannerWhoProvidedTarget, " provided target ", bestTargetOfLastPriority, " but yielded no actual job for pawn ", pawn, ". The CanGiveJob and JobOnX methods may not be synchronized.")); } num = workGiver.def.priorityInType; } __result = ThinkResult.NoJob; return(false); }
public void AddJobTarget(SavedTargetInfo target, bool firstTarget = false) { if (jobTargets.Contains(target)) { return; } if (target.HasThing && savedJob.bill != null) { MeeseeksBillStorage billStorage = Current.Game.World.GetComponent <MeeseeksBillStorage>(); if (firstTarget) { billStorage.SaveBill(savedJob.bill); savedJob.bill = billStorage.GetDuplicateBillFromOriginal(savedJob.bill); savedJob.bill.billStack.billGiver = target.Thing as IBillGiver; } WorkGiver_Scanner workGiverScanner = savedJob.workGiverDef.Worker as WorkGiver_Scanner; if (workGiverScanner != null) { Job job = workGiverScanner.JobOnThing(Meeseeks, target.Thing, true); if (job != null && job.bill != null) { billStorage.SaveBill(job.bill); target.bill = billStorage.GetDuplicateBillFromOriginal(job.bill); target.bill.billStack.billGiver = target.Thing as IBillGiver; } } } else if (target.HasThing && savedJob.IsConstruction) { ThingDef thingDefToBuild = null; TerrainDef terrainDefToBuild = null; ThingDef stuffDefToUse = null; Blueprint_Build blueprint = target.Thing as Blueprint_Build; Frame frame = target.Thing as Frame; if (blueprint != null) { thingDefToBuild = blueprint.def.entityDefToBuild as ThingDef; terrainDefToBuild = blueprint.def.entityDefToBuild as TerrainDef; stuffDefToUse = blueprint.stuffToUse; } else if (frame != null) { thingDefToBuild = frame.def.entityDefToBuild as ThingDef; terrainDefToBuild = frame.def.entityDefToBuild as TerrainDef; stuffDefToUse = frame.Stuff; } if (thingDefToBuild != null) { target.blueprintThingDef = thingDefToBuild; } else if (terrainDefToBuild != null) { target.blueprintTerrainDef = terrainDefToBuild; } target.blueprintStuff = stuffDefToUse; target.blueprintRotation = target.Thing.Rotation; // Redirect job to the cell so that we can continue various construction phases and replace blueprint if needed target.target = target.Cell; } else if (target.HasThing && savedJob.IsTraining) { target.trainable = (target.Thing as Pawn).training.NextTrainableToTrain(); } jobTargets.Add(target); }
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 override Job JobOnThing(Pawn pawn, Thing t, bool forced = false) => wrappedGiver.JobOnThing(pawn, t, 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); }
public override ThinkResult TryIssueJobPackage(Pawn pawn, JobIssueParams jobParams) { int num = -999; TargetInfo targetInfo = TargetInfo.Invalid; WorkGiver_Scanner workGiver_Scanner = null; WorkGiver workGiver = DefDatabase <WorkGiverDef> .GetNamed("Mine", true).Worker; if (workGiver.def.priorityInType != num && targetInfo.IsValid) { // break; } else { if (this.PawnCanUseWorkGiver(pawn, workGiver)) { try { Job job2 = workGiver.NonScanJob(pawn); if (job2 != null) { return(new ThinkResult(job2, this, new JobTag?(workGiver.def.tagToGive), false)); } WorkGiver_Scanner scanner = workGiver as WorkGiver_Scanner; if (scanner != null) { if (scanner.def.scanThings) { Predicate <Thing> predicate = (Thing t) => !t.IsForbidden(pawn) && scanner.HasJobOnThing(pawn, t, false); IEnumerable <Thing> enumerable = scanner.PotentialWorkThingsGlobal(pawn); Thing thing; if (scanner.Prioritized) { IEnumerable <Thing> enumerable2 = enumerable; if (enumerable2 == null) { enumerable2 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest); } if (scanner.AllowUnreachable) { IntVec3 position = pawn.Position; IEnumerable <Thing> searchSet = enumerable2; Predicate <Thing> validator = predicate; thing = GenClosest.ClosestThing_Global(position, searchSet, 99999f, validator, (Thing x) => scanner.GetPriority(pawn, x)); } else { IntVec3 position = pawn.Position; Map map = pawn.Map; IEnumerable <Thing> searchSet = enumerable2; PathEndMode pathEndMode = scanner.PathEndMode; TraverseParms traverseParams = TraverseParms.For(pawn, scanner.MaxPathDanger(pawn), TraverseMode.ByPawn, false); Predicate <Thing> validator = predicate; thing = GenClosest.ClosestThing_Global_Reachable(position, map, searchSet, pathEndMode, traverseParams, 9999f, validator, (Thing x) => scanner.GetPriority(pawn, x)); } } else if (scanner.AllowUnreachable) { IEnumerable <Thing> enumerable3 = enumerable; if (enumerable3 == null) { enumerable3 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest); } IntVec3 position = pawn.Position; IEnumerable <Thing> searchSet = enumerable3; Predicate <Thing> validator = predicate; thing = GenClosest.ClosestThing_Global(position, searchSet, 99999f, validator, null); } else { IntVec3 position = pawn.Position; Map map = pawn.Map; ThingRequest potentialWorkThingRequest = scanner.PotentialWorkThingRequest; PathEndMode pathEndMode = scanner.PathEndMode; TraverseParms traverseParams = TraverseParms.For(pawn, scanner.MaxPathDanger(pawn), TraverseMode.ByPawn, false); Predicate <Thing> validator = predicate; bool forceGlobalSearch = enumerable != null; thing = GenClosest.ClosestThingReachable(position, map, potentialWorkThingRequest, pathEndMode, traverseParams, 9999f, validator, enumerable, 0, scanner.MaxRegionsToScanBeforeGlobalSearch, forceGlobalSearch, RegionType.Set_Passable, false); } if (thing != null) { targetInfo = thing; workGiver_Scanner = scanner; } } if (scanner.def.scanCells) { IntVec3 position2 = pawn.Position; float num2 = 99999f; float num3 = -3.40282347E+38f; bool prioritized = scanner.Prioritized; bool allowUnreachable = scanner.AllowUnreachable; Danger maxDanger = scanner.MaxPathDanger(pawn); foreach (IntVec3 current in scanner.PotentialWorkCellsGlobal(pawn)) { bool flag = false; float num4 = (float)(current - position2).LengthHorizontalSquared; float num5 = 0f; if (prioritized) { if (!current.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, current, false)) { if (!allowUnreachable && !pawn.CanReach(current, scanner.PathEndMode, maxDanger, false, false, TraverseMode.ByPawn)) { continue; } num5 = scanner.GetPriority(pawn, current); if (num5 > num3 || (num5 == num3 && num4 < num2)) { flag = true; } } } else if (num4 < num2 && !current.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, current, false)) { if (!allowUnreachable && !pawn.CanReach(current, scanner.PathEndMode, maxDanger, false, false, TraverseMode.ByPawn)) { continue; } flag = true; } if (flag) { targetInfo = new TargetInfo(current, pawn.Map, false); workGiver_Scanner = scanner; num2 = num4; num3 = num5; } } } } } catch (Exception ex) { Log.Error(string.Concat(new object[] { pawn, " threw exception in WorkGiver ", workGiver.def.defName, ": ", ex.ToString() })); } finally { } if (targetInfo.IsValid) { Job job3; if (targetInfo.HasThing) { job3 = workGiver_Scanner.JobOnThing(pawn, targetInfo.Thing, false); } else { job3 = workGiver_Scanner.JobOnCell(pawn, targetInfo.Cell, false); } if (job3 != null) { return(new ThinkResult(job3, this, new JobTag?(workGiver.def.tagToGive), false)); } Log.ErrorOnce(string.Concat(new object[] { workGiver_Scanner, " provided target ", targetInfo, " but yielded no actual job for pawn ", pawn, ". The CanGiveJob and JobOnX methods may not be synchronized." }), 6112651); } num = workGiver.def.priorityInType; } } return(ThinkResult.NoJob); }
public static void GetJobFor(Pawn pawn, List <WorkGiverDef> workGiverDefs) { if (pawn.Dead || !pawn.Spawned) { return; } List <WorkGiver> list = AllowedWorkGiversFor(pawn, workGiverDefs).Select(x => x.Worker).ToList(); int num = -999; TargetInfo bestTargetOfLastPriority = TargetInfo.Invalid; WorkGiver_Scanner scannerWhoProvidedTarget = null; WorkGiver_Scanner scanner; IntVec3 pawnPosition; float closestDistSquared; float bestPriority; bool prioritized; bool allowUnreachable; Danger maxPathDanger; for (int j = 0; j < list.Count; j++) { WorkGiver workGiver = list[j]; if (workGiver.def.priorityInType != num && bestTargetOfLastPriority.IsValid) { break; } if (!PawnCanUseWorkGiver(pawn, workGiver)) { continue; } try { Job job2 = workGiver.NonScanJob(pawn); if (job2 != null) { GiveJob(pawn, job2, workGiver); return; } scanner = (workGiver as WorkGiver_Scanner); if (scanner != null) { if (scanner.def.scanThings) { Predicate <Thing> validator = (Thing t) => !t.IsForbidden(pawn) && scanner.HasJobOnThing(pawn, t); IEnumerable <Thing> enumerable = scanner.PotentialWorkThingsGlobal(pawn); Thing thing; if (scanner.Prioritized) { IEnumerable <Thing> enumerable2 = enumerable; if (enumerable2 == null) { enumerable2 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest); } thing = ((!scanner.AllowUnreachable) ? GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map, enumerable2, scanner.PathEndMode, TraverseParms.For(pawn, scanner.MaxPathDanger(pawn)), 9999f, validator, (Thing x) => scanner.GetPriority(pawn, x)) : GenClosest.ClosestThing_Global(pawn.Position, enumerable2, 99999f, validator, (Thing x) => scanner.GetPriority(pawn, x))); } else if (scanner.AllowUnreachable) { IEnumerable <Thing> enumerable3 = enumerable; if (enumerable3 == null) { enumerable3 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest); } thing = GenClosest.ClosestThing_Global(pawn.Position, enumerable3, 99999f, validator); } else { thing = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, scanner.PotentialWorkThingRequest, scanner.PathEndMode, TraverseParms.For(pawn, scanner.MaxPathDanger(pawn)), 9999f, validator, enumerable, 0, scanner.MaxRegionsToScanBeforeGlobalSearch, enumerable != null); } if (thing != null) { bestTargetOfLastPriority = thing; scannerWhoProvidedTarget = scanner; } } if (scanner.def.scanCells) { pawnPosition = pawn.Position; closestDistSquared = 99999f; bestPriority = float.MinValue; prioritized = scanner.Prioritized; allowUnreachable = scanner.AllowUnreachable; maxPathDanger = scanner.MaxPathDanger(pawn); IEnumerable <IntVec3> enumerable4 = scanner.PotentialWorkCellsGlobal(pawn); IList <IntVec3> list2; if ((list2 = (enumerable4 as IList <IntVec3>)) != null) { for (int k = 0; k < list2.Count; k++) { ProcessCell(list2[k]); } } else { foreach (IntVec3 item in enumerable4) { ProcessCell(item); } } } } void ProcessCell(IntVec3 c) { bool flag = false; float num2 = (c - pawnPosition).LengthHorizontalSquared; float num3 = 0f; if (prioritized) { if (!c.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, c)) { if (!allowUnreachable && !pawn.CanReach(c, scanner.PathEndMode, maxPathDanger)) { return; } num3 = scanner.GetPriority(pawn, c); if (num3 > bestPriority || (num3 == bestPriority && num2 < closestDistSquared)) { flag = true; } } } else if (num2 < closestDistSquared && !c.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, c)) { if (!allowUnreachable && !pawn.CanReach(c, scanner.PathEndMode, maxPathDanger)) { return; } flag = true; } if (flag) { bestTargetOfLastPriority = new TargetInfo(c, pawn.Map); scannerWhoProvidedTarget = scanner; closestDistSquared = num2; bestPriority = num3; } } } catch (Exception ex) { Log.Error(string.Concat(pawn, " threw exception in WorkGiver ", workGiver.def.defName, ": ", ex.ToString())); } finally { } if (bestTargetOfLastPriority.IsValid) { Job job3 = (!bestTargetOfLastPriority.HasThing) ? scannerWhoProvidedTarget.JobOnCell(pawn, bestTargetOfLastPriority.Cell) : scannerWhoProvidedTarget.JobOnThing(pawn, bestTargetOfLastPriority.Thing); if (job3 != null) { job3.workGiverDef = scannerWhoProvidedTarget.def; GiveJob(pawn, job3, scannerWhoProvidedTarget); return; } } num = workGiver.def.priorityInType; } }
// Token: 0x06000005 RID: 5 RVA: 0x000027F0 File Offset: 0x000009F0 private Job GiverTryGiveJobPrioritized(Pawn pawn, WorkGiver giver, IntVec3 cell) { bool flag = !this.PawnCanUseWorkGiver(pawn, giver); Job result; if (flag) { result = null; } else { try { Job job = giver.NonScanJob(pawn); bool flag2 = job != null; if (flag2) { return(job); } WorkGiver_Scanner scanner = giver as WorkGiver_Scanner; bool flag3 = scanner != null; if (flag3) { bool scanThings = giver.def.scanThings; if (scanThings) { Predicate <Thing> predicate = (Thing t) => !t.IsForbidden(pawn) && scanner.HasJobOnThing(pawn, t, false); List <Thing> thingList = cell.GetThingList(pawn.Map); for (int i = 0; i < thingList.Count; i++) { Thing thing = thingList[i]; bool flag4 = scanner.PotentialWorkThingRequest.Accepts(thing) && predicate(thing); if (flag4) { Job job2 = scanner.JobOnThing(pawn, thing, false); bool flag5 = job2 != null; if (flag5) { job2.workGiverDef = giver.def; } return(job2); } } } bool flag6 = giver.def.scanCells && !cell.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, cell, false); if (flag6) { Job job3 = scanner.JobOnCell(pawn, cell, false); bool flag7 = job3 != null; if (flag7) { job3.workGiverDef = giver.def; } return(job3); } } } catch (Exception ex) { Log.Error(string.Concat(new object[] { pawn, " threw exception in GiverTryGiveJobTargeted on WorkGiver ", giver.def.defName, ": ", ex.ToString() }), false); } result = null; } return(result); }
public override ThinkResult TryIssueJobPackage(Pawn pawn, JobIssueParams jobParams) { int num = -999; TargetInfo targetInfo = TargetInfo.Invalid; WorkGiver_Scanner workGiver_Scanner = null; if (workGiverDef != null) { WorkGiver workGiver = workGiverDef.Worker; if (workGiver.def.priorityInType != num && targetInfo.IsValid) { return(ThinkResult.NoJob); } if (this.PawnCanUseWorkGiver(pawn, workGiver)) { try { Job job2 = workGiver.NonScanJob(pawn); if (job2 != null) { return(new ThinkResult(job2, this, new JobTag?(workGiverDef.tagToGive))); } WorkGiver_Scanner scanner = workGiver as WorkGiver_Scanner; if (scanner != null) { if (workGiver.def.scanThings) { Predicate <Thing> predicate = (Thing t) => !t.IsForbidden(pawn) && scanner.HasJobOnThing(pawn, t, false); IEnumerable <Thing> enumerable = scanner.PotentialWorkThingsGlobal(pawn); Thing thing; if (scanner.Prioritized) { IEnumerable <Thing> enumerable2 = enumerable; if (enumerable2 == null) { enumerable2 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest); } Predicate <Thing> validator = predicate; thing = GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map, enumerable2, scanner.PathEndMode, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), 9999f, validator, (Thing x) => scanner.GetPriority(pawn, x)); } else { Predicate <Thing> validator = predicate; bool forceGlobalSearch = enumerable != null; thing = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, scanner.PotentialWorkThingRequest, scanner.PathEndMode, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), 9999f, validator, enumerable, 0, scanner.LocalRegionsToScanFirst, forceGlobalSearch, RegionType.Set_Passable, false); } if (thing != null) { targetInfo = thing; workGiver_Scanner = scanner; } } if (workGiver.def.scanCells) { IntVec3 position = pawn.Position; float num2 = 99999f; float num3 = -3.40282347E+38f; bool prioritized = scanner.Prioritized; foreach (IntVec3 current in scanner.PotentialWorkCellsGlobal(pawn)) { bool flag = false; float num4 = (float)(current - position).LengthHorizontalSquared; if (prioritized) { if (!current.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, current)) { float priority = scanner.GetPriority(pawn, current); if (priority > num3 || (priority == num3 && num4 < num2)) { flag = true; num3 = priority; } } } else if (num4 < num2 && !current.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, current)) { flag = true; } if (flag) { targetInfo = new TargetInfo(current, pawn.Map, false); workGiver_Scanner = scanner; num2 = num4; } } } } } catch (Exception ex) { Log.Error(string.Concat(new object[] { pawn, " threw exception in WorkGiver ", workGiver.def.defName, ": ", ex.ToString() })); } finally { } if (targetInfo.IsValid) { pawn.mindState.lastGivenWorkType = workGiver.def.workType; Job job3; if (targetInfo.HasThing) { job3 = workGiver_Scanner.JobOnThing(pawn, targetInfo.Thing, false); } else { job3 = workGiver_Scanner.JobOnCell(pawn, targetInfo.Cell); } if (job3 != null) { return(new ThinkResult(job3, this, new JobTag?(workGiverDef.tagToGive))); } Log.ErrorOnce(string.Concat(new object[] { workGiver_Scanner, " provided target ", targetInfo, " but yielded no actual job for pawn ", pawn, ". The CanGiveJob and JobOnX methods may not be synchronized." }), 6112651); } num = workGiver.def.priorityInType; } } return(ThinkResult.NoJob); }
// Token: 0x06000003 RID: 3 RVA: 0x0000212C File Offset: 0x0000032C public override ThinkResult TryIssueJobPackage(Pawn pawn, JobIssueParams jobParams) { bool isPrioritized = pawn.mindState.priorityWork.IsPrioritized; if (isPrioritized) { List <WorkGiverDef> workGiversByPriority = pawn.mindState.priorityWork.WorkGiver.workType.workGiversByPriority; for (int i = 0; i < workGiversByPriority.Count; i++) { WorkGiver worker = workGiversByPriority[i].Worker; Job job = this.GiverTryGiveJobPrioritized(pawn, worker, pawn.mindState.priorityWork.Cell); bool flag = job != null; if (flag) { job.playerForced = true; return(new ThinkResult(job, this, new JobTag?(workGiversByPriority[i].tagToGive), false)); } } pawn.mindState.priorityWork.Clear(); } int num = -999; TargetInfo targetInfo = TargetInfo.Invalid; WorkGiver_Scanner workGiver_Scanner = null; bool flag2 = this.workGiverDef != null; if (flag2) { WorkGiver worker2 = this.workGiverDef.Worker; bool flag3 = worker2.def.priorityInType != num && targetInfo.IsValid; if (flag3) { return(ThinkResult.NoJob); } bool flag4 = this.PawnCanUseWorkGiver(pawn, worker2); if (flag4) { try { Job job2 = worker2.NonScanJob(pawn); bool flag5 = job2 != null; if (flag5) { return(new ThinkResult(job2, this, new JobTag?(this.workGiverDef.tagToGive), false)); } WorkGiver_Scanner scanner = worker2 as WorkGiver_Scanner; bool flag6 = scanner != null; if (flag6) { bool scanThings = worker2.def.scanThings; if (scanThings) { Predicate <Thing> predicate = (Thing t) => !t.IsForbidden(pawn) && scanner.HasJobOnThing(pawn, t, false); IEnumerable <Thing> enumerable = scanner.PotentialWorkThingsGlobal(pawn); bool prioritized = scanner.Prioritized; Thing thing; if (prioritized) { IEnumerable <Thing> enumerable2 = enumerable; bool flag7 = enumerable2 == null; if (flag7) { enumerable2 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest); } Predicate <Thing> validator = predicate; thing = GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map, enumerable2, scanner.PathEndMode, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), 9999f, validator, (Thing x) => scanner.GetPriority(pawn, x)); } else { Predicate <Thing> validator2 = predicate; bool forceAllowGlobalSearch = enumerable != null; thing = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, scanner.PotentialWorkThingRequest, scanner.PathEndMode, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), 9999f, validator2, enumerable, 0, scanner.MaxRegionsToScanBeforeGlobalSearch, forceAllowGlobalSearch, RegionType.Set_Passable, false); } bool flag8 = thing != null; if (flag8) { targetInfo = thing; workGiver_Scanner = scanner; } } bool scanCells = worker2.def.scanCells; if (scanCells) { IntVec3 position = pawn.Position; float num2 = 99999f; float num3 = float.MinValue; bool prioritized2 = scanner.Prioritized; foreach (IntVec3 intVec in scanner.PotentialWorkCellsGlobal(pawn)) { bool flag9 = false; float num4 = (float)(intVec - position).LengthHorizontalSquared; bool flag10 = prioritized2; if (flag10) { bool flag11 = !intVec.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, intVec, false); if (flag11) { float priority = scanner.GetPriority(pawn, intVec); bool flag12 = priority > num3 || (priority == num3 && num4 < num2); if (flag12) { flag9 = true; num3 = priority; } } } else { bool flag13 = num4 < num2 && !intVec.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, intVec, false); if (flag13) { flag9 = true; } } bool flag14 = flag9; if (flag14) { targetInfo = new TargetInfo(intVec, pawn.Map, false); workGiver_Scanner = scanner; num2 = num4; } } } } } catch (Exception ex) { Log.Message(string.Concat(new object[] { pawn, " threw exception DONT WANT LAH in WorkGiver ", worker2.def.defName, ": ", ex.ToString() }), false); } finally { } bool isValid = targetInfo.IsValid; if (isValid) { bool hasThing = targetInfo.HasThing; Job job3; if (hasThing) { job3 = workGiver_Scanner.JobOnThing(pawn, targetInfo.Thing, false); } else { job3 = workGiver_Scanner.JobOnCell(pawn, targetInfo.Cell, false); } bool flag15 = job3 != null; if (flag15) { return(new ThinkResult(job3, this, new JobTag?(this.workGiverDef.tagToGive), false)); } Log.ErrorOnce(string.Concat(new object[] { workGiver_Scanner, " provided target ", targetInfo, " but yielded no actual job for pawn ", pawn, ". The CanGiveJob and JobOnX methods may not be synchronized." }), 6112651, false); } num = worker2.def.priorityInType; } } return(ThinkResult.NoJob); }
private static void Postfix(Vector3 clickPos, Pawn pawn, List <FloatMenuOption> opts, bool drafted, FloatMenuOption[] ___equivalenceGroupTempStorage) { if (pawn.thinker.TryGetMainTreeThinkNode <JobGiver_Work>() != null) { IntVec3 clickCell = IntVec3.FromVector3(clickPos); TargetingParameters targetingParameters = new TargetingParameters(); targetingParameters.canTargetPawns = true; targetingParameters.canTargetBuildings = true; targetingParameters.canTargetItems = true; targetingParameters.mapObjectTargetsMustBeAutoAttackable = false; var ZTracker = ZUtils.ZTracker; foreach (Thing item in GenUI.ThingsUnderMouse(clickPos, 1f, targetingParameters)) { bool flag = false; foreach (WorkTypeDef item2 in DefDatabase <WorkTypeDef> .AllDefsListForReading) { for (int i = 0; i < item2.workGiversByPriority.Count; i++) { WorkGiverDef workGiver2 = item2.workGiversByPriority[i]; if (!drafted || workGiver2.canBeDoneWhileDrafted) { WorkGiver_Scanner workGiver_Scanner = workGiver2.Worker as WorkGiver_Scanner; if (workGiver_Scanner != null && workGiver_Scanner.def.directOrderable) { JobFailReason.Clear(); if ((workGiver_Scanner.PotentialWorkThingRequest.Accepts(item) || (workGiver_Scanner.PotentialWorkThingsGlobal(pawn) != null && workGiver_Scanner.PotentialWorkThingsGlobal(pawn).Contains(item))) && !workGiver_Scanner.ShouldSkip(pawn, forced: true)) { string text = null; Action action = null; PawnCapacityDef pawnCapacityDef = workGiver_Scanner.MissingRequiredCapacity(pawn); if (pawnCapacityDef != null) { text = "CannotMissingHealthActivities".Translate(pawnCapacityDef.label); } else { Map oldMap = pawn.Map; Job job = null; Map dest = null; foreach (var otherMap in ZTracker.GetAllMapsInClosestOrder(oldMap)) { if (workGiver_Scanner is WorkGiver_Refuel scanner1) { job = JobPatches.TryIssueJobPackagePatch.JobOnThing( scanner1, pawn, item, true); } else if (workGiver_Scanner.def.defName == "HaulGeneral" || workGiver_Scanner.def.defName == "HaulCorpses") { job = JobPatches.TryIssueJobPackagePatch.JobOnThing(pawn, item, ref dest); } else if (workGiver_Scanner is WorkGiver_DoBill scanner2) { job = JobPatches.TryIssueJobPackagePatch.JobOnThing( scanner2, pawn, item); } else if (workGiver_Scanner is WorkGiver_ConstructDeliverResourcesToBlueprints scanner3) { job = JobPatches.TryIssueJobPackagePatch.JobOnThing( scanner3, pawn, item); } else if (workGiver_Scanner is WorkGiver_ConstructDeliverResourcesToFrames scanner4) { job = JobPatches.TryIssueJobPackagePatch.JobOnThing( scanner4, pawn, item); } else { job = workGiver_Scanner.HasJobOnThing(pawn, item, forced: true) ? workGiver_Scanner.JobOnThing(pawn, item, forced: true) : null; } if (job != null) { break; } } if (job == null) { if (JobFailReason.HaveReason) { text = (JobFailReason.CustomJobString.NullOrEmpty() ? ((string)"CannotGenericWork".Translate(workGiver_Scanner.def.verb, item.LabelShort, item)) : ((string)"CannotGenericWorkCustom".Translate(JobFailReason.CustomJobString))); text = text + ": " + JobFailReason.Reason.CapitalizeFirst(); } else { if (!item.IsForbidden(pawn)) { continue; } text = (item.Position.InAllowedArea(pawn) ? ((string)"CannotPrioritizeForbidden".Translate(item.Label, item)) : ((string)("CannotPrioritizeForbiddenOutsideAllowedArea".Translate() + ": " + pawn.playerSettings.EffectiveAreaRestriction.Label))); } } else { WorkTypeDef workType = workGiver_Scanner.def.workType; if (pawn.WorkTagIsDisabled(workGiver_Scanner.def.workTags)) { text = "CannotPrioritizeWorkGiverDisabled".Translate(workGiver_Scanner.def.label); } else if (pawn.jobs.curJob != null && pawn.jobs.curJob.JobIsSameAs(job)) { text = "CannotGenericAlreadyAm".Translate(workGiver_Scanner.PostProcessedGerund(job), item.LabelShort, item); } else if (pawn.workSettings.GetPriority(workType) == 0) { text = (pawn.WorkTypeIsDisabled(workType) ? ((string)"CannotPrioritizeWorkTypeDisabled".Translate(workType.gerundLabel)) : ((!"CannotPrioritizeNotAssignedToWorkType".CanTranslate()) ? ((string)"CannotPrioritizeWorkTypeDisabled".Translate(workType.pawnLabel)) : ((string)"CannotPrioritizeNotAssignedToWorkType".Translate(workType.gerundLabel)))); } else if (job.def == JobDefOf.Research && item is Building_ResearchBench) { text = "CannotPrioritizeResearch".Translate(); } else if (item.IsForbidden(pawn)) { text = (item.Position.InAllowedArea(pawn) ? ((string)"CannotPrioritizeForbidden".Translate(item.Label, item)) : ((string)("CannotPrioritizeForbiddenOutsideAllowedArea".Translate() + ": " + pawn.playerSettings.EffectiveAreaRestriction.Label))); } else if (!pawn.CanReach(item, workGiver_Scanner.PathEndMode, Danger.Deadly)) { text = (item.Label + ": " + "NoPath".Translate().CapitalizeFirst()).CapitalizeFirst(); } else { text = "PrioritizeGeneric".Translate(workGiver_Scanner.PostProcessedGerund(job), item.Label); Job localJob2 = job; WorkGiver_Scanner localScanner2 = workGiver_Scanner; job.workGiverDef = workGiver_Scanner.def; action = delegate { if (!ZTracker.jobTracker.ContainsKey(pawn)) { ZTracker.jobTracker[pawn] = new JobTracker(); } if (dest != null) { ZTracker.BuildJobListFor(pawn, dest, job); } else { ZTracker.BuildJobListFor(pawn, oldMap, job); } pawn.jobs.EndCurrentJob(JobCondition.InterruptForced); if (workGiver2.forceMote != null) { MoteMaker.MakeStaticMote(clickCell, pawn.Map, workGiver2.forceMote); } }; } } } if (DebugViewSettings.showFloatMenuWorkGivers) { text += $" (from {workGiver2.defName})"; } FloatMenuOption menuOption = FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption(text, action), pawn, item); if (drafted && workGiver2.autoTakeablePriorityDrafted != -1) { menuOption.autoTakeable = true; menuOption.autoTakeablePriority = workGiver2.autoTakeablePriorityDrafted; } if (!opts.Any((FloatMenuOption op) => op.Label == menuOption.Label)) { if (workGiver2.equivalenceGroup != null) { if (___equivalenceGroupTempStorage[workGiver2.equivalenceGroup.index] == null || (___equivalenceGroupTempStorage[workGiver2.equivalenceGroup.index].Disabled && !menuOption.Disabled)) { ___equivalenceGroupTempStorage[workGiver2.equivalenceGroup.index] = menuOption; flag = true; } } else { opts.Add(menuOption); } } } } } } } if (flag) { for (int j = 0; j < ___equivalenceGroupTempStorage.Length; j++) { if (___equivalenceGroupTempStorage[j] != null) { opts.Add(___equivalenceGroupTempStorage[j]); ___equivalenceGroupTempStorage[j] = null; } } } } foreach (WorkTypeDef item3 in DefDatabase <WorkTypeDef> .AllDefsListForReading) { for (int k = 0; k < item3.workGiversByPriority.Count; k++) { WorkGiverDef workGiver = item3.workGiversByPriority[k]; if (!drafted || workGiver.canBeDoneWhileDrafted) { WorkGiver_Scanner workGiver_Scanner2 = workGiver.Worker as WorkGiver_Scanner; if (workGiver_Scanner2 != null && workGiver_Scanner2.def.directOrderable) { JobFailReason.Clear(); if (workGiver_Scanner2.PotentialWorkCellsGlobal(pawn).Contains(clickCell) && !workGiver_Scanner2.ShouldSkip(pawn, forced: true)) { Action action2 = null; string label = null; PawnCapacityDef pawnCapacityDef2 = workGiver_Scanner2.MissingRequiredCapacity(pawn); if (pawnCapacityDef2 != null) { label = "CannotMissingHealthActivities".Translate(pawnCapacityDef2.label); } else { Job job2 = workGiver_Scanner2.HasJobOnCell(pawn, clickCell, forced: true) ? workGiver_Scanner2.JobOnCell(pawn, clickCell, forced: true) : null; if (job2 == null) { if (JobFailReason.HaveReason) { if (!JobFailReason.CustomJobString.NullOrEmpty()) { label = "CannotGenericWorkCustom".Translate(JobFailReason.CustomJobString); } else { label = "CannotGenericWork".Translate(workGiver_Scanner2.def.verb, "AreaLower".Translate()); } label = label + ": " + JobFailReason.Reason.CapitalizeFirst(); } else { if (!clickCell.IsForbidden(pawn)) { continue; } if (!clickCell.InAllowedArea(pawn)) { label = "CannotPrioritizeForbiddenOutsideAllowedArea".Translate() + ": " + pawn.playerSettings.EffectiveAreaRestriction.Label; } else { label = "CannotPrioritizeCellForbidden".Translate(); } } } else { WorkTypeDef workType2 = workGiver_Scanner2.def.workType; if (pawn.jobs.curJob != null && pawn.jobs.curJob.JobIsSameAs(job2)) { label = "CannotGenericAlreadyAmCustom".Translate(workGiver_Scanner2.PostProcessedGerund(job2)); } else if (pawn.workSettings.GetPriority(workType2) == 0) { if (pawn.WorkTypeIsDisabled(workType2)) { label = "CannotPrioritizeWorkTypeDisabled".Translate(workType2.gerundLabel); } else if ("CannotPrioritizeNotAssignedToWorkType".CanTranslate()) { label = "CannotPrioritizeNotAssignedToWorkType".Translate(workType2.gerundLabel); } else { label = "CannotPrioritizeWorkTypeDisabled".Translate(workType2.pawnLabel); } } else if (clickCell.IsForbidden(pawn)) { if (!clickCell.InAllowedArea(pawn)) { label = "CannotPrioritizeForbiddenOutsideAllowedArea".Translate() + ": " + pawn.playerSettings.EffectiveAreaRestriction.Label; } else { label = "CannotPrioritizeCellForbidden".Translate(); } } else if (!pawn.CanReach(clickCell, PathEndMode.Touch, Danger.Deadly)) { label = "AreaLower".Translate().CapitalizeFirst() + ": " + "NoPath".Translate().CapitalizeFirst(); } else { label = "PrioritizeGeneric".Translate(workGiver_Scanner2.PostProcessedGerund(job2), "AreaLower".Translate()); Job localJob = job2; WorkGiver_Scanner localScanner = workGiver_Scanner2; job2.workGiverDef = workGiver_Scanner2.def; action2 = delegate { if (pawn.jobs.TryTakeOrderedJobPrioritizedWork(localJob, localScanner, clickCell) && workGiver.forceMote != null) { MoteMaker.MakeStaticMote(clickCell, pawn.Map, workGiver.forceMote); } }; } } } if (!opts.Any((FloatMenuOption op) => op.Label == label.TrimEnd())) { FloatMenuOption floatMenuOption = FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption(label, action2), pawn, clickCell); if (drafted && workGiver.autoTakeablePriorityDrafted != -1) { floatMenuOption.autoTakeable = true; floatMenuOption.autoTakeablePriority = workGiver.autoTakeablePriorityDrafted; } opts.Add(floatMenuOption); } } } } } } } }
protected Job GetJobOnTarget(Pawn meeseeks, SavedTargetInfo targetInfo, WorkGiver_Scanner workGiverScanner, bool scanAllThingsOnCell = false) { Job job = null; try { DesignatorUtility.ForceAllDesignationsOnCell(targetInfo.Cell, meeseeks.MapHeld); if (targetInfo.HasThing && !targetInfo.ThingDestroyed) { // Special case for uninstall, the workgiver doesn't check to see if its already uninstalled if (workGiverScanner as WorkGiver_Uninstall != null && !targetInfo.Thing.Spawned) { Logger.WarningFormat(this, "Target is inside {0}", targetInfo.Thing.ParentHolder); DesignatorUtility.RestoreDesignationsOnCell(targetInfo.Cell, meeseeks.MapHeld); return(null); } // Have to try-catch all these damn things because other mods arent't doing null checks :( try { //Logger.MessageFormat(this, "Checking {0} for job on {1}", workGiverScanner, targetInfo.Thing); if (workGiverScanner.HasJobOnThing(meeseeks, targetInfo.Thing, true)) { //Logger.MessageFormat(this, "Getting {0} for job on {1}", workGiverScanner, targetInfo.Thing); job = workGiverScanner.JobOnThing(meeseeks, targetInfo.Thing, true); } } catch (Exception e) { } finally { } } else { // Have to try-catch all these damn things because other mods arent't doing null checks :( try { //Logger.MessageFormat(this, "Checking {0} for job on {1}", workGiverScanner, targetInfo.Cell); if (job == null && workGiverScanner.HasJobOnCell(meeseeks, targetInfo.Cell, true)) { job = workGiverScanner.JobOnCell(meeseeks, targetInfo.Cell, true); } } catch (Exception e) { } finally { } } if (job == null && scanAllThingsOnCell) { var thingsAtCell = meeseeks.MapHeld.thingGrid.ThingsAt(targetInfo.Cell); foreach (Thing thing in thingsAtCell) { //Logger.MessageFormat(this, "Checking {0} for {1}.", thing, workGiverScanner.def.defName); // Have to try-catch all these damn things because other mods arent't doing null checks :( try { Logger.MessageFormat(this, "Checking {0} for job on {1}", workGiverScanner, thing); if (workGiverScanner.HasJobOnThing(meeseeks, thing, true)) { job = workGiverScanner.JobOnThing(meeseeks, thing, true); } } catch (Exception e) { } finally { } if (job != null) { break; } } } } finally { DesignatorUtility.RestoreDesignationsOnCell(targetInfo.Cell, meeseeks.MapHeld); } return(job); }
public override ThinkResult TryIssueJobPackage(Pawn pawn, JobIssueParams jobParams) { X2_AIRobot robot = pawn as X2_AIRobot; if (robot == null || !robot.Spawned || robot.Destroyed || robot.GetWorkGivers(false) == null) { return(ThinkResult.NoJob); } //Profiler.BeginSample("JobGiver_Work"); //if (emergency && pawn.mindState.priorityWork.IsPrioritized) //{ // List<WorkGiverDef> workGiversByPriority = pawn.mindState.priorityWork.WorkGiver.workType.workGiversByPriority; // for (int i = 0; i < workGiversByPriority.Count; i++) // { // WorkGiver worker = workGiversByPriority[i].Worker; // if (WorkGiversRelated(pawn.mindState.priorityWork.WorkGiver, worker.def)) // { // Job job = GiverTryGiveJobPrioritized(pawn, worker, pawn.mindState.priorityWork.Cell); // if (job != null) // { // job.playerForced = true; // return new ThinkResult(job, this, workGiversByPriority[i].tagToGive); // } // } // } // pawn.mindState.priorityWork.Clear(); //} List <WorkGiver> list = robot.GetWorkGivers(false); // Get Non-Emergency WorkGivers int num = -999; TargetInfo bestTargetOfLastPriority = TargetInfo.Invalid; WorkGiver_Scanner scannerWhoProvidedTarget = null; WorkGiver_Scanner scanner; IntVec3 pawnPosition; bool prioritized; bool allowUnreachable; Danger maxPathDanger; for (int j = 0; j < list.Count; j++) { WorkGiver workGiver = list[j]; if (workGiver.def.priorityInType != num && bestTargetOfLastPriority.IsValid) { break; } if (!PawnCanUseWorkGiver(pawn, workGiver)) { continue; } try { Job job2 = workGiver.NonScanJob(pawn); if (job2 != null) { return(new ThinkResult(job2, this, list[j].def.tagToGive)); } scanner = (workGiver as WorkGiver_Scanner); float closestDistSquared; float bestPriority; if (scanner != null) { if (scanner.def.scanThings) { Predicate <Thing> validator = (Thing t) => !t.IsForbidden(pawn) && scanner.HasJobOnThing(pawn, t); IEnumerable <Thing> enumerable = scanner.PotentialWorkThingsGlobal(pawn); Thing thing; try { if (scanner.Prioritized) { IEnumerable <Thing> enumerable2 = enumerable; if (enumerable2 == null) { enumerable2 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest); } thing = ((!scanner.AllowUnreachable) ? GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map, enumerable2, scanner.PathEndMode, TraverseParms.For(pawn, scanner.MaxPathDanger(pawn)), 9999f, validator, (Thing x) => scanner.GetPriority(pawn, x)) : GenClosest.ClosestThing_Global(pawn.Position, enumerable2, 99999f, validator, (Thing x) => scanner.GetPriority(pawn, x))); } else if (scanner.AllowUnreachable) { IEnumerable <Thing> enumerable3 = enumerable; if (enumerable3 == null) { enumerable3 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest); } thing = GenClosest.ClosestThing_Global(pawn.Position, enumerable3, 99999f, validator); } else { thing = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, scanner.PotentialWorkThingRequest, scanner.PathEndMode, TraverseParms.For(pawn, scanner.MaxPathDanger(pawn)), 9999f, validator, enumerable, 0, scanner.MaxRegionsToScanBeforeGlobalSearch, enumerable != null); } } catch (Exception ex) { Log.Error("Error in WorkGiver: " + ex.Message); thing = null; } if (thing != null) { bestTargetOfLastPriority = thing; scannerWhoProvidedTarget = scanner; } } if (scanner.def.scanCells) { pawnPosition = pawn.Position; closestDistSquared = 99999f; bestPriority = float.MinValue; prioritized = scanner.Prioritized; allowUnreachable = scanner.AllowUnreachable; maxPathDanger = scanner.MaxPathDanger(pawn); IEnumerable <IntVec3> enumerable4 = scanner.PotentialWorkCellsGlobal(pawn); IList <IntVec3> list2; if ((list2 = (enumerable4 as IList <IntVec3>)) != null) { for (int k = 0; k < list2.Count; k++) { ProcessCell(list2[k]); } } else { foreach (IntVec3 item in enumerable4) { ProcessCell(item); } } } } void ProcessCell(IntVec3 c) { bool flag = false; float num2 = (c - pawnPosition).LengthHorizontalSquared; float num3 = 0f; if (prioritized) { if (!c.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, c)) { if (!allowUnreachable && !pawn.CanReach(c, scanner.PathEndMode, maxPathDanger)) { return; } num3 = scanner.GetPriority(pawn, c); if (num3 > bestPriority || (num3 == bestPriority && num2 < closestDistSquared)) { flag = true; } } } else if (num2 < closestDistSquared && !c.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, c)) { if (!allowUnreachable && !pawn.CanReach(c, scanner.PathEndMode, maxPathDanger)) { return; } flag = true; } if (flag) { bestTargetOfLastPriority = new TargetInfo(c, pawn.Map); scannerWhoProvidedTarget = scanner; closestDistSquared = num2; bestPriority = num3; } } } catch (Exception ex) { Log.Error(pawn + " threw exception in WorkGiver " + workGiver.def.defName + ": " + ex.ToString()); } finally { } if (bestTargetOfLastPriority.IsValid) { Job job3 = (!bestTargetOfLastPriority.HasThing) ? scannerWhoProvidedTarget.JobOnCell(pawn, bestTargetOfLastPriority.Cell) : scannerWhoProvidedTarget.JobOnThing(pawn, bestTargetOfLastPriority.Thing); if (job3 != null) { job3.workGiverDef = scannerWhoProvidedTarget.def; return(new ThinkResult(job3, this, list[j].def.tagToGive)); } Log.ErrorOnce(scannerWhoProvidedTarget + " provided target " + bestTargetOfLastPriority + " but yielded no actual job for pawn " + pawn + ". The CanGiveJob and JobOnX methods may not be synchronized.", 6112651); } num = workGiver.def.priorityInType; } return(ThinkResult.NoJob); }
//public bool emergency; protected override Job TryGiveTerminalJob(Pawn pawn) { if (!(pawn is Droid)) { return(null); } Droid droid = pawn as Droid; if (!droid.Active) { return(null); } List <WorkGiver> list = this.emergency ? droid.work.WorkGiversInOrderEmergency : droid.work.WorkGiversInOrder; int num = -999; TargetInfo targetInfo = TargetInfo.Invalid; WorkGiver_Scanner workGiver_Scanner = null; for (int i = 0; i < list.Count; i++) { WorkGiver workGiver = list[i]; if (workGiver.def.priorityInType != num && targetInfo.IsValid) { break; } if (workGiver.MissingRequiredCapacity(pawn) == null) { if (!workGiver.ShouldSkip(pawn)) { try { Job job = workGiver.NonScanJob(pawn); if (job != null) { Job result = job; return(result); } WorkGiver_Scanner scanner = workGiver as WorkGiver_Scanner; if (scanner != null) { if (workGiver.def.scanThings) { Predicate <Thing> predicate = (Thing t) => !t.IsForbidden(pawn) && scanner.HasJobOnThing(pawn, t); IEnumerable <Thing> enumerable = scanner.PotentialWorkThingsGlobal(pawn); Predicate <Thing> validator = predicate; Thing thing = GenClosest.ClosestThingReachable(pawn.Position, scanner.PotentialWorkThingRequest, scanner.PathEndMode, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), 9999f, validator, enumerable, scanner.LocalRegionsToScanFirst, enumerable != null); if (thing != null) { targetInfo = thing; workGiver_Scanner = scanner; } } if (workGiver.def.scanCells) { IntVec3 position = pawn.Position; float num2 = 99999f; foreach (IntVec3 current in scanner.PotentialWorkCellsGlobal(pawn)) { float lengthHorizontalSquared = (current - position).LengthHorizontalSquared; if (lengthHorizontalSquared < num2 && !current.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, current)) { targetInfo = current; workGiver_Scanner = scanner; num2 = lengthHorizontalSquared; } } } num = workGiver.def.priorityInType; } } catch (Exception ex) { Log.Error(string.Concat(new object[] { pawn, " threw exception in WorkGiver ", workGiver.def.defName, ": ", ex.ToString() })); } finally { } if (targetInfo.IsValid) { pawn.mindState.lastGivenWorkType = workGiver.def.workType; if (targetInfo.HasThing) { return(workGiver_Scanner.JobOnThing(pawn, targetInfo.Thing)); } return(workGiver_Scanner.JobOnCell(pawn, targetInfo.Cell)); } } } } return(null); }
// Method from RimWorld.JobGiver_Work.TryIssueJobPackage(Pawn pawn, JobIssueParams jobParams) // I modified the line if (!workGiver.ShouldSkip(pawn)) #pragma warning disable public ThinkResult TryIssueJobPackageDrone(Pawn pawn, bool emergency) { List <WorkGiver> list = emergency ? pawn.workSettings.WorkGiversInOrderEmergency : pawn.workSettings.WorkGiversInOrderNormal; int num = -999; TargetInfo targetInfo = TargetInfo.Invalid; WorkGiver_Scanner workGiver_Scanner = null; for (int j = 0; j < list.Count; j++) { WorkGiver workGiver = list[j]; if (workGiver.def.priorityInType != num && targetInfo.IsValid) { break; } if (!workGiver.ShouldSkip(pawn)) { try { Job job2 = workGiver.NonScanJob(pawn); if (job2 != null) { return(new ThinkResult(job2, null, new JobTag?(list[j].def.tagToGive), false)); } WorkGiver_Scanner scanner = workGiver as WorkGiver_Scanner; if (scanner != null) { if (scanner.def.scanThings) { Predicate <Thing> predicate = (Thing t) => !t.IsForbidden(pawn) && scanner.HasJobOnThing(pawn, t, false); IEnumerable <Thing> enumerable = scanner.PotentialWorkThingsGlobal(pawn); Thing thing; if (scanner.Prioritized) { IEnumerable <Thing> enumerable2 = enumerable; if (enumerable2 == null) { enumerable2 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest); } if (scanner.AllowUnreachable) { IntVec3 position = pawn.Position; IEnumerable <Thing> searchSet = enumerable2; Predicate <Thing> validator = predicate; thing = GenClosest.ClosestThing_Global(position, searchSet, 99999f, validator, (Thing x) => scanner.GetPriority(pawn, x)); } else { IntVec3 position = pawn.Position; Map map = pawn.Map; IEnumerable <Thing> searchSet = enumerable2; PathEndMode pathEndMode = scanner.PathEndMode; TraverseParms traverseParams = TraverseParms.For(pawn, scanner.MaxPathDanger(pawn), TraverseMode.ByPawn, false); Predicate <Thing> validator = predicate; thing = GenClosest.ClosestThing_Global_Reachable(position, map, searchSet, pathEndMode, traverseParams, 9999f, validator, (Thing x) => scanner.GetPriority(pawn, x)); } } else if (scanner.AllowUnreachable) { IEnumerable <Thing> enumerable3 = enumerable; if (enumerable3 == null) { enumerable3 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest); } IntVec3 position = pawn.Position; IEnumerable <Thing> searchSet = enumerable3; Predicate <Thing> validator = predicate; thing = GenClosest.ClosestThing_Global(position, searchSet, 99999f, validator, null); } else { IntVec3 position = pawn.Position; Map map = pawn.Map; ThingRequest potentialWorkThingRequest = scanner.PotentialWorkThingRequest; PathEndMode pathEndMode = scanner.PathEndMode; TraverseParms traverseParams = TraverseParms.For(pawn, scanner.MaxPathDanger(pawn), TraverseMode.ByPawn, false); Predicate <Thing> validator = predicate; bool forceGlobalSearch = enumerable != null; thing = GenClosest.ClosestThingReachable(position, map, potentialWorkThingRequest, pathEndMode, traverseParams, 9999f, validator, enumerable, 0, scanner.LocalRegionsToScanFirst, forceGlobalSearch, RegionType.Set_Passable, false); } if (thing != null) { targetInfo = thing; workGiver_Scanner = scanner; } } if (scanner.def.scanCells) { IntVec3 position2 = pawn.Position; float num2 = 99999f; float num3 = float.MinValue; bool prioritized = scanner.Prioritized; bool allowUnreachable = scanner.AllowUnreachable; Danger maxDanger = scanner.MaxPathDanger(pawn); foreach (IntVec3 intVec in scanner.PotentialWorkCellsGlobal(pawn)) { bool flag = false; float num4 = (float)(intVec - position2).LengthHorizontalSquared; float num5 = 0f; if (prioritized) { if (scanner.HasJobOnCell(pawn, intVec)) { if (!allowUnreachable && !pawn.CanReach(intVec, scanner.PathEndMode, maxDanger, false, TraverseMode.ByPawn)) { continue; } num5 = scanner.GetPriority(pawn, intVec); if (num5 > num3 || (num5 == num3 && num4 < num2)) { flag = true; } } } else if (num4 < num2 && scanner.HasJobOnCell(pawn, intVec)) { if (!allowUnreachable && !pawn.CanReach(intVec, scanner.PathEndMode, maxDanger, false, TraverseMode.ByPawn)) { continue; } flag = true; } if (flag) { targetInfo = new TargetInfo(intVec, pawn.Map, false); workGiver_Scanner = scanner; num2 = num4; num3 = num5; } } } } } catch (Exception ex) { Log.Error(string.Concat(new object[] { pawn, " threw exception in WorkGiver ", workGiver.def.defName, ": ", ex.ToString() })); } finally { } if (targetInfo.IsValid) { pawn.mindState.lastGivenWorkType = workGiver.def.workType; Job job3; if (targetInfo.HasThing) { job3 = workGiver_Scanner.JobOnThing(pawn, targetInfo.Thing, false); } else { job3 = workGiver_Scanner.JobOnCell(pawn, targetInfo.Cell); } if (job3 != null) { return(new ThinkResult(job3, null, new JobTag?(list[j].def.tagToGive), false)); } Log.ErrorOnce(string.Concat(new object[] { workGiver_Scanner, " provided target ", targetInfo, " but yielded no actual job for pawn ", pawn, ". The CanGiveJob and JobOnX methods may not be synchronized." }), 6112651); } num = workGiver.def.priorityInType; } } return(ThinkResult.NoJob); }
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); }