protected override IEnumerable <Toil> MakeNewToils() { this.FailOnDespawnedOrNull(TargetIndex.A); //Define Toil Toil toilWait = new Toil(); toilWait.initAction = () => { toilWait.actor.pather.StopDead(); }; Toil toilNothing = new Toil(); //toilNothing.initAction = () => {}; toilNothing.defaultCompleteMode = ToilCompleteMode.Delay; toilNothing.defaultDuration = getUpCheckInterval; // Start Toil yield return(toilWait); yield return(toilNothing); yield return(Toils_Jump.JumpIf(toilNothing, () => { CompSuppressable comp = pawn.TryGetComp <CompSuppressable>(); if (comp == null) { return false; } float distToSuppressor = (pawn.Position - comp.suppressorLoc).LengthHorizontal; if (distToSuppressor < CompSuppressable.minSuppressionDist) { return false; } return comp.isHunkering; })); }
protected override IEnumerable <Toil> MakeNewToils() { this.FailOnDespawnedOrNull(TargetIndex.A); //Define Toil Toil toilWait = new Toil(); toilWait.initAction = () => { toilWait.actor.pather.StopDead(); }; Toil toilNothing = new Toil(); //toilNothing.initAction = () => {}; toilNothing.defaultCompleteMode = ToilCompleteMode.Delay; toilNothing.defaultDuration = GetUpCheckInterval; // Start Toil yield return(toilWait); yield return(toilNothing); yield return(Toils_Jump.JumpIf(toilNothing, () => { CompSuppressable comp = pawn.TryGetComp <CompSuppressable>(); if (comp == null) { return false; } if (!comp.CanReactToSuppression) { return false; } return comp.IsHunkering; })); }
protected override IEnumerable <Toil> MakeNewToils() { var wait = Toils_General.Wait(50, TargetIndex.A).FailOnNotDiningQueued(TargetIndex.A); //this.FailOnNotDining(TargetIndex.A); this.FailOnDestroyedOrNull(TargetIndex.B); this.FailOnForbidden(TargetIndex.B); yield return(Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch)); yield return(Toils_Haul.StartCarryThing(TargetIndex.B)); yield return(Toils_Waiting.UpdateOrderConsumableTo(TargetIndex.A, TargetIndex.B)); yield return(Toils_Waiting.FindRandomAdjacentCell(TargetIndex.A, TargetIndex.C)); // A is the patron, C is the spot yield return(Toils_Haul.CarryHauledThingToCell(TargetIndex.C)); yield return(wait); yield return(Toils_Jump.JumpIf(wait, () => pawn.jobs.curJob?.GetTarget(TargetIndex.A).Pawn?.GetDriver <JobDriver_Dine>() == null)); // Driver not available yield return(Toils_Waiting.GetDiningSpot(TargetIndex.A, TargetIndex.C)); yield return(Toils_Haul.CarryHauledThingToCell(TargetIndex.C)); yield return(Toils_Jump.JumpIf(wait, () => pawn.jobs.curJob?.GetTarget(TargetIndex.A).Pawn?.GetDriver <JobDriver_Dine>() == null)); // Driver not available yield return(Toils_Waiting.AnnounceServing(TargetIndex.A, TargetIndex.B)); yield return(Toils_Waiting.ClearOrder(TargetIndex.A, TargetIndex.B, TargetIndex.B, TargetIndex.C)); // Got no silver or register? Job successful yield return(Toils_Misc.TakeItemFromInventoryToCarrier(pawn, TargetIndex.B)); yield return(Toils_Goto.GotoThing(TargetIndex.C, PathEndMode.Touch)); yield return(Toils_Haul.DepositHauledThingInContainer(TargetIndex.C, TargetIndex.None)); }
protected override IEnumerable <Toil> MakeNewToils() { this.FailOnDespawnedNullOrForbidden(TargetIndex.A); AddEndCondition(() => (!RefuelableComp.IsFull) ? JobCondition.Ongoing : JobCondition.Succeeded); AddFailCondition(() => (!job.playerForced && !RefuelableComp.ShouldAutoRefuelNowIgnoringFuelPct) || !RefuelableComp.allowAutoRefuel); AddFailCondition(() => !RefuelableComp.allowAutoRefuel && !job.playerForced); yield return(Toils_General.DoAtomic(delegate { job.count = RefuelableComp.GetFuelCountToFullyRefuel(); })); Toil getNextIngredient = Toils_General.Label(); yield return(getNextIngredient); yield return(Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.B)); yield return(Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.B).FailOnSomeonePhysicallyInteracting(TargetIndex.B)); yield return(Toils_Haul.StartCarryThing(TargetIndex.B, putRemainderInQueue: false, subtractNumTakenFromJobCount: true).FailOnDestroyedNullOrForbidden(TargetIndex.B)); yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch)); Toil findPlaceTarget = Toils_JobTransforms.SetTargetToIngredientPlaceCell(TargetIndex.A, TargetIndex.B, TargetIndex.C); yield return(findPlaceTarget); yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.C, findPlaceTarget, storageMode: false)); yield return(Toils_Jump.JumpIf(getNextIngredient, () => !job.GetTargetQueue(TargetIndex.B).NullOrEmpty())); yield return(Toils_General.Wait(240).FailOnDestroyedNullOrForbidden(TargetIndex.A).FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch) .WithProgressBarToilDelay(TargetIndex.A)); yield return(FinalizeRefueling(TargetIndex.A, TargetIndex.None, RefuelableComp)); }
protected override IEnumerable <Toil> MakeNewToils() { this.FailOnDespawnedNullOrForbidden(TargetIndex.A); base.AddEndCondition(() => (!this.RefuelableComp.IsFull) ? JobCondition.Ongoing : JobCondition.Succeeded); base.AddFailCondition(() => !this.job.playerForced && !this.RefuelableComp.ShouldAutoRefuelNowIgnoringFuelPct); yield return(Toils_General.DoAtomic(delegate { this.job.count = this.RefuelableComp.GetFuelCountToFullyRefuel(); })); Toil getNextIngredient = Toils_General.Label(); yield return(getNextIngredient); yield return(Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.B, true)); yield return(Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.B).FailOnSomeonePhysicallyInteracting(TargetIndex.B)); yield return(Toils_Haul.StartCarryThing(TargetIndex.B, false, true, false).FailOnDestroyedNullOrForbidden(TargetIndex.B)); yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch)); 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.JumpIf(getNextIngredient, () => !this.job.GetTargetQueue(TargetIndex.B).NullOrEmpty <LocalTargetInfo>())); yield return(Toils_General.Wait(240, TargetIndex.None).FailOnDestroyedNullOrForbidden(TargetIndex.A).FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch).WithProgressBarToilDelay(TargetIndex.A, false, -0.5f)); yield return(Toils_Refuel.FinalizeRefueling(TargetIndex.A, TargetIndex.None)); yield break; }
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() { 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() { /// //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); } ThingWithComps cart = TargetThingA as ThingWithComps; if (ToolsForHaulUtility.FindStorageCell(pawn, cart) == IntVec3.Invalid) { JobFailReason.Is(ToolsForHaulUtility.NoEmptyPlaceForCart); } if (cart.TryGetComp <CompMountable>().Driver != null) { this.FailOnSomeonePhysicallyInteracting(CartInd); } /// //Define Toil /// Toil toilGoToCell = Toils_Goto.GotoCell(StoreCellInd, PathEndMode.ClosestTouch); /// //Toils Start /// //Reserve thing to be stored and storage cell yield return(Toils_Reserve.Reserve(CartInd)); yield return(Toils_Reserve.Reserve(StoreCellInd)); //JumpIf already mounted yield return(Toils_Jump.JumpIf(toilGoToCell, () => { return cart.TryGetComp <CompMountable>().Driver == pawn ? true : false; })); //Mount on Target yield return(Toils_Goto.GotoThing(CartInd, PathEndMode.ClosestTouch) .FailOnDestroyedOrNull(CartInd)); yield return(Toils_Cart.MountOn(CartInd)); //Dismount yield return(toilGoToCell); yield return(Toils_Cart.DismountAt(CartInd, StoreCellInd)); }
public bool MoveNext() { uint num = (uint)this.$PC; this.$PC = -1; switch (num) { case 0u: this.FailOnDespawnedNullOrForbidden(TargetIndex.A); base.AddEndCondition(() => (!base.RefuelableComp.IsFull) ? JobCondition.Ongoing : JobCondition.Succeeded); base.AddFailCondition(() => !this.job.playerForced && !base.RefuelableComp.ShouldAutoRefuelNowIgnoringFuelPct); this.$current = Toils_General.DoAtomic(delegate { this.job.count = base.RefuelableComp.GetFuelCountToFullyRefuel(); }); if (!this.$disposing) { this.$PC = 1; } return(true); case 1u: getNextIngredient = Toils_General.Label(); this.$current = getNextIngredient; if (!this.$disposing) { this.$PC = 2; } return(true); case 2u: this.$current = Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.B, true); if (!this.$disposing) { this.$PC = 3; } return(true); case 3u: this.$current = Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.B).FailOnSomeonePhysicallyInteracting(TargetIndex.B); if (!this.$disposing) { this.$PC = 4; } return(true); case 4u: this.$current = Toils_Haul.StartCarryThing(TargetIndex.B, false, true, false).FailOnDestroyedNullOrForbidden(TargetIndex.B); if (!this.$disposing) { this.$PC = 5; } return(true); case 5u: this.$current = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch); if (!this.$disposing) { this.$PC = 6; } return(true); case 6u: findPlaceTarget = Toils_JobTransforms.SetTargetToIngredientPlaceCell(TargetIndex.A, TargetIndex.B, TargetIndex.C); this.$current = findPlaceTarget; if (!this.$disposing) { this.$PC = 7; } return(true); case 7u: this.$current = Toils_Haul.PlaceHauledThingInCell(TargetIndex.C, findPlaceTarget, false); if (!this.$disposing) { this.$PC = 8; } return(true); case 8u: this.$current = Toils_Jump.JumpIf(getNextIngredient, () => !this.job.GetTargetQueue(TargetIndex.B).NullOrEmpty <LocalTargetInfo>()); if (!this.$disposing) { this.$PC = 9; } return(true); case 9u: this.$current = Toils_General.Wait(240, TargetIndex.None).FailOnDestroyedNullOrForbidden(TargetIndex.A).FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch).WithProgressBarToilDelay(TargetIndex.A, false, -0.5f); if (!this.$disposing) { this.$PC = 10; } return(true); case 10u: this.$current = Toils_Refuel.FinalizeRefueling(TargetIndex.A, TargetIndex.None); if (!this.$disposing) { this.$PC = 11; } return(true); case 11u: this.$PC = -1; break; } return(false); }
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() { Building_ShellfishTrap crabPot = this.job.GetTarget(CrabPotIndex).Thing as Building_ShellfishTrap; Pawn actor = this.pawn; Toil unloadProcess = new Toil() { initAction = () => { storemode = crabPot.StoreMode; }, defaultDuration = BaseUnloadDuration, defaultCompleteMode = ToilCompleteMode.Delay, activeSkill = (() => SkillDefOf.Animals) } .FailOnDespawnedNullOrForbidden(CrabPotIndex) .FailOnBurningImmobile(CrabPotIndex) .FailOnThingHavingDesignation(CrabPotIndex, DesignationDefOf.Uninstall) .FailOnCannotTouch(CrabPotIndex, PathEndMode.Touch) .WithProgressBarToilDelay(CrabPotIndex); Toil unloadPot = new Toil() { initAction = () => { //Log.Message("unloadPot"); AddFinishAction(DropStuff); crabPot.LastOpenTick = Find.TickManager.TicksGame; var items = crabPot.GetDirectlyHeldThings(); //Log.Message("items"); //foreach(var item in items) //{ // Log.Message(item.def.defName + " " + item.stackCount); //} //Log.Message("unloading"); while (!MassUtility.IsOverEncumbered(pawn) && items.Count > 0) { int count = Math.Min(MassUtility.CountToPickUpUntilOverEncumbered(actor, items[0]), items[0].stackCount); //Log.Message(count + " " + items[0].stackCount + MassUtility.CountToPickUpUntilOverEncumbered(actor, items[0])); if (items.TryTransferToContainer(items[0], pawn.inventory.innerContainer, count, out Thing resultingItem, false) > 0) { if (!resultingItem.Destroyed && resultingItem.stackCount > 0) { LoadedFish.Add(resultingItem); } } } items.TryDropAll(pawn.Position, pawn.Map, ThingPlaceMode.Near); //actor.jobs.EndCurrentJob(JobCondition.Succeeded); }, defaultCompleteMode = ToilCompleteMode.Instant }; this.FailOnDespawnedNullOrForbidden(CrabPotIndex); this.FailOnBurningImmobile(CrabPotIndex); this.FailOnThingHavingDesignation(CrabPotIndex, DesignationDefOf.Uninstall); yield return(Toils_Goto.GotoThing(CrabPotIndex, PathEndMode.Touch) .FailOnDespawnedNullOrForbidden(CrabPotIndex) .FailOnBurningImmobile(CrabPotIndex) .FailOnThingHavingDesignation(CrabPotIndex, DesignationDefOf.Uninstall)); yield return(unloadProcess); yield return(unloadPot); //todo: repeatetive haul Toil finishAndStartHaul = FinishAndStartHaul(); yield return(finishAndStartHaul); yield return(Toils_Misc.TakeItemFromInventoryToCarrier(pawn, HaulableInd)); yield return(Toils_Reserve.Reserve(StoreCellInd)); Toil carryToCell = Toils_Haul.CarryHauledThingToCell(StoreCellInd); yield return(carryToCell); yield return(Toils_Haul.PlaceHauledThingInCell(StoreCellInd, carryToCell, storageMode: true, tryStoreInSameStorageIfSpotCantHoldWholeStack: true)); yield return(Toils_Jump.JumpIf(finishAndStartHaul, () => LoadedFish.Count > 0)); }
public bool MoveNext() { uint num = (uint)this.$PC; this.$PC = -1; switch (num) { case 0u: { this.FailOn(delegate() { if (!this.job.ignoreDesignations) { Pawn victim = base.Victim; if (victim != null && !victim.Dead && base.Map.designationManager.DesignationOn(victim, DesignationDefOf.Hunt) == null) { return(true); } } return(false); }); Toil init = new Toil(); init.initAction = delegate() { this.jobStartTick = Find.TickManager.TicksGame; }; this.$current = init; if (!this.$disposing) { this.$PC = 1; } return(true); } case 1u: this.$current = Toils_Combat.TrySetJobToUseAttackVerb(TargetIndex.A); if (!this.$disposing) { this.$PC = 2; } return(true); case 2u: startCollectCorpseLabel = Toils_General.Label(); slaughterLabel = Toils_General.Label(); gotoCastPos = Toils_Combat.GotoCastPosition(TargetIndex.A, true, 0.95f).JumpIfDespawnedOrNull(TargetIndex.A, startCollectCorpseLabel).FailOn(() => Find.TickManager.TicksGame > this.jobStartTick + 5000); this.$current = gotoCastPos; if (!this.$disposing) { this.$PC = 3; } return(true); case 3u: slaughterIfPossible = Toils_Jump.JumpIf(slaughterLabel, delegate { Pawn victim = base.Victim; return((victim.RaceProps.DeathActionWorker == null || !victim.RaceProps.DeathActionWorker.DangerousInMelee) && victim.Downed); }); this.$current = slaughterIfPossible; if (!this.$disposing) { this.$PC = 4; } return(true); case 4u: this.$current = Toils_Jump.JumpIfTargetNotHittable(TargetIndex.A, gotoCastPos); if (!this.$disposing) { this.$PC = 5; } return(true); case 5u: this.$current = Toils_Combat.CastVerb(TargetIndex.A, false).JumpIfDespawnedOrNull(TargetIndex.A, startCollectCorpseLabel).FailOn(() => Find.TickManager.TicksGame > this.jobStartTick + 5000); if (!this.$disposing) { this.$PC = 6; } return(true); case 6u: this.$current = Toils_Jump.JumpIfTargetDespawnedOrNull(TargetIndex.A, startCollectCorpseLabel); if (!this.$disposing) { this.$PC = 7; } return(true); case 7u: this.$current = Toils_Jump.Jump(slaughterIfPossible); if (!this.$disposing) { this.$PC = 8; } return(true); case 8u: this.$current = slaughterLabel; if (!this.$disposing) { this.$PC = 9; } return(true); case 9u: this.$current = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch).FailOnMobile(TargetIndex.A); if (!this.$disposing) { this.$PC = 10; } return(true); case 10u: this.$current = Toils_General.WaitWith(TargetIndex.A, 180, true, false).FailOnMobile(TargetIndex.A); if (!this.$disposing) { this.$PC = 11; } return(true); case 11u: this.$current = Toils_General.Do(delegate { if (base.Victim.Dead) { return; } ExecutionUtility.DoExecutionByCut(this.pawn, base.Victim); this.pawn.records.Increment(RecordDefOf.AnimalsSlaughtered); if (this.pawn.InMentalState) { this.pawn.MentalState.Notify_SlaughteredAnimal(); } }); if (!this.$disposing) { this.$PC = 12; } return(true); case 12u: this.$current = Toils_Jump.Jump(startCollectCorpseLabel); if (!this.$disposing) { this.$PC = 13; } return(true); case 13u: this.$current = startCollectCorpseLabel; if (!this.$disposing) { this.$PC = 14; } return(true); case 14u: this.$current = base.StartCollectCorpseToil(); if (!this.$disposing) { this.$PC = 15; } return(true); case 15u: this.$current = Toils_Goto.GotoCell(TargetIndex.A, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.A).FailOnSomeonePhysicallyInteracting(TargetIndex.A); if (!this.$disposing) { this.$PC = 16; } return(true); case 16u: this.$current = Toils_Haul.StartCarryThing(TargetIndex.A, false, false, false); if (!this.$disposing) { this.$PC = 17; } return(true); case 17u: carryToCell = Toils_Haul.CarryHauledThingToCell(TargetIndex.B); this.$current = carryToCell; if (!this.$disposing) { this.$PC = 18; } return(true); case 18u: this.$current = Toils_Haul.PlaceHauledThingInCell(TargetIndex.B, carryToCell, true); if (!this.$disposing) { this.$PC = 19; } return(true); case 19u: this.$PC = -1; break; } return(false); }
protected override IEnumerable <Toil> MakeNewToils() { AddFailCondition(() => pawn.WorkTagIsDisabled(WorkTags.Violent)); this.FailOnSomeonePhysicallyInteracting(TargetIndex.A); this.FailOnDespawnedNullOrForbidden(TargetIndex.A); jobStartTick = Find.TickManager.TicksGame; startingEquippedWeapon = pawn.equipment.Primary; trainingWeapon = null; if (startingEquippedWeapon == null || !startingEquippedWeapon.def.IsWithinCategory(CombatTrainingDefOf.TrainingWeapons)) { trainingWeapon = GetNearestTrainingWeapon(startingEquippedWeapon); if (trainingWeapon != null && !trainingWeapon.IsForbidden(pawn)) { if (Map.reservationManager.CanReserve(pawn, trainingWeapon)) { pawn.Reserve(trainingWeapon, job); job.SetTarget(TargetIndex.B, trainingWeapon); yield return(Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.B)); yield return(CreateEquipToil(TargetIndex.B)); } if (Map.reservationManager.CanReserve(pawn, startingEquippedWeapon)) { pawn.Reserve(startingEquippedWeapon, job); job.SetTarget(TargetIndex.C, startingEquippedWeapon); } } } Toil endOfTraining = Toils_General.Label(); Toil gotoCastPos = Toils_Combat.GotoCastPosition(TargetIndex.A, closeIfDowned: true, 0.95f).EndOnDespawnedOrNull(TargetIndex.A); Toil ifTrainingDoneJumpToReequip = Toils_Jump.JumpIf(endOfTraining, HasTrainingEnded); Toil castVerb = Toils_Combat.CastVerb(TargetIndex.A, canHitNonTargetPawns: false); castVerb.AddFinishAction(delegate { LearnAttackSkill(); }); Toil trainingRoomImpressivenessMoodBoost = Toils_General.Do(delegate { TryGainCombatTrainingRoomThought(); }); Toil dropTrainingWeapon = Toils_General.Do(delegate { pawn.equipment.TryDropEquipment(pawn.equipment.Primary, out _, pawn.Position, forbid: false); }); Toil reequipSwappedStartingWeapon = Toils_General.Do(delegate { pawn.inventory.innerContainer.Remove(startingEquippedWeapon); pawn.equipment.AddEquipment(startingEquippedWeapon); }); Toil jobEndedLabel = Toils_General.Label(); yield return(Toils_Combat.TrySetJobToUseAttackVerb(TargetIndex.A)); yield return(gotoCastPos); yield return(Toils_Jump.JumpIfTargetNotHittable(TargetIndex.A, gotoCastPos)); yield return(trainingRoomImpressivenessMoodBoost); yield return(ifTrainingDoneJumpToReequip); yield return(castVerb); yield return(Toils_Jump.Jump(ifTrainingDoneJumpToReequip)); yield return(endOfTraining); if (trainingWeapon != null) { yield return(dropTrainingWeapon); } yield return(Toils_Jump.JumpIf(reequipSwappedStartingWeapon, () => pawn.inventory.Contains(startingEquippedWeapon))); yield return(Toils_Goto.GotoThing(TargetIndex.C, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.C)); yield return(CreateEquipToil(TargetIndex.C)); yield return(Toils_Jump.Jump(jobEndedLabel)); yield return(reequipSwappedStartingWeapon); yield return(jobEndedLabel); }
protected override IEnumerable <Toil> MakeNewToils() { this.FailOn(delegate { if (!job.ignoreDesignations) { Pawn victim = Victim; if (victim != null && !victim.Dead && Map.designationManager.DesignationOn(victim, DesignationDefOf.Hunt) == null) { return(true); } } return(false); }); yield return(Toils_Reserve.Reserve(VictimInd, 1)); var init = new Toil(); init.initAction = delegate { jobStartTick = Find.TickManager.TicksGame; }; yield return(init); yield return(Toils_Combat.TrySetJobToUseAttackVerb(TargetIndex.A)); var comp = (pawn.equipment != null && pawn.equipment.Primary != null) ? pawn.equipment.Primary.TryGetComp <CompAmmoUser>() : null; var startCollectCorpse = StartCollectCorpseToil(); var gotoCastPos = GotoCastPosition(VictimInd, true).JumpIfDespawnedOrNull(VictimInd, startCollectCorpse).FailOn(() => Find.TickManager.TicksGame > jobStartTick + MaxHuntTicks); yield return(gotoCastPos); //var moveIfCannotHit = Toils_Jump.JumpIfTargetNotHittable(VictimInd, gotoCastPos); var moveIfCannotHit = Toils_Jump.JumpIf(gotoCastPos, delegate { var verb = pawn.CurJob.verbToUse; var optimalRange = HuntRangePerBodysize(Victim.RaceProps.baseBodySize, Victim.RaceProps.executionRange, verb.verbProps.range); if (pawn.Position.DistanceTo(Victim.Position) > optimalRange) { return(true); } return(!verb.CanHitTarget(Victim)); }); yield return(moveIfCannotHit); yield return(Toils_Jump.JumpIfTargetDespawnedOrNull(VictimInd, startCollectCorpse)); var startExecuteDowned = Toils_Goto.GotoThing(VictimInd, PathEndMode.Touch).JumpIfDespawnedOrNull(VictimInd, startCollectCorpse); yield return(Toils_Jump.JumpIf(startExecuteDowned, () => Victim.Downed && Victim.RaceProps.executionRange <= 2)); yield return(Toils_Jump.JumpIfTargetDowned(VictimInd, gotoCastPos)); yield return(Toils_Combat.CastVerb(VictimInd, false).JumpIfDespawnedOrNull(VictimInd, startCollectCorpse) .FailOn(() => { if (Find.TickManager.TicksGame <= jobStartTick + MaxHuntTicks) { if (comp == null || comp.HasAndUsesAmmoOrMagazine) { return false; } } return true; })); yield return(Toils_Jump.Jump(moveIfCannotHit)); // Execute downed animal - adapted from JobDriver_Slaughter yield return(startExecuteDowned); yield return(Toils_General.WaitWith(VictimInd, 180, true).JumpIfDespawnedOrNull(VictimInd, startCollectCorpse)); yield return(new Toil { initAction = delegate { ExecutionUtility.DoExecutionByCut(pawn, Victim); }, defaultCompleteMode = ToilCompleteMode.Instant }); // Haul corpse to stockpile yield return(startCollectCorpse); yield return(Toils_Goto.GotoCell(VictimInd, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(VictimInd).FailOnSomeonePhysicallyInteracting(VictimInd)); yield return(Toils_Haul.StartCarryThing(VictimInd)); var carryToCell = Toils_Haul.CarryHauledThingToCell(StoreCellInd); yield return(carryToCell); yield return(Toils_Haul.PlaceHauledThingInCell(StoreCellInd, carryToCell, true)); }
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() { base.AddFinishAction(delegate { this.$this.Map.attackTargetsCache.UpdateTarget(this.$this.pawn); }); Toil prepareToEatCorpse = new Toil(); prepareToEatCorpse.initAction = delegate { Pawn actor = prepareToEatCorpse.actor; Corpse corpse = this.$this.Corpse; if (corpse == null) { Pawn prey = this.$this.Prey; if (prey == null) { actor.jobs.EndCurrentJob(JobCondition.Incompletable, true); return; } corpse = prey.Corpse; if (corpse == null || !corpse.Spawned) { actor.jobs.EndCurrentJob(JobCondition.Incompletable, true); return; } } if (actor.Faction == Faction.OfPlayer) { corpse.SetForbidden(false, false); } else { corpse.SetForbidden(true, false); } actor.CurJob.SetTarget(TargetIndex.A, corpse); }; yield return(Toils_General.DoAtomic(delegate { this.$this.Map.attackTargetsCache.UpdateTarget(this.$this.pawn); })); Action onHitAction = delegate { Pawn prey = this.$this.Prey; bool surpriseAttack = this.$this.firstHit && !prey.IsColonist; if (this.$this.pawn.meleeVerbs.TryMeleeAttack(prey, this.$this.job.verbToUse, surpriseAttack)) { if (!this.$this.notifiedPlayerAttacked && PawnUtility.ShouldSendNotificationAbout(prey)) { this.$this.notifiedPlayerAttacked = true; Messages.Message("MessageAttackedByPredator".Translate(prey.LabelShort, this.$this.pawn.LabelIndefinite(), prey.Named("PREY"), this.$this.pawn.Named("PREDATOR")).CapitalizeFirst(), prey, MessageTypeDefOf.ThreatSmall, true); } this.$this.Map.attackTargetsCache.UpdateTarget(this.$this.pawn); this.$this.firstHit = false; } }; Toil followAndAttack = Toils_Combat.FollowAndMeleeAttack(TargetIndex.A, onHitAction).JumpIfDespawnedOrNull(TargetIndex.A, prepareToEatCorpse).JumpIf(() => this.$this.Corpse != null, prepareToEatCorpse).FailOn(() => Find.TickManager.TicksGame > this.$this.startTick + 5000 && (float)(this.$this.job.GetTarget(TargetIndex.A).Cell - this.$this.pawn.Position).LengthHorizontalSquared > 4f); followAndAttack.AddPreTickAction(new Action(this.CheckWarnPlayer)); yield return(followAndAttack); yield return(prepareToEatCorpse); Toil gotoCorpse = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch); yield return(gotoCorpse); float durationMultiplier = 1f / this.pawn.GetStatValue(StatDefOf.EatingSpeed, true); yield return(Toils_Ingest.ChewIngestible(this.pawn, durationMultiplier, TargetIndex.A, TargetIndex.None).FailOnDespawnedOrNull(TargetIndex.A).FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch)); yield return(Toils_Ingest.FinalizeIngest(this.pawn, TargetIndex.A)); yield return(Toils_Jump.JumpIf(gotoCorpse, () => this.$this.pawn.needs.food.CurLevelPercentage < 0.9f)); }
public static IEnumerable <Toil> Heat(JobDriver jd, TargetIndex foodIndex = TargetIndex.A, TargetIndex finalLocation = TargetIndex.C, TargetIndex tableIndex = TargetIndex.None) { LocalTargetInfo oldFinal = jd.job.GetTarget(finalLocation); Toil empty = new Toil(); yield return(Toils_Jump.JumpIf(empty, delegate() { Pawn actor = empty.actor; Job curJob = actor.jobs.curJob; LocalTargetInfo food = curJob.GetTarget(foodIndex).Thing; if (food.Thing == null) { return true; } CompDFoodTemperature comp = food.Thing.TryGetComp <CompDFoodTemperature>(); if (comp == null) { return true; } if (comp.PropsTemp.likesHeat) { return comp.curTemp >= comp.PropsTemp.tempLevels.goodTemp; } else if (HotMealsSettings.thawIt && !comp.PropsTemp.okFrozen) { return comp.curTemp > 0; } return true; })); Toil getHeater = new Toil(); getHeater.initAction = delegate() { Pawn actor = getHeater.actor; Job curJob = actor.jobs.curJob; Thing foodToHeat = curJob.GetTarget(foodIndex).Thing; Thing table = null; if (tableIndex != TargetIndex.None) { table = curJob.GetTarget(tableIndex).Thing; } Thing heater = Toils_HeatMeal.FindPlaceToHeatFood(foodToHeat, actor, searchNear: table); if (heater != null) { curJob.SetTarget(finalLocation, heater); } }; yield return(getHeater); yield return(Toils_Jump.JumpIf(empty, delegate() { Pawn actor = getHeater.actor; Job curJob = actor.jobs.curJob; Thing heater = curJob.GetTarget(finalLocation).Thing; return (heater == null); })); if (!HotMealsSettings.multipleHeat) { yield return(Toils_Reserve.Reserve(finalLocation)); yield return(Toils_Goto.GotoThing(finalLocation, PathEndMode.InteractionCell)); yield return(Toils_HeatMeal.HeatMeal(foodIndex, finalLocation).FailOnDespawnedNullOrForbiddenPlacedThings().FailOnCannotTouch(finalLocation, PathEndMode.InteractionCell)); yield return(Toils_Reserve.Release(finalLocation)); } else { yield return(Toils_Goto.GotoThing(finalLocation, PathEndMode.Touch)); yield return(Toils_HeatMeal.HeatMeal(foodIndex, finalLocation).FailOnDespawnedNullOrForbiddenPlacedThings().FailOnCannotTouch(finalLocation, PathEndMode.Touch)); } yield return(empty); if (oldFinal != LocalTargetInfo.Invalid) { Toil resetC = new Toil(); resetC.initAction = delegate() { Pawn actor = resetC.actor; Job curJob = actor.jobs.curJob; curJob.SetTarget(finalLocation, oldFinal); }; yield return(resetC); } }
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() { 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; }
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 = 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() { this.FailOn(delegate() { if (!this.job.ignoreDesignations) { Pawn victim = this.Victim; if (victim != null && !victim.Dead && base.Map.designationManager.DesignationOn(victim, DesignationDefOf.Hunt) == null) { return(true); } } return(false); }); yield return(new Toil { initAction = delegate() { this.jobStartTick = Find.TickManager.TicksGame; } }); yield return(Toils_Combat.TrySetJobToUseAttackVerb(TargetIndex.A)); Toil startCollectCorpseLabel = Toils_General.Label(); Toil slaughterLabel = Toils_General.Label(); Toil gotoCastPos = Toils_Combat.GotoCastPosition(TargetIndex.A, true, 0.95f).JumpIfDespawnedOrNull(TargetIndex.A, startCollectCorpseLabel).FailOn(() => Find.TickManager.TicksGame > this.jobStartTick + 5000); yield return(gotoCastPos); Toil slaughterIfPossible = Toils_Jump.JumpIf(slaughterLabel, delegate { Pawn victim = this.Victim; return((victim.RaceProps.DeathActionWorker == null || !victim.RaceProps.DeathActionWorker.DangerousInMelee) && victim.Downed); }); yield return(slaughterIfPossible); yield return(Toils_Jump.JumpIfTargetNotHittable(TargetIndex.A, gotoCastPos)); yield return(Toils_Combat.CastVerb(TargetIndex.A, false).JumpIfDespawnedOrNull(TargetIndex.A, startCollectCorpseLabel).FailOn(() => Find.TickManager.TicksGame > this.jobStartTick + 5000)); yield return(Toils_Jump.JumpIfTargetDespawnedOrNull(TargetIndex.A, startCollectCorpseLabel)); yield return(Toils_Jump.Jump(slaughterIfPossible)); yield return(slaughterLabel); yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch).FailOnMobile(TargetIndex.A)); yield return(Toils_General.WaitWith(TargetIndex.A, 180, true, false).FailOnMobile(TargetIndex.A)); yield return(Toils_General.Do(delegate { if (this.Victim.Dead) { return; } ExecutionUtility.DoExecutionByCut(this.pawn, this.Victim); this.pawn.records.Increment(RecordDefOf.AnimalsSlaughtered); if (this.pawn.InMentalState) { this.pawn.MentalState.Notify_SlaughteredAnimal(); } })); yield return(Toils_Jump.Jump(startCollectCorpseLabel)); yield return(startCollectCorpseLabel); yield return(this.StartCollectCorpseToil()); yield return(Toils_Goto.GotoCell(TargetIndex.A, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.A).FailOnSomeonePhysicallyInteracting(TargetIndex.A)); yield return(Toils_Haul.StartCarryThing(TargetIndex.A, false, false, false)); Toil carryToCell = Toils_Haul.CarryHauledThingToCell(TargetIndex.B); yield return(carryToCell); yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.B, carryToCell, true)); yield break; }
//get next, goto, take, check for more. Branches off to "all over the place" protected override IEnumerable <Toil> MakeNewToils() { CompHauledToInventory takenToInventory = pawn.TryGetComp <CompHauledToInventory>(); Toil wait = Toils_General.Wait(2); Toil nextTarget = Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.A); //also does count yield return(nextTarget); //honestly the workgiver checks for encumbered, so until CE checks are in this is unnecessary //yield return CheckForOverencumbered();//Probably redundant without CE checks Toil gotoThing = new Toil { initAction = () => { pawn.pather.StartPath(TargetThingA, PathEndMode.ClosestTouch); }, defaultCompleteMode = ToilCompleteMode.PatherArrival }; gotoThing.FailOnDespawnedNullOrForbidden(TargetIndex.A); yield return(gotoThing); Toil takeThing = new Toil { initAction = () => { Pawn actor = pawn; Thing thing = actor.CurJob.GetTarget(TargetIndex.A).Thing; Toils_Haul.ErrorCheckForCarry(actor, thing); //get max we can pick up int countToPickUp = Mathf.Min(job.count, MassUtility.CountToPickUpUntilOverEncumbered(actor, thing)); Log.Message($"{actor} is hauling to inventory {thing}:{countToPickUp}"); // yo dawg, I heard you like delegates so I put delegates in your delegate, so you can delegate your delegates. // because compilers don't respect IF statements in delegates and toils are fully iterated over as soon as the job starts. try { ((Action)(() => { if (ModCompatibilityCheck.CombatExtendedIsActive) { //CombatExtended.CompInventory ceCompInventory = actor.GetComp<CombatExtended.CompInventory>(); //ceCompInventory.CanFitInInventory(thing, out countToPickUp); } }))(); } catch (TypeLoadException) { } if (countToPickUp > 0) { Thing splitThing = thing.SplitOff(countToPickUp); bool shouldMerge = takenToInventory.GetHashSet().Any(x => x.def == thing.def); actor.inventory.GetDirectlyHeldThings().TryAdd(splitThing, shouldMerge); takenToInventory.RegisterHauledItem(splitThing); try { ((Action)(() => { if (ModCompatibilityCheck.CombatExtendedIsActive) { //CombatExtended.CompInventory ceCompInventory = actor.GetComp<CombatExtended.CompInventory>(); //ceCompInventory.UpdateInventory(); } }))(); } catch (TypeLoadException) { } } //thing still remains, so queue up hauling if we can + end the current job (smooth/instant transition) //This will technically release the reservations in the queue, but what can you do if (thing.Spawned) { Job haul = HaulAIUtility.HaulToStorageJob(actor, thing); if (haul?.TryMakePreToilReservations(actor, false) ?? false) { actor.jobs.jobQueue.EnqueueFirst(haul, JobTag.Misc); } actor.jobs.curDriver.JumpToToil(wait); } } }; yield return(takeThing); yield return(Toils_Jump.JumpIf(nextTarget, () => !job.targetQueueA.NullOrEmpty())); //Find more to haul, in case things spawned while this was in progess yield return(new Toil { initAction = () => { List <Thing> haulables = pawn.Map.listerHaulables.ThingsPotentiallyNeedingHauling(); WorkGiver_HaulToInventory haulMoreWork = DefDatabase <WorkGiverDef> .AllDefsListForReading.First(wg => wg.Worker is WorkGiver_HaulToInventory).Worker as WorkGiver_HaulToInventory; Thing haulMoreThing = GenClosest.ClosestThing_Global(pawn.Position, haulables, 12, t => haulMoreWork.HasJobOnThing(pawn, t)); //WorkGiver_HaulToInventory found more work nearby if (haulMoreThing != null) { Log.Message($"{pawn} hauling again : {haulMoreThing}"); Job haulMoreJob = haulMoreWork.JobOnThing(pawn, haulMoreThing); if (haulMoreJob.TryMakePreToilReservations(pawn, false)) { pawn.jobs.jobQueue.EnqueueFirst(haulMoreJob, JobTag.Misc); EndJobWith(JobCondition.Succeeded); } } } }); //maintain cell reservations on the trip back //TODO: do that when we carry things //I guess that means TODO: implement carrying the rest of the items in this job instead of falling back on HaulToStorageJob yield return(Toils_Goto.GotoCell(TargetIndex.B, PathEndMode.ClosestTouch)); yield return(new Toil //Queue next job { initAction = () => { Pawn actor = pawn; Job curJob = actor.jobs.curJob; LocalTargetInfo storeCell = curJob.targetB; Job unloadJob = new Job(PickUpAndHaulJobDefOf.UnloadYourHauledInventory, storeCell); if (unloadJob.TryMakePreToilReservations(actor, false)) { actor.jobs.jobQueue.EnqueueFirst(unloadJob, JobTag.Misc); EndJobWith(JobCondition.Succeeded); //This will technically release the cell reservations in the queue, but what can you do } } }); yield return(wait); }
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() { // ツールまで移動 yield return(Toils_Goto.GotoThing(ToolInd, PathEndMode.Touch).FailOnDespawnedNullOrForbidden(ToolInd)); // ツールを手に取る yield return(Toils_Haul.StartCarryThing(ToolInd)); // ターゲットが水やり対象として不適になっていたらリストから外す Toil initExtractTargetFromQueue = Toils_Mizu.ClearConditionSatisfiedTargets(WateringInd, (lti) => { var mapComp = this.Map.GetComponent <MapComponent_Watering>(); return(mapComp.Get(this.Map.cellIndices.CellToIndex(lti.Cell)) > 0); }); yield return(initExtractTargetFromQueue); yield return(Toils_JobTransforms.SucceedOnNoTargetInQueue(WateringInd)); // ターゲットキューから次のターゲットを取り出す yield return(Toils_JobTransforms.ExtractNextTargetFromQueue(WateringInd, true)); // ターゲットの元へ移動 yield return(Toils_Goto.GotoCell(WateringInd, PathEndMode.Touch)); // 作業中 Toil workToil = new Toil(); workToil.initAction = delegate { // 必要工数の計算 this.ticksLeftThisToil = WorkingTicks; }; // 細々とした設定 workToil.defaultCompleteMode = ToilCompleteMode.Delay; workToil.WithProgressBar(WateringInd, () => 1f - (float)this.ticksLeftThisToil / WorkingTicks, true, -0.5f); workToil.PlaySustainerOrSound(() => SoundDefOf.Interact_CleanFilth); yield return(workToil); // 作業終了 var finishToil = new Toil(); finishToil.initAction = () => { // 水やり更新 var mapComp = this.Map.GetComponent <MapComponent_Watering>(); mapComp.Set(this.Map.cellIndices.CellToIndex(WateringPos), MapComponent_Watering.MaxWateringValue); this.Map.mapDrawer.SectionAt(WateringPos).dirtyFlags = MapMeshFlag.Terrain; // ツールから水を減らす var compTool = Tool.GetComp <CompWaterTool>(); compTool.StoredWaterVolume -= ConsumeWaterVolume; }; finishToil.defaultCompleteMode = ToilCompleteMode.Instant; yield return(finishToil); // 最初に戻る yield return(Toils_Jump.JumpIf(initExtractTargetFromQueue, () => { return this.pawn.jobs.curJob.GetTargetQueue(WateringInd).Count > 0; })); // ツールを片付ける場所を決める yield return(Toils_Mizu.TryFindStoreCell(ToolInd, ToolPlaceInd)); // 倉庫まで移動 yield return(Toils_Goto.GotoCell(ToolPlaceInd, PathEndMode.Touch)); // 倉庫に置く yield return(Toils_Haul.PlaceHauledThingInCell(ToolPlaceInd, null, true)); }
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); }
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; }
/// <summary> /// Generates a series of actions (toils) that the pawn should perform. /// </summary> /// <returns>Ienumerable of type Toil</returns> /// <remarks>Remember that, in the case of jobs, effectively the entire method is executed before any actual activity occurs.</remarks> protected override IEnumerable <Toil> MakeNewToils() { // Error checking and 'helpful' messages for what is wrong. if (holder == null) // A later check will catch this (failon) but that fails silently. { Log.Error(errorBase + "TargetThingA is null. A Pawn is required to perform a reload."); yield return(null); } if (weapon == null) // Required. { Log.Error(errorBase + "TargetThingB is null. A weapon (ThingWithComps) is required to perform a reload."); yield return(null); } if (compReloader == null) // Required. { Log.Error(errorBase + pawn + " tried to do reload job on " + weapon.LabelCap + " which doesn't have a required CompAmmoUser."); yield return(null); } if (holder != pawn) // Helps restrict what this job does, not really necessary and may work fine (though possibly undesirable behavior) without this check. { Log.Error(errorBase + "TargetThingA (" + holder.Name + ") is not the same Pawn (" + pawn.Name + ") that was given the job."); yield return(null); } // get the state of the job (inventory vs other) at the start. reloadingInventory = weaponInInventory; reloadingEquipment = weaponEquipped; // A couple more more 'helpful' error check/message. if (!reloadingInventory && !reloadingEquipment) // prevent some bad states/behavior on FailOn and job text. { Log.Error(errorBase + "Unable to find the weapon to be reloaded (" + weapon.LabelCap + ") in the inventory nor equipment of " + pawn.Name); yield return(null); } if (reloadingInventory && reloadingEquipment) // prevent incorrect information on job text. If somehow this was true may cause a FailOn to trip. { Log.Error(errorBase + "Something went spectacularly wrong as the weapon to be reloaded was found in both the Pawn's equipment AND inventory at the same time."); yield return(null); } // current state of equipment, want to interrupt the reload if a pawn's equipment changes. initEquipment = pawn.equipment?.Primary; // choose ammo to be loaded and set failstate for no ammo in inventory if (compReloader.UseAmmo) { this.FailOn(() => !compReloader.TryFindAmmoInInventory(out initAmmo)); } // setup fail states, if something goes wrong with the pawn performing the reload, the weapon, or something else that we want to fail on. this.FailOnDespawnedOrNull(indReloader); this.FailOnMentalState(indReloader); this.FailOnDestroyedOrNull(indWeapon); this.FailOn(HasNoGunOrAmmo); // Throw mote if (compReloader.ShouldThrowMote && holder.Map != null) //holder.Map is temporarily null after game load, skip mote if a pawn was reloading when game was saved { MoteMaker.ThrowText(pawn.Position.ToVector3Shifted(), holder.Map, string.Format("CE_ReloadingMote".Translate(), weapon.def.LabelCap)); } //Toil of do-nothing Toil waitToil = new Toil() { actor = pawn }; // actor was always null in testing... waitToil.initAction = () => waitToil.actor.pather.StopDead(); waitToil.defaultCompleteMode = ToilCompleteMode.Delay; waitToil.defaultDuration = Mathf.CeilToInt(compReloader.Props.reloadTime.SecondsToTicks() / pawn.GetStatValue(CE_StatDefOf.ReloadSpeed)); yield return(waitToil.WithProgressBarToilDelay(indReloader)); //Actual reloader Toil reloadToil = new Toil(); reloadToil.AddFinishAction(() => compReloader.LoadAmmo(initAmmo)); yield return(reloadToil); // If reloading one shot at a time and if possible to reload, jump back to do-nothing toil System.Func <bool> jumpCondition = () => compReloader.Props.reloadOneAtATime && compReloader.CurMagCount < compReloader.Props.magazineSize && (!compReloader.UseAmmo || compReloader.TryFindAmmoInInventory(out initAmmo)); Toil jumpToil = Toils_Jump.JumpIf(waitToil, jumpCondition); yield return(jumpToil); //Continue previous job if possible Toil continueToil = new Toil { defaultCompleteMode = ToilCompleteMode.Instant }; yield return(continueToil); }
protected override IEnumerable <Toil> MakeNewToils() { // モップまで移動 yield return(Toils_Goto.GotoThing(MopInd, PathEndMode.Touch).FailOnDespawnedNullOrForbidden(MopInd)); // モップを手に取る yield return(Toils_Haul.StartCarryThing(MopInd)); // ターゲットが掃除対象として不適になっていたらリストから外す // Thing系にしか使えない var initExtractTargetFromQueue = Toils_Mizu.ClearConditionSatisfiedTargets( MoppingInd, lti => lti.Cell.GetFirstThing(pawn.Map, MizuDef.Thing_MoppedThing) != null); yield return(initExtractTargetFromQueue); yield return(Toils_JobTransforms.SucceedOnNoTargetInQueue(MoppingInd)); // ターゲットキューから次のターゲットを取り出す yield return(Toils_JobTransforms.ExtractNextTargetFromQueue(MoppingInd)); // ターゲットの元へ移動 yield return(Toils_Goto.GotoCell(MoppingInd, PathEndMode.Touch).JumpIf( () => { var target = pawn.jobs.curJob.GetTarget(MoppingInd); if (target.HasThing) { return true; } return target.Cell.GetFirstThing(pawn.Map, MizuDef.Thing_MoppedThing) != null; }, initExtractTargetFromQueue).JumpIfOutsideMopArea(MoppingInd, initExtractTargetFromQueue)); // モップ掛け作業中 var mopToil = new Toil { initAction = delegate { // 必要工数の計算 ticksLeftThisToil = MoppingTicks; }, // 細々とした設定 defaultCompleteMode = ToilCompleteMode.Delay }; mopToil.WithProgressBar(MoppingInd, () => 1f - ((float)ticksLeftThisToil / MoppingTicks), true); mopToil.PlaySustainerOrSound(() => SoundDefOf.Interact_CleanFilth); // 掃除中に条件が変更されたら最初に戻る mopToil.JumpIf( () => { var target = pawn.jobs.curJob.GetTarget(MoppingInd); if (target.HasThing) { return(true); } return(target.Cell.GetFirstThing(pawn.Map, MizuDef.Thing_MoppedThing) != null); }, initExtractTargetFromQueue); mopToil.JumpIfOutsideMopArea(MoppingInd, initExtractTargetFromQueue); yield return(mopToil); // モップ掛け終了 var finishToil = new Toil { initAction = () => { // モップオブジェクト生成 var moppedThing = ThingMaker.MakeThing(MizuDef.Thing_MoppedThing); GenSpawn.Spawn(moppedThing, MoppingPos, mopToil.actor.Map); // モップから水を減らす var compTool = Mop.GetComp <CompWaterTool>(); compTool.StoredWaterVolume -= ConsumeWaterVolume; }, defaultCompleteMode = ToilCompleteMode.Instant }; yield return(finishToil); // 最初に戻る yield return(Toils_Jump.JumpIf( initExtractTargetFromQueue, () => pawn.jobs.curJob.GetTargetQueue(MoppingInd).Count > 0)); // モップを片付ける場所を決める yield return(Toils_Mizu.TryFindStoreCell(MopInd, MopPlaceInd)); // Toil startCarryToil = new Toil(); // startCarryToil.initAction = () => // { // var actor = startCarryToil.actor; // var curJob = actor.jobs.curJob; // IntVec3 c; // if (StoreUtility.TryFindBestBetterStoreCellFor(Mop, actor, actor.Map, StoragePriority.Unstored, actor.Faction, out c)) // { // curJob.targetC = c; // curJob.count = 99999; // return; // } // }; // startCarryToil.defaultCompleteMode = ToilCompleteMode.Instant; // yield return startCarryToil; // 倉庫まで移動 yield return(Toils_Goto.GotoCell(MopPlaceInd, PathEndMode.Touch)); // 倉庫に置く yield return(Toils_Haul.PlaceHauledThingInCell(MopPlaceInd, null, true)); }
static IEnumerable <Toil> prepToils(JobDriver_Ingest driver, Toil chewToil) { if ((bool)LeatingFromInventory.GetValue(driver)) { yield return(Toils_Misc.TakeItemFromInventoryToCarrier(driver.pawn, TargetIndex.A)); } else { yield return((Toil)LReserveFood.Invoke(driver, new object[] { })); Toil gotoToPickup = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.A); yield return(Toils_Jump.JumpIf(gotoToPickup, () => driver.pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation))); yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch).FailOnDespawnedNullOrForbidden(TargetIndex.A)); yield return(Toils_Jump.Jump(chewToil)); yield return(gotoToPickup); yield return(Toils_Ingest.PickupIngestible(TargetIndex.A, driver.pawn)); gotoToPickup = null; } if (driver.job.takeExtraIngestibles > 0) { foreach (Toil toil in (IEnumerable <Toil>)LTakeExtraIngestibles.Invoke(driver, new object[] { })) { yield return(toil); } } if (!driver.pawn.Drafted) { yield return(reserveChewSpot(driver.pawn, TargetIndex.A, TargetIndex.B)); Toil gotospot = gotoSpot(TargetIndex.B).FailOnDestroyedOrNull(TargetIndex.A); if (!Utility.IncapableOfCleaning(driver.pawn)) { TargetIndex filthListIndex = TargetIndex.B; TargetIndex progIndex = TargetIndex.A; Toil FilthList = new Toil(); FilthList.initAction = delegate() { Job curJob = FilthList.actor.jobs.curJob; // if (curJob.GetTargetQueue(filthListIndex).NullOrEmpty()) { LocalTargetInfo A = curJob.GetTarget(filthListIndex); if (!A.HasThing) { return; } IEnumerable <Filth> l = Utility.SelectAllFilth(FilthList.actor, A, Settings.adv_clean_num); Utility.AddFilthToQueue(curJob, filthListIndex, l, FilthList.actor); FilthList.actor.ReserveAsManyAsPossible(curJob.GetTargetQueue(filthListIndex), curJob); curJob.GetTargetQueue(filthListIndex).Add(A); } }; yield return(FilthList); yield return(Toils_Jump.JumpIf(gotospot, () => driver.job.GetTargetQueue(filthListIndex).NullOrEmpty())); Toil nextTarget = Toils_JobTransforms.ExtractNextTargetFromQueue(filthListIndex, true); yield return(nextTarget); yield return(Toils_Jump.JumpIf(gotospot, () => driver.job.GetTargetQueue(filthListIndex).NullOrEmpty())); yield return(Toils_Goto.GotoThing(filthListIndex, PathEndMode.Touch).JumpIfDespawnedOrNullOrForbidden(filthListIndex, nextTarget).JumpIfOutsideHomeArea(filthListIndex, nextTarget)); // if (driver.job.GetTargetQueue(progIndex).Count == 0) { driver.job.GetTargetQueue(progIndex).Add(new IntVec3(0, 0, 0)); } // Toil clean = new Toil(); clean.initAction = delegate() { Filth filth = clean.actor.jobs.curJob.GetTarget(filthListIndex).Thing as Filth; var progQue = clean.actor.jobs.curJob.GetTargetQueue(progIndex); progQue[0] = new IntVec3(0, 0, (int)filth.def.filth.cleaningWorkToReduceThickness * filth.thickness); }; clean.tickAction = delegate() { Filth filth = clean.actor.jobs.curJob.GetTarget(filthListIndex).Thing as Filth; var progQue = clean.actor.jobs.curJob.GetTargetQueue(progIndex); IntVec3 iv = progQue[0].Cell; iv.x += 1; iv.y += 1; if (iv.x > filth.def.filth.cleaningWorkToReduceThickness) { filth.ThinFilth(); iv.x = 0; if (filth.Destroyed) { clean.actor.records.Increment(RecordDefOf.MessesCleaned); driver.ReadyForNextToil(); return; } } progQue[0] = iv; }; clean.defaultCompleteMode = ToilCompleteMode.Never; clean.WithEffect(EffecterDefOf.Clean, filthListIndex); clean.WithProgressBar(filthListIndex, delegate() { var q = driver.job.GetTargetQueue(progIndex)[0]; float result = (float)q.Cell.y / q.Cell.z; return(result); } , true, -0.5f); clean.PlaySustainerOrSound(() => SoundDefOf.Interact_CleanFilth); clean.JumpIfDespawnedOrNullOrForbidden(filthListIndex, nextTarget); clean.JumpIfOutsideHomeArea(filthListIndex, nextTarget); clean.FailOnDestroyedOrNull(TargetIndex.A); yield return(clean); yield return(Toils_Jump.Jump(nextTarget)); } yield return(gotospot); } yield return(Toils_Ingest.FindAdjacentEatSurface(TargetIndex.B, TargetIndex.A)); yield break; }