public static Toil CheckDuplicates(Toil jumpToil, TargetIndex CarrierInd, TargetIndex HaulableInd)
        {
            Toil toil = new Toil();

            toil.initAction = () =>
            {
                IntVec3 storeCell = IntVec3.Invalid;
                Pawn    actor     = toil.GetActor();

                TargetInfo target = toil.actor.jobs.curJob.GetTarget(HaulableInd);
                if (target.Thing.def.stackLimit <= 1)
                {
                    return;
                }
                List <TargetInfo> targetQueue = toil.actor.jobs.curJob.GetTargetQueue(HaulableInd);
                if (!targetQueue.NullOrEmpty() && target.Thing.def.defName == targetQueue.First().Thing.def.defName)
                {
                    toil.actor.jobs.curJob.SetTarget(HaulableInd, targetQueue.First());
                    Find.Reservations.Reserve(actor, targetQueue.First());
                    targetQueue.RemoveAt(0);
                    toil.actor.jobs.curDriver.JumpToToil(jumpToil);
                    return;
                }
                Vehicle_Cart     cart     = toil.actor.jobs.curJob.GetTarget(CarrierInd).Thing as Vehicle_Cart;
                Apparel_Backpack backpack = toil.actor.jobs.curJob.GetTarget(CarrierInd).Thing as Apparel_Backpack;

                if (cart == null && backpack == null)
                {
                    Log.Error(actor.LabelCap + " Report: Don't have Carrier");
                    toil.actor.jobs.curDriver.EndJobWith(JobCondition.Errored);
                    return;
                }
                int curItemCount = (cart != null ? cart.storage.Count : backpack.slotsComp.slots.Count) + targetQueue.Count;
                int curItemStack = (cart != null ? cart.storage.TotalStackCount : backpack.slotsComp.slots.TotalStackCount)
                                   + targetQueue.Sum(item => item.Thing.stackCount);
                int maxItem  = cart != null ? cart.MaxItem : backpack.MaxItem;
                int maxStack = cart != null ? cart.MaxStack : backpack.MaxStack;
                if (curItemCount >= maxItem || curItemStack >= maxStack)
                {
                    return;
                }
                //Check target's nearby
                Thing thing = GenClosest.ClosestThing_Global_Reachable(actor.Position,
                                                                       ListerHaulables.ThingsPotentiallyNeedingHauling(),
                                                                       PathEndMode.Touch,
                                                                       TraverseParms.For(actor, Danger.Some),
                                                                       NearbyCell,
                                                                       item => !targetQueue.Contains(item) &&
                                                                       item.def.defName == target.Thing.def.defName &&
                                                                       !item.IsBurning() &&
                                                                       Find.Reservations.CanReserve(actor, item));
                if (thing != null)
                {
                    toil.actor.jobs.curJob.SetTarget(HaulableInd, thing);
                    Find.Reservations.Reserve(actor, thing);
                    toil.actor.jobs.curDriver.JumpToToil(jumpToil);
                }
            };
            return(toil);
        }
        public override Job JobOnThing(Pawn pawn, Thing t)
        {
            Vehicle_Cart cart = t as Vehicle_Cart;

            if (cart == null)
            {
                return((Job)null);
            }
            if (cart.IsForbidden(pawn.Faction) || !ReservationUtility.CanReserveAndReach(pawn, cart, PathEndMode.ClosestTouch, DangerUtility.NormalMaxDanger(pawn)))
            {
                return((Job)null);
            }
            if (FireUtility.IsBurning(cart))
            {
                JobFailReason.Is(ToolsForHaulUtility.BurningLowerTrans);
                return((Job)null);
            }
            if (ListerHaulables.ThingsPotentiallyNeedingHauling().Count == 0 && cart.storage.Count == 0)
            {
                JobFailReason.Is(ToolsForHaulUtility.NoHaulable);
                return((Job)null);
            }
            if (Find.SlotGroupManager.AllGroupsListInPriorityOrder.Count == 0)
            {
                JobFailReason.Is(ToolsForHaulUtility.NoEmptyPlaceLowerTrans);
                return((Job)null);
            }
            if (ToolsForHaulUtility.AvailableAnimalCart(cart) || ToolsForHaulUtility.AvailableCart(cart, pawn))
            {
                return(ToolsForHaulUtility.HaulWithTools(pawn, cart));
            }
            JobFailReason.Is(ToolsForHaulUtility.NoAvailableCart);
            return((Job)null);
        }
 public override bool ShouldSkip(Pawn pawn)
 {
     // Ticker for checking special hauling cases of filling stacks in containers from stockpiles
     CFS_ListerHaulables.ListerHaulablesTick();
     FindHaulablesInsideContainers();
     // Skip if no haulables in any list (ListerHaulables.ThingsPotentiallyNeedingHauling() will still count things inside container as hauling required, but they won't be hauled because of future checks)
     return(ListerHaulables.ThingsPotentiallyNeedingHauling().Count == 0 && haulables_blockedInListerHaulables.Count == 0 && haulables_insideContainers.Count == 0 && CFS_ListerHaulables.haulables.Count == 0);
 }
Example #4
0
 private static bool Check(ListerHaulables __instance, Thing t)
 {
     lock (Locker)
     {
         Check_Internal(__instance, t);
     }
     return(false);
 }
Example #5
0
 private static bool ThingsPotentiallyNeedingHauling(ListerHaulables __instance, ref List <Thing> __result)
 {
     lock (Locker)
     {
         __result = new List <Thing>(__instance.haulables);
         //__result = __instance.haulables;
     }
     return(false);
 }
        // Loading ctor
        public FactionMapData(Map map)
        {
            this.map = map;

            haulDestinationManager = new HaulDestinationManager(map);
            listerHaulables        = new ListerHaulables(map);
            resourceCounter        = new ResourceCounter(map);
            listerFilthInHomeArea  = new ListerFilthInHomeArea(map);
        }
Example #7
0
        static void Postfix(Thing t, ListerHaulables __instance)
        {
            Map map = MapFieldInfo.GetValue(__instance) as Map;

            if (map == null)
            {
                throw new Exception($"Could not get map to despawn {t.Label} from...");
            }

            map.listerStackables().TryRemove(t);
        }
Example #8
0
 private static bool TryRemove(ListerHaulables __instance, Thing t)
 {
     lock (Locker)
     {
         if (t.def.category == ThingCategory.Item && __instance.haulables.Contains(t))
         {
             __instance.haulables.Remove(t);
         }
     }
     return(false);
 }
Example #9
0
        static void Postfix(SlotGroup sg, ListerHaulables __instance)
        {
            Map map = MapFieldInfo.GetValue(__instance) as Map;

            if (map == null)
            {
                throw new Exception($"Could not get map to change {sg.parent.SlotYielderLabel()} on...");
            }

            map.listerStackables().Update(sg);
        }
 public override IEnumerable <Thing> PotentialWorkThingsGlobal(Pawn pawn)
 {
     /* Required, because ListerHaulables removes things from haulables list, which are not fit in SlotGroups (can't stack things).
      * So i preserve the original list before it's changed after the first item is hauled to the destination point.
      */
     if (ListerHaulables.ThingsPotentiallyNeedingHauling().Count >= haulables_blockedInListerHaulables.Count)
     {
         haulables_blockedInListerHaulables = new List <Thing>(ListerHaulables.ThingsPotentiallyNeedingHauling());
     }
     // Merge all the required lists of haulables (original, blocked, inside containers and which are not counted at all, if containers already partially full (CFS_ListerHaulables.haulables), to fill the incomplete stacks)
     return(ListerHaulables.ThingsPotentiallyNeedingHauling().Union(haulables_blockedInListerHaulables).Union(haulables_insideContainers).Union(CFS_ListerHaulables.haulables).ToList());
 }
Example #11
0
        private static bool CheckAdd(ListerHaulables __instance, Thing t)
        {
            lock (Locker)
            {
                if (__instance.ShouldBeHaulable(t) && !__instance.haulables.Contains(t))
                {
                    __instance.haulables.Add(t);
                }
            }

            return(false);
        }
Example #12
0
 public static bool ShouldBeHaulableExt(this ListerHaulables lh,
                                        Thing t, bool will_toggle_haul_des = false)
 {
     if (t.IsForbidden(Faction.OfPlayer) || t.IsInValidBestStorage())
     {
         return(false);
     }
     if (will_toggle_haul_des)
     {
         return(t.IsAHaulableSetToUnhaulable());
     }
     return(t.IsAHaulableSetToHaulable());
 }
Example #13
0
 // internal check without lock object
 private static void Check_Internal(ListerHaulables lister, Thing t)
 {
     if (lister.ShouldBeHaulable(t))
     {
         if (!lister.haulables.Contains(t))
         {
             lister.haulables.Add(t);
         }
     }
     else if (lister.haulables.Contains(t))
     {
         lister.haulables.Remove(t);
     }
 }
Example #14
0
        // patch: ListerHaulablesTick replacement in thread
        private static void ListerHaulablesTick_New(this ListerHaulables lister)
        {
            ListerHaulables.groupCycleIndex++;

            if (ListerHaulables.groupCycleIndex >= int.MaxValue)
            {
                ListerHaulables.groupCycleIndex = 0;
            }

            var allGroupsListForReading = lister.map.haulDestinationManager.AllGroupsListForReading;

            if (allGroupsListForReading.Count == 0)
            {
                return;
            }

            var index     = ListerHaulables.groupCycleIndex % allGroupsListForReading.Count;
            var slotGroup = allGroupsListForReading[ListerHaulables.groupCycleIndex % allGroupsListForReading.Count];

            if (slotGroup.CellsList.Count != 0)
            {
                while (lister.cellCycleIndices.Count <= index)
                {
                    lister.cellCycleIndices.Add(0);
                }
                if (lister.cellCycleIndices[index] >= int.MaxValue)
                {
                    lister.cellCycleIndices[index] = 0;
                }

                for (var i = 0; i < 4; i++)
                {
                    var list = lister.cellCycleIndices;
                    list[index]++;
                    var thingList = slotGroup.CellsList[lister.cellCycleIndices[index] % slotGroup.CellsList.Count].GetThingList(lister.map)
                                    .ToList(); // Make copy of the list. Prevent System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
                    foreach (var thing in thingList)
                    {
                        if (thing.def.EverHaulable)
                        {
                            // this.Check(thingList[j]);
                            Check_Internal(lister, thing);
                            /* LWM.DeepStorage remove this break in transpiler */
                            // break;
                        }
                    }
                }
            }
        }
        public override IEnumerable <Thing> PotentialWorkThingsGlobal(Pawn pawn)
        {
            List <Thing>     list     = new List <Thing>();
            Apparel_Backpack backpack = ToolsForHaulUtility.TryGetBackpack(pawn);

            foreach (Thing thing in ListerHaulables.ThingsPotentiallyNeedingHauling())
            {
                if (thing.def.thingCategories.Exists(category => backpack.slotsComp.Properties.allowedThingCategoryDefs.Exists(subCategory => subCategory.ThisAndChildCategoryDefs.Contains(category)) && !backpack.slotsComp.Properties.forbiddenSubThingCategoryDefs.Exists(subCategory => subCategory.ThisAndChildCategoryDefs.Contains(category))))
                {
                    list.Add(thing);
                }
                //return ToolsForHaulUtility.Cart();
            }
            return(list);
        }
        public override bool ShouldSkip(Pawn pawn)
        {
            Trace.DebugWriteHaulingPawn(pawn);
            //Don't have haulables.
            if (ListerHaulables.ThingsPotentiallyNeedingHauling().Count == 0)
            {
                return(true);
            }

            //Should skip pawn that don't have backpack.
            if (ToolsForHaulUtility.TryGetBackpack(pawn) == null)
            {
                return(true);
            }
            return(false);
        }
Example #17
0
        static bool Prefix(Thing t, ListerHaulables __instance)
        {
            bool shouldhave = t.SpawnedOrAnyParentSpawned &&
                              __instance.ShouldBeHaulableExt(t, true);
            List <Thing> haulables =
                (List <Thing>) typeof(ListerHaulables).InvokeMember("haulables",
                                                                    BindingFlags.GetField | BindingFlags.Instance | BindingFlags.NonPublic,
                                                                    null, __instance, null);

            if (shouldhave != haulables.Contains(t))
            {
                if (shouldhave)
                {
                    haulables.Add(t);
                }
                else
                {
                    haulables.Remove(t);
                }
            }
            return(false);
        }
        public static Job HaulWithTools(Pawn pawn, Vehicle_Cart cart = null)
        {
            Trace.stopWatchStart();

            //Job Setting
            JobDef              jobDef;
            TargetInfo          targetC;
            int                 maxItem;
            int                 thresholdItem;
            int                 reservedMaxItem;
            IEnumerable <Thing> remainingItems;
            bool                ShouldDrop;
            Thing               lastItem = ToolsForHaulUtility.TryGetBackpackLastItem(pawn);

            if (cart == null)
            {
                Apparel_Backpack backpack = ToolsForHaulUtility.TryGetBackpack(pawn);
                jobDef          = jobDefHaulWithBackpack;
                targetC         = backpack;
                maxItem         = backpack.MaxItem;
                thresholdItem   = (int)Math.Ceiling(maxItem * 0.5);
                reservedMaxItem = pawn.inventory.container.Count;
                remainingItems  = pawn.inventory.container;
                ShouldDrop      = true;
                if (lastItem != null)
                {
                    for (int i = 0; i < pawn.inventory.container.Count; i++)
                    {
                        if (pawn.inventory.container[i] == lastItem && (reservedMaxItem - (i + 1)) <= 0)
                        {
                            ShouldDrop = false;
                            break;
                        }
                    }
                }
            }
            else
            {
                jobDef = (cart.TryGetComp <CompMountable>().IsMounted&& cart.TryGetComp <CompMountable>().Driver.RaceProps.Animal)?
                         jobDefHaulWithAnimalCart : jobDefHaulWithCart;
                targetC         = cart;
                maxItem         = cart.MaxItem;
                thresholdItem   = (int)Math.Ceiling(maxItem * 0.5);
                reservedMaxItem = cart.storage.Count;
                remainingItems  = cart.storage;
                ShouldDrop      = (reservedMaxItem > 0) ? true : false;
            }
            Job job = new Job(jobDef);

            job.targetQueueA = new List <TargetInfo>();
            job.targetQueueB = new List <TargetInfo>();
            job.targetC      = targetC;

            Trace.AppendLine(pawn.LabelCap + " In HaulWithTools: " + jobDef.defName + "\n"
                             + "MaxItem: " + maxItem + " reservedMaxItem: " + reservedMaxItem);

            //Drop remaining item
            if (ShouldDrop)
            {
                Trace.AppendLine("Start Drop remaining item");
                bool startDrop = false;
                for (int i = 0; i < remainingItems.Count(); i++)
                {
                    if (cart == null && startDrop == false)
                    {
                        if (remainingItems.ElementAt(i) == lastItem)
                        {
                            startDrop = true;
                        }
                        else
                        {
                            continue;
                        }
                    }
                    IntVec3 storageCell = FindStorageCell(pawn, remainingItems.ElementAt(i), job.targetQueueB);
                    if (storageCell == IntVec3.Invalid)
                    {
                        break;
                    }
                    job.targetQueueB.Add(storageCell);
                }
                if (!job.targetQueueB.NullOrEmpty())
                {
                    Trace.AppendLine("Droping Job is issued");
                    Trace.LogMessage();
                    return(job);
                }
                if (cart != null && job.def == jobDefHaulWithCart && !cart.IsInValidStorage())
                {
                    Trace.AppendLine("In DismountInBase");
                    return(DismountInBase(pawn, cart));
                }
                JobFailReason.Is(ToolsForHaulUtility.NoEmptyPlaceLowerTrans);
                Trace.AppendLine("End Drop remaining item");
                Trace.AppendLine("No Job. Reason: " + JobFailReason.Reason);
                Trace.LogMessage();
                return((Job)null);
            }

            //Collect item
            Trace.AppendLine("Start Collect item");
            IntVec3 searchPos = (cart != null) ? cart.Position : pawn.Position;
            bool    flag1     = false;

            foreach (SlotGroup slotGroup in Find.SlotGroupManager.AllGroupsListInPriorityOrder)
            {
                Trace.AppendLine("Start searching slotGroup");
                if (slotGroup.CellsList.Count() - slotGroup.HeldThings.Count() < maxItem)
                {
                    continue;
                }

                //Counting valid items
                Trace.AppendLine("Start Counting valid items");
                int thingsCount = ListerHaulables.ThingsPotentiallyNeedingHauling().Count(item => slotGroup.Settings.AllowedToAccept(item));

                //Finding valid items
                Trace.AppendLine("Start Finding valid items");
                if (thingsCount > thresholdItem)
                {
                    //ClosestThing_Global_Reachable Configuration
                    Predicate <Thing> predicate = item
                                                  => !job.targetQueueA.Contains(item) && !FireUtility.IsBurning(item) &&
                                                  ((cart != null && cart.allowances.Allows(item)) || cart == null) &&
                                                  slotGroup.Settings.AllowedToAccept(item) &&
                                                  pawn.CanReserveAndReach(item, PathEndMode.Touch, DangerUtility.NormalMaxDanger(pawn));
                    //&& !(item is UnfinishedThing && ((UnfinishedThing)item).BoundBill != null)
                    //&& (item.def.IsNutritionSource && !SocialProperness.IsSociallyProper(item, pawn, false, false));
                    Thing thing = GenClosest.ClosestThing_Global_Reachable(searchPos,
                                                                           ListerHaulables.ThingsPotentiallyNeedingHauling(),
                                                                           PathEndMode.ClosestTouch,
                                                                           TraverseParms.For(TraverseMode.ByPawn, DangerUtility.NormalMaxDanger(pawn)),
                                                                           9999,
                                                                           predicate);
                    if (thing == null)
                    {
                        continue;
                    }
                    IntVec3 center = thing.Position;

                    //Enqueue items in valid distance
                    Trace.AppendLine("Start Enqueuing items in valid distance");
                    foreach (Thing item in ListerHaulables.ThingsPotentiallyNeedingHauling().Where(item
                                                                                                   => !job.targetQueueA.Contains(item) && !FireUtility.IsBurning(item) &&
                                                                                                   ((cart != null && cart.allowances.Allows(item)) || cart == null) &&
                                                                                                   slotGroup.Settings.AllowedToAccept(item) &&
                                                                                                   pawn.CanReserveAndReach(item, PathEndMode.Touch, DangerUtility.NormalMaxDanger(pawn)) &&
                                                                                                   center.DistanceToSquared(item.Position) <= ValidDistance))
                    {
                        job.targetQueueA.Add(item);
                        if (reservedMaxItem + job.targetQueueA.Count >= maxItem)
                        {
                            break;
                        }
                    }

                    //Find storage cell
                    Trace.AppendLine("Start Finding storage cell");
                    if (reservedMaxItem + job.targetQueueA.Count > thresholdItem)
                    {
                        List <IntVec3> availableCells = new List <IntVec3>();
                        foreach (IntVec3 cell in slotGroup.CellsList.Where(cell => ReservationUtility.CanReserve(pawn, cell) && cell.Standable() && cell.GetStorable() == null))
                        {
                            job.targetQueueB.Add(cell);
                            if (job.targetQueueB.Count >= job.targetQueueA.Count)
                            {
                                break;
                            }
                        }
                        flag1 = true;
                        break;
                    }
                    else
                    {
                        job.targetQueueA.Clear();
                    }
                }
                if (flag1)
                {
                    break;
                }
            }
            Trace.AppendLine("Elapsed Time");
            Trace.stopWatchStop();

            //Check job is valid
            if (!job.targetQueueA.NullOrEmpty() && reservedMaxItem + job.targetQueueA.Count > thresholdItem &&
                !job.targetQueueB.NullOrEmpty())
            {
                Trace.AppendLine("Hauling Job is issued");
                Trace.LogMessage();
                return(job);
            }
            if (cart != null && job.def == jobDefHaulWithCart && !cart.IsInValidStorage())
            {
                Trace.AppendLine("In DismountInBase: ");
                return(DismountInBase(pawn, cart));
            }

            if (job.targetQueueA.NullOrEmpty())
            {
                JobFailReason.Is(ToolsForHaulUtility.NoHaulable);
            }
            else if (reservedMaxItem + job.targetQueueA.Count <= thresholdItem)
            {
                JobFailReason.Is(ToolsForHaulUtility.TooLittleHaulable);
            }
            else if (job.targetQueueB.NullOrEmpty())
            {
                JobFailReason.Is(ToolsForHaulUtility.NoEmptyPlaceLowerTrans);
            }
            Trace.AppendLine("No Job. Reason: " + JobFailReason.Reason);
            Trace.LogMessage();
            return((Job)null);
        }
Example #19
0
 public override IEnumerable <Thing> PotentialWorkThingsGlobal(Pawn pawn)
 {
     //return ToolsForHaulUtility.Cart();
     return(ListerHaulables.ThingsPotentiallyNeedingHauling());
 }
Example #20
0
        internal void _SpawnSetup()
        {
            if (this.Destroyed)
            {
                Log.Error(string.Concat(new object[]
                {
                    "Spawning destroyed thing ",
                    this,
                    " at ",
                    this.Position,
                    ". Correcting."
                }));
                SetThingStateInt(this, ThingState.Unspawned);
                if (this.HitPoints <= 0 && this.def.useHitPoints)
                {
                    this.HitPoints = 1;
                }
            }
            if (this.Spawned)
            {
                Log.Error(string.Concat(new object[]
                {
                    "Tried to spawn already-spawned thing ",
                    this,
                    " at ",
                    this.Position
                }));
                return;
            }

            this.holder = null;
            SetThingStateInt(this, ThingState.Spawned);
            Find.Map.listerThings.Add(this);
            if (Find.TickManager != null)
            {
                Find.TickManager.RegisterAllTickabilityFor(this);
            }
            if (this.def.drawerType != DrawerType.RealtimeOnly)
            {
                CellRect.CellRectIterator iterator = this.OccupiedRect().GetIterator();
                while (!iterator.Done())
                {
                    Find.Map.mapDrawer.MapMeshDirty(iterator.Current, MapMeshFlag.Things);
                    iterator.MoveNext();
                }
            }
            if (this.def.drawerType != DrawerType.MapMeshOnly)
            {
                Find.DynamicDrawManager.RegisterDrawable(this);
            }
            if (this.def.hasTooltip)
            {
                Find.TooltipGiverList.RegisterTooltipGiver(this);
            }
            if (this.def.graphicData != null && this.def.graphicData.Linked)
            {
                LinkGrid.Notify_LinkerCreatedOrDestroyed(this);
                Find.MapDrawer.MapMeshDirty(this.Position, MapMeshFlag.Things, true, false);
            }
            if (!this.def.CanOverlapZones)
            {
                rNotify_NoZoneOverlapThingSpawned(this);
            }
            if (this.def.regionBarrier)
            {
                rNotify_BarrierSpawned(this);
            }
            if (this.def.pathCost != 0 || this.def.passability == Traversability.Impassable)
            {
                Find.PathGrid.RecalculatePerceivedPathCostUnderThing(this);
            }
            if (this.def.passability == Traversability.Impassable)
            {
                Reachability.ClearCache();
            }
            Find.CoverGrid.Register(this);
            if (this.def.category == ThingCategory.Item)
            {
                ListerHaulables.Notify_Spawned(this);
            }
            Find.AttackTargetsCache.Notify_ThingSpawned(this);
            Region validRegionAt_NoRebuild = Find.RegionGrid.GetValidRegionAt_NoRebuild(this.Position);
            Room   room = (validRegionAt_NoRebuild != null) ? validRegionAt_NoRebuild.Room : null;

            if (room != null)
            {
                room.Notify_ContainedThingSpawnedOrDespawned(this);
            }
            if (this.def.category == ThingCategory.Item)
            {
                Building_Door building_Door = this.Position.GetEdifice() as Building_Door;
                if (building_Door != null)
                {
                    building_Door.Notify_ItemSpawnedOrDespawnedOnTop(this);
                }
            }
            StealAIDebugDrawer.Notify_ThingChanged(this);
        }
        protected override Job TryGiveTerminalJob(Pawn pawn)
        {
            Thing closestHaulable;
            Job   jobCollectThing   = new Job(DefDatabase <JobDef> .GetNamed("CollectThing"));
            Job   jobDropInCell     = new Job(DefDatabase <JobDef> .GetNamed("DropInCell"));
            Job   jobDismountInBase = new Job(DefDatabase <JobDef> .GetNamed("DismountInBase"));

            jobCollectThing.maxNumToCarry = 99999;
            jobCollectThing.haulMode      = HaulMode.ToCellStorage;


            //Find Available Carrier
            Vehicle_Cargo carrier = Find.ListerThings.AllThings.Find((Thing t)
                                                                     => (t.TryGetComp <CompMountable>() != null && t.TryGetComp <CompMountable>().Driver == pawn)) as Vehicle_Cargo;

            //No Carrier
            if (carrier == null)
            {
                //Log.Message("No Carrier");
                return(null);
            }
            jobCollectThing.targetC   = carrier;
            jobDropInCell.targetC     = carrier;
            jobDismountInBase.targetA = carrier;

            //collectThing Predicate
            Predicate <Thing> predicate = (Thing t)
                                          => (!t.IsForbidden(pawn.Faction) && !t.IsInAnyStorage() &&
                                              pawn.CanReserve(t) && carrier.storage.CanAcceptAnyOf(t));

            //Log.Message("flagInProgressDrop" + flagInProgressDrop);
            if (carrier.storage.TotalStackCount < carrier.GetMaxStackCount && carrier.storage.Contents.Count() < carrier.maxItem &&
                !ListerHaulables.ThingsPotentiallyNeedingHauling().NullOrEmpty() && flagInProgressDrop == false)
            {
                //Log.Message("Finding Haulable");
                closestHaulable = GenClosest.ClosestThing_Global_Reachable(pawn.Position,
                                                                           ListerHaulables.ThingsPotentiallyNeedingHauling(),
                                                                           PathMode.ClosestTouch,
                                                                           TraverseParms.For(pawn, Danger.Deadly, false),
                                                                           9999,
                                                                           predicate);
                if (closestHaulable == null)
                {
                    //Log.Message("No Haulable");
                    return(null);
                }
                jobCollectThing.targetA = closestHaulable;
                return(jobCollectThing);
            }
            else
            {
                //Log.Message("flagInProgressDrop" + flagInProgressDrop);
                flagInProgressDrop = true;
                if (carrier.storage.Contents.Count() <= 0)
                {
                    flagInProgressDrop = false;
                    //Log.Message("End Progress Drop");
                    if (ListerHaulables.ThingsPotentiallyNeedingHauling().NullOrEmpty())
                    {
                        return(jobDismountInBase);
                    }
                    return(null);
                }

                foreach (Zone zone in Find.ZoneManager.AllZones)
                {
                    if (zone is Zone_Stockpile)
                    {
                        foreach (var zoneCell in zone.cells)
                        {
                            Thing dropThing = carrier.storage.Contents.Last();

                            if (zoneCell.IsValidStorageFor(dropThing) && pawn.CanReserve(zoneCell))
                            {
                                jobDropInCell.targetA = dropThing;
                                jobDropInCell.targetB = zoneCell;
                                return(jobDropInCell);
                            }
                        }
                    }
                }

                //No zone for stock
                //Log.Message("No Zone");
                return(null);
            }
        }
        protected override Job TryGiveJob(Pawn pawn)
        {
            Predicate <Thing> validator = (Thing t) => !t.IsForbidden(pawn) && HaulAIUtility.PawnCanAutomaticallyHaulFast(pawn, t);
            //Start my code
            Thing        thing     = null;
            List <Thing> things    = ListerHaulables.ThingsPotentiallyNeedingHauling();
            List <Thing> degrade   = new List <Thing>();
            List <Thing> undegrade = new List <Thing>();

            foreach (Thing t in things)
            {
                if (t.GetStatValue(StatDefOf.DeteriorationRate) > 0)
                {
                    degrade.Add(t);
                }
                else
                {
                    undegrade.Add(t);
                }
            }
            //Loop through all haul areas in order
            foreach (Area a in AreaFinder.getHaulAreas())
            {
                //Check if got degradable item
                thing = GenClosest.ClosestThing_Global_Reachable(pawn.Position, AreaFinder.searcher(a, degrade), PathEndMode.OnCell, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), 9999f, validator, null);
                if (thing != null)
                {
                    break;
                }

                //Check if got undegradable item
                thing = GenClosest.ClosestThing_Global_Reachable(pawn.Position, AreaFinder.searcher(a, undegrade), PathEndMode.OnCell, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), 9999f, validator, null);
                if (thing != null)
                {
                    break;
                }
            }
            if (thing == null)
            {
                thing = GenClosest.ClosestThing_Global_Reachable(pawn.Position, degrade, PathEndMode.OnCell, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), 9999f, validator, null);
                if (thing == null)
                {
                    thing = GenClosest.ClosestThing_Global_Reachable(pawn.Position, undegrade, PathEndMode.OnCell, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), 9999f, validator, null);
                }
            }

            /* old 50 cell code
             * Thing thing = GenClosest.ClosestThing_Global_Reachable(pawn.Position, degrade, PathEndMode.OnCell, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), 50f, validator, null);
             * if (thing == null)
             * {
             *  thing = GenClosest.ClosestThing_Global_Reachable(pawn.Position, undegrade, PathEndMode.OnCell, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), 50f, validator, null);
             *  if (thing == null)
             *  {
             *      thing = GenClosest.ClosestThing_Global_Reachable(pawn.Position, degrade, PathEndMode.OnCell, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), 9999f, validator, null);
             *      if (thing == null)
             *      {
             *          thing = GenClosest.ClosestThing_Global_Reachable(pawn.Position, undegrade, PathEndMode.OnCell, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), 9999f, validator, null);
             *      }
             *  }
             * }*/
            //End my code
            if (thing != null)
            {
                return(HaulAIUtility.HaulToStorageJob(pawn, thing));
            }
            return(null);
        }
Example #23
0
        public static Job HaulWithTools(Pawn pawn, Vehicle_Cart cart = null, Thing haulThing = null)
        {
            Trace.stopWatchStart();

            //Job Setting
            bool                UseBackpack = false;
            JobDef              jobDef      = null;
            TargetInfo          targetC;
            int                 maxItem;
            int                 thresholdItem;
            int                 reservedMaxItem;
            IEnumerable <Thing> remainingItems;
            bool                ShouldDrop;
            Thing               lastItem = TryGetBackpackLastItem(pawn);
            Apparel_Backpack    backpack = TryGetBackpack(pawn);

            if (cart == null)
            {
                jobDef  = HaulJobDefOf.HaulWithBackpack;
                targetC = backpack;
                maxItem = backpack.MaxItem;
                // thresholdItem = (int)Math.Ceiling(maxItem * 0.5);
                thresholdItem   = 2;
                reservedMaxItem = backpack.slotsComp.slots.Count;
                remainingItems  = backpack.slotsComp.slots;
                ShouldDrop      = false;
                UseBackpack     = true;
                if (lastItem != null)
                {
                    for (int i = 0; i < backpack.slotsComp.slots.Count; i++)
                    {
                        if (backpack.slotsComp.slots[i] == lastItem && reservedMaxItem - (i + 1) <= 0)
                        {
                            ShouldDrop = false;
                            break;
                        }
                    }
                }
            }
            else
            {
                if (cart.mountableComp.IsMounted)
                {
                    jobDef = cart.mountableComp.Driver.RaceProps.Animal
                        ? HaulJobDefOf.HaulWithAnimalCart
                        : HaulJobDefOf.HaulWithCart;
                }
                else
                {
                    jobDef = HaulJobDefOf.HaulWithCart;
                }

                targetC = cart;

                maxItem         = cart.MaxItem;
                thresholdItem   = (int)Math.Ceiling(maxItem * 0.25);
                reservedMaxItem = cart.storage.Count;
                remainingItems  = cart.storage;


                ShouldDrop = reservedMaxItem > 0 ? true : false;
            }
            Job job = new Job(jobDef)
            {
                targetQueueA = new List <TargetInfo>(),
                targetQueueB = new List <TargetInfo>(),
                targetC      = targetC
            };

            if (UseBackpack)
            {
                job.numToBringList = new List <int>();
            }

            Trace.AppendLine(pawn.LabelCap + " In HaulWithTools: " + jobDef.defName + "\n"
                             + "MaxItem: " + maxItem + " reservedMaxItem: " + reservedMaxItem);

            //Drop remaining item
            if (ShouldDrop)
            {
                Trace.AppendLine("Start Drop remaining item");
                bool startDrop = false;
                for (int i = 0; i < remainingItems.Count(); i++)
                {
                    if (UseBackpack && startDrop == false)
                    {
                        if (remainingItems.ElementAt(i) == lastItem)
                        {
                            startDrop = true;
                        }
                        else
                        {
                            continue;
                        }
                    }
                    IntVec3 storageCell = FindStorageCell(pawn, remainingItems.ElementAt(i), job.targetQueueB);
                    if (storageCell == IntVec3.Invalid)
                    {
                        break;
                    }
                    job.targetQueueB.Add(storageCell);
                }
                if (!job.targetQueueB.NullOrEmpty())
                {
                    Trace.AppendLine("Dropping Job is issued");
                    Trace.LogMessage();
                    return(job);
                }
                if (!UseBackpack && job.def == HaulJobDefOf.HaulWithCart && !cart.IsInValidStorage())
                {
                    Trace.AppendLine("In DismountInBase");
                    return(DismountInBase(pawn, cart));
                }
                JobFailReason.Is(NoEmptyPlaceLowerTrans);
                Trace.AppendLine("End Drop remaining item");
                Trace.AppendLine("No Job. Reason: " + JobFailReason.Reason);
                Trace.LogMessage();
                return(null);
            }

            //Collect item
            Trace.AppendLine("Start Collect item");
            IntVec3 searchPos;

            if (haulThing != null)
            {
                searchPos = haulThing.Position;
            }
            else if (!UseBackpack)
            {
                searchPos = cart.Position;
            }
            else
            {
                searchPos = pawn.Position;
            }
            foreach (SlotGroup slotGroup in Find.SlotGroupManager.AllGroupsListInPriorityOrder)
            {
                Trace.AppendLine("Start searching slotGroup");
                if (slotGroup.CellsList.Count - slotGroup.HeldThings.Count() < maxItem)
                {
                    continue;
                }

                //Counting valid items
                Trace.AppendLine("Start Counting valid items");
                int thingsCount =
                    ListerHaulables.ThingsPotentiallyNeedingHauling()
                    .Count(item => slotGroup.Settings.AllowedToAccept(item));

                //Finding valid items
                Trace.AppendLine("Start Finding valid items");
                if (thingsCount > thresholdItem)
                {
                    Thing thing;
                    if (haulThing == null)
                    {
                        //ClosestThing_Global_Reachable Configuration
                        Predicate <Thing> predicate = item
                                                      => !job.targetQueueA.Contains(item) && !item.IsBurning() &&
                                                      !item.IsInAnyStorage() &&
                                                      (UseBackpack
                                   ? item.def.thingCategories.Exists(
                                                           category =>
                                                           backpack.slotsComp.Properties.allowedThingCategoryDefs.Exists(
                                                               subCategory =>
                                                               subCategory.ThisAndChildCategoryDefs.Contains(category))
                                                           &&
                                                           !backpack.slotsComp.Properties.forbiddenSubThingCategoryDefs.Exists(
                                                               subCategory =>
                                                               subCategory.ThisAndChildCategoryDefs.Contains(category)))
                                   : cart.allowances.Allows(item)) &&
                                                      !item.IsForbidden(pawn.Faction) &&
                                                      slotGroup.Settings.AllowedToAccept(item) &&
                                                      pawn.CanReserveAndReach(item, PathEndMode.Touch, pawn.NormalMaxDanger());
                        //&& !(item is UnfinishedThing && ((UnfinishedThing)item).BoundBill != null)
                        //&& (item.def.IsNutritionSource && !SocialProperness.IsSociallyProper(item, pawn, false, false));
                        thing = GenClosest.ClosestThing_Global_Reachable(searchPos,
                                                                         ListerHaulables.ThingsPotentiallyNeedingHauling(),
                                                                         PathEndMode.ClosestTouch,
                                                                         TraverseParms.For(pawn, pawn.NormalMaxDanger()),
                                                                         9999,
                                                                         predicate);
                        if (thing == null)
                        {
                            continue;
                        }
                    }
                    else
                    {
                        thing = haulThing;
                    }

                    //Find StorageCell
                    IntVec3 storageCell = FindStorageCell(pawn, thing, job.targetQueueB);
                    if (storageCell == IntVec3.Invalid)
                    {
                        break;
                    }

                    //Add Queue & Reserve
                    job.targetQueueA.Add(thing);
                    //for backpacks
                    if (UseBackpack)
                    {
                        job.numToBringList.Add(thing.def.stackLimit);
                    }

                    job.targetQueueB.Add(storageCell);


                    IntVec3 center = thing.Position;

                    //Enqueue SAME items in valid distance
                    Trace.AppendLine("Start Enqueuing SAME items in valid distance");
                    foreach (Thing item in ListerHaulables.ThingsPotentiallyNeedingHauling().Where(item
                                                                                                   => !job.targetQueueA.Contains(item) && !item.IsBurning() &&
                                                                                                   !item.IsInAnyStorage() &&
                                                                                                   (UseBackpack
                               ? item.def.thingCategories.Exists(
                                                                                                        category =>
                                                                                                        backpack.slotsComp.Properties.allowedThingCategoryDefs.Exists(
                                                                                                            subCategory =>
                                                                                                            subCategory.ThisAndChildCategoryDefs.Contains(category))
                                                                                                        &&
                                                                                                        !backpack.slotsComp.Properties.forbiddenSubThingCategoryDefs.Exists(
                                                                                                            subCategory =>
                                                                                                            subCategory.ThisAndChildCategoryDefs.Contains(category)))
                               : cart.allowances.Allows(item)) &&
                                                                                                   !item.IsForbidden(pawn.Faction) &&
                                                                                                   slotGroup.Settings.AllowedToAccept(item) &&
                                                                                                   pawn.CanReserveAndReach(item, PathEndMode.Touch, pawn.NormalMaxDanger()) &&
                                                                                                   center.DistanceToSquared(item.Position) <= ValidDistance))
                    {
                        job.targetQueueA.Add(item);
                        if (UseBackpack)
                        {
                            job.numToBringList.Add(item.def.stackLimit);
                        }


                        reservedMaxItem++;

                        if (reservedMaxItem + job.targetQueueA.Count >= maxItem)
                        {
                            break;
                        }
                    }

                    //Enqueue other items in valid distance
                    if (reservedMaxItem + job.targetQueueA.Count < maxItem)
                    {
                        Trace.AppendLine("Start Enqueuing items in valid distance");

                        foreach (Thing item in ListerHaulables.ThingsPotentiallyNeedingHauling().Where(item
                                                                                                       => !job.targetQueueA.Contains(item) && !item.IsBurning() &&
                                                                                                       !item.IsInAnyStorage() &&
                                                                                                       (UseBackpack
                                   ? item.def.thingCategories.Exists(
                                                                                                            category =>
                                                                                                            backpack.slotsComp.Properties.allowedThingCategoryDefs.Exists(
                                                                                                                subCategory =>
                                                                                                                subCategory.ThisAndChildCategoryDefs.Contains(category))
                                                                                                            &&
                                                                                                            !backpack.slotsComp.Properties.forbiddenSubThingCategoryDefs.Exists(
                                                                                                                subCategory =>
                                                                                                                subCategory.ThisAndChildCategoryDefs.Contains(category)))
                                   : cart.allowances.Allows(item)) &&
                                                                                                       !item.IsForbidden(pawn.Faction) &&
                                                                                                       slotGroup.Settings.AllowedToAccept(item) &&
                                                                                                       pawn.CanReserveAndReach(item, PathEndMode.Touch, pawn.NormalMaxDanger()) &&
                                                                                                       center.DistanceToSquared(item.Position) <= ValidDistance))
                        {
                            job.targetQueueA.Add(item);
                            if (UseBackpack)
                            {
                                job.numToBringList.Add(item.def.stackLimit);
                            }
                            reservedMaxItem++;

                            if (reservedMaxItem + job.targetQueueA.Count >= maxItem)
                            {
                                break;
                            }
                        }
                    }

                    //Also enqueue items in whiche are not in their best storage cell
                    if (reservedMaxItem + job.targetQueueA.Count < maxItem)
                    {
                        Trace.AppendLine("Start Enqueuing items in valid distance & not in best storage cell");
                        foreach (Thing item in ListerHaulables.ThingsPotentiallyNeedingHauling().Where(item
                                                                                                       => !job.targetQueueA.Contains(item) && !item.IsBurning() &&
                                                                                                       !item.IsInValidBestStorage() &&
                                                                                                       (UseBackpack
                                   ? item.def.thingCategories.Exists(
                                                                                                            category =>
                                                                                                            backpack.slotsComp.Properties.allowedThingCategoryDefs.Exists(
                                                                                                                subCategory =>
                                                                                                                subCategory.ThisAndChildCategoryDefs.Contains(category))
                                                                                                            &&
                                                                                                            !backpack.slotsComp.Properties.forbiddenSubThingCategoryDefs.Exists(
                                                                                                                subCategory =>
                                                                                                                subCategory.ThisAndChildCategoryDefs.Contains(category)))
                                   : cart.allowances.Allows(item)) &&
                                                                                                       !item.IsForbidden(pawn.Faction) &&
                                                                                                       slotGroup.Settings.AllowedToAccept(item) &&
                                                                                                       pawn.CanReserveAndReach(item, PathEndMode.Touch, pawn.NormalMaxDanger()) &&
                                                                                                       center.DistanceToSquared(item.Position) <= ValidDistance))
                        {
                            job.targetQueueA.Add(item);
                            if (UseBackpack)
                            {
                                job.numToBringList.Add(item.def.stackLimit);
                            }
                            reservedMaxItem++;

                            if (reservedMaxItem + job.targetQueueA.Count >= maxItem)
                            {
                                break;
                            }
                        }
                    }

                    //Find storage cell
                    Trace.AppendLine("Start Finding storage cell");
                    if (reservedMaxItem + job.targetQueueA.Count > thresholdItem)
                    {
                        foreach (
                            IntVec3 cell in
                            slotGroup.CellsList.Where(
                                cell =>
                                pawn.CanReserveAndReach(cell, PathEndMode.ClosestTouch, Danger.Some) &&
                                cell.Standable() && cell.GetStorable() == null))
                        {
                            StoragePriority currentPriority = HaulAIUtility.StoragePriorityAtFor(thing.Position, thing);
                            IntVec3         storeCell       = cell;
                            if (
                                !StoreUtility.TryFindBestBetterStoreCellFor(thing, pawn, currentPriority, pawn.Faction,
                                                                            out storeCell))
                            {
                                if (cell.InAllowedArea(pawn))
                                {
                                    job.targetQueueB.Add(cell);
                                }
                                if (job.targetQueueB.Count >= job.targetQueueA.Count)
                                {
                                    break;
                                }
                            }
                            else
                            {
                                if (storeCell.InAllowedArea(pawn))
                                {
                                    job.targetQueueB.Add(storeCell);
                                }
                                if (job.targetQueueB.Count >= job.targetQueueA.Count)
                                {
                                    break;
                                }
                            }
                        }
                        break;
                    }
                    job.targetQueueA.Clear();
                }
            }
            Trace.AppendLine("Elapsed Time");
            Trace.stopWatchStop();

            //Check job is valid
            if (!job.targetQueueA.NullOrEmpty() && reservedMaxItem + job.targetQueueA.Count > thresholdItem &&
                !job.targetQueueB.NullOrEmpty())
            {
                Trace.AppendLine("Hauling Job is issued");
                Trace.LogMessage();
                return(job);
            }
            if (cart != null && job.def == HaulJobDefOf.HaulWithCart && !cart.IsInValidStorage())
            {
                Trace.AppendLine("In DismountInBase: ");
                return(DismountInBase(pawn, cart));
            }

            if (job.targetQueueA.NullOrEmpty())
            {
                JobFailReason.Is("NoHaulable".Translate());
            }
            else if (reservedMaxItem + job.targetQueueA.Count <= thresholdItem)
            {
                JobFailReason.Is(TooLittleHaulable);
            }
            else if (job.targetQueueB.NullOrEmpty())
            {
                JobFailReason.Is(NoEmptyPlaceLowerTrans);
            }
            Trace.AppendLine("No Job. Reason: " + JobFailReason.Reason);
            Trace.LogMessage();
            return(null);
        }
        public override Job JobOnThing(Pawn pawn, Thing t)
        {
            if (!(t is Vehicle_Cargo))
            {
                return(null);
            }
            Vehicle_Cargo       carrier        = t as Vehicle_Cargo;
            List <Thing>        haulables      = ListerHaulables.ThingsPotentiallyNeedingHauling();
            IEnumerable <Thing> remainingItems = carrier.storage.Contents;
            //bool IsMountedVehicle = ((carrier.GetComp<CompMountable>().Driver == pawn)? true: false);
            int reservedStackCount = carrier.storage.TotalStackCount;
            int reservedMaxItem    = carrier.storage.Contents.Count();
            Job jobDismountInBase  = new Job(DefDatabase <JobDef> .GetNamed("DismountInBase"));
            Job jobCollect         = new Job(DefDatabase <JobDef> .GetNamed("Collect"));

            jobCollect.maxNumToCarry = 99999;
            jobCollect.haulMode      = HaulMode.ToCellStorage;
            jobCollect.targetQueueA  = new List <TargetInfo>();
            jobCollect.targetQueueB  = new List <TargetInfo>();

            //Set carrier
            jobDismountInBase.targetA = carrier;
            jobCollect.targetC        = carrier;
            ReservationUtility.Reserve(pawn, t);

            //If IgnoreForbidden is true, add forbidden
            if (carrier.ignoreForbidden)
            {
                List <Thing> forbiddens = Find.ListerThings.AllThings.FindAll((Thing thing) =>
                                                                              (thing.TryGetComp <CompForbiddable>() != null && thing.TryGetComp <CompForbiddable>().Forbidden == true));
                haulables = forbiddens.Concat(haulables).ToList();

                /*string logStr = "";
                 * foreach (var forbidden in forbiddens)
                 *  logStr += forbidden.ThingID;
                 * Log.Message("Haulable: " + logStr);*/
            }

            //Drop remaining item
            foreach (var remainingItem in remainingItems)
            {
                IntVec3 storageCell = new IntVec3(-1000, -1000, -1000);
                foreach (Zone zone in Find.ZoneManager.AllZones)
                {
                    if (storageCell.IsValid)
                    {
                        break;
                    }
                    if (zone is Zone_Stockpile)
                    {
                        foreach (var zoneCell in zone.cells)
                        {
                            if (!jobCollect.targetQueueB.Contains(zoneCell) && zoneCell.IsValidStorageFor(remainingItem) && pawn.CanReserve(zoneCell))
                            {
                                storageCell = zoneCell;
                                break;
                            }
                        }
                    }
                }
                if (!storageCell.IsValid)
                {
                    break;
                }

                //Just drop, not collect. It was already collected
                //jobCollect.targetQueueA.Add(remainingItem);
                //ReservationUtility.Reserve(pawn, remainingItem, ReservationType.Total);
                jobCollect.targetQueueB.Add(storageCell);
                ReservationUtility.Reserve(pawn, storageCell);
            }
            if (!jobCollect.targetQueueB.NullOrEmpty())
            {
                return(jobCollect);
            }

            //collectThing Predicate
            Predicate <Thing> predicate = (Thing item)
                                          => ((carrier.ignoreForbidden || !item.IsForbidden(pawn.Faction)) &&
                                              !item.IsInValidStorage() && pawn.CanReserve(item) &&
                                              carrier.storage.CanAcceptAnyOf(item));

            //Collect and drop item
            while (!haulables.NullOrEmpty() && reservedStackCount < carrier.GetMaxStackCount && reservedMaxItem < carrier.maxItem)
            {
                IntVec3 storageCell     = new IntVec3(-1000, -1000, -1000);
                Thing   closestHaulable = null;
                //Log.Message("reservedStackCount, reservedMaxItem :" + reservedStackCount + ',' +  reservedMaxItem);
                closestHaulable = GenClosest.ClosestThing_Global_Reachable(pawn.Position,
                                                                           haulables,
                                                                           PathMode.ClosestTouch,
                                                                           TraverseParms.For(pawn, Danger.Deadly, false),
                                                                           9999,
                                                                           predicate);
                if (closestHaulable == null)
                {
                    break;
                }

                if (!jobCollect.targetQueueB.NullOrEmpty())
                {
                    foreach (TargetInfo target in jobCollect.targetQueueB)
                    {
                        if (storageCell.IsValid)
                        {
                            break;
                        }
                        foreach (var adjCell in GenAdjFast.AdjacentCells8Way(target))
                        {
                            if (!jobCollect.targetQueueB.Contains(adjCell) && adjCell.IsValidStorageFor(closestHaulable) && pawn.CanReserve(adjCell))
                            {
                                storageCell = adjCell;
                                break;
                            }
                        }
                    }
                }

                foreach (Zone zone in Find.ZoneManager.AllZones)
                {
                    if (storageCell.IsValid)
                    {
                        break;
                    }
                    if (zone is Zone_Stockpile)
                    {
                        foreach (var zoneCell in zone.cells)
                        {
                            if (!jobCollect.targetQueueB.Contains(zoneCell) && zoneCell.IsValidStorageFor(closestHaulable) && pawn.CanReserve(zoneCell))
                            {
                                storageCell = zoneCell;
                                //Log.Message("storageCell: " + storageCell);
                                break;
                            }
                        }
                    }
                }
                //No Storage
                if (!storageCell.IsValid)
                {
                    break;
                }

                jobCollect.targetQueueA.Add(closestHaulable);
                ReservationUtility.Reserve(pawn, closestHaulable);
                haulables.Remove(closestHaulable);
                jobCollect.targetQueueB.Add(storageCell);
                ReservationUtility.Reserve(pawn, storageCell);
                reservedMaxItem++;
                reservedStackCount += closestHaulable.stackCount;
            }

            //No haulables or zone
            if (jobCollect.targetQueueA.NullOrEmpty() || jobCollect.targetQueueB.NullOrEmpty())
            {
                foreach (Zone zone in Find.ZoneManager.AllZones)
                {
                    if (jobDismountInBase.targetB != null)
                    {
                        break;
                    }
                    if (zone is Zone_Stockpile)
                    {
                        foreach (var zoneCell in zone.cells)
                        {
                            Thing dropThing = carrier;
                            if (zoneCell.IsValidStorageFor(dropThing) && pawn.CanReserve(zoneCell))
                            {
                                ReservationUtility.Reserve(pawn, zoneCell);
                                jobDismountInBase.targetB = zoneCell;
                                break;
                            }
                        }
                    }
                }

                //Move cargo in Base
                if (!carrier.IsInValidStorage() && jobDismountInBase.targetB != null)
                {
                    return(jobDismountInBase);
                }

                //No job, no move to cargo
                if (Find.Reservations.IsReserved(carrier, pawn.Faction))
                {
                    Find.Reservations.Release(carrier, pawn);
                }
                return(null);
            }

            return(jobCollect);
        }
Example #25
0
        public override Job JobOnThing(Pawn pawn, Thing t)
        {
            Vehicle_Cart cart = null;

            if (!HaulAIUtility.PawnCanAutomaticallyHaulFast(pawn, t))
            {
                return(null);
            }

            // Vehicle selection

            if (ToolsForHaulUtility.IsDriver(pawn))
            {
                cart = ToolsForHaulUtility.GetCartByDriver(pawn);

                if (cart == null)
                {
                    //  JobFailReason.Is("Can't haul with military vehicle");
                    return(ToolsForHaulUtility.DismountInBase(pawn, MapComponent_ToolsForHaul.currentVehicle[pawn]));
                }
            }


            if (cart == null)
            {
                cart = RightTools.GetRightVehicle(pawn, WorkTypeDefOf.Hauling, t) as Vehicle_Cart;

                if (cart == null)
                {
                    return(null);
                }
            }



            if (cart.IsBurning())
            {
                JobFailReason.Is(ToolsForHaulUtility.BurningLowerTrans);
                return(null);
            }

            if (!cart.allowances.Allows(t))
            {
                JobFailReason.Is("Cart does not allow that thing");
                return(null);
            }

            if (ListerHaulables.ThingsPotentiallyNeedingHauling().Count == 0 && cart.storage.Count == 0)
            {
                JobFailReason.Is("NoHaulable".Translate());
                return(null);
            }

            if (Find.SlotGroupManager.AllGroupsListInPriorityOrder.Count == 0)
            {
                JobFailReason.Is(ToolsForHaulUtility.NoEmptyPlaceLowerTrans);
                return(null);
            }

            if (ToolsForHaulUtility.AvailableAnimalCart(cart) || ToolsForHaulUtility.AvailableVehicle(pawn, cart))
            {
                return(ToolsForHaulUtility.HaulWithTools(pawn, cart, t));
            }
            JobFailReason.Is(ToolsForHaulUtility.NoAvailableCart);
            return(null);
        }
Example #26
0
 static bool Prefix(Thing t, ListerHaulables __instance, ref bool __result)
 {
     __result = __instance.ShouldBeHaulableExt(t);
     return(false);
 }
Example #27
0
 public void ConstructComponents()
 {
     this.spawnedThings      = new ThingOwner <Thing>(this);
     this.cellIndices        = new CellIndices(this);
     this.listerThings       = new ListerThings(ListerThingsUse.Global);
     this.listerBuildings    = new ListerBuildings();
     this.mapPawns           = new MapPawns(this);
     this.dynamicDrawManager = new DynamicDrawManager(this);
     this.mapDrawer          = new MapDrawer(this);
     this.tooltipGiverList   = new TooltipGiverList();
     this.pawnDestinationReservationManager = new PawnDestinationReservationManager();
     this.reservationManager = new ReservationManager(this);
     this.physicalInteractionReservationManager = new PhysicalInteractionReservationManager();
     this.designationManager             = new DesignationManager(this);
     this.lordManager                    = new LordManager(this);
     this.debugDrawer                    = new DebugCellDrawer();
     this.passingShipManager             = new PassingShipManager(this);
     this.haulDestinationManager         = new HaulDestinationManager(this);
     this.gameConditionManager           = new GameConditionManager(this);
     this.weatherManager                 = new WeatherManager(this);
     this.zoneManager                    = new ZoneManager(this);
     this.resourceCounter                = new ResourceCounter(this);
     this.mapTemperature                 = new MapTemperature(this);
     this.temperatureCache               = new TemperatureCache(this);
     this.areaManager                    = new AreaManager(this);
     this.attackTargetsCache             = new AttackTargetsCache(this);
     this.attackTargetReservationManager = new AttackTargetReservationManager(this);
     this.lordsStarter                   = new VoluntarilyJoinableLordsStarter(this);
     this.thingGrid                  = new ThingGrid(this);
     this.coverGrid                  = new CoverGrid(this);
     this.edificeGrid                = new EdificeGrid(this);
     this.blueprintGrid              = new BlueprintGrid(this);
     this.fogGrid                    = new FogGrid(this);
     this.glowGrid                   = new GlowGrid(this);
     this.regionGrid                 = new RegionGrid(this);
     this.terrainGrid                = new TerrainGrid(this);
     this.pathGrid                   = new PathGrid(this);
     this.roofGrid                   = new RoofGrid(this);
     this.fertilityGrid              = new FertilityGrid(this);
     this.snowGrid                   = new SnowGrid(this);
     this.deepResourceGrid           = new DeepResourceGrid(this);
     this.exitMapGrid                = new ExitMapGrid(this);
     this.linkGrid                   = new LinkGrid(this);
     this.glowFlooder                = new GlowFlooder(this);
     this.powerNetManager            = new PowerNetManager(this);
     this.powerNetGrid               = new PowerNetGrid(this);
     this.regionMaker                = new RegionMaker(this);
     this.pathFinder                 = new PathFinder(this);
     this.pawnPathPool               = new PawnPathPool(this);
     this.regionAndRoomUpdater       = new RegionAndRoomUpdater(this);
     this.regionLinkDatabase         = new RegionLinkDatabase();
     this.moteCounter                = new MoteCounter();
     this.gatherSpotLister           = new GatherSpotLister();
     this.windManager                = new WindManager(this);
     this.listerBuildingsRepairable  = new ListerBuildingsRepairable();
     this.listerHaulables            = new ListerHaulables(this);
     this.listerMergeables           = new ListerMergeables(this);
     this.listerFilthInHomeArea      = new ListerFilthInHomeArea(this);
     this.reachability               = new Reachability(this);
     this.itemAvailability           = new ItemAvailability(this);
     this.autoBuildRoofAreaSetter    = new AutoBuildRoofAreaSetter(this);
     this.roofCollapseBufferResolver = new RoofCollapseBufferResolver(this);
     this.roofCollapseBuffer         = new RoofCollapseBuffer();
     this.wildAnimalSpawner          = new WildAnimalSpawner(this);
     this.wildPlantSpawner           = new WildPlantSpawner(this);
     this.steadyEnvironmentEffects   = new SteadyEnvironmentEffects(this);
     this.skyManager                 = new SkyManager(this);
     this.overlayDrawer              = new OverlayDrawer();
     this.floodFiller                = new FloodFiller(this);
     this.weatherDecider             = new WeatherDecider(this);
     this.fireWatcher                = new FireWatcher(this);
     this.dangerWatcher              = new DangerWatcher(this);
     this.damageWatcher              = new DamageWatcher();
     this.strengthWatcher            = new StrengthWatcher(this);
     this.wealthWatcher              = new WealthWatcher(this);
     this.regionDirtyer              = new RegionDirtyer(this);
     this.cellsInRandomOrder         = new MapCellsInRandomOrder(this);
     this.rememberedCameraPos        = new RememberedCameraPos(this);
     this.mineStrikeManager          = new MineStrikeManager();
     this.storyState                 = new StoryState(this);
     this.retainedCaravanData        = new RetainedCaravanData(this);
     this.components.Clear();
     this.FillComponents();
 }
Example #28
0
 static bool Prefix(ListerHaulables __instance, Thing t) =>
 FactionRepeater.Template(d => d.listerHaulables.Notify_DeSpawned(t), __instance.map, ref ignore);