public static Job HaulToStorageJob(Pawn p, Thing t)
        {
            StoragePriority currentPriority = HaulAIUtility.StoragePriorityAtFor(t.Position, t);
            IntVec3         storeCell       = default(IntVec3);

            if (!StoreUtility.TryFindBestBetterStoreCellFor(t, p, p.Map, currentPriority, p.Faction, out storeCell, true))
            {
                JobFailReason.Is(HaulAIUtility.NoEmptyPlaceLowerTrans);
                return(null);
            }
            return(HaulAIUtility.HaulMaxNumToCellJob(p, t, storeCell, false));
        }
예제 #2
0
        public static Job HaulAsideJobFor(Pawn p, Thing t)
        {
            IntVec3 c;

            if (!HaulAIUtility.CanHaulAside(p, t, out c))
            {
                return(null);
            }
            return(new Job(JobDefOf.HaulToCell, t, c)
            {
                count = 99999,
                haulOpportunisticDuplicates = false,
                haulMode = HaulMode.ToCellNonStorage,
                ignoreDesignations = true
            });
        }
예제 #3
0
 internal bool <> m__1(Region r)
 {
     HaulAIUtility.candidates.Clear();
     HaulAIUtility.candidates.AddRange(r.Cells);
     HaulAIUtility.candidates.Sort((IntVec3 a, IntVec3 b) => a.DistanceToSquared(this.center).CompareTo(b.DistanceToSquared(this.center)));
     for (int i = 0; i < HaulAIUtility.candidates.Count; i++)
     {
         IntVec3 c = HaulAIUtility.candidates[i];
         if (HaulAIUtility.HaulablePlaceValidator(this.haulable, this.worker, c))
         {
             this.foundCell = c;
             return(true);
         }
     }
     return(false);
 }
        public static Job HaulAsideJobFor(Pawn p, Thing t)
        {
            IntVec3 c = default(IntVec3);

            if (!HaulAIUtility.CanHaulAside(p, t, out c))
            {
                return(null);
            }
            Job job = new Job(JobDefOf.HaulToCell, t, c);

            job.count = 99999;
            job.haulOpportunisticDuplicates = false;
            job.haulMode           = HaulMode.ToCellNonStorage;
            job.ignoreDesignations = true;
            return(job);
        }
예제 #5
0
        private static bool TryFindSpotToPlaceHaulableCloseTo(Thing haulable, Pawn worker, IntVec3 center, out IntVec3 spot)
        {
            Region region = center.GetRegion(worker.Map, RegionType.Set_Passable);
            bool   result;

            if (region == null)
            {
                spot   = center;
                result = false;
            }
            else
            {
                TraverseParms traverseParms = TraverseParms.For(worker, Danger.Deadly, TraverseMode.ByPawn, false);
                IntVec3       foundCell     = IntVec3.Invalid;
                RegionTraverser.BreadthFirstTraverse(region, (Region from, Region r) => r.Allows(traverseParms, false), delegate(Region r)
                {
                    HaulAIUtility.candidates.Clear();
                    HaulAIUtility.candidates.AddRange(r.Cells);
                    HaulAIUtility.candidates.Sort((IntVec3 a, IntVec3 b) => a.DistanceToSquared(center).CompareTo(b.DistanceToSquared(center)));
                    for (int i = 0; i < HaulAIUtility.candidates.Count; i++)
                    {
                        IntVec3 intVec = HaulAIUtility.candidates[i];
                        if (HaulAIUtility.HaulablePlaceValidator(haulable, worker, intVec))
                        {
                            foundCell = intVec;
                            return(true);
                        }
                    }
                    return(false);
                }, 100, RegionType.Set_Passable);
                if (foundCell.IsValid)
                {
                    spot   = foundCell;
                    result = true;
                }
                else
                {
                    spot   = center;
                    result = false;
                }
            }
            return(result);
        }
 public static bool CanHaulAside(Pawn p, Thing t, out IntVec3 storeCell)
 {
     storeCell = IntVec3.Invalid;
     if (!t.def.EverHaulable)
     {
         return(false);
     }
     if (t.IsBurning())
     {
         return(false);
     }
     if (!p.CanReserveAndReach(t, PathEndMode.ClosestTouch, p.NormalMaxDanger(), 1, -1, null, false))
     {
         return(false);
     }
     if (!HaulAIUtility.TryFindSpotToPlaceHaulableCloseTo(t, p, t.PositionHeld, out storeCell))
     {
         return(false);
     }
     return(true);
 }
예제 #7
0
        public static Job HaulToStorageJob(Pawn p, Thing t)
        {
            StoragePriority  currentPriority = StoreUtility.CurrentStoragePriorityOf(t);
            IntVec3          storeCell;
            IHaulDestination haulDestination;

            if (!StoreUtility.TryFindBestBetterStorageFor(t, p, p.Map, currentPriority, p.Faction, out storeCell, out haulDestination, true))
            {
                JobFailReason.Is(HaulAIUtility.NoEmptyPlaceLowerTrans, null);
                return(null);
            }
            if (haulDestination is ISlotGroupParent)
            {
                return(HaulAIUtility.HaulToCellStorageJob(p, t, storeCell, false));
            }
            Thing thing = haulDestination as Thing;

            if (thing != null && thing.TryGetInnerInteractableThingOwner() != null)
            {
                return(HaulAIUtility.HaulToContainerJob(p, t, thing));
            }
            Log.Error("Don't know how to handle HaulToStorageJob for storage " + haulDestination.ToStringSafe <IHaulDestination>() + ". thing=" + t.ToStringSafe <Thing>(), false);
            return(null);
        }
예제 #8
0
 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)
        {
            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);
        }
예제 #10
0
 public static bool PawnCanAutomaticallyHaulFast(Pawn p, Thing t, bool forced)
 {
     return(HaulAIUtility.PawnCanAutomaticallyHaulBasicChecks(p, t, forced));
 }
예제 #11
0
        public static Toil PlaceHauledThingInCell(TargetIndex cellInd, Toil nextToilOnPlaceFailOrIncomplete, bool storageMode, bool tryStoreInSameStorageIfSpotCantHoldWholeStack = false)
        {
            Toil toil = new Toil();

            toil.initAction = delegate
            {
                Pawn    actor  = toil.actor;
                Job     curJob = actor.jobs.curJob;
                IntVec3 cell   = curJob.GetTarget(cellInd).Cell;
                if (actor.carryTracker.CarriedThing == null)
                {
                    Log.Error(string.Concat(actor, " tried to place hauled thing in cell but is not hauling anything."));
                }
                else
                {
                    SlotGroup slotGroup = actor.Map.haulDestinationManager.SlotGroupAt(cell);
                    if (slotGroup != null && slotGroup.Settings.AllowedToAccept(actor.carryTracker.CarriedThing))
                    {
                        actor.Map.designationManager.TryRemoveDesignationOn(actor.carryTracker.CarriedThing, DesignationDefOf.Haul);
                    }
                    Action <Thing, int> placedAction = null;
                    if (curJob.def == JobDefOf.DoBill || curJob.def == JobDefOf.RefuelAtomic || curJob.def == JobDefOf.RearmTurretAtomic)
                    {
                        placedAction = delegate(Thing th, int added)
                        {
                            if (curJob.placedThings == null)
                            {
                                curJob.placedThings = new List <ThingCountClass>();
                            }
                            ThingCountClass thingCountClass = curJob.placedThings.Find((ThingCountClass x) => x.thing == th);
                            if (thingCountClass != null)
                            {
                                thingCountClass.Count += added;
                            }
                            else
                            {
                                curJob.placedThings.Add(new ThingCountClass(th, added));
                            }
                        };
                    }
                    if (!actor.carryTracker.TryDropCarriedThing(cell, ThingPlaceMode.Direct, out var _, placedAction))
                    {
                        if (storageMode)
                        {
                            if (nextToilOnPlaceFailOrIncomplete != null && ((tryStoreInSameStorageIfSpotCantHoldWholeStack && StoreUtility.TryFindBestBetterStoreCellForIn(actor.carryTracker.CarriedThing, actor, actor.Map, StoragePriority.Unstored, actor.Faction, cell.GetSlotGroup(actor.Map), out var foundCell)) || StoreUtility.TryFindBestBetterStoreCellFor(actor.carryTracker.CarriedThing, actor, actor.Map, StoragePriority.Unstored, actor.Faction, out foundCell)))
                            {
                                if (actor.CanReserve(foundCell))
                                {
                                    actor.Reserve(foundCell, actor.CurJob);
                                }
                                actor.CurJob.SetTarget(cellInd, foundCell);
                                actor.jobs.curDriver.JumpToToil(nextToilOnPlaceFailOrIncomplete);
                            }
                            else
                            {
                                Job job = HaulAIUtility.HaulAsideJobFor(actor, actor.carryTracker.CarriedThing);
                                if (job != null)
                                {
                                    curJob.targetA = job.targetA;
                                    curJob.targetB = job.targetB;
                                    curJob.targetC = job.targetC;
                                    curJob.count   = job.count;
                                    curJob.haulOpportunisticDuplicates = job.haulOpportunisticDuplicates;
                                    curJob.haulMode = job.haulMode;
                                    actor.jobs.curDriver.JumpToToil(nextToilOnPlaceFailOrIncomplete);
                                }
                                else
                                {
                                    Log.Error(string.Concat("Incomplete haul for ", actor, ": Could not find anywhere to put ", actor.carryTracker.CarriedThing, " near ", actor.Position, ". Destroying. This should never happen!"));
                                    actor.carryTracker.CarriedThing.Destroy();
                                }
                            }
                        }
예제 #12
0
        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);
        }
예제 #13
0
        public static Toil PlaceHauledThingInCell(TargetIndex cellInd, Toil nextToilOnPlaceFailOrIncomplete, bool storageMode)
        {
            Toil toil = new Toil();

            toil.initAction = delegate
            {
                Pawn    actor  = toil.actor;
                Job     curJob = actor.jobs.curJob;
                IntVec3 cell   = curJob.GetTarget(cellInd).Cell;
                if (actor.carryTracker.CarriedThing == null)
                {
                    Log.Error(actor + " tried to place hauled thing in cell but is not hauling anything.");
                }
                else
                {
                    SlotGroup slotGroup = actor.Map.slotGroupManager.SlotGroupAt(cell);
                    if (slotGroup != null && slotGroup.Settings.AllowedToAccept(actor.carryTracker.CarriedThing))
                    {
                        actor.Map.designationManager.RemoveAllDesignationsOn(actor.carryTracker.CarriedThing, false);
                    }
                    Action <Thing, int> placedAction = null;
                    if (curJob.def == JobDefOf.DoBill)
                    {
                        placedAction = delegate(Thing th, int added)
                        {
                            if (curJob.placedThings == null)
                            {
                                curJob.placedThings = new List <ThingStackPartClass>();
                            }
                            ThingStackPartClass thingStackPartClass = curJob.placedThings.Find((ThingStackPartClass x) => x.thing == th);
                            if (thingStackPartClass != null)
                            {
                                thingStackPartClass.Count += added;
                            }
                            else
                            {
                                curJob.placedThings.Add(new ThingStackPartClass(th, added));
                            }
                        };
                    }
                    Thing thing = default(Thing);
                    if (!actor.carryTracker.TryDropCarriedThing(cell, ThingPlaceMode.Direct, out thing, placedAction))
                    {
                        if (storageMode)
                        {
                            IntVec3 c = default(IntVec3);
                            if (nextToilOnPlaceFailOrIncomplete != null && StoreUtility.TryFindBestBetterStoreCellFor(actor.carryTracker.CarriedThing, actor, actor.Map, StoragePriority.Unstored, actor.Faction, out c, true))
                            {
                                if (actor.CanReserve(c, 1, -1, null, false))
                                {
                                    actor.Reserve(c, actor.CurJob, 1, -1, null);
                                }
                                actor.CurJob.SetTarget(cellInd, c);
                                actor.jobs.curDriver.JumpToToil(nextToilOnPlaceFailOrIncomplete);
                            }
                            else
                            {
                                Job job = HaulAIUtility.HaulAsideJobFor(actor, actor.carryTracker.CarriedThing);
                                if (job != null)
                                {
                                    curJob.targetA = job.targetA;
                                    curJob.targetB = job.targetB;
                                    curJob.targetC = job.targetC;
                                    curJob.count   = job.count;
                                    curJob.haulOpportunisticDuplicates = job.haulOpportunisticDuplicates;
                                    curJob.haulMode = job.haulMode;
                                    actor.jobs.curDriver.JumpToToil(nextToilOnPlaceFailOrIncomplete);
                                }
                                else
                                {
                                    Log.Error("Incomplete haul for " + actor + ": Could not find anywhere to put " + actor.carryTracker.CarriedThing + " near " + actor.Position + ". Destroying. This should never happen!");
                                    actor.carryTracker.CarriedThing.Destroy(DestroyMode.Vanish);
                                }
                            }
                        }
                        else if (nextToilOnPlaceFailOrIncomplete != null)
                        {
                            actor.jobs.curDriver.JumpToToil(nextToilOnPlaceFailOrIncomplete);
                        }
                    }
                }
            };
            return(toil);
        }