private void RenderHighlightOverSelectableCells(List <IntVec3> dragCells) { SavedJob savedJob = Memory.savedJob; if (savedJob != null) { if (savedJob.workGiverDef != null) { WorkGiver_Scanner workGiverScanner = savedJob.workGiverDef.Worker as WorkGiver_Scanner; foreach (IntVec3 cell in dragCells) { if (cachedCellResults.ContainsKey(cell) && cachedCellResults[cell] == true) { RenderHighlightOverCell(cell); } else { foreach (Thing thing in cell.GetThingList(base.Map)) { if (cachedThingResults.ContainsKey(thing) && cachedThingResults[thing] == true) { RenderHighlightOverThing(thing); break; } } } } } } }
public static void Postfix(Pawn pawn, TargetInfo t, ref float __result, WorkGiver_Scanner __instance) { if (!(pawn != null && pawn.Faction?.IsPlayer == true)) { return; } Map map = pawn.Map; if (map == null) { map = t.Map; } float modPriority = MainMod.Data.GetPriorityOnCell(map, t.Cell); if (t.HasThing) { modPriority += MainMod.Data.GetPriority(t.Thing); } if (__result < 0f && !LoggedNegWarn) { Log.Warning("Patching priority but old priority was less than 0. This can cause unexpected behavior. WorkGiver type was " + __instance.GetType().FullName); LoggedNegWarn = true; } __result += modPriority; }
public static void Postfix(Pawn pawn, TargetInfo t, ref float __result, WorkGiver_Scanner __instance) { if (!(__instance is WorkGiver_Grower)) { return; } var cell = t.Cell; var zone = (Zone_Growing)pawn.Map.zoneManager.AllZones.FirstOrFallback(x => x is Zone_Growing growZone && growZone.cells.Contains(cell)); if (zone != null) { __result = PriorityTracker.growingZonePriorities.TryGetValue(zone, out var intp) ? intp.Int : (int)Priority.Normal; } else { foreach (var plantGrower in getPlantGrowers(pawn)) { foreach (var unused in plantGrower.OccupiedRect()) { var priority = PriorityTracker.plantBuildingPriorities.TryGetValue((Building_PlantGrower)plantGrower, out var intp) ? (Priority)intp.Int : Priority.Normal; __result = (float)priority; } } } }
static void TempReduceStoragePriorityForHaulBeforeCarry(WorkGiver_Scanner __instance, ref bool __state, Pawn pawn, Thing thing) { if (!haulToInventory.Value || !enabled.Value) { return; } if (!haulToEqualPriority.Value) { return; } var haulTracker = haulTrackers.GetValueSafe(pawn); if (haulTracker == null || haulTracker.haulType != SpecialHaulType.HaulBeforeCarry) { return; } var currentHaulDestination = StoreUtility.CurrentHaulDestinationOf(thing); if (currentHaulDestination == null) { return; } var storeSettings = currentHaulDestination.GetStoreSettings(); if (storeSettings.Priority > StoragePriority.Unstored) { storeSettings.Priority -= 1; __state = true; } }
public static void Postfix(Pawn pawn, TargetInfo t, ref float __result, WorkGiver_Scanner __instance) { if (!__instance.Prioritized || !pawn.CanAffectedByPriority()) { return; } Map map = pawn.Map; if (map == null) { map = t.Map; } float modPriority = MainMod.Data.GetPriorityOnCell(map, t.Cell); if (t.HasThing && !MainMod.ModConfig.patchGenClosest && PriorityData.CanPrioritize(t.Thing)) { modPriority += MainMod.Data.GetPriority(t.Thing); } modPriority *= MainMod.ModConfig.priorityMultiplier; __result += modPriority; }
public static void Postfix(WorkGiver_Scanner __instance, ref float __result, Pawn pawn, TargetInfo t) { if (!(__instance is WorkGiver_Miner) || !t.HasThing) { return; } BuildingProperties building = t.Thing.def.building; if (building == null) { return; } float p = Priority(building.mineableScatterCommonality, building.mineableScatterLumpSizeRange); if (Settings.Get().continueWork) { float damage = t.Thing.MaxHitPoints - t.Thing.HitPoints; p += damage / 1000000f; } __result = p; Log.Message($"Miner priority for {t.Thing} is {__result}"); }
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); }
public override Job GetJob(Pawn meeseeks, CompMeeseeksMemory memory, SavedJob savedJob, SavedTargetInfo jobTarget, ref JobAvailability jobAvailabilty) { Job job = null; WorkGiver_Scanner scanner = savedJob.WorkGiverScanner; if (scanner != null && jobTarget != null && jobTarget.HasThing && !jobTarget.ThingDestroyed && jobTarget.Thing is Pawn) { Pawn targetPawn = jobTarget.Thing as Pawn; if (targetPawn.Dead) { Logger.MessageFormat(this, "{0} dead.", targetPawn); jobAvailabilty = JobAvailability.Complete; } else if (this.TrainingCompleted(meeseeks, targetPawn, jobTarget)) { jobAvailabilty = JobAvailability.Complete; } else if (targetPawn.RaceProps.EatsFood && !HasFoodToInteractAnimal(meeseeks, targetPawn)) { job = TakeFoodForAnimalInteractJob(meeseeks, targetPawn); } else if (TrainableUtility.TrainedTooRecently(targetPawn)) { jobAvailabilty = JobAvailability.Delayed; } else if (targetPawn.MapHeld != meeseeks.MapHeld) { Logger.MessageFormat(this, "{0} not on map with {1}.", targetPawn); job = ExitMapJob(meeseeks); } else if (targetPawn.Spawned) { job = this.GetJobOnTarget(meeseeks, jobTarget, scanner); if (job == null) { jobAvailabilty = JobAvailability.Delayed; } } else { Logger.WarningFormat(this, "Could not get handling job for {0}.", targetPawn); jobAvailabilty = JobAvailability.Delayed; } } else { Logger.WarningFormat(this, "Unable to get scanner or target for job."); } if (job != null) { jobAvailabilty = JobAvailability.Available; } return(job); }
static void Postfix(WorkGiver_Scanner __instance, ref Pawn pawn, ref TargetInfo t, ref float __result) { if (__instance is WorkGiver_Tend) { if (__result == 0f) { __result = Computations.computeTendPriority(pawn, (Pawn)t.Thing); } } else if (__instance is WorkGiver_FeedPatient) { if (__result == 0f) { __result = Computations.computeFeedPriority(pawn, (Pawn)t.Thing); } } else if (__instance is WorkGiver_Train) { if (__result == 0f) { __result = Computations.computeTrainPriority(pawn, (Pawn)t.Thing); } } else if (__instance is WorkGiver_PlantsCut) { if (__result == 0f) { __result = Computations.computePlantCutPriority(pawn, t); } } else if (__instance is WorkGiver_GrowerSow) { if (__result == 0f) { __result = Computations.computeGrowerPriority(pawn, t); } } else if (__instance is WorkGiver_GrowerHarvest) { if (__result == 0f) { __result = Computations.computeGrowerPriority(pawn, t); } } else if (__instance is WorkGiver_ConstructFinishFrames) { if (__result == 0f) { __result = Computations.computeConstructPriority(pawn, (Frame)t); } } else if (__instance is WorkGiver_RescueDowned) { if (__result == 0f) { __result = Computations.computeRescuePriority(pawn, (Pawn)t); } } }
public static bool Prefix(WorkGiver_Scanner __instance, ref bool __result) { bool isPatchAllowed = MainMod.ModConfig.IsPatchAllowed(__instance.GetType()); __result = isPatchAllowed; return(!isPatchAllowed); }
static bool Postfix(bool __result, WorkGiver_Scanner __instance, Pawn pawn, Thing t, bool forced = false) { if (__result && t != null) { return(PrisonLaborUtility.CanWorkHere(t.Position, pawn, __instance.def.workType)); } return(__result); }
public static bool Prefix(ref bool __result, ref WorkGiver_Scanner __instance) { if (!(__instance is WorkGiver_Grower)) { return(true); } __result = true; return(false); }
internal IEnumerable <WorkTarget> PotentialThings(WorkGiver_Scanner workgiver, Pawn pawn) { var potentialThings = workgiver.PotentialWorkThingsGlobal(pawn); if (potentialThings == null) { potentialThings = pawn.Map.listerThings.ThingsMatching(workgiver.PotentialWorkThingRequest); } return(potentialThings.Select(t => new WorkTarget(pawn, t, workgiver))); }
internal IEnumerable <WorkTarget> PotentialCells(WorkGiver_Scanner workgiver, Pawn pawn) { var potentialCells = workgiver.PotentialWorkCellsGlobal(pawn); if (potentialCells?.Any() ?? false) { return(potentialCells.Select(c => new WorkTarget(pawn, c, pawn.Map, workgiver))); } return(EmptyTargetList); }
static IEnumerable <IntVec3> Postfix(IEnumerable <IntVec3> __result, WorkGiver_Scanner __instance, Pawn pawn) { if (__result != null && __instance != null) { return(checkFields(__result, __instance, pawn)); } else { return(__result); } }
public override AcceptanceReport CanDesignateCell(IntVec3 cell) { if (!cell.InBounds(base.Map)) { return(false); } bool success = false; SavedJob savedJob = Memory.savedJob; if (savedJob != null) { if (savedJob.workGiverDef != null) { WorkGiver_Scanner workGiverScanner = savedJob.workGiverDef.Worker as WorkGiver_Scanner; if (workGiverScanner != null) { bool prepared = false; try { prepared = PrepareDesignations(savedJob, cell); success = this.HasJobOnCell(workGiverScanner, cell); cachedCellResults[cell] = success; if (!success) { foreach (Thing thing in cell.GetThingList(base.Map)) { success = HasJobOnThing(workGiverScanner, thing); cachedThingResults[thing] = success; if (success) { break; } } } } finally { if (prepared) { RestoreDesignations(cell); } } } } } return(success); }
private static IEnumerable <Thing> CheckFields(IEnumerable <Thing> __result, WorkGiver_Scanner __instance, Pawn pawn) { foreach (Thing thing in __result) { //Log.Message($"Work type: { __instance.def.workType}, thing is {thing}, value: {PrisonLaborUtility.canWorkHere(thing.Position, pawn, __instance.def.workType)}"); if (thing != null && PrisonLaborUtility.CanWorkHere(thing.Position, pawn, __instance.def.workType)) { // Log.Message($"Work type { __instance.def.workType}, value: {PrisonLaborUtility.canWorkHere(thing.Position, pawn, __instance.def.workType)}"); yield return(thing); } } }
private Job GiverTryGiveJobPrioritized(Pawn pawn, WorkGiver giver, IntVec3 cell) { if (!this.PawnCanUseWorkGiver(pawn, giver)) { return(null); } try { Job job = giver.NonScanJob(pawn); if (job != null) { Job result = job; return(result); } WorkGiver_Scanner scanner = giver as WorkGiver_Scanner; if (scanner != null) { if (giver.def.scanThings) { Predicate <Thing> predicate = (Thing t) => !t.IsForbidden(pawn) && scanner.HasJobOnThing(pawn, t, false); List <Thing> thingList = cell.GetThingList(pawn.Map); for (int i = 0; i < thingList.Count; i++) { Thing thing = thingList[i]; if (scanner.PotentialWorkThingRequest.Accepts(thing) && predicate(thing)) { //pawn.mindState.lastGivenWorkType = giver.def.workType; Job result = scanner.JobOnThing(pawn, thing, false); return(result); } } } if (giver.def.scanCells && !cell.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, cell, false)) { // pawn.mindState.lastGivenWorkType = giver.def.workType; Job result = scanner.JobOnCell(pawn, cell, false); return(result); } } } catch (Exception ex) { Log.Error(string.Concat(new object[] { pawn, " threw exception in GiverTryGiveJobTargeted on WorkGiver ", giver.def.defName, ": ", ex.ToString() })); } return(null); }
private void CreateWrappedScanner() { var scannerType = (def.modExtensions.First(ext => ext is DefModExt_LocalZoneWrapping) as DefModExt_LocalZoneWrapping)?.defToWrap.giverClass; if (scannerType is null) { return; } wrappedScanner = (WorkGiver_Scanner)Activator.CreateInstance(scannerType); wrappedScanner.def = def; }
private bool HasSameJobOnCell(Job job, WorkGiver_Scanner workGiverScanner, LocalTargetInfo targetInfo) { if (HasValidTarget(targetInfo) && !targetInfo.HasThing) { Job getJob = workGiverScanner.JobOnCell(Meeseeks, targetInfo.Cell, true); if (getJob != null && getJob.def == job.def) { return(true); } } return(false); }
static void Postfix(WorkGiver_Scanner __instance, ref bool __result) { if (__instance is WorkGiver_Tend || __instance is WorkGiver_FeedPatient || __instance is WorkGiver_Train || __instance is WorkGiver_PlantsCut || __instance is WorkGiver_GrowerSow || __instance is WorkGiver_GrowerHarvest || __instance is WorkGiver_ConstructFinishFrames || __instance is WorkGiver_RescueDowned) { __result = true; } }
static WorkGiver_Scanner Helper(WorkGiver_Scanner scanner, Pawn pawn) { var aPM = pawn.Map.GetComponent <AreaPriorityManager>(); if (scanner == null) { return(scanner); } if (!aPM.Prioritizations.ContainsKey(scanner.def) || (aPM.Prioritizations [scanner.def]?.disabled ?? true) == true) { return(scanner); } return(new WorkGiver_Scanner_AreaPriorityWrapper(scanner, pawn.Map)); }
private bool HasJobOnThing(WorkGiver_Scanner workGiverScanner, Thing thing) { List <WorkGiver_Scanner> workGivers = WorkerDefUtility.GetCombinedWorkGiverScanners(workGiverScanner); foreach (WorkGiver_Scanner scanner in workGivers) { var potentialWorkThings = scanner.PotentialWorkThingsGlobal(Meeseeks); if ((potentialWorkThings == null || potentialWorkThings.Contains(thing)) && !Memory.jobTargets.Contains(thing) && scanner.HasJobOnThing(Meeseeks, thing, true)) { return(true); } } return(false); }
private bool HasJobOnCell(WorkGiver_Scanner workGiverScanner, IntVec3 cell) { List <WorkGiver_Scanner> workGivers = WorkerDefUtility.GetCombinedWorkGiverScanners(workGiverScanner); foreach (WorkGiver_Scanner scanner in workGivers) { var potentialWorkCells = scanner.PotentialWorkCellsGlobal(Meeseeks); if ((potentialWorkCells == null || potentialWorkCells.Contains(cell)) && !Memory.jobTargets.Contains(cell) && scanner.HasJobOnCell(Meeseeks, cell, true)) { return(true); } } return(false); }
protected Job ScanForJob(Pawn meeseeks, CompMeeseeksMemory memory, SavedJob savedJob, SavedTargetInfo jobTarget, ref JobAvailability jobAvailabilty, bool scanAllThingsOnCell = false) { Job job = null; if (savedJob.workGiverDef != null && savedJob.workGiverDef.Worker != null) { WorkGiver_Scanner workGiverScanner = savedJob.workGiverDef.Worker as WorkGiver_Scanner; if (workGiverScanner != null) { List <WorkGiver_Scanner> workGivers = WorkerDefUtility.GetCombinedWorkGiverScanners(workGiverScanner); foreach (WorkGiver_Scanner scanner in workGivers) { job = this.GetJobOnTarget(meeseeks, jobTarget, scanner, scanAllThingsOnCell); if (job != null) { if (memory.JobStuckRepeat(job)) { Logger.ErrorFormat(this, "Stuck job detected and removed on {0}.", jobTarget); jobAvailabilty = JobAvailability.Delayed; job = null; } else { //Logger.MessageFormat(this, "Job WAS found for {0}.", scanner.def.defName); jobAvailabilty = JobAvailability.Available; return(job); } } //Logger.MessageFormat(this, "No {0} job found.", scanner.def.defName); } } else { Logger.WarningFormat(this, "No work scanner"); } } else { Logger.WarningFormat(this, "Missing saved job workGiverDef or Worker for savedJob: {0}", savedJob.def.defName); } return(job); }
internal IEnumerable <WorkTarget> PotentialTargets(WorkGiver_Scanner workgiver, Pawn pawn) { if (workgiver == null) { Debug.Log($"Trying to get potential targets fron non-scanner"); return(EmptyTargetList); } var potentialTargets = new List <WorkTarget>(); if (workgiver.def.scanThings) { potentialTargets.AddRange(PotentialThings(workgiver, pawn)); } if (workgiver.def.scanCells) { potentialTargets.AddRange(PotentialCells(workgiver, pawn)); } return(potentialTargets); }
public static void Postfix(WorkGiver_Scanner __instance, ref float __result, Pawn pawn, TargetInfo t) { if (!(__instance is WorkGiver_DeepDrill) || !t.HasThing) { return; } IntVec3 drillPos = t.Thing.Position; Map map = pawn.Map; ThingDef def = DeepDrillUtility.GetNextResource(drillPos, map); if (def == null) { return; } float p = WorkGiver_Miner_GetPriority_Patch.Priority(def.deepCommonality, def.deepLumpSizeRange); if (Settings.Get().finishUpDrills) { int count = 0; for (int i = 0; i < 9; i++) { IntVec3 deepPos = drillPos + GenRadial.RadialPattern[i]; if (deepPos.InBounds(map)) { ThingDef thingDef = map.deepResourceGrid.ThingDefAt(deepPos); if (thingDef != null) { count += map.deepResourceGrid.CountAt(deepPos); } } } p -= count / 1000000f; //Less is more! } __result = p; Log.Message($"DeepDrill priority for {t.Thing} is {__result}"); }
private void ProcessCell(IntVec3 c, Pawn pawn, WorkGiver_Scanner scanner, IntVec3 pawnPosition, bool prioritized, bool allowUnreachable, Danger maxPathDanger, ref TargetInfo bestTargetOfLastPriority, ref WorkGiver_Scanner scannerWhoProvidedTarget, ref float closestDistSquared, ref float bestPriority) { bool found = false; float distSquared = (c - pawnPosition).LengthHorizontalSquared; float priority = 0f; if (prioritized) { if (!c.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, c)) { if (!allowUnreachable && !pawn.CanReach(c, scanner.PathEndMode, maxPathDanger)) { return; } priority = scanner.GetPriority(pawn, c); if (priority > bestPriority || (priority == bestPriority && distSquared < closestDistSquared)) { found = true; } } } else if (distSquared < closestDistSquared && !c.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, c)) { if (!allowUnreachable && !pawn.CanReach(c, scanner.PathEndMode, maxPathDanger)) { return; } found = true; } if (found) { bestTargetOfLastPriority = new TargetInfo(c, pawn.Map); scannerWhoProvidedTarget = scanner; closestDistSquared = distSquared; bestPriority = priority; } }
public override AcceptanceReport CanDesignateThing(Thing thing) { bool success = false; SavedJob savedJob = Memory.savedJob; if (savedJob != null) { if (savedJob.workGiverDef != null) { WorkGiver_Scanner workGiverScanner = savedJob.workGiverDef.Worker as WorkGiver_Scanner; if (workGiverScanner != null) { bool prepared = false; try { prepared = PrepareDesignations(savedJob, thing.PositionHeld); if (HasJobOnThing(workGiverScanner, thing)) { success = true; } } finally { if (prepared) { RestoreDesignations(thing.PositionHeld); } } } } } return(success); }
static void AddFirstRegularHaulToTracker(WorkGiver_Scanner __instance, bool __state, Job __result, Pawn pawn, Thing thing) { // restore storage priority if (__state) { StoreUtility.CurrentHaulDestinationOf(thing).GetStoreSettings().Priority += 1; } if (__result == null) { return; } if (!haulToInventory.Value || !enabled.Value) { return; } // JobOnThing() can run additional times (e.g. haulMoreWork toil) so don't assume this is already added if there's a jobCell or destCell var haulTracker = haulTrackers.GetValueSafe(pawn) ?? HaulTracker.CreateAndAdd(SpecialHaulType.None, pawn, IntVec3.Invalid); // thing from parameter because targetA is null because things are in queues instead // https://github.com/Mehni/PickUpAndHaul/blob/af50a05a8ae5ca64d9b95fee8f593cf91f13be3d/Source/PickUpAndHaul/WorkGiver_HaulToInventory.cs#L98 haulTracker.Add(thing, __result.targetB.Cell, false); }