public override Job GetJob(Pawn meeseeks, CompMeeseeksMemory memory, SavedJob savedJob, SavedTargetInfo jobTarget, ref JobAvailability jobAvailabilty)
        {
            Job job = null;

            WorkGiver_Scanner scanner = savedJob.WorkGiverScanner;

            if (scanner != null && jobTarget != null && jobTarget.HasThing && !jobTarget.ThingDestroyed && jobTarget.Thing is Pawn)
            {
                Pawn targetPawn = jobTarget.Thing as Pawn;

                if (targetPawn.Dead)
                {
                    Logger.MessageFormat(this, "{0} dead.", targetPawn);
                    jobAvailabilty = JobAvailability.Complete;
                }
                else if (this.TrainingCompleted(meeseeks, targetPawn, jobTarget))
                {
                    jobAvailabilty = JobAvailability.Complete;
                }
                else if (targetPawn.RaceProps.EatsFood && !HasFoodToInteractAnimal(meeseeks, targetPawn))
                {
                    job = TakeFoodForAnimalInteractJob(meeseeks, targetPawn);
                }
                else if (TrainableUtility.TrainedTooRecently(targetPawn))
                {
                    jobAvailabilty = JobAvailability.Delayed;
                }
                else if (targetPawn.MapHeld != meeseeks.MapHeld)
                {
                    Logger.MessageFormat(this, "{0} not on map with {1}.", targetPawn);
                    job = ExitMapJob(meeseeks);
                }
                else if (targetPawn.Spawned)
                {
                    job = this.GetJobOnTarget(meeseeks, jobTarget, scanner);

                    if (job == null)
                    {
                        jobAvailabilty = JobAvailability.Delayed;
                    }
                }
                else
                {
                    Logger.WarningFormat(this, "Could not get handling job for {0}.", targetPawn);
                    jobAvailabilty = JobAvailability.Delayed;
                }
            }
            else
            {
                Logger.WarningFormat(this, "Unable to get scanner or target for job.");
            }

            if (job != null)
            {
                jobAvailabilty = JobAvailability.Available;
            }

            return(job);
        }
        public override Job GetJob(Pawn meeseeks, CompMeeseeksMemory memory, SavedJob savedJob, SavedTargetInfo jobTarget, ref JobAvailability jobAvailabilty)
        {
            Map map = meeseeks.MapHeld;
            Job job = ScanForJob(meeseeks, memory, savedJob, jobTarget, ref jobAvailabilty);

            // Mark them now because building a roof will cover most if them, and we will need a chance to check their neighbors
            CollectNewTargets(meeseeks, memory, jobTarget.Cell, map);

            if (job != null)
            {
                jobAvailabilty = JobAvailability.Available;
            }

            return(job);
        }
Beispiel #3
0
        private Job GetNextJob(Pawn meeseeks, CompMeeseeksMemory memory)
        {
            Job nextJob = null;

            SavedJob savedJob = memory.savedJob;

            if (savedJob == null)
            {
                Logger.MessageFormat(this, "No saved job...");
                return(null);
            }

            if (memory.jobStuck)
            {
                Logger.MessageFormat(this, "Wait a tick...");
                return(JobMaker.MakeJob(JobDefOf.Wait_MaintainPosture, 1));
            }

            //Logger.MessageFormat(this, "Job target count: {0}", memory.jobTargets.Count);

            Map map = meeseeks.MapHeld;

            List <SavedTargetInfo> delayedTargets = new List <SavedTargetInfo>();
            MeeseeksJobSelector    jobSelector    = defaultJobSelector;

            foreach (MeeseeksJobSelector eachJobSelector in jobSelectors)
            {
                if (eachJobSelector.UseForJob(meeseeks, memory, savedJob))
                {
                    jobSelector = eachJobSelector;
                    break;
                }
            }

            try
            {
                jobSelector.SortAndFilterJobTargets(meeseeks, memory, savedJob);

                while (memory.jobTargets.Count > 0 && nextJob == null)
                {
                    JobAvailability jobAvailabilty = JobAvailability.Invalid;
                    SavedTargetInfo jobTarget      = memory.jobTargets.FirstOrDefault();

                    if (jobTarget == null || !jobTarget.IsValid)
                    {
                        Logger.WarningFormat(this, "Invalid or null target in queue");
                        memory.jobTargets.RemoveAt(0);
                        continue;
                    }

                    nextJob = jobSelector.GetJob(meeseeks, memory, savedJob, jobTarget, ref jobAvailabilty);
                    //Logger.MessageFormat(this, "Job selector: {0}, result: {1}", jobSelector.GetType().ToString(), jobAvailabilty.ToString());

                    if (nextJob != null)
                    {
                        bool reservationsMade = nextJob.TryMakePreToilReservations(meeseeks, false);
                        if (!reservationsMade)
                        {
                            jobAvailabilty = JobAvailability.Delayed;
                            Logger.MessageFormat(this, "Delaying job for {0} because reservations could not be made.", jobTarget.ToString());

                            nextJob = null;
                        }
                    }

                    if (jobAvailabilty == JobAvailability.Delayed)
                    {
                        delayedTargets.Add(jobTarget);
                        memory.jobTargets.RemoveAt(0);
                    }
                    else if (nextJob == null)
                    {
                        memory.jobTargets.RemoveAt(0);
                    }
                }

                if (delayedTargets.Count > 0 && nextJob == null)
                {
                    nextJob = jobSelector.GetJobDelayed(meeseeks, memory, savedJob, delayedTargets[0]);
                }
            }
            finally
            {
                // Put delayed targets back on the target list
                memory.jobTargets.AddRange(delayedTargets);
            }
            return(nextJob);
        }
Beispiel #4
0
        public override Job GetJob(Pawn meeseeks, CompMeeseeksMemory memory, SavedJob savedJob, SavedTargetInfo jobTarget, ref JobAvailability jobAvailabilty)
        {
            Job job = null;

            if (jobTarget != null && jobTarget.HasThing && !jobTarget.ThingDestroyed)
            {
                CompHasButton hasButton = jobTarget.Thing.TryGetComp <CompHasButton>();

                if (!hasButton.WantsPress)
                {
                    jobAvailabilty = JobAvailability.Complete;
                }
            }
            else
            {
                Logger.WarningFormat(this, "Unable to get scanner or target for job.");
            }

            if (job != null)
            {
                jobAvailabilty = JobAvailability.Available;
            }

            return(job);
        }
Beispiel #5
0
        protected Job ScanForJob(Pawn meeseeks, CompMeeseeksMemory memory, SavedJob savedJob, SavedTargetInfo jobTarget, ref JobAvailability jobAvailabilty, bool scanAllThingsOnCell = false)
        {
            Job job = null;

            if (savedJob.workGiverDef != null && savedJob.workGiverDef.Worker != null)
            {
                WorkGiver_Scanner workGiverScanner = savedJob.workGiverDef.Worker as WorkGiver_Scanner;
                if (workGiverScanner != null)
                {
                    List <WorkGiver_Scanner> workGivers = WorkerDefUtility.GetCombinedWorkGiverScanners(workGiverScanner);

                    foreach (WorkGiver_Scanner scanner in workGivers)
                    {
                        job = this.GetJobOnTarget(meeseeks, jobTarget, scanner, scanAllThingsOnCell);

                        if (job != null)
                        {
                            if (memory.JobStuckRepeat(job))
                            {
                                Logger.ErrorFormat(this, "Stuck job detected and removed on {0}.", jobTarget);
                                jobAvailabilty = JobAvailability.Delayed;
                                job            = null;
                            }
                            else
                            {
                                //Logger.MessageFormat(this, "Job WAS found for {0}.", scanner.def.defName);
                                jobAvailabilty = JobAvailability.Available;
                                return(job);
                            }
                        }

                        //Logger.MessageFormat(this, "No {0} job found.", scanner.def.defName);
                    }
                }
                else
                {
                    Logger.WarningFormat(this, "No work scanner");
                }
            }
            else
            {
                Logger.WarningFormat(this, "Missing saved job workGiverDef or Worker for savedJob: {0}", savedJob.def.defName);
            }

            return(job);
        }
        public override Job GetJob(Pawn meeseeks, CompMeeseeksMemory memory, SavedJob savedJob, SavedTargetInfo jobTarget, ref JobAvailability jobAvailabilty)
        {
            bool wait = true;

            IntVec3 guardPosition = memory.guardPosition;

            if (memory.guardPosition.IsValid && meeseeks.Position != guardPosition)
            {
                guardPosition = RCellFinder.BestOrderedGotoDestNear(memory.guardPosition, meeseeks);
                if (guardPosition.IsValid && meeseeks.Position != guardPosition)
                {
                    wait = false;
                }
            }

            Job job = null;

            if (wait)
            {
                Logger.MessageFormat(this, "Wait");
                job = JobMaker.MakeJob(JobDefOf.Wait_Combat, memory.guardPosition);
                job.expiryInterval = 600;
            }
            else
            {
                Logger.MessageFormat(this, "Goto spot");
                job = JobMaker.MakeJob(JobDefOf.Goto, guardPosition);
                job.expiryInterval = 120;
            }

            return(job);
        }
Beispiel #7
0
 public virtual Job GetJob(Pawn meeseeks, CompMeeseeksMemory memory, SavedJob savedJob, SavedTargetInfo jobTarget, ref JobAvailability jobAvailabilty)
 {
     return(ScanForJob(meeseeks, memory, savedJob, jobTarget, ref jobAvailabilty));
 }
        public override Job GetJob(Pawn meeseeks, CompMeeseeksMemory memory, SavedJob savedJob, SavedTargetInfo jobTarget, ref JobAvailability jobAvailabilty)
        {
            Job job = null;

            ConstructionStatus status = jobTarget.TargetConstructionStatus(meeseeks.MapHeld);

            Logger.MessageFormat(this, "Checking for blocker, construction status: {0}", status);

            if (status == ConstructionStatus.None)
            {
                BuildableDef buildableDef = jobTarget.BuildableDef;

                if (buildableDef != null && GenConstruct.PlaceBlueprintForBuild(buildableDef, jobTarget.Cell, meeseeks.MapHeld, jobTarget.blueprintRotation, meeseeks.Faction, jobTarget.blueprintStuff) != null)
                {
                    status = ConstructionStatus.InProgress;
                }
            }

            if (status == ConstructionStatus.Blocked)
            {
                job = GetDeconstructingJob(meeseeks, jobTarget, meeseeks.MapHeld);
                if (job == null)
                {
                    jobAvailabilty = JobAvailability.Delayed;
                }
                else
                {
                    jobAvailabilty = JobAvailability.Available;
                }
            }
            else if (status == ConstructionStatus.InProgress)
            {
                job = ScanForJob(meeseeks, memory, savedJob, jobTarget, ref jobAvailabilty, true);
                if (job == null)
                {
                    jobAvailabilty = JobAvailability.Delayed;
                }
                else
                {
                    jobAvailabilty = JobAvailability.Available;
                }
            }
            else if (status == ConstructionStatus.Complete)
            {
                jobAvailabilty = JobAvailability.Complete;
            }

            return(job);
        }
        private Job GetMedicalBillJob(Pawn meeseeks, CompMeeseeksMemory memory, SavedJob savedJob, SavedTargetInfo jobTarget, ref JobAvailability jobAvailabilty)
        {
            Bill_Medical bill = jobTarget.bill as Bill_Medical;
            Job          job  = null;

            if (jobTarget != null && jobTarget.HasThing && !jobTarget.ThingDestroyed && jobTarget.Thing is Pawn && !(jobTarget.Thing as Pawn).Dead)
            {
                Pawn targetPawn = jobTarget.Thing as Pawn;
                if (targetPawn == null || targetPawn.Dead || !bill.CompletableEver)
                {
                    bill.deleted   = true;
                    jobAvailabilty = JobAvailability.Complete;
                }
                else
                {
                    MeeseeksBillStorage billStorage = Current.Game.World.GetComponent <MeeseeksBillStorage>();
                    BillStack           billStack   = targetPawn.BillStack;

                    jobAvailabilty = JobAvailability.Delayed;

                    if (targetPawn.UsableForBillsAfterFueling() && meeseeks.CanReserve(targetPawn, 1, -1, null, true))
                    {
                        List <ThingCount> chosenIngredients = new List <ThingCount>();
                        // Screw you I need this function
                        bool result = (bool)typeof(WorkGiver_DoBill).GetMethod("TryFindBestBillIngredients", BindingFlags.NonPublic | BindingFlags.Static).Invoke(null, new object[] { bill, meeseeks, targetPawn, chosenIngredients });

                        if (result)
                        {
                            Job haulOffJob;
                            job = WorkGiver_DoBill.TryStartNewDoBillJob(meeseeks, bill, targetPawn, chosenIngredients, out haulOffJob);
                            bill.billStack.billGiver = targetPawn as IBillGiver;
                        }

                        if (job == null)
                        {
                            jobAvailabilty = JobAvailability.Delayed;
                        }
                        else
                        {
                            jobAvailabilty = JobAvailability.Available;
                        }
                    }
                }
            }
            else
            {
                bill.deleted   = true;
                jobAvailabilty = JobAvailability.Complete;
            }

            return(job);
        }
        public override Job GetJob(Pawn meeseeks, CompMeeseeksMemory memory, SavedJob savedJob, SavedTargetInfo jobTarget, ref JobAvailability jobAvailabilty)
        {
            Bill bill = jobTarget.bill;

            Logger.MessageFormat(this, "Checking for bill job...");

            if (bill == null)
            {
                return(ScanForJob(meeseeks, memory, savedJob, jobTarget, ref jobAvailabilty));
            }

            if (bill.deleted)
            {
                jobAvailabilty = JobAvailability.Complete;
                return(null);
            }

            if (bill is Bill_Medical)
            {
                return(GetMedicalBillJob(meeseeks, memory, savedJob, jobTarget, ref jobAvailabilty));
            }
            else if (bill is Bill_Production)
            {
                return(GetProductionBillJob(meeseeks, memory, savedJob, jobTarget, ref jobAvailabilty));
            }

            return(null);
        }
        private Job GetProductionBillJob(Pawn meeseeks, CompMeeseeksMemory memory, SavedJob savedJob, SavedTargetInfo jobTarget, ref JobAvailability jobAvailabilty)
        {
            Bill_Production bill = jobTarget.bill as Bill_Production;
            Job             job  = null;

            Logger.MessageFormat(this, "Checking for production bill job...");

            if (bill.repeatMode == BillRepeatModeDefOf.RepeatCount && bill.repeatCount < 1)
            {
                bill.deleted   = true;
                jobAvailabilty = JobAvailability.Complete;
                return(null);
            }
            else if (bill.repeatMode == BillRepeatModeDefOf.TargetCount)
            {
                // Might be here without a billgiver (after a save?) so try to set the current target
                if (jobTarget.Thing != null)
                {
                    bill.billStack.billGiver = jobTarget.Thing as IBillGiver;
                }

                // Otherwise count them later I guess :P
                if (bill.Map != null)
                {
                    int productCount = bill.recipe.WorkerCounter.CountProducts(bill);
                    if (productCount >= bill.targetCount)
                    {
                        bill.deleted   = true;
                        jobAvailabilty = JobAvailability.Complete;
                        return(null);
                    }
                }
            }

            Logger.MessageFormat(this, "Checking workstations...");

            bool workStationValid = (jobTarget.HasThing && !jobTarget.ThingDestroyed &&
                                     meeseeks.CanReserve(jobTarget.Thing, 1, -1, null, false) &&
                                     ((jobTarget.Thing as IBillGiver).CurrentlyUsableForBills() || (jobTarget.Thing as IBillGiver).UsableForBillsAfterFueling()));

            if (!workStationValid)
            {
                Logger.MessageFormat(this, "We think the workstation is invalid looking for new one");
                List <Building> buildings = meeseeks.MapHeld.listerBuildings.allBuildingsColonist.Where(building => building is IBillGiver &&
                                                                                                        savedJob.workGiverDef.fixedBillGiverDefs.Contains(building.def) &&
                                                                                                        meeseeks.CanReserve(building, 1, -1, null, false) &&
                                                                                                        ((building as IBillGiver).CurrentlyUsableForBills() || (building as IBillGiver).UsableForBillsAfterFueling())).ToList();

                if (buildings.Count > 0)
                {
                    Logger.MessageFormat(this, "Found new one");

                    buildings.Sort((a, b) => (int)(meeseeks.PositionHeld.DistanceTo(a.Position) - meeseeks.PositionHeld.DistanceTo(b.Position)));
                    jobTarget.target = buildings[0];
                    workStationValid = true;
                }
                else
                {
                    Logger.MessageFormat(this, "Found no alternate workstations...");
                }
            }
            else
            {
                Logger.MessageFormat(this, "We think the workstation is valid...");
            }

            if (workStationValid)
            {
                IBillGiver billGiver = jobTarget.Thing as IBillGiver;
                bill.billStack.billGiver = billGiver;

                Bill_ProductionWithUft bill_ProductionWithUft = bill as Bill_ProductionWithUft;
                if (bill_ProductionWithUft != null)
                {
                    if (bill_ProductionWithUft.BoundUft != null)
                    {
                        if (bill_ProductionWithUft.BoundUft.Creator.kindDef == MeeseeksDefOf.MeeseeksKind && meeseeks.CanReserveAndReach(bill_ProductionWithUft.BoundUft, PathEndMode.Touch, Danger.Deadly))
                        {
                            job = FinishUftJob(meeseeks, bill_ProductionWithUft.BoundUft, bill_ProductionWithUft, billGiver);
                        }
                    }
                    else
                    {
                        Predicate <Thing> validator       = (Thing t) => ((UnfinishedThing)t).Recipe == bill.recipe && ((UnfinishedThing)t).Creator.kindDef == MeeseeksDefOf.MeeseeksKind && ((UnfinishedThing)t).ingredients.TrueForAll((Thing x) => bill.IsFixedOrAllowedIngredient(x.def)) && meeseeks.CanReserve(t);
                        UnfinishedThing   unfinishedThing = (UnfinishedThing)GenClosest.ClosestThingReachable(meeseeks.Position, meeseeks.Map, ThingRequest.ForDef(bill.recipe.unfinishedThingDef), PathEndMode.InteractionCell, TraverseParms.For(meeseeks), 9999f, validator);
                        if (unfinishedThing != null)
                        {
                            job = FinishUftJob(meeseeks, unfinishedThing, bill_ProductionWithUft, billGiver);
                        }
                    }
                }

                if (job == null)
                {
                    List <ThingCount> chosenIngredients = new List <ThingCount>();
                    // Screw you I need this function
                    bool result = (bool)typeof(WorkGiver_DoBill).GetMethod("TryFindBestBillIngredients", BindingFlags.NonPublic | BindingFlags.Static).Invoke(null, new object[] { bill, meeseeks, jobTarget.Thing, chosenIngredients });

                    if (result)
                    {
                        Job haulOffJob = null;
                        job = WorkGiver_DoBill.TryStartNewDoBillJob(meeseeks, bill, billGiver, chosenIngredients, out haulOffJob);
                    }
                }
            }

            if (job == null)
            {
                jobAvailabilty = JobAvailability.Delayed;
            }
            else
            {
                jobAvailabilty = JobAvailability.Available;
            }

            return(job);
        }