public static Profiler Start(WorkGiver giver) { if (!Active) { return(null); } wg = giver; CurrentKey = string.Empty; if (ByWorkType) { CurrentKey = giver.def.workType.defName; } else { CurrentKey = giver.def.defName; } if (PerPawn) { CurrentKey = string.Intern(CurrentKey + pawnname); } if (!meths.TryGetValue(giver, out var meth)) { if (giver is WorkGiver_Scanner) { if (giver.def.scanThings) { meth = AccessTools.Method(giver.GetType(), "PotentialWorkThingsGlobal"); } else { meth = AccessTools.Method(giver.GetType(), "PotentialWorkCellsGlobal"); } } else { meth = AccessTools.Method(giver.GetType(), "NonScanJob"); } meths.Add(giver, meth); } return(ProfileController.Start(CurrentKey, namer, null, null, null, meth)); }
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; Job 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(); } 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]; 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 { Job job2 = workGiver.NonScanJob(pawn); 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)) { 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; } } 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; } } return(ThinkResult.NoJob); }
public static Profiler Start(WorkGiver giver, Pawn p) { if (!Active) { return(null); } var key = ""; key = ByWorkType ? giver.def.workType.defName : giver.def.defName; if (PerPawn) { key += p?.Name?.ToStringShort; } if (cachedMethods.TryGetValue(giver, out var meth) == false) { if (giver is WorkGiver_Scanner) { if (giver.def.scanThings) { meth = AccessTools.Method(giver.GetType(), "PotentialWorkThingsGlobal"); } else { meth = AccessTools.Method(giver.GetType(), "PotentialWorkCellsGlobal"); } } else { meth = AccessTools.Method(giver.GetType(), "NonScanJob"); } cachedMethods.Add(giver, meth); } return(ProfileController.Start(key, () => { var label = ""; if (ByWorkType) { label = giver.def?.workType?.defName; } else { label = $"{giver.def?.defName} - {giver.def?.workType?.defName} - {giver.def?.modContentPack?.Name}"; if (RequestTypes && giver is WorkGiver_Scanner scan) { label += $" - {scan.PotentialWorkThingRequest}"; if (scan.PotentialWorkThingRequest.group == ThingRequestGroup.BuildingArtificial) { label += " VERY BAD!"; } } } if (PerPawn) { label += $" - {p?.Name?.ToStringShort}"; } return label; }, null, meth)); }