Inheritance: ThingWithComps, IThingContainerOwner
Exemple #1
0
        public override string GetReport()
        {
            Vehicle_Cart cart = TargetThingA as Vehicle_Cart;

            IntVec3   destLoc   = new IntVec3(-1000, -1000, -1000);
            string    destName  = null;
            SlotGroup destGroup = null;

            if (pawn.jobs.curJob.targetB != null)
            {
                destLoc   = pawn.jobs.curJob.targetB.Cell;
                destGroup = StoreUtility.GetSlotGroup(destLoc);
            }

            if (destGroup != null)
            {
                destName = destGroup.parent.SlotYielderLabel();
            }

            string repString;

            if (destName != null)
            {
                repString = "ReportDismountingOn".Translate(cart.LabelCap, destName);
            }
            else
            {
                repString = "ReportDismounting".Translate(cart.LabelCap);
            }

            return(repString);
        }
        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 : actor.inventory.container.Count) + targetQueue.Count;
                int curItemStack = (cart != null ? cart.storage.TotalStackCount : actor.inventory.container.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 &&
                                                                       !FireUtility.IsBurning(item) &&
                                                                       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;
                }
            };
            return(toil);
        }
        public static Toil CheckNeedStorageCell(Toil jumpToil, TargetIndex CarrierInd, TargetIndex StoreCellInd)
        {
            Toil toil = new Toil();

            toil.initAction = () =>
            {
                Pawn actor = toil.actor;

                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);
                }
                ThingContainer container = cart != null ? cart.storage : actor.inventory.container;
                if (container.Count == 0)
                {
                    return;
                }

                IntVec3 cell = ToolsForHaulUtility.FindStorageCell(actor, container.First());
                if (cell != IntVec3.Invalid)
                {
                    toil.actor.jobs.curJob.SetTarget(StoreCellInd, cell);
                    Find.Reservations.Reserve(actor, cell);
                    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 static bool AvailableAnimalCart(Vehicle_Cart cart)
        {
            Pawn Driver = (cart.TryGetComp<CompMountable>().IsMounted) ? cart.TryGetComp<CompMountable>().Driver : null;
            if (Driver == null)
                return false;

            return Driver.RaceProps.Animal && PawnUtility.CasualInterruptibleNow(Driver)
                && Driver.needs.food.CurCategory < HungerCategory.Starving
                && Driver.needs.rest.CurCategory < RestCategory.VeryTired
                && !Driver.health.ShouldBeTreatedNow;
        }
        public static bool AvailableAnimalCart(Vehicle_Cart cart)
        {
            Pawn Driver = (cart.TryGetComp <CompMountable>().IsMounted) ? cart.TryGetComp <CompMountable>().Driver : null;

            if (Driver == null)
            {
                return(false);
            }

            return(Driver.RaceProps.Animal && PawnUtility.CasualInterruptibleNow(Driver) &&
                   Driver.needs.food.CurCategory < HungerCategory.Starving &&
                   Driver.needs.rest.CurCategory < RestCategory.VeryTired &&
                   !Driver.health.ShouldBeTendedNow);
        }
        public static Toil DropTheCarriedInCell(TargetIndex StoreCellInd, ThingPlaceMode placeMode, TargetIndex CarrierInd)
        {
            Toil toil = new Toil();

            toil.initAction = () =>
            {
                Pawn         actor   = toil.actor;
                Job          curJob  = actor.jobs.curJob;
                Vehicle_Cart carrier = actor.jobs.curJob.GetTarget(CarrierInd).Thing as Vehicle_Cart;
                if (carrier.storage.Count <= 0)
                {
                    return;
                }
                toil.actor.jobs.curJob.SetTarget(TargetIndex.A, carrier.storage.First());
                Thing   dropThing = toil.actor.jobs.curJob.targetA.Thing;
                IntVec3 destLoc   = actor.jobs.curJob.GetTarget(StoreCellInd).Cell;
                Thing   dummy;

                if (destLoc.GetStorable() == null)
                {
                    Find.DesignationManager.RemoveAllDesignationsOn(dropThing);
                    carrier.storage.TryDrop(dropThing, destLoc, placeMode, out dummy);
                }

                //Check cell queue is adjacent
                List <TargetInfo> cells = curJob.GetTargetQueue(StoreCellInd);
                for (int i = 0; i < cells.Count && i < carrier.storage.Count; i++)
                {
                    if (destLoc.AdjacentTo8Way(cells[i].Cell) && cells[i].Cell.GetStorable() == null)
                    {
                        Find.DesignationManager.RemoveAllDesignationsOn(carrier.storage[i]);
                        carrier.storage.TryDrop(carrier.storage[i], cells[i].Cell, ThingPlaceMode.Direct, out dummy);
                        cells.RemoveAt(i);
                        i--;
                    }
                }
                //Check item queue is valid storage for adjacent cell
                foreach (IntVec3 adjCell in GenAdj.CellsAdjacent8Way(destLoc))
                {
                    if (carrier.storage.Count > 0 && adjCell.GetStorable() == null && StoreUtility.IsValidStorageFor(adjCell, carrier.storage.First()))
                    {
                        Find.DesignationManager.RemoveAllDesignationsOn(carrier.storage.First());
                        carrier.storage.TryDrop(carrier.storage.First(), adjCell, ThingPlaceMode.Direct, out dummy);
                    }
                }
            };
            toil.FailOnDestroyedOrNull(CarrierInd);
            return(toil);
        }
 protected override bool TryFindGoodExitDest(Pawn pawn, out IntVec3 spot)
 {
     using (List <Thing> .Enumerator enumerator = ToolsForHaulUtility.Cart().GetEnumerator())
     {
         while (enumerator.MoveNext())
         {
             Vehicle_Cart vehicle_Cart = (Vehicle_Cart)enumerator.Current;
             if (vehicle_Cart.mountableComp.IsMounted && !vehicle_Cart.mountableComp.Driver.RaceProps.Animal && vehicle_Cart.mountableComp.Driver.ThingID == pawn.ThingID)
             {
                 vehicle_Cart.despawnAtEdge = true;
             }
         }
     }
     return(ExitUtility.TryFindRandomExitSpot(pawn, ref spot, 1));
 }
 public static Job DismountInBase(Pawn pawn, Vehicle_Cart cart)
 {
     Job job = new Job(jobDefDismountInBase);
     job.targetA = cart;
     job.targetB = FindStorageCell(pawn, cart);
     if (job.targetB != IntVec3.Invalid)
     {
         Trace.AppendLine("DismountInBase Job is issued");
         Trace.LogMessage();
         return job;
     }
     JobFailReason.Is(ToolsForHaulUtility.NoEmptyPlaceForCart);
     Trace.AppendLine("No Job. Reason: " + JobFailReason.Reason);
     Trace.LogMessage();
     return (Job)null;
 }
Exemple #10
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            ///
            //Set fail conditions
            ///

            this.FailOnDestroyedOrNull(CartInd);
            //Note we only fail on forbidden if the target doesn't start that way
            //This helps haul-aside jobs on forbidden items
            if (!TargetThingA.IsForbidden(pawn.Faction))
            {
                this.FailOnForbidden(CartInd);
            }

            Vehicle_Cart cart = TargetThingA as Vehicle_Cart;


            ///
            //Define Toil
            ///

            Toil toilGoToCell = Toils_Goto.GotoCell(StoreCellInd, PathEndMode.ClosestTouch);

            ///
            //Toils Start
            ///


            //Reserve thing to be stored and storage cell
            yield return(Toils_Reserve.Reserve(CartInd));

            yield return(Toils_Reserve.Reserve(StoreCellInd));

            //JumpIf already mounted
            yield return(Toils_Jump.JumpIf(toilGoToCell, () => { return (cart.GetComp <CompMountable>().Driver == pawn) ? true : false; }));

            //Mount on Target
            yield return(Toils_Goto.GotoThing(CartInd, PathEndMode.ClosestTouch)
                         .FailOnDestroyedOrNull(CartInd));

            yield return(Toils_Cart.MountOn(CartInd));

            //Dismount
            yield return(toilGoToCell);

            yield return(Toils_Cart.DismountAt(CartInd, StoreCellInd));
        }
        public static Job DismountInBase(Pawn pawn, Vehicle_Cart cart)
        {
            Job job = new Job(jobDefDismountInBase);

            job.targetA = cart;
            job.targetB = FindStorageCell(pawn, cart);
            if (job.targetB != IntVec3.Invalid)
            {
                Trace.AppendLine("DismountInBase Job is issued");
                Trace.LogMessage();
                return(job);
            }
            JobFailReason.Is(ToolsForHaulUtility.NoEmptyPlaceForCart);
            Trace.AppendLine("No Job. Reason: " + JobFailReason.Reason);
            Trace.LogMessage();
            return((Job)null);
        }
Exemple #12
0
        public static Toil DismountAt(TargetIndex CartInd, TargetIndex StoreCellInd)
        {
            Toil toil = new Toil();

            toil.initAction = () =>
            {
                Pawn         actor = toil.GetActor();
                Vehicle_Cart cart  = toil.actor.jobs.curJob.GetTarget(CartInd).Thing as Vehicle_Cart;
                if (cart == null)
                {
                    Log.Error(actor.LabelCap + " Report: Cart is invalid.");
                    toil.actor.jobs.curDriver.EndJobWith(JobCondition.Errored);
                }
                cart.GetComp <CompMountable>().DismountAt(toil.actor.jobs.curJob.GetTarget(StoreCellInd).Cell);
            };
            return(toil);
        }
Exemple #13
0
        public static Toil CallAnimalCart(TargetIndex CartInd, TargetIndex Ind)
        {
            Toil toil = new Toil();

            toil.initAction = () =>
            {
                Pawn         actor = toil.GetActor();
                Vehicle_Cart cart  = toil.actor.jobs.curJob.GetTarget(CartInd).Thing as Vehicle_Cart;
                if (cart == null)
                {
                    Log.Error(actor.LabelCap + " Report: Cart is invalid.");
                    toil.actor.jobs.curDriver.EndJobWith(JobCondition.Errored);
                }
                Job job = new Job(jobDefStandby, toil.actor.jobs.curJob.GetTarget(Ind), defaultWaitWorker);
                cart.mountableComp.Driver.jobs.StartJob(job, JobCondition.InterruptForced);
            };
            return(toil);
        }
        public HeadLights(IntVec3 position, Rot4 orientation, Vehicle_Cart vehicleCart)
        {
            Position    = position;
            Orientation = orientation;

            //TODO move the colors to xml along with the angleModulus + targetDistance
            ColorCellIndexCache = new List <GlowGridCache>();
            //FloodBlockers = new List<FloodBlocker>();

            //Color = new Color32(191, 63, 191, 1);
            //Color = new Color32(254, 255, 179, 0);
            Color = new Color32(210, 210, 140, 0);


            innerArray = Find.EdificeGrid.InnerArray;

            targetDistance = 20;
            angleModulus   = 4; //0 is 90 and the higher you go the more narrow the angle. //angle 45 is every two tiles? - actually its 90 because left side is 0->45 and then right is 45<-0
        }
Exemple #15
0
        public static Toil ReleaseAnimalCart(TargetIndex CartInd)
        {
            Toil toil = new Toil();

            toil.initAction = () =>
            {
                Pawn         actor = toil.GetActor();
                Vehicle_Cart cart  = toil.actor.jobs.curJob.GetTarget(CartInd).Thing as Vehicle_Cart;
                if (cart == null)
                {
                    Log.Error(actor.LabelCap + " Report: Cart is invalid.");
                    toil.actor.jobs.curDriver.EndJobWith(JobCondition.Errored);
                }
                if (cart.mountableComp.IsMounted && cart.mountableComp.Driver.CurJob.def == jobDefStandby)
                {
                    cart.mountableComp.Driver.jobs.curDriver.EndJobWith(JobCondition.Succeeded);
                }
            };
            return(toil);
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            ///
            //Set fail conditions
            ///

            this.FailOnDestroyed(MountableInd);
            this.FailOnDowned(DriverInd);
            //Note we only fail on forbidden if the target doesn't start that way
            //This helps haul-aside jobs on forbidden items
            if (!TargetThingA.IsForbidden(pawn.Faction))
            {
                this.FailOnForbidden(MountableInd);
            }



            ///
            //Define Toil
            ///

            Toil toilMakeStandby = new Toil();

            toilMakeStandby.initAction = () =>
            {
                Pawn driver = CurJob.GetTarget(DriverInd).Thing as Pawn;
                driver.jobs.StartJob(new Job(DefDatabase <JobDef> .GetNamed("Standby"), driver.Position, 2400 + (int)((pawn.Position - driver.Position).LengthHorizontal * 120)), JobCondition.InterruptForced);
            };

            Toil toilGoto = null;

            toilGoto = Toils_Goto.GotoThing(MountableInd, PathEndMode.ClosestTouch)
                       .FailOn(() =>
            {
                //Note we don't fail on losing hauling designation
                //Because that's a special case anyway

                //While hauling to cell storage, ensure storage dest is still valid
                Pawn actor = toilGoto.actor;
                Job curJob = actor.jobs.curJob;
                if (curJob.haulMode == HaulMode.ToCellStorage)
                {
                    Thing haulThing = curJob.GetTarget(MountableInd).Thing;

                    IntVec3 destLoc = actor.jobs.curJob.GetTarget(TargetIndex.B).Cell;
                    if (!destLoc.IsValidStorageFor(haulThing))
                    {
                        return(true);
                    }
                }

                return(false);
            });

            Toil toilMountOn = new Toil();

            toilMountOn.initAction = () =>
            {
                Pawn driver = TargetB.Thing as Pawn;
                if (driver != null && TargetThingA.TryGetComp <CompMountable>() != null)
                {
                    TargetThingA.TryGetComp <CompMountable>().MountOn(driver);
                }
                else
                {
                    Log.Error(GetActor().LabelCap + ": Try make mount without target B Driver");
                    EndJobWith(JobCondition.Errored);
                }
            };

            Toil toilEnd = new Toil();

            toilEnd.initAction = () =>
            {
                Vehicle_Cart   cart   = CurJob.GetTarget(MountableInd).Thing as Vehicle_Cart;
                Vehicle_Saddle saddle = CurJob.GetTarget(MountableInd).Thing as Vehicle_Saddle;
                if (cart == null || saddle == null)
                {
                    Log.Error(GetActor().LabelCap + ": MakeMount get TargetA not cart or saddle.");
                    EndJobWith(JobCondition.Errored);
                    return;
                }
                if (cart.mountableComp.IsMounted && cart.mountableComp.Driver.CurJob.def == DefDatabase <JobDef> .GetNamed("Standby"))
                {
                    cart.mountableComp.Driver.jobs.curDriver.EndJobWith(JobCondition.Succeeded);
                }
                EndJobWith(JobCondition.Succeeded);
            };

            ///
            //Toils Start
            ///

            //Reserve thing to be stored and storage cell
            yield return(Toils_Reserve.Reserve(MountableInd));

            yield return(Toils_Reserve.Reserve(DriverInd));

            yield return(toilMakeStandby);

            yield return(toilGoto);

            yield return(Toils_Haul.StartCarryThing(MountableInd));

            yield return(Toils_Haul.CarryHauledThingToCell(DriverInd));

            yield return(toilMountOn);

            yield return(toilEnd);
        }
 public static bool AvailableCart(Vehicle_Cart cart, Pawn pawn)
 {
     return(!cart.TryGetComp <CompMountable>().IsMounted || cart.TryGetComp <CompMountable>().Driver == pawn);
 }
Exemple #18
0
        public static Toil WaitAnimalCart(TargetIndex CartInd, TargetIndex HaulableInd)
        {
            Toil toil     = new Toil();
            int  tickTime = 0;

            toil.initAction = () =>
            {
                Pawn         actor = toil.GetActor();
                Vehicle_Cart cart  = toil.actor.jobs.curJob.GetTarget(CartInd).Thing as Vehicle_Cart;
                if (cart == null)
                {
                    Log.Error(actor.LabelCap + " Report: Cart is invalid.");
                    toil.actor.jobs.curDriver.EndJobWith(JobCondition.Errored);
                }
                tickTime = 0;
                if (cart.mountableComp.IsMounted)
                {
                    //Worker is arrival and Animal cart is coming
                    if (cart.mountableComp.Driver.CurJob.def == jobDefStandby && !actor.Position.AdjacentTo8WayOrInside(cart))
                    {
                        tickTime = 0;
                    }
                    //Worker is arrival and Animal cart is arrival
                    else if (cart.mountableComp.Driver.CurJob.def == jobDefStandby && actor.Position.AdjacentTo8WayOrInside(cart))
                    {
                        toil.actor.jobs.curDriver.ReadyForNextToil();
                    }
                    //Worker is arrival but Animal cart is missing
                    else
                    {
                        Job job = new Job(jobDefStandby, actor.jobs.curJob.GetTarget(HaulableInd), defaultWaitWorker);
                        cart.mountableComp.Driver.jobs.StartJob(job, JobCondition.InterruptForced);
                    }
                }
                else
                {
                    toil.actor.jobs.curDriver.EndJobWith(JobCondition.Incompletable);
                }
            };
            toil.tickAction = () =>
            {
                Pawn         actor = toil.GetActor();
                Vehicle_Cart cart  = toil.actor.jobs.curJob.GetTarget(CartInd).Thing as Vehicle_Cart;
                if (cart == null)
                {
                    Log.Error(actor.LabelCap + " Report: Cart is invalid.");
                    toil.actor.jobs.curDriver.EndJobWith(JobCondition.Errored);
                }
                if (Find.TickManager.TicksGame % tickCheckInterval == 0)
                {
                    if (cart.mountableComp.IsMounted)
                    {
                        //Animal cart is arrival
                        if (cart.mountableComp.Driver.CurJob.def == jobDefStandby && actor.Position.AdjacentTo8WayOrInside(cart))
                        {
                            toil.actor.jobs.curDriver.ReadyForNextToil();
                        }
                        //Animal cart would never come. Imcompletable.
                        else if (cart.mountableComp.Driver.CurJob.def != jobDefStandby || tickTime >= defaultWaitWorker)
                        {
                            toil.actor.jobs.curDriver.EndJobWith(JobCondition.Incompletable);
                        }
                    }
                    else
                    {
                        toil.actor.jobs.curDriver.EndJobWith(JobCondition.Incompletable);
                    }
                }
            };
            toil.defaultCompleteMode = ToilCompleteMode.Never;
            return(toil);
        }
        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);
        }
Exemple #20
0
        protected override void FillTab()
        {
            float fieldHeight = 30.0f;

            Vehicle_Cart cart = this.SelThing as Vehicle_Cart;

            ConceptDatabase.KnowledgeDemonstrated(ConceptDefOf.PrisonerTab, KnowledgeAmount.GuiFrame);
            Text.Font = GameFont.Small;
            Rect innerRect1 = GenUI.ContractedBy(new Rect(0.0f, 0.0f, this.size.x, this.size.y), 10f);

            GUI.BeginGroup(innerRect1);
            Rect  mountedRect  = new Rect(0.0f, 30.0f, innerRect1.width, fieldHeight);
            float mountedRectY = mountedRect.y;

            Widgets.ListSeparator(ref mountedRectY, innerRect1.width, txtDriver.Translate());
            mountedRect.y += fieldHeight;
            Rect thingIconRect   = new Rect(mountedRect.x, mountedRect.y, 30f, fieldHeight);
            Rect thingLabelRect  = new Rect(mountedRect.x + 35f, mountedRect.y + 5.0f, innerRect1.width - 35f, fieldHeight);
            Rect thingButtonRect = new Rect(mountedRect.x, mountedRect.y, innerRect1.width, fieldHeight);

            if (cart.mountableComp.IsMounted)
            {
                Pawn driver = cart.mountableComp.Driver;
                Widgets.ThingIcon(thingIconRect, driver);
                Widgets.Label(thingLabelRect, driver.Label);
                if (Event.current.button == 1 && Widgets.InvisibleButton(thingButtonRect))
                {
                    List <FloatMenuOption> options  = new List <FloatMenuOption>();
                    FloatMenuOption        dismount = new FloatMenuOption(txtDismount.Translate(driver.LabelBase), () =>
                    {
                        cart.mountableComp.Dismount();
                    });
                    options.Add(dismount);

                    Find.WindowStack.Add(new FloatMenu(options));
                }
                thingIconRect.y  += fieldHeight;
                thingLabelRect.y += fieldHeight;
            }
            Rect  storageRect  = new Rect(0.0f, thingIconRect.y, innerRect1.width, fieldHeight);
            float storageRectY = storageRect.y;

            Widgets.ListSeparator(ref storageRectY, innerRect1.width, txtStorage.Translate());
            storageRect.y    += fieldHeight;
            thingIconRect.y   = storageRect.y;
            thingLabelRect.y  = storageRect.y;
            thingButtonRect.y = storageRect.y;
            foreach (var thing in cart.storage)
            {
                if ((thing.ThingID.IndexOf("Human_Corpse") <= -1) ? false : true)
                {
                    Widgets.DrawTextureFitted(thingIconRect, ContentFinder <Texture2D> .Get("Things/Pawn/IconHuman_Corpse"), 1.0f);
                }
                else if ((thing.ThingID.IndexOf("Corpse") <= -1) ? false : true)
                {
                    Corpse corpse = thing as Corpse;
                    Widgets.ThingIcon(thingIconRect, corpse.innerPawn.def);
                }
                else
                {
                    Widgets.ThingIcon(thingIconRect, thing);
                }
                Widgets.Label(thingLabelRect, thing.Label.Translate());
                if (Event.current.button == 1 && Widgets.InvisibleButton(thingButtonRect))
                {
                    List <FloatMenuOption> options = new List <FloatMenuOption>();
                    options.Add(new FloatMenuOption(Translator.Translate("ThingInfo"), () =>
                    {
                        Find.WindowStack.Add((Window) new Dialog_InfoCard(thing));
                    }));
                    options.Add(new FloatMenuOption(Translator.Translate("DropThing"), () =>
                    {
                        Thing dummy;
                        cart.storage.TryDrop(thing, cart.Position, ThingPlaceMode.Near, out dummy);
                    }));

                    Find.WindowStack.Add((Window) new FloatMenu(options, thing.LabelCap, false, false));
                }
                thingIconRect.y  += fieldHeight;
                thingLabelRect.y += fieldHeight;
            }
            if (Widgets.TextButton(new Rect(180f, 400f, 100f, 30f), "Drop All"))
            {
                cart.storage.TryDropAll(cart.Position, ThingPlaceMode.Near);
            }

            GUI.EndGroup();
        }
 public static bool AvailableCart(Vehicle_Cart cart, Pawn pawn)
 {
     return (!cart.TryGetComp<CompMountable>().IsMounted || cart.TryGetComp<CompMountable>().Driver == pawn);
 }
        public static Toil CollectInCarrier(TargetIndex CarrierInd, TargetIndex HaulableInd)
        {
            Toil toil = new Toil();

            toil.initAction = () =>
            {
                Pawn         actor     = toil.actor;
                Job          curJob    = actor.jobs.curJob;
                Thing        haulThing = curJob.GetTarget(HaulableInd).Thing;
                Vehicle_Cart carrier   = curJob.GetTarget(CarrierInd).Thing as Vehicle_Cart;
                //Check haulThing is human_corpse. If other race has apparel, It need to change

                Find.DesignationManager.RemoveAllDesignationsOn(haulThing);
                if ((haulThing.ThingID.IndexOf("Human_Corpse") <= -1) ? false : true)
                {
                    Corpse corpse      = (Corpse)haulThing;
                    var    wornApparel = corpse.innerPawn.apparel.WornApparel;

                    //Drop wornApparel. wornApparel cannot Add to container directly because it will be duplicated.
                    corpse.innerPawn.apparel.DropAll(corpse.innerPawn.Position, false);

                    //Transfer in container
                    foreach (Thing apparel in wornApparel)
                    {
                        if (carrier.storage.TryAdd(apparel))
                        {
                            apparel.holder       = carrier.GetContainer();
                            apparel.holder.owner = carrier;
                        }
                    }
                }
                //Collecting TargetIndex ind
                if (carrier.storage.TryAdd(haulThing))
                {
                    haulThing.holder       = carrier.GetContainer();
                    haulThing.holder.owner = carrier;
                }

                List <TargetInfo> thingList = curJob.GetTargetQueue(HaulableInd);
                for (int i = 0; i < thingList.Count; i++)
                {
                    if (actor.Position.AdjacentTo8Way(thingList[i].Thing.Position))
                    {
                        if (carrier.storage.TryAdd(thingList[i].Thing))
                        {
                            thingList[i].Thing.holder       = carrier.GetContainer();
                            thingList[i].Thing.holder.owner = carrier;
                        }
                        thingList.RemoveAt(i);
                        i--;
                    }
                }
            };
            toil.FailOn(() =>
            {
                Pawn actor           = toil.actor;
                Job curJob           = actor.jobs.curJob;
                Thing haulThing      = curJob.GetTarget(HaulableInd).Thing;
                Vehicle_Cart carrier = curJob.GetTarget(CarrierInd).Thing as Vehicle_Cart;

                if (!carrier.storage.CanAcceptAnyOf(haulThing) &&
                    actor.Position.IsAdjacentTo8WayOrInside(haulThing.Position, haulThing.Rotation, haulThing.RotatedSize))
                {
                    return(true);
                }
                return(false);
            });
            toil.FailOnDestroyedOrNull(CarrierInd);
            return(toil);
        }
Exemple #23
0
 private void ImpactSomething()
 {
     if (def.projectile.flyOverhead)
     {
         RoofDef roofDef = Find.RoofGrid.RoofAt(Position);
         if (roofDef != null)
         {
             if (roofDef.isThickRoof)
             {
                 def.projectile.soundHitThickRoof.PlayOneShot(Position);
                 Destroy();
                 return;
             }
             if (Position.GetEdifice() == null || Position.GetEdifice().def.Fillage != FillCategory.Full)
             {
                 RoofCollapserImmediate.DropRoofInCells(Position);
             }
         }
     }
     if (assignedTarget != null)
     {
         Pawn pawn = assignedTarget as Pawn;
         if (pawn != null && pawn.GetPosture() != PawnPosture.Standing && (origin - destination).MagnitudeHorizontalSquared() >= 20.25f && Rand.Value > 0.2f)
         {
             Impact(null);
             return;
         }
         Impact(assignedTarget);
         return;
     }
     else
     {
         cellThingsFiltered.Clear();
         List <Thing> thingList = Position.GetThingList();
         for (int i = 0; i < thingList.Count; i++)
         {
             Pawn pawn2 = thingList[i] as Pawn;
             if (pawn2 != null)
             {
                 cellThingsFiltered.Add(pawn2);
             }
             Vehicle_Cart cart = thingList[i] as Vehicle_Cart;
             if (cart != null)
             {
                 cellThingsFiltered.Add(cart);
             }
         }
         if (cellThingsFiltered.Count > 0)
         {
             Impact(cellThingsFiltered.RandomElement());
             return;
         }
         cellThingsFiltered.Clear();
         for (int j = 0; j < thingList.Count; j++)
         {
             Thing thing = thingList[j];
             if (thing.def.fillPercent > 0f || thing.def.passability != Traversability.Standable)
             {
                 cellThingsFiltered.Add(thing);
             }
         }
         if (cellThingsFiltered.Count > 0)
         {
             Impact(cellThingsFiltered.RandomElement());
             return;
         }
         Impact(null);
         return;
     }
 }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            Vehicle_Cart cart = CurJob.GetTarget(CartInd).Thing as Vehicle_Cart;

            ///
            //Set fail conditions
            ///

            this.FailOnDestroyedOrNull(CartInd);
            //Note we only fail on forbidden if the target doesn't start that way
            //This helps haul-aside jobs on forbidden items
            if (!TargetThingA.IsForbidden(pawn.Faction))
            {
                this.FailOnForbidden(CartInd);
            }


            ///
            //Define Toil
            ///

            Toil findStoreCellForCart = Toils_Cart.FindStoreCellForCart(CartInd);
            Toil checkCartEmpty       = Toils_Jump.JumpIf(findStoreCellForCart, () => cart.storage.Count <= 0);
            Toil checkStoreCellEmpty  = Toils_Jump.JumpIf(findStoreCellForCart, () => CurJob.GetTargetQueue(StoreCellInd).NullOrEmpty());
            Toil checkHaulableEmpty   = Toils_Jump.JumpIf(checkStoreCellEmpty, () => CurJob.GetTargetQueue(HaulableInd).NullOrEmpty());

            ///
            //Toils Start
            ///

            //Reserve thing to be stored and storage cell
            yield return(Toils_Reserve.Reserve(CartInd));

            yield return(Toils_Reserve.ReserveQueue(HaulableInd));

            yield return(Toils_Reserve.ReserveQueue(StoreCellInd));

            //JumpIf already mounted
            yield return(Toils_Jump.JumpIf(checkHaulableEmpty, () => { return (cart.GetComp <CompMountable>().Driver == pawn) ? true : false; }));

            //Mount on Target
            yield return(Toils_Goto.GotoThing(CartInd, PathEndMode.ClosestTouch)
                         .FailOnDestroyedOrNull(CartInd));

            yield return(Toils_Cart.MountOn(CartInd));

            //JumpIf checkStoreCellEmpty
            yield return(checkHaulableEmpty);

            //Collect TargetQueue
            {
                Toil extractA = Toils_Collect.Extract(HaulableInd);
                yield return(extractA);

                Toil gotoThing = Toils_Goto.GotoThing(HaulableInd, PathEndMode.ClosestTouch)
                                 .FailOnDestroyedOrNull(HaulableInd);
                yield return(gotoThing);

                yield return(Toils_Collect.CollectInCarrier(CartInd, HaulableInd));

                yield return(Toils_Collect.CheckDuplicates(gotoThing, CartInd, HaulableInd));

                yield return(Toils_Jump.JumpIfHaveTargetInQueue(HaulableInd, extractA));
            }

            //JumpIf findStoreCellForCart
            yield return(checkStoreCellEmpty);

            //Drop TargetQueue
            {
                yield return(checkCartEmpty);

                Toil extractB = Toils_Collect.Extract(StoreCellInd);
                yield return(extractB);

                Toil gotoCell = Toils_Goto.GotoCell(StoreCellInd, PathEndMode.ClosestTouch);
                yield return(gotoCell);

                yield return(Toils_Collect.DropTheCarriedInCell(StoreCellInd, ThingPlaceMode.Direct, CartInd));

                yield return(Toils_Jump.JumpIfHaveTargetInQueue(StoreCellInd, checkCartEmpty));

                yield return(Toils_Collect.CheckNeedStorageCell(gotoCell, CartInd, StoreCellInd));
            }

            yield return(findStoreCellForCart);

            yield return(Toils_Goto.GotoCell(StoreCellInd, PathEndMode.OnCell));

            yield return(Toils_Cart.DismountAt(CartInd, StoreCellInd));
        }
Exemple #25
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            Vehicle_Cart cart   = CurJob.GetTarget(CartInd).Thing as Vehicle_Cart;
            Job          jobNew = new Job();

            ///
            //Set fail conditions
            ///

            this.FailOnDestroyed(CartInd);
            this.FailOn(() => !cart.mountableComp.IsMounted);
            //Note we only fail on forbidden if the target doesn't start that way
            //This helps haul-aside jobs on forbidden items
            if (!TargetThingA.IsForbidden(pawn.Faction))
            {
                this.FailOnForbidden(CartInd);
            }

            ///
            //Define Toil
            ///

            Toil releaseAnimalCart   = Toils_Cart.ReleaseAnimalCart(CartInd);
            Toil checkCartEmpty      = Toils_Jump.JumpIf(releaseAnimalCart, () => cart.storage.Count <= 0);
            Toil checkStoreCellEmpty = Toils_Jump.JumpIf(releaseAnimalCart, () => CurJob.GetTargetQueue(StoreCellInd).NullOrEmpty());
            Toil checkHaulableEmpty  = Toils_Jump.JumpIf(checkStoreCellEmpty, () => CurJob.GetTargetQueue(HaulableInd).NullOrEmpty());

            ///
            //Toils Start
            ///

            //Reserve thing to be stored and storage cell
            yield return(Toils_Reserve.Reserve(CartInd));

            yield return(Toils_Reserve.ReserveQueue(HaulableInd));

            yield return(Toils_Reserve.ReserveQueue(StoreCellInd));

            yield return(Toils_Goto.GotoThing(CartInd, PathEndMode.Touch)
                         .FailOn(() => cart.Destroyed || !cart.TryGetComp <CompMountable>().IsMounted));

            //JumpIf toilCheckStoreCellEmpty
            yield return(checkHaulableEmpty);

            //Collect TargetQueue
            {
                Toil extractA = Toils_Collect.Extract(HaulableInd);
                yield return(extractA);

                Toil callAnimalCartForCollect = Toils_Cart.CallAnimalCart(CartInd, HaulableInd)
                                                .FailOnDestroyed(HaulableInd);
                yield return(callAnimalCartForCollect);

                yield return(Toils_Goto.GotoThing(HaulableInd, PathEndMode.ClosestTouch)
                             .FailOnDestroyed(HaulableInd));

                yield return(Toils_Cart.WaitAnimalCart(CartInd, HaulableInd));

                yield return(Toils_Collect.CollectInCarrier(CartInd, HaulableInd));

                yield return(Toils_Collect.CheckDuplicates(callAnimalCartForCollect, CartInd, HaulableInd));

                yield return(Toils_Jump.JumpIfHaveTargetInQueue(HaulableInd, extractA));
            }

            //JumpIf releaseAnimalCart
            yield return(checkStoreCellEmpty);

            //Drop TargetQueue
            {
                yield return(checkCartEmpty);

                Toil extractB = Toils_Collect.Extract(StoreCellInd);
                yield return(extractB);

                Toil callAnimalCartForDrop = Toils_Cart.CallAnimalCart(CartInd, StoreCellInd);
                yield return(callAnimalCartForDrop);

                yield return(Toils_Goto.GotoCell(StoreCellInd, PathEndMode.ClosestTouch)
                             .FailOnBurningImmobile(StoreCellInd));

                yield return(Toils_Cart.WaitAnimalCart(CartInd, HaulableInd));

                yield return(Toils_Collect.DropTheCarriedInCell(StoreCellInd, ThingPlaceMode.Direct, CartInd));

                yield return(Toils_Jump.JumpIfHaveTargetInQueue(StoreCellInd, checkCartEmpty));

                yield return(Toils_Collect.CheckNeedStorageCell(callAnimalCartForDrop, CartInd, StoreCellInd));
            }

            yield return(releaseAnimalCart);
        }
        /// <summary>
        /// Selects the appropriate vehicle by worktype
        /// </summary>
        /// <param name="pawn"></param>
        /// <param name="worktype"></param>
        /// <returns></returns>
        public static Thing GetRightVehicle(Pawn pawn, WorkTypeDef worktype, Thing t = null)
        {
            Thing cart = null;

            if (worktype.Equals(WorkTypeDefOf.Hunting))
            {
                bool skip = false;
                IOrderedEnumerable <Thing> orderedEnumerable =
                    ToolsForHaulUtility.CartTurret.OrderBy(x => pawn.Position.DistanceToSquared(x.Position));
                foreach (Thing thing in orderedEnumerable)
                {
                    Vehicle_Turret vehicleTurret = (Vehicle_Turret)thing;
                    if (vehicleTurret == null)
                    {
                        continue;
                    }
                    if (!ToolsForHaulUtility.AvailableVehicle(pawn, vehicleTurret))
                    {
                        continue;
                    }
                    if (!vehicleTurret.IsCurrentlyMotorized())
                    {
                        continue;
                    }
                    if (vehicleTurret.vehicleComp.tankLeaking)
                    {
                        continue;
                    }
                    cart = vehicleTurret;
                    skip = true;
                    break;
                }
                if (!skip)
                {
                    IOrderedEnumerable <Thing> orderedEnumerable2 =
                        ToolsForHaulUtility.Cart.OrderBy(x => pawn.Position.DistanceToSquared(x.Position));
                    foreach (Thing thing in orderedEnumerable2)
                    {
                        Vehicle_Cart vehicleCart = (Vehicle_Cart)thing;
                        if (vehicleCart == null)
                        {
                            continue;
                        }
                        if (!ToolsForHaulUtility.AvailableVehicle(pawn, vehicleCart))
                        {
                            continue;
                        }
                        if (!vehicleCart.IsCurrentlyMotorized())
                        {
                            continue;
                        }
                        if (vehicleCart.vehicleComp.tankLeaking)
                        {
                            continue;
                        }
                        cart = vehicleCart;
                        break;
                    }
                }
            }
            if (worktype.Equals(WorkTypeDefOf.Hauling))
            {
                IOrderedEnumerable <Thing> orderedEnumerable2 =
                    ToolsForHaulUtility.Cart.OrderByDescending(x => (x as Vehicle_Cart).MaxItem).ThenBy(x => pawn.Position.DistanceToSquared(x.Position));

                foreach (Thing thing in orderedEnumerable2)
                {
                    Vehicle_Cart vehicleCart = (Vehicle_Cart)thing;
                    if (vehicleCart == null)
                    {
                        continue;
                    }
                    if (!ToolsForHaulUtility.AvailableVehicle(pawn, vehicleCart))
                    {
                        continue;
                    }
                    if (vehicleCart.vehicleComp.tankLeaking)
                    {
                        continue;
                    }
                    cart = vehicleCart;
                    break;
                }
            }
            if (worktype.Equals(WorkTypeDefOf.Construction))
            {
                IOrderedEnumerable <Thing> orderedEnumerable2 =
                    ToolsForHaulUtility.Cart.OrderBy(x => pawn.Position.DistanceToSquared(x.Position)).ThenByDescending(x => (x as Vehicle_Cart).VehicleSpeed);
                foreach (Thing thing in orderedEnumerable2)
                {
                    Vehicle_Cart vehicleCart = (Vehicle_Cart)thing;
                    if (vehicleCart == null)
                    {
                        continue;
                    }
                    if (!ToolsForHaulUtility.AvailableVehicle(pawn, vehicleCart))
                    {
                        continue;
                    }
                    if (!vehicleCart.IsCurrentlyMotorized())
                    {
                        continue;
                    }
                    if (vehicleCart.vehicleComp.tankLeaking)
                    {
                        continue;
                    }
                    cart = vehicleCart;
                    break;
                }
            }
            return(cart);
        }
        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;
        }
Exemple #28
0
        public static Toil FindStoreCellForCart(TargetIndex CartInd)
        {
            const int NearbyCell       = 8;
            const int RegionCellOffset = 16;
            IntVec3   invalid          = new IntVec3(0, 0, 0);

            #if DEBUG
            StringBuilder stringBuilder = new StringBuilder();
            #endif
            Toil toil = new Toil();
            toil.initAction = () =>
            {
                IntVec3      storeCell = IntVec3.Invalid;
                Pawn         actor     = toil.GetActor();
                Vehicle_Cart cart      = toil.actor.jobs.curJob.GetTarget(CartInd).Thing as Vehicle_Cart;
                if (cart == null)
                {
                    Log.Error(actor.LabelCap + " Report: Cart is invalid.");
                    toil.actor.jobs.curDriver.EndJobWith(JobCondition.Errored);
                }
                //Find Valid Storage
                foreach (IntVec3 cell in GenRadial.RadialCellsAround(cart.Position, NearbyCell, false))
                {
                    if (cell.IsValidStorageFor(cart) &&
                        ReservationUtility.CanReserveAndReach(actor, cell, PathEndMode.ClosestTouch, DangerUtility.NormalMaxDanger(actor)))
                    {
                        storeCell = cell;
                        #if DEBUG
                        stringBuilder.AppendLine("Found cell: " + storeCell);
                        #endif
                    }
                }

                if (storeCell == IntVec3.Invalid)
                {
                    //Regionwise Flood-fill cellFinder
                    int           regionInd = 0;
                    List <Region> regions   = new List <Region>();
                    regions.Add(cart.Position.GetRegion());
                    #if DEBUG
                    stringBuilder.AppendLine(actor.LabelCap + " Report");
                    #endif
                    bool flag1 = false;
                    while (regionInd < regions.Count)
                    {
                        #if DEBUG
                        stringBuilder.AppendLine("Region id: " + regions[regionInd].id);
                        #endif
                        if (regions[regionInd].extentsClose.Center.InHorDistOf(cart.Position, NearbyCell + RegionCellOffset))
                        {
                            IntVec3 foundCell     = IntVec3.Invalid;
                            IntVec3 distCell      = (regionInd > 0)? regions[regionInd - 1].extentsClose.Center : cart.Position;
                            float   distFoundCell = float.MaxValue;
                            foreach (IntVec3 cell in regions[regionInd].Cells)
                            {
                                //Find best cell for placing cart
                                if (cell.GetEdifice() == null && cell.GetZone() == null && cell.Standable() &&
                                    !GenAdj.CellsAdjacentCardinal(cell, Rot4.North, IntVec2.One).Any(cardinal => cardinal.GetEdifice() is Building_Door) &&
                                    ReservationUtility.CanReserveAndReach(actor, cell, PathEndMode.ClosestTouch, DangerUtility.NormalMaxDanger(actor)))
                                {
                                    if (distCell.DistanceToSquared(cell) < distFoundCell)
                                    {
                                        foundCell     = cell;
                                        distFoundCell = distCell.DistanceToSquared(cell);
                                        flag1         = true;
                                    }
                                }
                            }
                            if (flag1 == true)
                            {
                                storeCell = foundCell;
                                #if DEBUG
                                stringBuilder.AppendLine("Found cell: " + storeCell);
                                #endif
                                break;
                            }
                            foreach (RegionLink link in regions[regionInd].links)
                            {
                                if (regions.Contains(link.RegionA) == false)
                                {
                                    regions.Add(link.RegionA);
                                }
                                if (regions.Contains(link.RegionB) == false)
                                {
                                    regions.Add(link.RegionB);
                                }
                            }
                        }
                        regionInd++;
                    }
                }
                //Log.Message(stringBuilder.ToString());

                /*
                 * //Home Area
                 * if (storeCell == IntVec3.Invalid)
                 *  foreach (IntVec3 cell in Find.AreaHome.ActiveCells.Where(cell => (cell.GetZone() == null || cell.IsValidStorageFor(cart)) && cell.Standable() && cell.GetEdifice() == null))
                 *      if (cell.DistanceToSquared(cart.Position) < NearbyCell)
                 *          storeCell = cell;
                 */
                ReservationUtility.Reserve(actor, storeCell);
                toil.actor.jobs.curJob.targetB = (storeCell != invalid && storeCell != IntVec3.Invalid) ? storeCell : cart.Position;
            };
            return(toil);
        }