public override ThinkResult TryIssueJobPackage(Pawn pawn, JobIssueParams jobParams) { Logger.MessageFormat(this, "Checking for saved job on Meeseeks."); CompMeeseeksMemory compMeeseeksMemory = pawn.GetComp <CompMeeseeksMemory>(); if (compMeeseeksMemory != null && compMeeseeksMemory.GivenTask) { SavedJob savedJob = compMeeseeksMemory.savedJob; if (savedJob == null || CompMeeseeksMemory.noContinueJobs.Contains(savedJob.def)) { return(ThinkResult.NoJob); } Job nextJob = GetNextJob(pawn, compMeeseeksMemory); if (nextJob == null && compMeeseeksMemory.jobTargets.Count == 0) { nextJob = JobMaker.MakeJob(MeeseeksDefOf.CM_Meeseeks_Box_Job_EmbraceTheVoid); } if (nextJob != null) { return(new ThinkResult(nextJob, this, JobTag.MiscWork, fromQueue: false)); } } return(ThinkResult.NoJob); }
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); }
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); }
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); }
private void RenderHighlightOverSelectableCells(List <IntVec3> dragCells) { SavedJob savedJob = Memory.savedJob; if (savedJob != null) { if (savedJob.workGiverDef != null) { WorkGiver_Scanner workGiverScanner = savedJob.workGiverDef.Worker as WorkGiver_Scanner; foreach (IntVec3 cell in dragCells) { if (cachedCellResults.ContainsKey(cell) && cachedCellResults[cell] == true) { RenderHighlightOverCell(cell); } else { foreach (Thing thing in cell.GetThingList(base.Map)) { if (cachedThingResults.ContainsKey(thing) && cachedThingResults[thing] == true) { RenderHighlightOverThing(thing); break; } } } } } } }
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 void DesignateThing(Thing thing) { SavedJob savedJob = Memory.savedJob; if (savedJob != null) { Memory.AddJobTarget(new SavedTargetInfo(thing)); } }
public void PreTryTakeOrderedJob(Job job) { // This allows Mr Meeseeks to know what clothes he could wear if he does take the job if (!givenTask) { Meeseeks.mindState.nextApparelOptimizeTick = Find.TickManager.TicksGame - 1; savedJob = new SavedJob(job); } }
public override Job GetJobDelayed(Pawn meeseeks, CompMeeseeksMemory memory, SavedJob savedJob, SavedTargetInfo jobTarget) { Pawn targetPawn = jobTarget.Thing as Pawn; Job job = JobMaker.MakeJob(MeeseeksDefOf.CM_Meeseeks_Box_Job_WaitNear, targetPawn); job.locomotionUrgency = LocomotionUrgency.Walk; job.checkOverrideOnExpire = true; job.expiryInterval = 120; return(job); }
public override AcceptanceReport CanDesignateCell(IntVec3 cell) { if (!cell.InBounds(base.Map)) { return(false); } bool success = false; SavedJob savedJob = Memory.savedJob; if (savedJob != null) { if (savedJob.workGiverDef != null) { WorkGiver_Scanner workGiverScanner = savedJob.workGiverDef.Worker as WorkGiver_Scanner; if (workGiverScanner != null) { bool prepared = false; try { prepared = PrepareDesignations(savedJob, cell); success = this.HasJobOnCell(workGiverScanner, cell); cachedCellResults[cell] = success; if (!success) { foreach (Thing thing in cell.GetThingList(base.Map)) { success = HasJobOnThing(workGiverScanner, thing); cachedThingResults[thing] = success; if (success) { break; } } } } finally { if (prepared) { RestoreDesignations(cell); } } } } } return(success); }
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); }
// This sometimes can get called out of order from normal flow, by Achtung mod for example public void PostTryTakeOrderedJob(bool success, Job job) { // If he didn't take the job and hasn't been officially given one, clear out the saved job if (!success && !givenTask) { savedJob = null; } if (success) { JobStarted(job); } }
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); }
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); }
public void ForceNewJob(Job newJob, SavedTargetInfo targetInfo) { jobTargets = new List <SavedTargetInfo> { targetInfo }; givenTask = true; startedTask = true; taskCompleted = false; savedJob = new SavedJob(newJob); givenTaskTick = Find.TickManager.TicksGame; potentialTargetCache.Clear(); }
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); }
private bool PrepareDesignations(SavedJob savedJob, IntVec3 cell) { bool result = false; // Holy shit the things I do for plants - checking for plant cutting jobs that match normal designations - chop wood, harvest plants, cut plants if (savedJob.def.driverClass.IsSubclassOf(typeof(JobDriver_PlantWork))) { if (Memory.jobTargets.Count > 0 && Memory.jobTargets[0].HasThing) { Plant plant = Memory.jobTargets[0].Thing as Plant; if (plant != null) { if (plant.HarvestableNow) { if (plant.def.plant.IsTree) { DesignatorUtility.ForceDesignationOnThingsInCell(cell, base.Map, DesignationDefOf.HarvestPlant, ((Func <Thing, bool>)((Thing thing) => thing.def.plant?.IsTree ?? false))); //Logger.MessageFormat(this, "It's a tree harvest job..."); } else { DesignatorUtility.ForceDesignationOnThingsInCell(cell, base.Map, DesignationDefOf.HarvestPlant, ((Func <Thing, bool>)((Thing thing) => !thing.def.plant?.IsTree ?? false))); //Logger.MessageFormat(this, "It's a plant harvest job..."); } result = true; } else { DesignatorUtility.ForceDesignationOnThingsInCell(cell, base.Map, DesignationDefOf.CutPlant, ((Func <Thing, bool>)((Thing thing) => thing.def.plant != null))); //Logger.MessageFormat(this, "It's a plant cut job..."); result = true; } } } } else { DesignatorUtility.ForceAllDesignationsOnCell(cell, base.Map); result = true; } return(result); }
public override void DesignateSingleCell(IntVec3 cell) { SavedJob savedJob = Memory.savedJob; if (savedJob != null) { if (cachedCellResults.ContainsKey(cell) && cachedCellResults[cell] == true) { Memory.AddJobTarget(new SavedTargetInfo(cell)); } foreach (Thing thing in cell.GetThingList(base.Map)) { if (cachedThingResults.ContainsKey(thing) && cachedThingResults[thing] == true) { DesignateThing(thing); } } } }
private void JobStarted(Job job) { if (givenTask || !job.playerForced || freeJobs.Contains(job.def)) { return; } givenTask = true; startedTask = true; givenTaskTick = Find.TickManager.TicksGame; if (!playedAcceptSound) { MeeseeksUtility.PlayAcceptTaskSound(this.parent, voice); playedAcceptSound = true; } savedJob = new SavedJob(job); if (job.workGiverDef != null && job.workGiverDef.Worker != null && potentialTargetCache.ContainsKey(job.workGiverDef.Worker)) { AddJobTarget(new SavedTargetInfo(potentialTargetCache[job.workGiverDef.Worker]), true); } else { TargetIndex targetIndex = GetJobPrimaryTarget(job); if (targetIndex != TargetIndex.None) { AddJobTarget(new SavedTargetInfo(job.GetTarget(targetIndex)), true); } else { Logger.MessageFormat(this, "No target found for {0}", job.def.defName); } } potentialTargetCache.Clear(); }
public void CopyJobDataFrom(CompMeeseeksMemory otherMemory) { if (otherMemory.givenTask) { jobTargets = new List <SavedTargetInfo>(otherMemory.jobTargets); givenTask = otherMemory.givenTask; startedTask = otherMemory.startedTask; taskCompleted = otherMemory.taskCompleted; savedJob = new SavedJob(otherMemory.savedJob.MakeJob()); givenTaskTick = Find.TickManager.TicksGame; guardPosition = otherMemory.guardPosition; if (guardPosition.IsValid) { ((Pawn)parent).drafter.Drafted = true; } MeeseeksUtility.PlayAcceptTaskSound(this.parent, voice); } }
public override AcceptanceReport CanDesignateThing(Thing thing) { bool success = false; SavedJob savedJob = Memory.savedJob; if (savedJob != null) { if (savedJob.workGiverDef != null) { WorkGiver_Scanner workGiverScanner = savedJob.workGiverDef.Worker as WorkGiver_Scanner; if (workGiverScanner != null) { bool prepared = false; try { prepared = PrepareDesignations(savedJob, thing.PositionHeld); if (HasJobOnThing(workGiverScanner, thing)) { success = true; } } finally { if (prepared) { RestoreDesignations(thing.PositionHeld); } } } } } return(success); }
public virtual void SortAndFilterJobTargets(Pawn meeseeks, CompMeeseeksMemory memory, SavedJob savedJob) { memory.SortJobTargets(); }
public virtual Job GetJob(Pawn meeseeks, CompMeeseeksMemory memory, SavedJob savedJob, SavedTargetInfo jobTarget, ref JobAvailability jobAvailabilty) { return(ScanForJob(meeseeks, memory, savedJob, jobTarget, ref jobAvailabilty)); }
public virtual Job GetJobDelayed(Pawn meeseeks, CompMeeseeksMemory memory, SavedJob savedJob, SavedTargetInfo jobTarget) { return(null); }
public override bool UseForJob(Pawn meeseeks, CompMeeseeksMemory memory, SavedJob savedJob) { return(savedJob.IsTraining); }
public override bool UseForJob(Pawn meeseeks, CompMeeseeksMemory memory, SavedJob savedJob) { return(memory.guardPosition.IsValid); }
public static void MonitorMeeseeksJob(EditWindow_DebugInspector __instance, ref string __result) { if (MeeseeksMod.settings.showDebugLogMessages) { Map map = Find.CurrentMap; if (map != null) { List <Pawn> allMeeseeks = map.mapPawns.AllPawnsSpawned.Where(p => p.GetComp <CompMeeseeksMemory>() != null).ToList(); if (allMeeseeks.Count > 0) { StringBuilder stringBuilder = new StringBuilder(__result); foreach (Pawn imMrMeeseeksLookAtMe in allMeeseeks) { CompMeeseeksMemory meeseeksMemory = imMrMeeseeksLookAtMe.GetComp <CompMeeseeksMemory>(); Job currentJob = imMrMeeseeksLookAtMe.CurJob; SavedJob savedJob = meeseeksMemory.savedJob; stringBuilder.AppendLine(imMrMeeseeksLookAtMe.Name.ToStringFull); if (currentJob != null) { stringBuilder.AppendLine(String.Format("Current job: {0}", currentJob.def.defName)); stringBuilder.AppendLine(meeseeksMemory.givenTaskTick.ToString()); if (currentJob.workGiverDef != null && currentJob.workGiverDef.workType.relevantSkills != null) { foreach (SkillDef skillDef in currentJob.workGiverDef.workType.relevantSkills) { stringBuilder.AppendLine(skillDef.skillLabel); } } string targetAString = GetTargetString("Target A", currentJob.targetA); string targetBString = GetTargetString("Target B", currentJob.targetB); string targetCString = GetTargetString("Target C", currentJob.targetC); if (targetAString != null) { stringBuilder.AppendLine(targetAString); } if (targetBString != null) { stringBuilder.AppendLine(targetBString); } if (targetCString != null) { stringBuilder.AppendLine(targetCString); } } if (meeseeksMemory.jobStuck) { stringBuilder.AppendLine("***JOB STUCK***"); } if (savedJob != null) { stringBuilder.AppendLine(String.Format("Saved job: {0}", savedJob.def.defName)); if (savedJob.workGiverDef != null && savedJob.workGiverDef.workType.relevantSkills != null) { stringBuilder.AppendLine(savedJob.workGiverDef.defName); foreach (SkillDef skillDef in savedJob.workGiverDef.workType.relevantSkills) { stringBuilder.AppendLine(skillDef.skillLabel); } } string targetAString = GetTargetString("Target A", savedJob.targetA); string targetBString = GetTargetString("Target B", savedJob.targetB); string targetCString = GetTargetString("Target C", savedJob.targetC); if (targetAString != null) { stringBuilder.AppendLine(targetAString); } if (targetBString != null) { stringBuilder.AppendLine(targetBString); } if (targetCString != null) { stringBuilder.AppendLine(targetCString); } } foreach (SavedTargetInfo jobTarget in meeseeksMemory.jobTargets) { stringBuilder.AppendLine(jobTarget.target.ToString()); if (jobTarget.BuildableDef != null) { string nextLine = " - " + jobTarget.BuildableDef.defName; if (jobTarget.blueprintStuff != null) { nextLine += " - " + jobTarget.blueprintStuff.defName; } stringBuilder.AppendLine(nextLine); } if (jobTarget.bill != null) { Bill_Production billProduction = jobTarget.bill as Bill_Production; if (billProduction != null) { string nextLine = " - " + billProduction.ToString(); if (billProduction.repeatMode == BillRepeatModeDefOf.RepeatCount) { nextLine += " - x" + billProduction.repeatCount; } else if (billProduction.repeatMode == BillRepeatModeDefOf.TargetCount) { nextLine += " - until " + billProduction.targetCount; } else { nextLine += " - forever"; } stringBuilder.AppendLine(nextLine); } } } stringBuilder.AppendLine(""); } __result = stringBuilder.ToString(); } } } }
public override bool UseForJob(Pawn meeseeks, CompMeeseeksMemory memory, SavedJob savedJob) { return(savedJob.UsesWorkGiver <WorkGiver_RemoveRoof>()); }
public override void SortAndFilterJobTargets(Pawn meeseeks, CompMeeseeksMemory memory, SavedJob savedJob) { Map map = meeseeks.MapHeld; WorkGiver_RemoveRoof scanner = savedJob.workGiverDef.Worker as WorkGiver_RemoveRoof; SavedTargetInfo bestTarget = null; float bestPriority = float.MinValue; float bestDistanceSquared = float.MaxValue; for (int i = memory.jobTargets.Count - 1; i >= 0; --i) { SavedTargetInfo target = memory.jobTargets[i]; if (!target.Cell.Roofed(map)) { CollectNewTargets(meeseeks, memory, target.Cell, map); memory.jobTargets.RemoveAt(i); } } foreach (SavedTargetInfo target in memory.jobTargets) { if (meeseeks.CanReach(target.Cell, scanner.PathEndMode, Danger.Deadly) && meeseeks.CanReserve(target.Cell, 1, -1, ReservationLayerDefOf.Ceiling, false)) { float priority = scanner.GetPriority(meeseeks, target.Cell); float distanceSquared = (target.Cell - meeseeks.Position).LengthHorizontalSquared; if (priority > bestPriority || (priority == bestPriority && distanceSquared < bestDistanceSquared)) { bestTarget = target; bestPriority = priority; bestDistanceSquared = distanceSquared; } } } if (bestTarget != null) { memory.jobTargets.Remove(bestTarget); memory.jobTargets.Insert(0, bestTarget); } }
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); }