public void DriverTick() { try { ticksLeftThisToil--; debugTicksSpentThisToil++; if (CurToil == null) { if (!pawn.stances.FullBodyBusy || CanStartNextToilInBusyStance) { ReadyForNextToil(); } } else if (!CheckCurrentToilEndOrFail()) { if (curToilCompleteMode == ToilCompleteMode.Delay) { if (ticksLeftThisToil > 0) { goto IL_00b6; } ReadyForNextToil(); } else { if (curToilCompleteMode != ToilCompleteMode.FinishedBusy || pawn.stances.FullBodyBusy) { goto IL_00b6; } ReadyForNextToil(); } } goto end_IL_0000; IL_00b6: if (wantBeginNextToil) { TryActuallyStartNextToil(); } else if (curToilCompleteMode == ToilCompleteMode.Instant && debugTicksSpentThisToil > 300) { Log.Error(pawn + " had to be broken from frozen state. He was doing job " + job + ", toilindex=" + curToilIndex); ReadyForNextToil(); } else { Job curJob = pawn.CurJob; if (CurToil.preTickActions != null) { Toil curToil = CurToil; for (int i = 0; i < curToil.preTickActions.Count; i++) { curToil.preTickActions[i](); if (pawn.CurJob != curJob || CurToil != curToil || wantBeginNextToil) { return; } } } if (CurToil.tickAction != null) { CurToil.tickAction(); } } end_IL_0000 :; } catch (Exception exception) { JobUtility.TryStartErrorRecoverJob(pawn, "Exception in JobDriver tick for pawn " + pawn.ToStringSafe(), exception, this); } }
public override IEnumerable <Toil> MakeNewToils() { AddEndCondition(delegate { Thing thing = GetActor().jobs.curJob.GetTarget(TargetIndex.A).Thing; if (thing is Building && !thing.Spawned) { return(JobCondition.Incompletable); } return(JobCondition.Ongoing); }); this.FailOnBurningImmobile(TargetIndex.A); this.FailOn(delegate() { IBillGiver billGiver = job.GetTarget(TargetIndex.A).Thing as IBillGiver; if (billGiver != null) { if (job.bill.DeletedOrDereferenced) { return(true); } if (!billGiver.CurrentlyUsableForBills()) { return(true); } if (project == null) { Log.Error("[HumanResources] Tried to document a null project."); TryMakePreToilReservations(true); return(true); } if (!techComp.homework.Contains(project)) { return(true); } } return(false); }); Toil gotoBillGiver = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell); yield return(new Toil { initAction = delegate() { if (job.targetQueueB != null && job.targetQueueB.Count == 1) { UnfinishedThing unfinishedThing = job.targetQueueB[0].Thing as UnfinishedThing; if (unfinishedThing != null) { unfinishedThing.BoundBill = (Bill_ProductionWithUft)job.bill; } } } }); yield return(Toils_Jump.JumpIf(gotoBillGiver, () => job.GetTargetQueue(TargetIndex.B).NullOrEmpty <LocalTargetInfo>())); Toil extract = Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.B, true); yield return(extract); Toil getToHaulTarget = Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.B).FailOnSomeonePhysicallyInteracting(TargetIndex.B); yield return(getToHaulTarget); yield return(Toils_Haul.StartCarryThing(TargetIndex.B, true, false, true)); yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell).FailOnDestroyedOrNull(TargetIndex.B)); Toil findPlaceTarget = Toils_JobTransforms.SetTargetToIngredientPlaceCell(TargetIndex.A, TargetIndex.B, TargetIndex.C); yield return(findPlaceTarget); yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.C, findPlaceTarget, false, false)); yield return(Toils_Jump.JumpIfHaveTargetInQueue(TargetIndex.B, extract)); extract = null; getToHaulTarget = null; findPlaceTarget = null; yield return(gotoBillGiver); yield return(MakeUnfinishedThingIfNeeded()); yield return(Toils_Recipe.DoRecipeWork().FailOnDespawnedNullOrForbiddenPlacedThings().FailOnCannotTouch(TargetIndex.A, PathEndMode.InteractionCell)); yield return(FinishRecipeAndStartStoringProduct()); if (!job.RecipeDef.products.NullOrEmpty <ThingDefCountClass>() || !job.RecipeDef.specialProducts.NullOrEmpty <SpecialProductType>()) { yield return(Toils_Reserve.Reserve(TargetIndex.B)); yield return(Toils_Haul.StartCarryThing(TargetIndex.A, false, true, false)); findPlaceTarget = Toils_Haul.CarryHauledThingToContainer(); yield return(findPlaceTarget); Toil prepare = Toils_General.Wait(250); prepare.WithProgressBarToilDelay(TargetIndex.B, false, -0.5f); yield return(prepare); yield return(new Toil { initAction = delegate { Building_BookStore shelf = (Building_BookStore)job.GetTarget(TargetIndex.B).Thing; CurToil.FailOn(() => shelf == null); Thing book = pawn.carryTracker.CarriedThing; if (pawn.carryTracker.CarriedThing == null) { Log.Error($"[HumanResources] {pawn} tried to place a book on shelf but is not hauling anything."); return; } if (shelf.Accepts(book)) { bool flag = false; if (book.holdingOwner != null) { book.holdingOwner.TryTransferToContainer(book, shelf.TryGetInnerInteractableThingOwner(), book.stackCount, true); flag = true; } else { flag = shelf.TryGetInnerInteractableThingOwner().TryAdd(book, true); } pawn.carryTracker.innerContainer.Remove(book); } else { Log.Error($"[HumanResources] {pawn} tried to place a book in {shelf}, but it won't accept it."); return; } pawn.jobs.EndCurrentJob(JobCondition.Succeeded, true, true); } }); } yield break; }