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); }
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); }
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); }
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); }
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); }