protected override IEnumerable <Toil> MakeNewToils() { this.FailOnDespawnedNullOrForbidden(TargetIndex.A); Toil extract = Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.B); yield return(extract); yield return(Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.B).FailOnSomeonePhysicallyInteracting(TargetIndex.B)); yield return(Toils_Haul.StartCarryThing(TargetIndex.B, true, false, true)); yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.ClosestTouch)); yield return(Toils_General.Wait(400).WithProgressBarToilDelay(TargetIndex.A).FailOnDestroyedNullOrForbidden(TargetIndex.A)); Toil finish = new Toil { initAction = delegate { if (item != null) { furnace.AddItemToFurnace(item); } }, defaultCompleteMode = ToilCompleteMode.Instant }; yield return(finish); yield return(Toils_Jump.JumpIfHaveTargetInQueue(TargetIndex.B, extract)); }
protected override IEnumerable <Toil> MakeNewToils() { Apparel_Backpack backpack = CurJob.GetTarget(BackpackInd).Thing as Apparel_Backpack; // no free slots this.FailOn(() => backpack.slotsComp.slots.Count >= backpack.MaxItem); // reserve resources yield return(Toils_Reserve.ReserveQueue(HaulableInd)); // extract next target thing from targetQueue Toil toilExtractNextTarget = Toils_JobTransforms.ExtractNextTargetFromQueue(HaulableInd); yield return(toilExtractNextTarget); Toil toilGoToThing = Toils_Goto.GotoThing(HaulableInd, PathEndMode.ClosestTouch) .FailOnDespawnedOrNull(HaulableInd); yield return(toilGoToThing); Toil pickUpThingIntoSlot = new Toil { initAction = () => { if (!backpack.slotsComp.slots.TryAdd(CurJob.targetA.Thing)) { EndJobWith(JobCondition.Incompletable); } } }; yield return(pickUpThingIntoSlot); yield return(Toils_Jump.JumpIfHaveTargetInQueue(HaulableInd, toilExtractNextTarget)); }
protected 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(IsDeletedOrNotUsableForBills); // Copied from JobDriver_DoBill (removed a few things that were not needed for dissecton) Toil gotoBillGiver = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell); yield return(Toils_Jump.JumpIf(gotoBillGiver, () => job.GetTargetQueue(TargetIndex.B).NullOrEmpty())); 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_Dissection.JumpToCollectNextIntoHandsForBill(getToHaulTarget, TargetIndex.B)); 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_Dissection.PlaceHauledThingInCell(TargetIndex.C, findPlaceTarget, false)); yield return(Toils_Jump.JumpIfHaveTargetInQueue(TargetIndex.B, extract)); yield return(gotoBillGiver); // Strip body Toil doDissectionRecipeWork = Toils_Dissection.DoDissectionRecipeWork().FailOnDespawnedNullOrForbiddenPlacedThings().FailOnCannotTouch(TargetIndex.A, PathEndMode.InteractionCell); yield return(Toils_Jump.JumpIf(doDissectionRecipeWork, () => { LocalTargetInfo targetInfo = job.GetTarget(TargetIndex.B); if (targetInfo.HasThing) { return !(targetInfo.Thing is Corpse corpse) || !corpse.AnythingToStrip(); }
protected override IEnumerable <Toil> MakeNewToils() { yield return(Waiting()); Toil stageEnded = Toils_ReligionActivity.StageEnded(pawn); yield return(Toils_Jump.JumpIf(stageEnded, () => this.job.GetTargetQueue(TargetIndex.B).NullOrEmpty <LocalTargetInfo>())); Toil extract = Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.B, true); yield return(extract); Toil getToTarget = Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.B).FailOnSomeonePhysicallyInteracting(TargetIndex.B); yield return(getToTarget); yield return(Sacrifce(TargetIndex.B)); yield return(Toils_Jump.JumpIfHaveTargetInQueue(TargetIndex.B, extract)); yield return(Waiting()); yield return(stageEnded); }
protected override IEnumerable <Toil> MakeNewToils() { yield return(Toils_JobTransforms.MoveCurrentTargetIntoQueue(TargetIndex.A)); yield return(Toils_Reserve.ReserveQueue(TargetIndex.A, 1)); var init = Toils_JobTransforms.ClearDespawnedNullOrForbiddenQueuedTargets(TargetIndex.A); yield return(init); yield return(Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.A)); var clear = Toils_JobTransforms.ClearDespawnedNullOrForbiddenQueuedTargets(TargetIndex.A); yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch).JumpIfDespawnedOrNullOrForbidden(TargetIndex.A, clear)); yield return(HarvestSeedsToil()); yield return(Toils_Jump.JumpIfHaveTargetInQueue(TargetIndex.A, init)); yield return(Toils_General.RemoveDesignationsOnThing(TargetIndex.A, DesignationDefOf.HarvestPlant)); yield break; }
protected override IEnumerable <Toil> MakeNewToils() { yield return(Toils_JobTransforms.MoveCurrentTargetIntoQueue(TargetIndex.A)); yield return(Toils_Reserve.ReserveQueue(TargetIndex.A)); var init = Toils_JobTransforms.ClearDespawnedNullOrForbiddenQueuedTargets(TargetIndex.A); yield return(init); yield return(Toils_JobTransforms.SucceedOnNoTargetInQueue(TargetIndex.A)); yield return(Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.A)); var clear = Toils_JobTransforms.ClearDespawnedNullOrForbiddenQueuedTargets(TargetIndex.A); yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch).JumpIfDespawnedOrNullOrForbidden(TargetIndex.A, clear)); yield return(HarvestSeedsToil()); yield return(PlantWorkDoneToil()); yield return(Toils_Jump.JumpIfHaveTargetInQueue(TargetIndex.A, init)); }
protected override IEnumerable <Toil> MakeNewToils() { Bill bill = job.bill; 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); } } return(false); }); AddFinishAction(delegate() { //Log.Message("LearnWeapon: finishing"); ThingWithComps thingWithComps = (ThingWithComps)job.targetB.Thing; if (pawn.equipment.Primary != null) { pawn.equipment.TryDropEquipment(thingWithComps, out thingWithComps, pawn.Position, false); } }); Toil gotoBillGiver = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell); 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); //temporary equip yield return(new Toil { initAction = delegate() { ThingWithComps thingWithComps = (ThingWithComps)job.targetB.Thing; ThingWithComps thingWithComps2; if (thingWithComps.def.stackLimit > 1 && thingWithComps.stackCount > 1) { thingWithComps2 = (ThingWithComps)thingWithComps.SplitOff(1); } else { thingWithComps2 = thingWithComps; thingWithComps2.DeSpawn(DestroyMode.Vanish); } pawn.equipment.MakeRoomFor(thingWithComps2); pawn.equipment.AddEquipment(thingWithComps2); if (thingWithComps.def.soundInteract != null) { thingWithComps.def.soundInteract.PlayOneShot(new TargetInfo(pawn.Position, pawn.Map, false)); } }, defaultCompleteMode = ToilCompleteMode.Instant }); yield return(Toils_Jump.JumpIfHaveTargetInQueue(TargetIndex.B, extract)); yield return(gotoBillGiver); yield return(Toils_Combat.TrySetJobToUseAttackVerb(TargetIndex.A)); Toil train = new Toil(); train.initAction = delegate() { Pawn actor = train.actor; Job curJob = actor.jobs.curJob; ThingDef weapon = job.targetB.Thing.def; workLeft = curJob.bill.recipe.WorkAmountTotal(null); billStartTick = Find.TickManager.TicksGame; ticksSpentDoingRecipeWork = 0; curJob.bill.Notify_DoBillStarted(actor); //sound: if (weapon.soundInteract != null) { weapon.soundInteract.PlayOneShot(new TargetInfo(pawn.Position, pawn.Map, false)); } }; train.tickAction = delegate() { Pawn actor = train.actor; Job curJob = actor.jobs.curJob; ThingDef weapon = job.targetB.Thing.def; ticksSpentDoingRecipeWork++; curJob.bill.Notify_PawnDidWork(actor); IBillGiverWithTickAction billGiverWithTickAction = train.actor.CurJob.GetTarget(TargetIndex.A).Thing as IBillGiverWithTickAction; if (billGiverWithTickAction != null) { billGiverWithTickAction.UsedThisTick(); } float num = (curJob.RecipeDef.workSpeedStat != null) ? actor.GetStatValue(curJob.RecipeDef.workSpeedStat, true) : 1f; if (curJob.RecipeDef.workTableSpeedStat != null) { Building_WorkTable building_WorkTable = BillGiver as Building_WorkTable; if (building_WorkTable != null) { num *= building_WorkTable.GetStatValue(curJob.RecipeDef.workTableSpeedStat, true); } } if (DebugSettings.fastCrafting) { num *= 30f; } workLeft -= num; actor.GainComfortFromCellIfPossible(); if (workLeft <= 0f) { ReadyForNextToil(); } //pawn posture Verb verbToUse = actor.jobs.curJob.verbToUse; LocalTargetInfo target = actor.jobs.curJob.GetTarget(TargetIndex.A); pawn.stances.SetStance(new Stance_Warmup(1, target, verbToUse)); //sound: if (verbToUse.verbProps != null && verbToUse.verbProps.warmupTime > 0) { if ((ticksSpentDoingRecipeWork % verbToUse.verbProps.AdjustedFullCycleTime(verbToUse, actor).SecondsToTicks()) == 0) { if (verbToUse.verbProps.soundCast != null) { verbToUse.verbProps.soundCast.PlayOneShot(new TargetInfo(pawn.Position, pawn.Map, false)); } if (verbToUse.verbProps.soundCastTail != null) { verbToUse.verbProps.soundCastTail.PlayOneShotOnCamera(pawn.Map); } } } if (job.RecipeDef.workSkill != null) { //float xpDelta = techComp.proficientWeapons.Contains(job.targetB.Thing.def) ? 1f : 0.1f; float xp = 0.1f * job.RecipeDef.workSkillLearnFactor; actor.skills.GetSkill(job.RecipeDef.workSkill).Learn(xp, false); } }; train.defaultCompleteMode = ToilCompleteMode.Never; train.WithEffect(() => train.actor.CurJob.bill.recipe.effectWorking, TargetIndex.A); train.PlaySustainerOrSound(() => train.actor.CurJob.bill.recipe.soundWorking); train.WithProgressBar(TargetIndex.A, delegate { Pawn actor = train.actor; Job curJob = actor.CurJob; //return 1f - ((JobDriver_DoBill)actor.jobs.curDriver).workLeft / curJob.bill.recipe.WorkAmountTotal(null); return(1f - (workLeft / curJob.bill.recipe.WorkAmountTotal(null))); }, false, -0.5f); train.FailOn(() => train.actor.CurJob.bill.suspended); train.activeSkill = () => train.actor.CurJob.bill.recipe.workSkill; yield return(train.FailOnDespawnedNullOrForbiddenPlacedThings().FailOnCannotTouch(TargetIndex.A, PathEndMode.InteractionCell)); Toil finalizeTraining = new Toil(); finalizeTraining.initAction = delegate { Pawn actor = finalizeTraining.actor; CompKnowledge techComp = actor.TryGetComp <CompKnowledge>(); if (!techComp.proficientWeapons.Contains(job.targetB.Thing.def)) { techComp.proficientWeapons.Add(TargetThingB.def); } job.bill.Notify_IterationCompleted(actor, new List <Thing> { }); actor.jobs.EndCurrentJob(JobCondition.Succeeded, false); }; finalizeTraining.defaultCompleteMode = ToilCompleteMode.Instant; finalizeTraining.FailOnDespawnedOrNull(TargetIndex.A); yield return(finalizeTraining); //testing yield return(Toils_Reserve.Reserve(TargetIndex.B, 1, -1, null)); Toil findPlaceTarget = Toils_Haul.CarryHauledThingToCell(TargetIndex.B); yield return(findPlaceTarget); yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.B, findPlaceTarget, true, true)); yield break; }
protected override IEnumerable <Toil> MakeNewToils() { base.AddEndCondition(delegate { Thing thing = this.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 = this.job.GetTarget(TargetIndex.A).Thing as IBillGiver; // if (billGiver != null) // { // if (this.job.bill.DeletedOrDereferenced) //{ // return true; //} //if (!billGiver.CurrentlyUsableForBills()) //{ // return true; //} // } // return false; // }); Toil gotoBillGiver = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell); yield return(Toils_Jump.JumpIf(gotoBillGiver, () => this.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(new Toil() { initAction = delegate { if (PawnRelic != null) { if (this.job.def.makeTargetPrisoner) { Lord lord = PawnRelic.GetLord(); if (lord != null) { lord.Notify_PawnAttemptArrested(PawnRelic); } GenClamor.DoClamor(PawnRelic, 10f, ClamorDefOf.Harm); if (!PawnRelic.CheckAcceptArrest(this.pawn)) { this.pawn.jobs.EndCurrentJob(JobCondition.Incompletable, true); } } } } }); yield return(Toils_Haul.StartCarryThing(TargetIndex.B, true, false, true)); yield return(JumpToCollectNextIntoHandsForBill(getToHaulTarget, TargetIndex.B)); 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(PlaceHauledThingInCell(TargetIndex.C, findPlaceTarget, false)); yield return(new Toil { initAction = delegate { if (PawnRelic != null) { IntVec3 position = this.job.GetTarget(TargetIndex.B).Cell; this.pawn.Notify_Teleported(false, true); this.pawn.stances.CancelBusyStanceHard(); PawnRelic.jobs.StartJob(new Job(MiscDefOf.TiedDown, (LocalTargetInfo)position), JobCondition.InterruptForced, (ThinkNode)null, false, true, (ThinkTreeDef)null, new JobTag?(JobTag.Idle), false); } }, defaultCompleteMode = ToilCompleteMode.Instant }); yield return(Toils_Jump.JumpIfHaveTargetInQueue(TargetIndex.B, extract)); yield return(gotoBillGiver); yield return(StartActivity()); //yield return Waiting(); //yield return DoRecipeWork(); //yield return Toils_Recipe.FinishRecipeAndStartStoringProduct();/////////////////////// //if (!this.job.RecipeDef.products.NullOrEmpty<ThingDefCountClass>() || !this.job.RecipeDef.specialProducts.NullOrEmpty<SpecialProductType>()) //{ // yield return Toils_Reserve.Reserve(TargetIndex.B, 1, -1, null); // Toil carryToCell = Toils_Haul.CarryHauledThingToCell(TargetIndex.B); // yield return carryToCell; // yield return Toils_Haul.PlaceHauledThingInCell(TargetIndex.B, carryToCell, true); // Toil recount = new Toil(); // recount.initAction = delegate // { // Bill_Production bill_Production = recount.actor.jobs.curJob.bill as Bill_Production; // if (bill_Production != null && bill_Production.repeatMode == BillRepeatModeDefOf.TargetCount) // { // this.Map.resourceCounter.UpdateResourceCounts(); // } // }; // yield return recount; //} }
protected override IEnumerable <Toil> MakeNewToils() { base.AddEndCondition(delegate { Thing thing = base.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 = this.job.GetTarget(TargetIndex.A).Thing as IBillGiver; if (billGiver != null) { if (this.job.bill.DeletedOrDereferenced) { return(true); } if (!billGiver.CurrentlyUsableForBills()) { return(true); } } return(false); }); Toil gotoBillGiver = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell); yield return(new Toil { initAction = delegate() { if (this.job.targetQueueB != null && this.job.targetQueueB.Count == 1) { UnfinishedThing unfinishedThing = this.job.targetQueueB[0].Thing as UnfinishedThing; if (unfinishedThing != null) { unfinishedThing.BoundBill = (Bill_ProductionWithUft)this.job.bill; } } } }); //yield return Toils_Jump.JumpIf(gotoBillGiver, () => this.job.GetTargetQueue(TargetIndex.B).NullOrEmpty<LocalTargetInfo>()); Toil extract = Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.B, true); yield return(extract); yield return(new Toil { initAction = delegate() { var alien = TargetB.Thing; var container = (Building_СontainmentBreach)TargetA.Thing; if (container.innerContainer.Contains(alien) && ReservationUtility.CanReserveAndReach (GetActor(), container, PathEndMode.ClosestTouch, DangerUtility.NormalMaxDanger(GetActor()) , 1, -1, null, false)) { Log.Message(GetActor() + " JUMP"); //Toils_Reserve.Reserve(TargetIndex.A, 1); this.JumpToToil(gotoBillGiver); } } }); Toil getToHaulTarget = Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch);//.FailOnSomeonePhysicallyInteracting(TargetIndex.B); yield return(getToHaulTarget); yield return(new Toil { initAction = delegate() { base.GetActor().CurJob.count = 1; } }); yield return(Toils_Haul.StartCarryThing(TargetIndex.B, true, false, false)); yield return(JobDriver_PreciseVivisection.JumpToCollectNextIntoHandsForBill(getToHaulTarget, TargetIndex.B)); //yield return Toils_Haul.CarryHauledThingToCell(TargetIndex.B); yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell).FailOnDestroyedOrNull(TargetIndex.B)); yield return(Toils_Haul.DepositHauledThingInContainer(TargetIndex.A, 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(Toils_Recipe.MakeUnfinishedThingIfNeeded()); yield return(Toils_Recipe.DoRecipeWork().FailOnCannotTouch(TargetIndex.A, PathEndMode.InteractionCell)); yield return(new Toil { initAction = delegate() { var alien = TargetB.Thing; foreach (var product in alien.ButcherProducts(base.GetActor(), 1f)) { Log.Message(product.def.defName); GenPlace.TryPlaceThing(product, base.GetActor().Position, base.GetActor().Map, ThingPlaceMode.Near); } var container = (Building_СontainmentBreach)TargetA.Thing; container.innerContainer.Remove(alien); alien.Destroy(DestroyMode.Vanish); } }); yield return(new Toil { initAction = delegate() { var container = (Building_СontainmentBreach)TargetA.Thing; if (GetActor().Map.reservationManager.ReservedBy(container, GetActor(), GetActor().CurJob)) { GetActor().Map.reservationManager.Release(container, GetActor(), GetActor().CurJob); } } }); yield return(Toils_Recipe.FinishRecipeAndStartStoringProduct()); if (!this.job.bill.recipe.products.NullOrEmpty <ThingDefCountClass>() || !this.job.bill.recipe.specialProducts.NullOrEmpty <SpecialProductType>()) { yield return(Toils_Reserve.Reserve(TargetIndex.B, 1, -1, null)); findPlaceTarget = Toils_Haul.CarryHauledThingToCell(TargetIndex.B); yield return(findPlaceTarget); //yield return Toils_Haul.PlaceHauledThingInCell(TargetIndex.B, findPlaceTarget, true, true); Toil toil = new Toil(); toil.initAction = delegate() { this.Map.resourceCounter.UpdateResourceCounts(); }; yield return(toil); toil = null; findPlaceTarget = null; } yield return(new Toil { initAction = delegate() { Log.Message("Job ended"); } }); yield break; }
protected override IEnumerable <Toil> MakeNewToils() { Bill bill = job.bill; 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); } } return(false); }); AddFinishAction(delegate() { if (pawn.equipment.Primary != null && !practice) { if (pawn.equipment.Primary == (ThingWithComps)job.targetB.Thing) { ThingWithComps thingWithComps = (ThingWithComps)job.targetB.Thing; pawn.equipment.TryDropEquipment(thingWithComps, out thingWithComps, pawn.Position, false); } if (job.GetTarget(TargetIndex.C).IsValid) { Equip(TargetIndex.C, false); } } }); Toil gotoBillGiver = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell); if (!practice) { 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(new Toil { initAction = delegate() { Equip(TargetIndex.B, true); }, defaultCompleteMode = ToilCompleteMode.Instant }); yield return(Toils_Jump.JumpIfHaveTargetInQueue(TargetIndex.B, extract)); } Thing currentWeapon = practice ? pawn.equipment.Primary : job.targetB.Thing; yield return(gotoBillGiver); yield return(Toils_Combat.TrySetJobToUseAttackVerb(TargetIndex.A)); yield return(Train(currentWeapon).FailOnDespawnedNullOrForbiddenPlacedThings().FailOnCannotTouch(TargetIndex.A, PathEndMode.InteractionCell)); yield return(FinalizeTraining()); yield break; }
static IEnumerable <Toil> DoMakeToils(JobDriver_DoBill_Access __instance) { //normal scenario __instance.AddEndCondition(delegate { Thing thing = __instance.GetActor().jobs.curJob.GetTarget(TargetIndex.A).Thing; if (thing is Building && !thing.Spawned) { return(JobCondition.Incompletable); } return(JobCondition.Ongoing); }); __instance.FailOnBurningImmobile(TargetIndex.A); __instance.FailOn(delegate() { if (__instance.job.GetTarget(TargetIndex.A).Thing is Filth) { return(false); } IBillGiver billGiver = __instance.job.GetTarget(TargetIndex.A).Thing as IBillGiver; if (billGiver != null) { if (__instance.job.bill.DeletedOrDereferenced) { return(true); } if (!billGiver.CurrentlyUsableForBills()) { return(true); } } return(false); }); Toil gotoBillGiver = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell); yield return(new Toil { initAction = delegate() { if (__instance.job.targetQueueB != null && __instance.job.targetQueueB.Count == 1) { UnfinishedThing unfinishedThing = __instance.job.targetQueueB[0].Thing as UnfinishedThing; if (unfinishedThing != null) { unfinishedThing.BoundBill = (Bill_ProductionWithUft)__instance.job.bill; } } } }); yield return(Toils_Jump.JumpIf(gotoBillGiver, () => __instance.job.GetTargetQueue(TargetIndex.B).NullOrEmpty())); //hauling patch if (Settings.adv_haul_all_ings && __instance.pawn.Faction == Faction.OfPlayer) { Toil checklist = new Toil(); checklist.initAction = delegate() { Pawn actor = checklist.actor; Job curJob = actor.jobs.curJob; List <LocalTargetInfo> targetQueue = curJob.GetTargetQueue(TargetIndex.B); if (targetQueue.NullOrEmpty()) { actor.jobs.curDriver.EndJobWith(JobCondition.Incompletable); } else { foreach (var target in (targetQueue)) { if (target == null || target.Thing.DestroyedOrNull()) { actor.jobs.curDriver.EndJobWith(JobCondition.Incompletable); break; } } } }; yield return(checklist); Toil extract = new Toil(); extract.initAction = delegate() { Pawn actor = extract.actor; Job curJob = actor.jobs.curJob; List <LocalTargetInfo> targetQueue = curJob.GetTargetQueue(TargetIndex.B); if (!curJob.countQueue.NullOrEmpty()) { if (curJob.countQueue[0] > targetQueue[0].Thing.stackCount) { actor.jobs.curDriver.EndJobWith(JobCondition.Incompletable); } else { curJob.SetTarget(TargetIndex.B, targetQueue[0]); targetQueue.RemoveAt(0); curJob.count = curJob.countQueue[0]; curJob.countQueue.RemoveAt(0); } } }; Toil PickUpThing; List <LocalTargetInfo> L = __instance.job.GetTargetQueue(TargetIndex.B); if (L.Count < 2 && (L.Count == 0 || L[0].Thing.def.stackLimit < 2)) { PickUpThing = Toils_Haul.StartCarryThing(TargetIndex.B, true, false, true); } else { PickUpThing = new Toil(); PickUpThing.initAction = delegate() { Pawn actor = PickUpThing.actor; Job curJob = actor.jobs.curJob; Thing thing = curJob.GetTarget(TargetIndex.B).Thing; List <LocalTargetInfo> targetQueue = curJob.GetTargetQueue(TargetIndex.B); bool InventorySpawned = thing.ParentHolder == actor.inventory; if (InventorySpawned || !Toils_Haul.ErrorCheckForCarry(actor, thing)) { if (thing.stackCount < curJob.count) { actor.jobs.curDriver.EndJobWith(JobCondition.Incompletable); } else { Thing splitThing = thing.SplitOff(curJob.count); if (splitThing.ParentHolder != actor.inventory && !actor.inventory.GetDirectlyHeldThings().TryAdd(splitThing, false)) { actor.jobs.curDriver.EndJobWith(JobCondition.Incompletable); } if (!splitThing.Destroyed && splitThing.stackCount != 0) { targetQueue.Add(splitThing); if (!InventorySpawned) { CompUnloadChecker CUC = splitThing.TryGetComp <CompUnloadChecker>(); if (CUC != null) { CUC.ShouldUnload = true; } } } if (splitThing != thing && actor.Map.reservationManager.ReservedBy(thing, actor, curJob)) { actor.Map.reservationManager.Release(thing, actor, curJob); } } } }; } Toil TakeToHands = new Toil(); TakeToHands.initAction = delegate() { Pawn actor = TakeToHands.actor; Job curJob = actor.jobs.curJob; List <LocalTargetInfo> targetQueue = curJob.GetTargetQueue(TargetIndex.B); if (!targetQueue.NullOrEmpty() && targetQueue[0].Thing.ParentHolder != actor.carryTracker) { actor.inventory.innerContainer.TryTransferToContainer(targetQueue[0].Thing, actor.carryTracker.innerContainer); actor.Reserve(targetQueue[0], curJob); curJob.SetTarget(TargetIndex.B, targetQueue[0]); targetQueue.RemoveAt(0); } }; yield return(extract); Toil getToHaulTarget = Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.B).FailOnSomeonePhysicallyInteracting(TargetIndex.B); yield return(Toils_Jump.JumpIf(PickUpThing, () => __instance.job.GetTarget(TargetIndex.B).Thing.ParentHolder == __instance.pawn.inventory)); yield return(getToHaulTarget); yield return(PickUpThing); yield return(Toils_Jump.JumpIf(extract, () => !__instance.job.countQueue.NullOrEmpty())); yield return(TakeToHands); 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)); yield return(Toils_Jump.JumpIfHaveTargetInQueue(TargetIndex.B, TakeToHands)); } else { 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(JobDriver_DoBill_Access.JumpToCollectNextIntoHandsForBillCrutch(getToHaulTarget, TargetIndex.B)); 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)); yield return(Toils_Jump.JumpIfHaveTargetInQueue(TargetIndex.B, extract)); } yield return(gotoBillGiver); //one line from normal scenario //cleaning patch if (Settings.adv_cleaning && !Utility.IncapableOfCleaning(__instance.pawn)) { Toil returnToBillGiver = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell); Toil FilthList = new Toil(); FilthList.initAction = delegate() { Job curJob = FilthList.actor.jobs.curJob; if (curJob.GetTargetQueue(TargetIndex.A).NullOrEmpty()) { LocalTargetInfo A = curJob.GetTarget(TargetIndex.A); DoCleanComp comp; if (!Settings.clean_gizmo || (comp = A.Thing?.TryGetComp <DoCleanComp>()) == null || comp.Active) { IEnumerable <Filth> l = Utility.SelectAllFilth(FilthList.actor, A, Settings.adv_clean_num); Utility.AddFilthToQueue(curJob, TargetIndex.A, l, FilthList.actor); FilthList.actor.ReserveAsManyAsPossible(curJob.GetTargetQueue(TargetIndex.A), curJob); } curJob.targetQueueA.Add(A); } }; yield return(FilthList); yield return(Toils_Jump.JumpIf(returnToBillGiver, () => __instance.job.GetTargetQueue(TargetIndex.A).NullOrEmpty())); Toil CleanFilthList = Toils_JobTransforms.ClearDespawnedNullOrForbiddenQueuedTargets(TargetIndex.A, null); yield return(CleanFilthList); yield return(Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.A, true)); yield return(Toils_Jump.JumpIf(returnToBillGiver, () => __instance.job.GetTargetQueue(TargetIndex.A).NullOrEmpty())); yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch).JumpIfDespawnedOrNullOrForbidden(TargetIndex.A, CleanFilthList).JumpIfOutsideHomeArea(TargetIndex.A, CleanFilthList)); Toil clean = new Toil(); clean.initAction = delegate() { Filth filth = clean.actor.jobs.curJob.GetTarget(TargetIndex.A).Thing as Filth; __instance.billStartTick = 0; __instance.ticksSpentDoingRecipeWork = 0; __instance.workLeft = filth.def.filth.cleaningWorkToReduceThickness * filth.thickness; }; clean.tickAction = delegate() { Filth filth = clean.actor.jobs.curJob.GetTarget(TargetIndex.A).Thing as Filth; __instance.billStartTick += 1; __instance.ticksSpentDoingRecipeWork += 1; if (__instance.billStartTick > filth.def.filth.cleaningWorkToReduceThickness) { filth.ThinFilth(); __instance.billStartTick = 0; if (filth.Destroyed) { clean.actor.records.Increment(RecordDefOf.MessesCleaned); __instance.ReadyForNextToil(); return; } } }; clean.defaultCompleteMode = ToilCompleteMode.Never; clean.WithEffect(EffecterDefOf.Clean, TargetIndex.A); clean.WithProgressBar(TargetIndex.A, () => __instance.ticksSpentDoingRecipeWork / __instance.workLeft, true, -0.5f); clean.PlaySustainerOrSound(() => SoundDefOf.Interact_CleanFilth); clean.JumpIfDespawnedOrNullOrForbidden(TargetIndex.A, CleanFilthList); clean.JumpIfOutsideHomeArea(TargetIndex.A, CleanFilthList); yield return(clean); yield return(Toils_Jump.Jump(CleanFilthList)); yield return(returnToBillGiver); } //continuation of normal scenario yield return(Toils_Recipe.MakeUnfinishedThingIfNeeded()); yield return(Toils_Recipe.DoRecipeWork().FailOnDespawnedNullOrForbiddenPlacedThings().FailOnCannotTouch(TargetIndex.A, PathEndMode.InteractionCell)); yield return(Toils_Recipe.FinishRecipeAndStartStoringProduct()); if (!__instance.job.RecipeDef.products.NullOrEmpty() || !__instance.job.RecipeDef.specialProducts.NullOrEmpty()) { yield return(Toils_Reserve.Reserve(TargetIndex.B, 1, -1, null)); Toil carryToCell = Toils_Haul.CarryHauledThingToCell(TargetIndex.B); yield return(carryToCell); yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.B, carryToCell, true)); Toil recount = new Toil(); recount.initAction = delegate() { Bill_Production bill_Production = recount.actor.jobs.curJob.bill as Bill_Production; if (bill_Production != null && bill_Production.repeatMode == BillRepeatModeDefOf.TargetCount) { __instance.MapCrutch().resourceCounter.UpdateResourceCounts(); } }; yield return(recount); } yield break; }
protected override IEnumerable <Toil> MakeNewToils() { //Workbench giver destroyed (only in bill using phase! Not in carry phase) this.AddEndCondition(() => { var targ = GetActor().jobs.curJob.GetTarget(StationIndex).Thing; if (targ == null || (targ is Building && !targ.Spawned)) { return(JobCondition.Incompletable); } return(JobCondition.Ongoing); }); this.FailOnBurningImmobile(StationIndex); //Rechargestation is burning this.FailOn(() => { X2_Building_AIRobotRechargeStation workbench = job.GetTarget(StationIndex).Thing as X2_Building_AIRobotRechargeStation; //conditions only apply during the billgiver-use phase if (workbench == null) { return(true); } return(false); }); //Go to the recharge station, this is yielded later, but needed here! Toil gotoStation = Toils_Goto.GotoThing(StationIndex, PathEndMode.Touch); //Jump over ingredient gathering if there are no ingredients needed yield return(Toils_Jump.JumpIf(gotoStation, () => this.job.GetTargetQueue(IngredientIndex).NullOrEmpty())); { //Get to ingredient and pick it up //Note that these fail cases must be on these toils, otherwise the recipe work fails if you stacked // your targetB into another object on the bill giver square. Toil extract = Toils_JobTransforms.ExtractNextTargetFromQueue(IngredientIndex); yield return(extract); //Note that these fail cases must be on these toils, otherwise the recipe work fails if you stacked // your targetB into another object on the bill giver square. var getToHaulTarget2 = Toils_Goto.GotoThing(IngredientIndex, PathEndMode.Touch) .FailOnDespawnedNullOrForbidden(IngredientIndex) .FailOnSomeonePhysicallyInteracting(IngredientIndex); yield return(getToHaulTarget2); //Carry ingredient to the workbench yield return(Toils_Haul.StartCarryThing(IngredientIndex, true)); //Jump to pick up more in this run if we're collecting from multiple stacks at once yield return(JumpToAlsoCollectTargetInQueue(getToHaulTarget2, IngredientIndex)); //Carry ingredient to the workbench yield return(Toils_Goto.GotoThing(StationIndex, PathEndMode.Touch) .FailOnDestroyedOrNull(IngredientIndex)); //Place ingredient on the appropriate cell Toil findPlaceTarget2 = Toils_JobTransforms.SetTargetToIngredientPlaceCell(StationIndex, IngredientIndex, IngredientPlaceCellIndex); yield return(findPlaceTarget2); yield return(Toils_Haul.PlaceHauledThingInCell(IngredientPlaceCellIndex, findPlaceTarget2, false, false)); // save the ingredient, so that it can be deleted later on! Toil saveIngredient = new Toil(); saveIngredient.initAction = delegate { this.ingredients.Add(GetActor().jobs.curJob.GetTarget(IngredientIndex).Thing); }; saveIngredient.defaultCompleteMode = ToilCompleteMode.Instant; yield return(saveIngredient); //Jump back if another ingredient is queued, or you didn't finish carrying your current ingredient target yield return(Toils_Jump.JumpIfHaveTargetInQueue(IngredientIndex, extract)); extract = null; getToHaulTarget2 = null; findPlaceTarget2 = null; } //yield return GetDebugToil("goto station", true); //Go to the recharge station yield return(gotoStation); //Do the repair work yield return(DoRepairWork(500, "Interact_ConstructMetal") .FailOnDespawnedNullOrForbiddenPlacedThings() .FailOnCannotTouch(StationIndex, PathEndMode.Touch)); yield break; }
protected override IEnumerable <Toil> MakeNewToils() { this.AddEndCondition(delegate { Thing thing = this.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 = this.pawn.jobs.curJob.GetTarget(TargetIndex.A).Thing as IBillGiver; // if (billGiver != null) // { // if (this.pawn.jobs.curJob.bill.DeletedOrDereferenced) // { // return true; // } // if (!billGiver.CurrentlyUsable()) // { // return true; // } // } // return false; //}); //yield return ToilLogMessage("Pass 0 - Start"); Toil toil = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell); yield return(new Toil { initAction = delegate { offerings = new List <Thing>(); } }); yield return(Toils_Reserve.Reserve(TargetIndex.A, 1)); //yield return new Toil {initAction = delegate {Log.Message("Pass 2");}}; yield return(Toils_Reserve.ReserveQueue(TargetIndex.B, 1)); //yield return new Toil {initAction = delegate {Log.Message("Pass 3");}}; yield return(new Toil { initAction = delegate { if (this.job.targetQueueB != null && this.job.targetQueueB.Count == 1) { UnfinishedThing unfinishedThing = this.job.targetQueueB[0].Thing as UnfinishedThing; if (unfinishedThing != null) { unfinishedThing.BoundBill = (Bill_ProductionWithUft)this.job.bill; } } } }); //yield return new Toil {initAction = delegate {Log.Message("Pass 4");}}; yield return(Toils_Jump.JumpIf(toil, () => this.job.GetTargetQueue(TargetIndex.B).NullOrEmpty <LocalTargetInfo>())); //yield return new Toil {initAction = delegate {Log.Message("Pass 5");}}; Toil toil2 = Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.B, false); yield return(toil2); //yield return new Toil {initAction = delegate {Log.Message("Pass 6");}}; Toil toil3 = Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.B).FailOnSomeonePhysicallyInteracting(TargetIndex.B); yield return(toil3); //yield return new Toil {initAction = delegate {Log.Message("Pass 7");}}; yield return(Toils_Haul.StartCarryThing(TargetIndex.B, true, false)); //yield return new Toil {initAction = delegate {Log.Message("Pass 8");}}; yield return(JumpToCollectNextIntoHandsForBill(toil3, TargetIndex.B)); //yield return new Toil {initAction = delegate {Log.Message("Pass 9");}}; yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.ClosestTouch).FailOnDestroyedOrNull(TargetIndex.B)); //yield return new Toil {initAction = delegate {Log.Message("Pass 10");}}; Toil toil4 = Toils_JobTransforms.SetTargetToIngredientPlaceCell(TargetIndex.A, TargetIndex.B, TargetIndex.C); yield return(toil4); //yield return new Toil {initAction = delegate {Log.Message("Pass 11");}}; yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.C, toil4, false)); //yield return new Toil {initAction = delegate {Log.Message("Pass 12");}}; yield return(new Toil { initAction = delegate { if (offerings.Count > 0) { offerings.RemoveAll(x => x.DestroyedOrNull()); } offerings.Add(TargetB.Thing); } }); yield return(Toils_Jump.JumpIfHaveTargetInQueue(TargetIndex.B, toil2)); yield return(toil); //yield return ToilLogMessage("Pass 13"); Toil chantingTime = new Toil(); chantingTime.defaultCompleteMode = ToilCompleteMode.Delay; chantingTime.defaultDuration = CultUtility.ritualDuration; chantingTime.WithProgressBarToilDelay(TargetIndex.A, false, -0.5f); chantingTime.PlaySustainerOrSound(CultsDefOf.RitualChanting); Texture2D deitySymbol = ((CosmicEntityDef)DropAltar.currentOfferingDeity.def).Symbol; chantingTime.initAction = delegate { if (deitySymbol != null) { MoteMaker.MakeInteractionBubble(this.pawn, null, ThingDefOf.Mote_Speech, deitySymbol); } }; yield return(chantingTime); //yield return ToilLogMessage("Pass 14"); //Toil 8: Execution of Prisoner yield return(new Toil { initAction = delegate { CultUtility.OfferingComplete(this.pawn, DropAltar, DropAltar.currentOfferingDeity, offerings); }, defaultCompleteMode = ToilCompleteMode.Instant }); //yield return ToilLogMessage("Pass 15 - Final"); yield break; //this.AddEndCondition(delegate //{ // Thing thing = this.GetActor().jobs.curJob.GetTarget(TargetIndex.A).Thing; // if (thing is Building && !thing.Spawned) // { // return JobCondition.Incompletable; // } // return JobCondition.Ongoing; //}); //this.FailOnBurningImmobile(TargetIndex.A); //Toil toil = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell); //yield return Toils_Reserve.Reserve(TargetIndex.A, 1); //yield return Toils_Reserve.ReserveQueue(TargetIndex.B, 1); //yield return new Toil //{ // initAction = delegate // { // if (this.job.targetQueueB != null && this.job.targetQueueB.Count == 1) // { // UnfinishedThing unfinishedThing = this.job.targetQueueB[0].Thing as UnfinishedThing; // if (unfinishedThing != null) // { // unfinishedThing.BoundBill = (Bill_ProductionWithUft)this.job.bill; // } // } // } //}; //yield return Toils_Jump.JumpIf(toil, () => this.job.GetTargetQueue(TargetIndex.B).NullOrEmpty<LocalTargetInfo>()); //Toil toil2 = Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.B); //yield return toil2; //Toil toil3 = Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.B).FailOnSomeonePhysicallyInteracting(TargetIndex.B); //yield return toil3; //yield return Toils_Haul.StartCarryThing(TargetIndex.B); //yield return JumpToCollectNextIntoHandsForBill(toil3, TargetIndex.B); //yield return Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell).FailOnDestroyedOrNull(TargetIndex.B); //Toil toil4 = Toils_JobTransforms.SetTargetToIngredientPlaceCell(TargetIndex.A, TargetIndex.B, TargetIndex.C); //yield return toil4; //yield return Toils_Haul.PlaceHauledThingInCell(TargetIndex.C, toil4, false); //yield return Toils_Jump.JumpIfHaveTargetInQueue(TargetIndex.B, toil2); //yield return toil; //Toil chantingTime = new Toil(); //chantingTime.defaultCompleteMode = ToilCompleteMode.Delay; //CultUtility.remainingDuration = CultUtility.ritualDuration; //chantingTime.defaultDuration = CultUtility.remainingDuration - 360; //chantingTime.WithProgressBarToilDelay(TargetIndex.A, false, -0.5f); //chantingTime.PlaySustainerOrSound(CultDefOfs.RitualChanting); //Texture2D deitySymbol = ((CosmicEntityDef)DropAltar.currentOfferingDeity.def).Symbol; //chantingTime.initAction = delegate //{ // if (deitySymbol != null) // MoteMaker.MakeInteractionBubble(this.pawn, null, ThingDefOf.Mote_Speech, deitySymbol); //}; //yield return chantingTime; ////Toil 8: Execution of Prisoner //yield return new Toil //{ // initAction = delegate // { // CultUtility.OfferingComplete(this.pawn, DropAltar, DropAltar.currentOfferingDeity); // }, // defaultCompleteMode = ToilCompleteMode.Instant //}; ////this.AddFinishAction(() => ////{ //// if (this.pawn.CurJob.targetQueueB.Count == 0 && //// DropAltar.currentOfferingState == Building_SacrificialAltar.OfferingState.started) //// //When the ritual is finished -- then let's give the thoughts //// CultUtility.OfferingReady(this.pawn, DropAltar); ////}); }
protected override IEnumerable <Toil> MakeNewToils() { Apparel_Backpack backpack = CurJob.GetTarget(BackpackInd).Thing as Apparel_Backpack; Thing lastItem = ToolsForHaulUtility.TryGetBackpackLastItem(pawn); /// //Set fail conditions /// /// //Define Toil /// Toil endOfJob = new Toil(); endOfJob.initAction = () => { EndJobWith(JobCondition.Succeeded); }; Toil checkStoreCellEmpty = Toils_Jump.JumpIf(endOfJob, () => CurJob.GetTargetQueue(StoreCellInd).NullOrEmpty()); Toil checkHaulableEmpty = Toils_Jump.JumpIf(checkStoreCellEmpty, () => CurJob.GetTargetQueue(HaulableInd).NullOrEmpty()); /// //Toils Start /// //Reserve thing to be stored and storage cell yield return(Toils_Reserve.ReserveQueue(HaulableInd)); yield return(Toils_Reserve.ReserveQueue(StoreCellInd)); //JumpIf checkStoreCellEmpty yield return(checkHaulableEmpty); //Collect TargetQueue { Toil extractA = Toils_Collect.Extract(HaulableInd); yield return(extractA); Toil gotoThing = Toils_Goto.GotoThing(HaulableInd, PathEndMode.ClosestTouch) .FailOnDestroyed(HaulableInd); yield return(gotoThing); yield return(ToolsForHaul.Toils_Collect.CollectInInventory(HaulableInd)); yield return(Toils_Collect.CheckDuplicates(gotoThing, BackpackInd, HaulableInd)); yield return(Toils_Jump.JumpIfHaveTargetInQueue(HaulableInd, extractA)); } //JumpIf toilEnd yield return(checkStoreCellEmpty); //Drop TargetQueue { Toil extractB = Toils_Collect.Extract(StoreCellInd); yield return(extractB); yield return(Toils_Goto.GotoCell(StoreCellInd, PathEndMode.ClosestTouch) .FailOnBurningImmobile(StoreCellInd)); yield return(ToolsForHaul.Toils_Collect.DropTheCarriedInCell(StoreCellInd, ThingPlaceMode.Direct, lastItem)); yield return(Toils_Jump.JumpIfHaveTargetInQueue(StoreCellInd, extractB)); } yield return(endOfJob); }
protected override IEnumerable <Toil> MakeNewToils() { Vehicle_Cart cart = CurJob.GetTarget(CartInd).Thing as Vehicle_Cart; /// //Set fail conditions /// this.FailOnDestroyedOrNull(CartInd); //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(CartInd); } /// //Define Toil /// Toil findStoreCellForCart = Toils_Cart.FindStoreCellForCart(CartInd); Toil checkCartEmpty = Toils_Jump.JumpIf(findStoreCellForCart, () => cart.storage.Count <= 0); Toil checkStoreCellEmpty = Toils_Jump.JumpIf(findStoreCellForCart, () => CurJob.GetTargetQueue(StoreCellInd).NullOrEmpty()); Toil checkHaulableEmpty = Toils_Jump.JumpIf(checkStoreCellEmpty, () => CurJob.GetTargetQueue(HaulableInd).NullOrEmpty()); /// //Toils Start /// //Reserve thing to be stored and storage cell yield return(Toils_Reserve.Reserve(CartInd)); yield return(Toils_Reserve.ReserveQueue(HaulableInd)); yield return(Toils_Reserve.ReserveQueue(StoreCellInd)); //JumpIf already mounted yield return(Toils_Jump.JumpIf(checkHaulableEmpty, () => { return (cart.GetComp <CompMountable>().Driver == pawn) ? true : false; })); //Mount on Target yield return(Toils_Goto.GotoThing(CartInd, PathEndMode.ClosestTouch) .FailOnDestroyedOrNull(CartInd)); yield return(Toils_Cart.MountOn(CartInd)); //JumpIf checkStoreCellEmpty yield return(checkHaulableEmpty); //Collect TargetQueue { Toil extractA = Toils_Collect.Extract(HaulableInd); yield return(extractA); Toil gotoThing = Toils_Goto.GotoThing(HaulableInd, PathEndMode.ClosestTouch) .FailOnDestroyedOrNull(HaulableInd); yield return(gotoThing); yield return(Toils_Collect.CollectInCarrier(CartInd, HaulableInd)); yield return(Toils_Collect.CheckDuplicates(gotoThing, CartInd, HaulableInd)); yield return(Toils_Jump.JumpIfHaveTargetInQueue(HaulableInd, extractA)); } //JumpIf findStoreCellForCart yield return(checkStoreCellEmpty); //Drop TargetQueue { yield return(checkCartEmpty); Toil extractB = Toils_Collect.Extract(StoreCellInd); yield return(extractB); Toil gotoCell = Toils_Goto.GotoCell(StoreCellInd, PathEndMode.ClosestTouch); yield return(gotoCell); yield return(Toils_Collect.DropTheCarriedInCell(StoreCellInd, ThingPlaceMode.Direct, CartInd)); yield return(Toils_Jump.JumpIfHaveTargetInQueue(StoreCellInd, checkCartEmpty)); yield return(Toils_Collect.CheckNeedStorageCell(gotoCell, CartInd, StoreCellInd)); } yield return(findStoreCellForCart); yield return(Toils_Goto.GotoCell(StoreCellInd, PathEndMode.OnCell)); yield return(Toils_Cart.DismountAt(CartInd, StoreCellInd)); }
protected override IEnumerable <Toil> MakeNewToils() { Init(); yield return(Toils_JobTransforms.MoveCurrentTargetIntoQueue(TargetIndex.A)); yield return(Toils_Reserve.ReserveQueue(TargetIndex.A, 1, -1, null)); var initExtractTargetFromQueue = Toils_JobTransforms.ClearDespawnedNullOrForbiddenQueuedTargets(TargetIndex.A); yield return(initExtractTargetFromQueue); yield return(Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.A)); var checkNextQueuedTarget = Toils_JobTransforms.ClearDespawnedNullOrForbiddenQueuedTargets(TargetIndex.A); yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch) .JumpIfDespawnedOrNullOrForbidden(TargetIndex.A, checkNextQueuedTarget)); var cut = new Toil(); cut.tickAction = delegate { var actor = cut.actor; if (actor.skills != null) { actor.skills.Learn(SkillDefOf.Plants, xpPerTick, false); } var statValue = actor.GetStatValue(StatDefOf.PlantWorkSpeed, true); var num = statValue; var plant = Plant; workDone += num; if (workDone >= plant.def.plant.harvestWork) { if (plant.def.plant.harvestedThingDef != null) { if (actor.RaceProps.Humanlike && plant.def.plant.harvestFailable && Rand.Value > actor.GetStatValue(StatDefOf.PlantHarvestYield, true)) { var loc = (pawn.DrawPos + plant.DrawPos) / 2f; MoteMaker.ThrowText(loc, Map, "TextMote_HarvestFailed".Translate(), 3.65f); } else { var num2 = plant.YieldNow(); if (num2 > 0) { var thing = ThingMaker.MakeThing(plant.def.plant.harvestedThingDef, null); thing.stackCount = num2; GenPlace.TryPlaceThing(thing, actor.Position, Map, ThingPlaceMode.Near, null); actor.records.Increment(RecordDefOf.PlantsHarvested); } } } plant.def.plant.soundHarvestFinish.PlayOneShot(actor); plant.PlantCollected(); workDone = 0f; ReadyForNextToil(); } }; cut.FailOnDespawnedNullOrForbidden(TargetIndex.A); cut.FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch); cut.defaultCompleteMode = ToilCompleteMode.Never; cut.WithEffect(EffecterDefOf.Harvest, TargetIndex.A); cut.WithProgressBar(TargetIndex.A, () => workDone / Plant.def.plant.harvestWork, true, -0.5f); cut.PlaySustainerOrSound(() => Plant.def.plant.soundHarvesting); yield return(cut); yield return(checkNextQueuedTarget); yield return(Toils_Jump.JumpIfHaveTargetInQueue(TargetIndex.A, initExtractTargetFromQueue)); }
protected override IEnumerable <Toil> MakeNewToils() { Vehicle_Cart cart = CurJob.GetTarget(CartInd).Thing as Vehicle_Cart; Job jobNew = new Job(); /// //Set fail conditions /// this.FailOnDestroyed(CartInd); this.FailOn(() => !cart.mountableComp.IsMounted); //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(CartInd); } /// //Define Toil /// Toil releaseAnimalCart = Toils_Cart.ReleaseAnimalCart(CartInd); Toil checkCartEmpty = Toils_Jump.JumpIf(releaseAnimalCart, () => cart.storage.Count <= 0); Toil checkStoreCellEmpty = Toils_Jump.JumpIf(releaseAnimalCart, () => CurJob.GetTargetQueue(StoreCellInd).NullOrEmpty()); Toil checkHaulableEmpty = Toils_Jump.JumpIf(checkStoreCellEmpty, () => CurJob.GetTargetQueue(HaulableInd).NullOrEmpty()); /// //Toils Start /// //Reserve thing to be stored and storage cell yield return(Toils_Reserve.Reserve(CartInd)); yield return(Toils_Reserve.ReserveQueue(HaulableInd)); yield return(Toils_Reserve.ReserveQueue(StoreCellInd)); yield return(Toils_Goto.GotoThing(CartInd, PathEndMode.Touch) .FailOn(() => cart.Destroyed || !cart.TryGetComp <CompMountable>().IsMounted)); //JumpIf toilCheckStoreCellEmpty yield return(checkHaulableEmpty); //Collect TargetQueue { Toil extractA = Toils_Collect.Extract(HaulableInd); yield return(extractA); Toil callAnimalCartForCollect = Toils_Cart.CallAnimalCart(CartInd, HaulableInd) .FailOnDestroyed(HaulableInd); yield return(callAnimalCartForCollect); yield return(Toils_Goto.GotoThing(HaulableInd, PathEndMode.ClosestTouch) .FailOnDestroyed(HaulableInd)); yield return(Toils_Cart.WaitAnimalCart(CartInd, HaulableInd)); yield return(Toils_Collect.CollectInCarrier(CartInd, HaulableInd)); yield return(Toils_Collect.CheckDuplicates(callAnimalCartForCollect, CartInd, HaulableInd)); yield return(Toils_Jump.JumpIfHaveTargetInQueue(HaulableInd, extractA)); } //JumpIf releaseAnimalCart yield return(checkStoreCellEmpty); //Drop TargetQueue { yield return(checkCartEmpty); Toil extractB = Toils_Collect.Extract(StoreCellInd); yield return(extractB); Toil callAnimalCartForDrop = Toils_Cart.CallAnimalCart(CartInd, StoreCellInd); yield return(callAnimalCartForDrop); yield return(Toils_Goto.GotoCell(StoreCellInd, PathEndMode.ClosestTouch) .FailOnBurningImmobile(StoreCellInd)); yield return(Toils_Cart.WaitAnimalCart(CartInd, HaulableInd)); yield return(Toils_Collect.DropTheCarriedInCell(StoreCellInd, ThingPlaceMode.Direct, CartInd)); yield return(Toils_Jump.JumpIfHaveTargetInQueue(StoreCellInd, checkCartEmpty)); yield return(Toils_Collect.CheckNeedStorageCell(callAnimalCartForDrop, CartInd, StoreCellInd)); } yield return(releaseAnimalCart); }
protected override IEnumerable <Toil> MakeNewToils() { Toil toil = new Toil(); yield return(new Toil { initAction = delegate() { try { ZLogger.Message("--------------------------"); for (int i = job.targetQueueB.Count - 1; i >= 0; i--) { var target = job.targetQueueB[i]; ZLogger.Message("-1 job.targetQueueB: " + target.Thing); ZLogger.Message("-1 job.targetQueueB.Map: " + target.Thing.Map); ZLogger.Message("-1 job.targetQueueB.stackCount: " + target.Thing.stackCount); ZLogger.Message("-1 job.targetQueueB.countQueue: " + job.countQueue[i]); } } catch { } ZLogger.Message("-1 toil.actor: " + toil.actor); ZLogger.Message("-1 toil.actor.Position: " + toil.actor.Position); ZLogger.Message("-1 toil.actor.Map: " + toil.actor.Map); ZLogger.Message("-1 TargetB.Thing: " + TargetB.Thing); ZLogger.Message("-1 TargetB.Thing.Position: " + TargetB.Thing?.Position); ZLogger.Message("-1 TargetB.Thing.Map: " + TargetB.Thing?.Map); ZLogger.Message(toil.actor + " - checking reservations on: " + TargetB.Thing, true); ZLogger.Message("-1 pawn.Map.physicalInteractionReservationManager.FirstReserverOf(target): " + toil.actor.Map.physicalInteractionReservationManager.FirstReserverOf(TargetB)); ZLogger.Message("-1 TargetB.Thing == null: " + (TargetB.Thing == null).ToString()); ZLogger.Message("-1 !toil.actor.Map.physicalInteractionReservationManager.IsReserved(TargetB.Thing): " + (!toil.actor.Map.physicalInteractionReservationManager.IsReserved(TargetB.Thing)).ToString()); ZLogger.Message("-1 toil.actor.Map.physicalInteractionReservationManager.IsReservedBy(toil.actor, TargetB.Thing)): " + (toil.actor.Map.physicalInteractionReservationManager.IsReservedBy(toil.actor, TargetB.Thing)).ToString()); ZLogger.Message("-1 failcondition" + ((TargetB == null || !toil.actor.Map.physicalInteractionReservationManager.IsReserved(TargetB) || toil.actor.Map.physicalInteractionReservationManager.IsReservedBy(toil.actor, TargetB)) ? JobCondition.Ongoing : JobCondition.Incompletable).ToString()); try { for (int i = job.targetQueueA.Count - 1; i >= 0; i--) { var target = job.targetQueueA[i]; ZLogger.Message("-1 job.targetQueueA: " + target.Thing); ZLogger.Message("-1 job.targetQueueA: " + target.Thing.Map); } } catch { } } }); AddEndCondition(delegate { Thing thing = GetActor().jobs.curJob.GetTarget(TargetIndex.A).Thing; return((!(thing is Building) || thing.Spawned) ? JobCondition.Ongoing : JobCondition.Incompletable); }); this.FailOnBurningImmobile(TargetIndex.A); this.FailOn(delegate { IBillGiver billGiver = job.GetTarget(TargetIndex.A).Thing as IBillGiver; if (billGiver != null) { if (job.bill.DeletedOrDereferenced) { Log.Message(this.pawn + " - 1 fail", true); return(true); } if (!billGiver.CurrentlyUsableForBills()) { Log.Message(this.pawn + " - 2 fail", true); return(true); } } return(false); }); Toil gotoBillGiver = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell); 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(toil); yield return(new Toil { initAction = delegate() { ZLogger.Message("1 toil.actor: " + toil.actor); ZLogger.Message("1 toil.actor.Position: " + toil.actor.Position); ZLogger.Message("1 toil.actor.Map: " + toil.actor.Map); ZLogger.Message("1 TargetB.Thing: " + TargetB.Thing); ZLogger.Message("1 TargetB.Thing.Position: " + TargetB.Thing?.Position); ZLogger.Message("1 TargetB.Thing.Map: " + TargetB.Thing?.Map); ZLogger.Message(toil.actor + " - checking reservations on: " + TargetB.Thing, true); ZLogger.Message("1 pawn.Map.physicalInteractionReservationManager.FirstReserverOf(target): " + toil.actor.Map.physicalInteractionReservationManager.FirstReserverOf(TargetB)); ZLogger.Message("1 TargetB.Thing == null: " + (TargetB.Thing == null).ToString()); ZLogger.Message("1 !toil.actor.Map.physicalInteractionReservationManager.IsReserved(TargetB.Thing): " + (!toil.actor.Map.physicalInteractionReservationManager.IsReserved(TargetB.Thing)).ToString()); ZLogger.Message("1 toil.actor.Map.physicalInteractionReservationManager.IsReservedBy(toil.actor, TargetB.Thing)): " + (toil.actor.Map.physicalInteractionReservationManager.IsReservedBy(toil.actor, TargetB.Thing)).ToString()); ZLogger.Message("1 failcondition" + ((TargetB == null || !toil.actor.Map.physicalInteractionReservationManager.IsReserved(TargetB) || toil.actor.Map.physicalInteractionReservationManager.IsReservedBy(toil.actor, TargetB)) ? JobCondition.Ongoing : JobCondition.Incompletable).ToString()); try { for (int i = job.targetQueueA.Count - 1; i >= 0; i--) { var target = job.targetQueueA[i]; ZLogger.Message("1 job.targetQueueA: " + target.Thing); ZLogger.Message("1 job.targetQueueA: " + target.Thing.Map); ZLogger.Message("1 job.targetQueueA: " + target.Thing.stackCount); } } catch { } try { ZLogger.Message("--------------------------"); for (int i = job.targetQueueB.Count - 1; i >= 0; i--) { var target = job.targetQueueB[i]; ZLogger.Message("1 job.targetQueueB: " + target.Thing); ZLogger.Message("1 job.targetQueueB.Map: " + target.Thing.Map); ZLogger.Message("1 job.targetQueueB.stackCount: " + target.Thing.stackCount); ZLogger.Message("1 job.targetQueueB.countQueue: " + job.countQueue[i]); } } catch { } } }); yield return(Toils_Jump.JumpIf(gotoBillGiver, () => job.GetTargetQueue(TargetIndex.B).NullOrEmpty())); Toil extract = ExtractNextTargetFromQueue(TargetIndex.B); yield return(new Toil { initAction = delegate() { ZLogger.Message("2 toil.actor: " + toil.actor); ZLogger.Message("2 toil.actor.Position: " + toil.actor.Position); ZLogger.Message("2 toil.actor.Map: " + toil.actor.Map); ZLogger.Message("2 TargetB.Thing: " + TargetB.Thing); ZLogger.Message("2 TargetB.Thing.Position: " + TargetB.Thing?.Position); ZLogger.Message("2 TargetB.Thing.Map: " + TargetB.Thing?.Map); ZLogger.Message(toil.actor + " - checking reservations on: " + TargetB.Thing, true); ZLogger.Message("2 pawn.Map.physicalInteractionReservationManager.FirstReserverOf(target): " + toil.actor.Map.physicalInteractionReservationManager.FirstReserverOf(TargetB)); ZLogger.Message("2 TargetB.Thing == null: " + (TargetB.Thing == null).ToString()); ZLogger.Message("2 !toil.actor.Map.physicalInteractionReservationManager.IsReserved(TargetB.Thing): " + (!toil.actor.Map.physicalInteractionReservationManager.IsReserved(TargetB.Thing)).ToString()); ZLogger.Message("2 toil.actor.Map.physicalInteractionReservationManager.IsReservedBy(toil.actor, TargetB.Thing)): " + (toil.actor.Map.physicalInteractionReservationManager.IsReservedBy(toil.actor, TargetB.Thing)).ToString()); ZLogger.Message("2 failcondition" + ((TargetB == null || !toil.actor.Map.physicalInteractionReservationManager.IsReserved(TargetB) || toil.actor.Map.physicalInteractionReservationManager.IsReservedBy(toil.actor, TargetB)) ? JobCondition.Ongoing : JobCondition.Incompletable).ToString()); try { for (int i = job.targetQueueA.Count - 1; i >= 0; i--) { var target = job.targetQueueA[i]; ZLogger.Message("2 job.targetQueueA: " + target.Thing); ZLogger.Message("2 job.targetQueueA: " + target.Thing.Map); } } catch { } try { ZLogger.Message("--------------------------"); for (int i = job.targetQueueB.Count - 1; i >= 0; i--) { var target = job.targetQueueB[i]; ZLogger.Message("2 job.targetQueueB: " + target.Thing); ZLogger.Message("2 job.targetQueueB.Map: " + target.Thing.Map); ZLogger.Message("2 job.targetQueueB.stackCount: " + target.Thing.stackCount); ZLogger.Message("2 job.targetQueueB.countQueue: " + job.countQueue[i]); } } catch { } } }); yield return(extract); Toil getToHaulTarget = Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch); yield return(new Toil { initAction = delegate() { ZLogger.Message("3 toil.actor: " + toil.actor); ZLogger.Message("3 toil.actor.Position: " + toil.actor.Position); ZLogger.Message("3 toil.actor.Map: " + toil.actor.Map); ZLogger.Message("3 TargetB.Thing: " + TargetB.Thing); ZLogger.Message("3 TargetB.Thing.Position: " + TargetB.Thing?.Position); ZLogger.Message("3 TargetB.Thing.Map: " + TargetB.Thing?.Map); ZLogger.Message(toil.actor + " - checking reservations on: " + TargetB.Thing, true); ZLogger.Message("3 pawn.Map.physicalInteractionReservationManager.FirstReserverOf(target): " + toil.actor.Map.physicalInteractionReservationManager.FirstReserverOf(TargetB)); ZLogger.Message("3 TargetB.Thing == null: " + (TargetB.Thing == null).ToString()); ZLogger.Message("3 !toil.actor.Map.physicalInteractionReservationManager.IsReserved(TargetB.Thing): " + (!toil.actor.Map.physicalInteractionReservationManager.IsReserved(TargetB.Thing)).ToString()); ZLogger.Message("3 toil.actor.Map.physicalInteractionReservationManager.IsReservedBy(toil.actor, TargetB.Thing)): " + (toil.actor.Map.physicalInteractionReservationManager.IsReservedBy(toil.actor, TargetB.Thing)).ToString()); ZLogger.Message("3 failcondition" + ((TargetB == null || !toil.actor.Map.physicalInteractionReservationManager.IsReserved(TargetB) || toil.actor.Map.physicalInteractionReservationManager.IsReservedBy(toil.actor, TargetB)) ? JobCondition.Ongoing : JobCondition.Incompletable).ToString()); try { for (int i = job.targetQueueA.Count - 1; i >= 0; i--) { var target = job.targetQueueA[i]; ZLogger.Message("3 job.targetQueueA: " + target.Thing); ZLogger.Message("3 job.targetQueueA: " + target.Thing.Map); } } catch { } try { ZLogger.Message("--------------------------"); for (int i = job.targetQueueB.Count - 1; i >= 0; i--) { var target = job.targetQueueB[i]; ZLogger.Message("3 job.targetQueueB: " + target.Thing); ZLogger.Message("3 job.targetQueueB.Map: " + target.Thing.Map); ZLogger.Message("3 job.targetQueueB.stackCount: " + target.Thing.stackCount); ZLogger.Message("3 job.targetQueueB.countQueue: " + job.countQueue[i]); } } catch { } } }); yield return(getToHaulTarget); yield return(Toils_Haul.StartCarryThing(TargetIndex.B, putRemainderInQueue: true, subtractNumTakenFromJobCount: false, failIfStackCountLessThanJobCount: true)); yield return(JumpToCollectNextIntoHandsForBill(getToHaulTarget, TargetIndex.B)); yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell).FailOnDestroyedOrNull(TargetIndex.B)); Toil findPlaceTarget2 = Toils_JobTransforms.SetTargetToIngredientPlaceCell(TargetIndex.A, TargetIndex.B, TargetIndex.C); yield return(findPlaceTarget2); yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.C, findPlaceTarget2, storageMode: false)); yield return(Toils_Jump.JumpIfHaveTargetInQueue(TargetIndex.B, extract)); yield return(gotoBillGiver); yield return(Toils_Recipe.MakeUnfinishedThingIfNeeded()); yield return(DoRecipeWork().FailOnDespawnedNullOrForbiddenPlacedThings().FailOnCannotTouch(TargetIndex.A, PathEndMode.InteractionCell)); yield return(FinishRecipeAndStartStoringProduct()); if (!job.RecipeDef.products.NullOrEmpty() || !job.RecipeDef.specialProducts.NullOrEmpty()) { yield return(Toils_Reserve.Reserve(TargetIndex.B)); findPlaceTarget2 = Toils_Haul.CarryHauledThingToCell(TargetIndex.B); yield return(findPlaceTarget2); yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.B, findPlaceTarget2, storageMode: true, tryStoreInSameStorageIfSpotCantHoldWholeStack: true)); Toil recount = new Toil(); recount.initAction = delegate { Bill_Production bill_Production = recount.actor.jobs.curJob.bill as Bill_Production; if (bill_Production != null && bill_Production.repeatMode == BillRepeatModeDefOf.TargetCount) { base.Map.resourceCounter.UpdateResourceCounts(); } }; yield return(recount); } }
protected override IEnumerable <Toil> MakeNewToils() { Apparel_Toolbelt toolbelt = this.CurJob.GetTarget(SlotterInd).Thing as Apparel_Toolbelt; // no free slots this.FailOn(() => toolbelt.slotsComp.slots.Count >= toolbelt.MaxItem); // reserve resources yield return(Toils_Reserve.ReserveQueue(HaulableInd)); // extract next target thing from targetQueue Toil toilExtractNextTarget = Toils_JobTransforms.ExtractNextTargetFromQueue(HaulableInd); yield return(toilExtractNextTarget); Toil toilGoToThing = Toils_Goto.GotoThing(HaulableInd, PathEndMode.ClosestTouch) .FailOnDespawnedOrNull(HaulableInd); yield return(toilGoToThing); Toil pickUpThingIntoSlot = new Toil { initAction = () => { if (!toolbelt.slotsComp.slots.TryAdd(this.CurJob.targetA.Thing)) { this.EndJobWith(JobCondition.Incompletable); } else { float statfloat = 0; Thing thing = this.TargetThingA; // add stats to pawn inventory foreach (KeyValuePair <StatDef, float> stat in pawn.GetWeightedWorkStats()) { statfloat = RightTools.GetMaxStat(thing as ThingWithComps, stat.Key); if (statfloat > 0) { MapComponent_ToolsForHaul.CachedToolEntries.Add(new MapComponent_ToolsForHaul.Entry(pawn, thing, stat.Key, statfloat)); } for (int i = toolbelt.slotsComp.slots.Count - 1; i >= 0; i--) { var tool = toolbelt.slotsComp.slots[i]; var checkstat = RightTools.GetMaxStat(tool as ThingWithComps, stat.Key); if (checkstat > 0 && checkstat < statfloat) { Thing dropTool; toolbelt.slotsComp.slots.TryDrop(tool, pawn.Position, pawn.Map, ThingPlaceMode.Near, out dropTool, null); for (int j = MapComponent_ToolsForHaul.CachedToolEntries.Count - 1; j >= 0; j--) { var entry = MapComponent_ToolsForHaul.CachedToolEntries[j]; if (entry.tool == tool) { MapComponent_ToolsForHaul.CachedToolEntries.RemoveAt(j); } } } } } } } }; yield return(pickUpThingIntoSlot); yield return(Toils_Jump.JumpIfHaveTargetInQueue(HaulableInd, toilExtractNextTarget)); }
protected override IEnumerable <Toil> MakeNewToils() { AddEndCondition(delegate { Thing thing = GetActor().jobs.curJob.GetTarget(TargetIndex.A).Thing; return((!(thing is Building) || thing.Spawned) ? JobCondition.Ongoing : JobCondition.Incompletable); }); 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); } } return(false); }); Toil gotoBillGiver = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell); Toil toil = new Toil(); 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(toil); yield return(Toils_Jump.JumpIf(gotoBillGiver, () => job.GetTargetQueue(TargetIndex.B).NullOrEmpty())); Toil extract = Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.B); 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, putRemainderInQueue: true, subtractNumTakenFromJobCount: false, failIfStackCountLessThanJobCount: true)); yield return(JumpToCollectNextIntoHandsForBill(getToHaulTarget, TargetIndex.B)); yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell).FailOnDestroyedOrNull(TargetIndex.B)); Toil findPlaceTarget2 = Toils_JobTransforms.SetTargetToIngredientPlaceCell(TargetIndex.A, TargetIndex.B, TargetIndex.C); yield return(findPlaceTarget2); yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.C, findPlaceTarget2, storageMode: false)); yield return(Toils_Jump.JumpIfHaveTargetInQueue(TargetIndex.B, extract)); yield return(gotoBillGiver); yield return(Toils_Recipe.MakeUnfinishedThingIfNeeded()); yield return(Toils_Recipe.DoRecipeWork().FailOnDespawnedNullOrForbiddenPlacedThings().FailOnCannotTouch(TargetIndex.A, PathEndMode.InteractionCell)); yield return(Toils_Recipe.FinishRecipeAndStartStoringProduct()); if (job.RecipeDef.products.NullOrEmpty() && job.RecipeDef.specialProducts.NullOrEmpty()) { yield break; } yield return(Toils_Reserve.Reserve(TargetIndex.B)); findPlaceTarget2 = Toils_Haul.CarryHauledThingToCell(TargetIndex.B); yield return(findPlaceTarget2); yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.B, findPlaceTarget2, storageMode: true, tryStoreInSameStorageIfSpotCantHoldWholeStack: true)); Toil recount = new Toil(); recount.initAction = delegate { Bill_Production bill_Production = recount.actor.jobs.curJob.bill as Bill_Production; if (bill_Production != null && bill_Production.repeatMode == BillRepeatModeDefOf.TargetCount) { base.Map.resourceCounter.UpdateResourceCounts(); } }; yield return(recount); }
protected override IEnumerable <Toil> MakeNewToils() { //Bill giver destroyed (only in bill using phase! Not in carry phase) this.AddEndCondition(() => { var targ = this.GetActor().jobs.curJob.GetTarget(BuildingInd).Thing; if (targ == null || (targ is Building && !targ.Spawned)) { return(JobCondition.Incompletable); } return(JobCondition.Ongoing); }); this.FailOnBurningImmobile(BuildingInd); //Bill giver, or product burning in carry phase //Reserve the workbench and the ingredients yield return(Toils_Reserve.Reserve(BuildingInd)); //yield return Toils_Logging("Reserving done.", false); //-- DEBUG -- //This toil is yielded later Toil gotoBillGiver = Toils_Goto.GotoThing(IngredientInd, PathEndMode.InteractionCell); //Jump over ingredient gathering if there are no ingredients needed yield return(Toils_Jump.JumpIf(gotoBillGiver, () => job.GetTargetQueue(IngredientInd).NullOrEmpty())); //Gather ingredients { //Extract an ingredient into IngredientInd target Toil extract = Toils_JobTransforms.ExtractNextTargetFromQueue(IngredientInd); yield return(extract); //Reserve the the ingredient yield return(Toils_Reserve.Reserve(IngredientInd) .FailOnDespawnedNullOrForbidden(IngredientInd)); //Get to ingredient and pick it up //Note that these fail cases must be on these toils, otherwise the recipe work fails if you stacked // your targetB into another object on the bill giver square. var getToHaulTarget = Toils_Goto.GotoThing(IngredientInd, PathEndMode.Touch) .FailOnDespawnedNullOrForbidden(IngredientInd) .FailOnSomeonePhysicallyInteracting(IngredientInd); yield return(getToHaulTarget); yield return(Toils_Haul.StartCarryThing(IngredientInd)); //Jump to pick up more in this run if we're collecting from multiple stacks at once yield return(JumpToCollectNextIntoHands(getToHaulTarget, BuildingInd)); //Carry ingredient to the bill giver yield return(Toils_Goto.GotoThing(BuildingInd, PathEndMode.InteractionCell) .FailOnDestroyedOrNull(BuildingInd)); //Place ingredient on the appropriate cell Toil findPlaceTarget = Toils_JobTransforms.SetTargetToIngredientPlaceCell(BuildingInd, IngredientInd, IngredientPlaceCellInd); yield return(findPlaceTarget); yield return(Toils_FillThingIntoConstructor(this.pawn)); //yield return Toils_Haul.PlaceHauledThingInCell(IngredientPlaceCellInd, // nextToilOnPlaceFailOrIncomplete: findPlaceTarget, // storageMode: false); //Jump back if another ingredient is queued, or you didn't finish carrying your current ingredient target yield return(Toils_Jump.JumpIfHaveTargetInQueue(IngredientInd, extract)); } yield return(gotoBillGiver); }
private IEnumerable <Toil> Clipboard() { yield return(Toils_JobTransforms.MoveCurrentTargetIntoQueue(TargetIndex.A)); yield return(Toils_Reserve.ReserveQueue(TargetIndex.A)); Toil initExtractTargetFromQueue = Toils_JobTransforms.ClearDespawnedNullOrForbiddenQueuedTargets(TargetIndex.A); yield return(initExtractTargetFromQueue); yield return(Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.A)); Toil checkNextQueuedTarget = Toils_JobTransforms.ClearDespawnedNullOrForbiddenQueuedTargets(TargetIndex.A); yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch).JumpIfDespawnedOrNullOrForbidden(TargetIndex.A, checkNextQueuedTarget)); Toil cut = new Toil() { tickAction = delegate { Pawn actor = GetActor(); if (actor.skills != null) { actor.skills.Learn(SkillDefOf.Growing, 0.11f); } float statValue = actor.GetStatValue(StatDefOf.PlantWorkSpeed, true); float num = statValue; workDone += num; if (workDone >= Duration) { if (Plant.def.plant.harvestedThingDef != null) { if (actor.RaceProps.Humanlike && Plant.def.plant.harvestFailable && Rand.Value > actor.GetStatValue(StatDefOf.PlantHarvestYield, true)) { Vector3 loc = (pawn.DrawPos + Plant.DrawPos) / 2f; MoteMaker.ThrowText(loc, Map, "TextMote_HarvestFailed".Translate(), 3.65f); } else { Thing thing = Plant.CollectSecondaryThing(); if (actor.Faction != Faction.OfPlayer) { thing.SetForbidden(true, true); } GenPlace.TryPlaceThing(thing, actor.Position, Map, ThingPlaceMode.Near); actor.records.Increment(RecordDefOf.PlantsHarvested); // If there is a SeedsPlease seed, try to drop it if (Plant.seedDef != null) { int stack = Rand.RangeInclusive(-1, 1); if (pawn.skills != null) { stack += GenMath.RoundRandom(pawn.skills.GetSkill(SkillDefOf.Growing).Level / 8f); } if (stack > 0) { Thing seed = ThingMaker.MakeThing(Plant.seedDef); seed.stackCount = stack; GenPlace.TryPlaceThing(seed, pawn.Position, pawn.Map, ThingPlaceMode.Near); } } } } Plant.def.plant.soundHarvestFinish.PlayOneShot(actor); workDone = 0f; ReadyForNextToil(); return; } } }; cut.FailOn(() => !Plant.Sec_HarvestableNow); cut.FailOnDespawnedNullOrForbidden(TargetIndex.A); cut.FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch); cut.defaultCompleteMode = ToilCompleteMode.Never; cut.WithEffect(EffecterDefOf.Harvest, TargetIndex.A); cut.WithProgressBar(TargetIndex.A, () => workDone / Duration, true, -0.5f); cut.PlaySustainerOrSound(() => Plant.def.plant.soundHarvesting); yield return(cut); yield return(checkNextQueuedTarget); yield return(Toils_Jump.JumpIfHaveTargetInQueue(TargetIndex.A, initExtractTargetFromQueue)); }
protected override IEnumerable <Toil> MakeNewToils() { Apparel_Backpack backpack = this.CurJob.GetTarget(BackpackInd).Thing as Apparel_Backpack; /// // Set fail conditions /// // no free slots this.FailOn(() => backpack.SlotsComp.slots.Count >= backpack.MaxItem); //// hauling stuff not allowed // foreach (ThingCategoryDef category in CurJob.targetA.Thing.def.thingCategories) // { // this.FailOn(() => !backpack.slotsComp.Properties.allowedThingCategoryDefs.Contains(category)); // this.FailOn(() => backpack.slotsComp.Properties.forbiddenSubThingCategoryDefs.Contains(category)); // } /// // Define Toil /// Toil endOfJob = new Toil { initAction = () => { this.EndJobWith(JobCondition.Succeeded); } }; Toil checkStoreCellEmpty = Toils_Jump.JumpIf(endOfJob, () => this.CurJob.GetTargetQueue(StoreCellInd).NullOrEmpty()); Toil checkHaulableEmpty = Toils_Jump.JumpIf(checkStoreCellEmpty, () => this.CurJob.GetTargetQueue(HaulableInd).NullOrEmpty()); Toil checkBackpackEmpty = Toils_Jump.JumpIf(endOfJob, () => backpack.SlotsComp.slots.Count <= 0); /// // Toils Start /// // Reserve thing to be stored and storage cell yield return(Toils_Reserve.ReserveQueue(HaulableInd)); yield return(Toils_Reserve.ReserveQueue(StoreCellInd)); // JumpIf checkStoreCellEmpty yield return(checkHaulableEmpty); { // Collect TargetQueue Toil extractA = Toils_Collect.Extract(HaulableInd); yield return(extractA); Toil gotoThing = Toils_Goto.GotoThing(HaulableInd, PathEndMode.ClosestTouch) .FailOnDestroyedOrNull(HaulableInd); yield return(gotoThing); // yield return Toils_Collect.CollectInBackpack(HaulableInd, backpack); Toil pickUpThingIntoSlot = new Toil { initAction = () => { if (!backpack.SlotsComp.slots.TryAdd(this.CurJob.targetA.Thing)) { this.EndJobWith(JobCondition.Incompletable); } } }; yield return(pickUpThingIntoSlot); yield return(Toils_Collect.CheckDuplicates(gotoThing, BackpackInd, HaulableInd)); yield return(Toils_Jump.JumpIfHaveTargetInQueue(HaulableInd, extractA)); } // JumpIf toilEnd yield return(checkStoreCellEmpty); { // Drop TargetQueue yield return(checkBackpackEmpty); Toil extractB = Toils_Collect.Extract(StoreCellInd); yield return(extractB); Toil gotoCell = Toils_Goto.GotoCell(StoreCellInd, PathEndMode.ClosestTouch); yield return(gotoCell); yield return(Toils_Collect.DropTheCarriedFromBackpackInCell(StoreCellInd, ThingPlaceMode.Direct, backpack)); yield return(Toils_Jump.JumpIfHaveTargetInQueue(StoreCellInd, checkBackpackEmpty)); yield return(Toils_Collect.CheckNeedStorageCell(gotoCell, BackpackInd, StoreCellInd)); } yield return(endOfJob); }
protected 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.Warning("[HumanResources] " + pawn + " 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_Reserve.Reserve(TargetIndex.A); 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(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(pawn + " tried to place a book in " + shelf + ", but won't accept it."); return; } pawn.jobs.EndCurrentJob(JobCondition.Succeeded, true, true); } }); } yield break; }
protected override IEnumerable <Toil> MakeNewToils() { Apparel_Backpack backpack = CurJob.GetTarget(BackpackInd).Thing as Apparel_Backpack; /// //Set fail conditions /// //Backpack is full. this.FailOn(() => { return((pawn.inventory.container.Count < backpack.MaxItem) ? false : true); }); /// //Define Toil /// Toil extractB = new Toil(); extractB.initAction = () => { if (!CurJob.targetQueueB.NullOrEmpty()) { CurJob.targetB = CurJob.targetQueueB.First(); CurJob.targetQueueB.RemoveAt(0); this.FailOnDestroyedOrNull(HaulableInd); } else { this.EndJobWith(JobCondition.Succeeded); } }; Toil toilGoToThing = Toils_Goto.GotoThing(HaulableInd, PathEndMode.ClosestTouch) .FailOnDestroyedOrNull(HaulableInd); /// //Toils Start /// //Reserve thing to be stored and storage cell yield return(Toils_Reserve.Reserve(BackpackInd)); yield return(Toils_Reserve.Reserve(HaulableInd)); yield return(Toils_Reserve.ReserveQueue(HaulableInd)); yield return(Toils_Jump.JumpIf(toilGoToThing, () => { return (CurJob.targetB.HasThing) ? true : false; })); //Collect TargetQueue { //Extract an haulable into TargetA yield return(extractB); yield return(toilGoToThing); //CollectIntoCarrier Toil toilPutInInventory = new Toil(); toilPutInInventory.initAction = () => { if (pawn.inventory.container.Count < backpack.MaxItem && backpack.wearer.inventory.container.TotalStackCount < backpack.MaxStack) { if (CurJob.targetB.Thing.TryGetComp <CompForbiddable>() != null && CurJob.targetB.Thing.TryGetComp <CompForbiddable>().Forbidden == true) { CurJob.targetB.Thing.TryGetComp <CompForbiddable>().Forbidden = false; } if (pawn.inventory.container.TryAdd(CurJob.targetB.Thing, CurJob.maxNumToCarry)) { CurJob.targetB.Thing.holder = pawn.inventory.GetContainer(); CurJob.targetB.Thing.holder.owner = pawn.inventory; backpack.numOfSavedItems++; } } else { this.EndJobWith(JobCondition.Incompletable); } }; yield return(toilPutInInventory); yield return(Toils_Jump.JumpIfHaveTargetInQueue(HaulableInd, extractB)); } }
protected override IEnumerable <Toil> MakeNewToils() { //This toil is yielded later var gotoBillGiver = Toils_Goto.GotoThing(TI_REPBENCH, PathEndMode.InteractionCell); this.FailOnDestroyedNullOrForbidden(TI_REPBENCH); this.FailOnBurningImmobile(TI_REPBENCH); //Reserve the bill giver and all the ingredients yield return(Toils_Reserve.Reserve(TI_REPBENCH)); yield return(Toils_Reserve.ReserveQueue(TI_ITEM)); //these are initially set up by workgiver var itemTargetQueue = job.GetTargetQueue(TI_ITEM); if (itemTargetQueue.NullOrEmpty()) { Log.Warning("RepBench: JobDriver - itemTargetQueue was null."); yield return(Toils_Reserve.Release(TI_REPBENCH)); yield return(Toils_Reserve.Release(TI_ITEM)); yield break; } var firstTargetInfo = itemTargetQueue.First(); var item = firstTargetInfo.Thing; var table = job.GetTarget(TI_REPBENCH).Thing as Building_WorkTable; if (table == null) { Log.Warning("RepBench: JobDriver - RepairTable was null."); yield return(Toils_Reserve.Release(TI_REPBENCH)); yield return(Toils_Reserve.Release(TI_ITEM)); yield break; } //Gather ingredients { //Extract an ingredient into TargetB var extract = Toils_JobTransforms.ExtractNextTargetFromQueue(TI_ITEM); yield return(extract); //Get to ingredient and pick it up //Note that these fail cases must be on these toils, otherwise the recipe work fails if you stacked // your targetB into another object on the bill giver square. var getToHaulTarget = Toils_Goto.GotoThing(TI_ITEM, PathEndMode.ClosestTouch) .FailOnDespawnedNullOrForbidden(TI_ITEM); yield return(getToHaulTarget); yield return(Toils_Haul.StartCarryThing(TI_ITEM)); //Jump to pick up more in this run if we're collecting from multiple stacks at once yield return(JumpToCollectNextIntoHandsForBill(getToHaulTarget, TargetIndex.B)); //Carry ingredient to the bill giver and put it on the square yield return(Toils_Goto.GotoThing(TI_REPBENCH, PathEndMode.InteractionCell) .FailOnDestroyedOrNull(TI_ITEM)); var findPlaceTarget = Toils_JobTransforms.SetTargetToIngredientPlaceCell(TI_REPBENCH, TI_ITEM, TI_CELL); yield return(findPlaceTarget); yield return(Toils_Haul.PlaceHauledThingInCell(TI_CELL, findPlaceTarget, false)); //Jump back if there is another ingredient needed //Can happen if you can't carry all the ingredients in one run yield return(Toils_Jump.JumpIfHaveTargetInQueue(TI_ITEM, extract)); } //For it no ingredients needed, just go to the bill giver //This will do nothing if we took ingredients and are thus already at the bill giver yield return(gotoBillGiver); var controller = new ItemRepairProgress(pawn, table.IngredientStackCells, WorkGiver_Repair.CalculateTotalIngredients(item), item.MaxHitPoints - item.HitPoints); float ticksToNextRepair = Settings.RepairRate; var repairedAmount = 0; var repairToil = new Toil { initAction = () => { Debug.PrintLine("repairToil.PreInit"); job.bill.Notify_DoBillStarted(pawn); Debug.PrintLine("repairToil.PostInit"); }, tickAction = () => { // Debug.PrintLine("repairToil.tick.Check"); // pawn.jobs.CheckForJobOverride(); job.bill.Notify_PawnDidWork(pawn); job.SetTarget(TargetIndex.B, item); pawn.skills.Learn(SkillDefOf.Crafting, Settings.SkillGain); pawn.GainComfortFromCellIfPossible(); ticksToNextRepair -= pawn.GetStatValue(StatDefOf.WorkSpeedGlobal) * table.GetStatValue(StatDefOf.WorkTableWorkSpeedFactor); if (ticksToNextRepair > 0.0) { return; } ticksToNextRepair = Settings.RepairRate; item.HitPoints += Settings.HP_GAIN; repairedAmount += Settings.HP_GAIN; if (!controller.AddRepairedAmount(Settings.HP_GAIN)) { //Technically we did not Succeed, but the job itself did not fail, we just ran out of kits. EndJobWith(JobCondition.Succeeded); return; } if (item.HitPoints < item.MaxHitPoints) { return; } // break ReadyForNextToil(); }, defaultCompleteMode = ToilCompleteMode.Never }; repairToil.WithEffect(item.def.repairEffect, TI_ITEM); yield return(repairToil); var itemRepairedToil = new Toil { initAction = () => { var list = new List <Thing> { item }; job.bill.Notify_IterationCompleted(pawn, list); RecordsUtility.Notify_BillDone(pawn, list); } }; yield return(itemRepairedToil); yield return(Toils_Haul.StartCarryThing(TI_ITEM)); if (job.bill.GetStoreMode() == BillStoreModeDefOf.BestStockpile) { yield return(new Toil { initAction = () => { if (!StoreUtility.TryFindBestBetterStoreCellFor(item, pawn, pawn.Map, StoragePriority.Unstored, pawn.Faction, out var foundCell)) { return; } pawn.Reserve(foundCell, job); job.SetTarget(TI_CELL, foundCell); } });