public Job TryOpportunisticJob(Job job) { Job result; if (this.pawn.def.race.intelligence < Intelligence.Humanlike) { result = null; } else if (this.pawn.Faction != Faction.OfPlayer) { result = null; } else if (this.pawn.Drafted) { result = null; } else if (job.playerForced) { result = null; } else if (this.pawn.RaceProps.intelligence < Intelligence.Humanlike) { result = null; } else if (!job.def.allowOpportunisticPrefix) { result = null; } else if (this.pawn.story.WorkTagIsDisabled(WorkTags.ManualDumb | WorkTags.Hauling)) { result = null; } else if (this.pawn.InMentalState) { result = null; } else { IntVec3 cell = job.targetA.Cell; if (!cell.IsValid) { result = null; } else { float num = this.pawn.Position.DistanceTo(cell); if (num < AITuning.OpportunisticJobMinDistPawnToDest) { result = null; } else { List <Thing> list = this.pawn.Map.listerHaulables.ThingsPotentiallyNeedingHauling(); for (int i = 0; i < list.Count; i++) { Thing thing = list[i]; if (this.pawn.Map.reservationManager.FirstRespectedReserver(thing, this.pawn) == null) { float num2 = this.pawn.Position.DistanceTo(thing.Position); if (num2 <= AITuning.OpportunisticJobMaxDistPawnToItem) { if (num2 <= num * AITuning.OpportunisticJobMaxPickupDistanceFactor) { if (num2 + thing.Position.DistanceTo(cell) <= num * AITuning.OpportunisticJobMaxRatioOppHaulDistanceToDestDistance) { if (HaulAIUtility.PawnCanAutomaticallyHaulFast(this.pawn, thing, false)) { StoragePriority currentPriority = StoreUtility.CurrentStoragePriorityOf(thing); IntVec3 invalid = IntVec3.Invalid; if (StoreUtility.TryFindBestBetterStoreCellFor(thing, this.pawn, this.pawn.Map, currentPriority, this.pawn.Faction, out invalid, true)) { float num3 = invalid.DistanceTo(cell); if (num3 <= AITuning.OpportunisticJobMaxDistDestToDropoff) { if (num3 <= num * AITuning.OpportunisticJobMaxDistDestToDropoffFactor) { if (num2 + thing.Position.DistanceTo(invalid) + num3 <= num * AITuning.OpportunisticJobMaxRatioOppHaulDistanceToDestDistance) { if (num2 + num3 <= num) { if (this.pawn.Position.WithinRegions(thing.Position, this.pawn.Map, AITuning.OpportunisticJobMaxPickupRegions, TraverseParms.For(this.pawn, Danger.Deadly, TraverseMode.ByPawn, false), RegionType.Set_Passable)) { if (invalid.WithinRegions(cell, this.pawn.Map, AITuning.OpportunisticJobMaxDropoffRegions, TraverseParms.For(this.pawn, Danger.Deadly, TraverseMode.ByPawn, false), RegionType.Set_Passable)) { if (DebugViewSettings.drawOpportunisticJobs) { Log.Message("Opportunistic job spawned", false); this.pawn.Map.debugDrawer.FlashLine(this.pawn.Position, thing.Position, 600, SimpleColor.Red); this.pawn.Map.debugDrawer.FlashLine(thing.Position, invalid, 600, SimpleColor.Green); this.pawn.Map.debugDrawer.FlashLine(invalid, cell, 600, SimpleColor.Blue); } return(HaulAIUtility.HaulToCellStorageJob(this.pawn, thing, invalid, false)); } } } } } } } } } } } } } result = null; } } } return(result); }
public static bool PawnCanAutomaticallyHaul(Pawn p, Thing t, bool forced) { if (!t.def.EverHaulable) { return(false); } if (t.IsForbidden(p)) { if (!t.Position.InAllowedArea(p)) { JobFailReason.Is(HaulAIUtility.ForbiddenOutsideAllowedAreaLowerTrans, null); } else { JobFailReason.Is(HaulAIUtility.ForbiddenLowerTrans, null); } return(false); } return((t.def.alwaysHaulable || t.Map.designationManager.DesignationOn(t, DesignationDefOf.Haul) != null || t.IsInValidStorage()) && HaulAIUtility.PawnCanAutomaticallyHaulFast(p, t, forced)); }
public Job TryOpportunisticJob(Job job) { if ((int)pawn.def.race.intelligence < 2) { return(null); } if (pawn.Faction != Faction.OfPlayer) { return(null); } if (pawn.Drafted) { return(null); } if (job.playerForced) { return(null); } if ((int)pawn.RaceProps.intelligence < 2) { return(null); } if (!job.def.allowOpportunisticPrefix) { return(null); } if (pawn.WorkTagIsDisabled(WorkTags.ManualDumb | WorkTags.Hauling)) { return(null); } if (pawn.InMentalState || pawn.IsBurning()) { return(null); } IntVec3 cell = job.targetA.Cell; if (!cell.IsValid || cell.IsForbidden(pawn)) { return(null); } float num = pawn.Position.DistanceTo(cell); if (num < 3f) { return(null); } List <Thing> list = pawn.Map.listerHaulables.ThingsPotentiallyNeedingHauling(); for (int i = 0; i < list.Count; i++) { Thing thing = list[i]; float num2 = pawn.Position.DistanceTo(thing.Position); if (num2 > 30f || num2 > num * 0.5f || num2 + thing.Position.DistanceTo(cell) > num * 1.7f || pawn.Map.reservationManager.FirstRespectedReserver(thing, pawn) != null || thing.IsForbidden(pawn) || !HaulAIUtility.PawnCanAutomaticallyHaulFast(pawn, thing, forced: false)) { continue; } StoragePriority currentPriority = StoreUtility.CurrentStoragePriorityOf(thing); IntVec3 foundCell = IntVec3.Invalid; if (!StoreUtility.TryFindBestBetterStoreCellFor(thing, pawn, pawn.Map, currentPriority, pawn.Faction, out foundCell)) { continue; } float num3 = foundCell.DistanceTo(cell); if (!(num3 > 50f) && !(num3 > num * 0.6f) && !(num2 + thing.Position.DistanceTo(foundCell) + num3 > num * 1.7f) && !(num2 + num3 > num) && pawn.Position.WithinRegions(thing.Position, pawn.Map, 25, TraverseParms.For(pawn)) && foundCell.WithinRegions(cell, pawn.Map, 25, TraverseParms.For(pawn))) { if (DebugViewSettings.drawOpportunisticJobs) { Log.Message("Opportunistic job spawned"); pawn.Map.debugDrawer.FlashLine(pawn.Position, thing.Position, 600, SimpleColor.Red); pawn.Map.debugDrawer.FlashLine(thing.Position, foundCell, 600, SimpleColor.Green); pawn.Map.debugDrawer.FlashLine(foundCell, cell, 600, SimpleColor.Blue); } return(HaulAIUtility.HaulToCellStorageJob(pawn, thing, foundCell, fitInStoreCell: false)); } } return(null); }