Beispiel #1
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            ///
            //Set fail conditions
            ///

            this.FailOnDestroyed(HaulableInd);
            this.FailOnDestroyed(CarrierInd);
            //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(HaulableInd);
            }



            ///
            //Define Toil
            ///
            Toil toilGoto = null;

            toilGoto = Toils_Goto.GotoThing(HaulableInd, PathMode.ClosestTouch)
                       .FailOn(() =>
            {
                Vehicle_Cargo vc = CurJob.GetTarget(CarrierInd).Thing as Vehicle_Cargo;

                if (!vc.storage.CanAcceptAnyOf(CurJob.GetTarget(HaulableInd).Thing))
                {
                    return(true);
                }
                return(false);
            });



            ///
            //Toils Start
            ///

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

            //Collect Target
            yield return(toilGoto);

            yield return(ToolsForHaul.Toils_Collect.CollectThing(HaulableInd, CarrierInd));
        }
        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);
            }
        }
        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);
        }