private IEnumerable <Toil> TakeExtraIngestibles() { if (!pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation)) { yield break; } Toil reserveExtraFoodToCollect = Toils_WendigoIngest.ReserveFoodFromStackForIngesting(TargetIndex.C); Toil findExtraFoodToCollect = new Toil { initAction = delegate { if (pawn.inventory.innerContainer.TotalStackCountOfDef(IngestibleSource.def) < job.takeExtraIngestibles) { Thing thing = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, ThingRequest.ForDef(IngestibleSource.def), PathEndMode.Touch, TraverseParms.For(pawn), 30f, (Thing x) => pawn.CanReserve(x, 10, 1) && !x.IsForbidden(pawn) && x.IsSociallyProper(pawn)); if (thing != null) { job.SetTarget(TargetIndex.C, thing); JumpToToil(reserveExtraFoodToCollect); } } }, defaultCompleteMode = ToilCompleteMode.Instant }; yield return(Toils_Jump.Jump(findExtraFoodToCollect)); yield return(reserveExtraFoodToCollect); yield return(Toils_Goto.GotoThing(TargetIndex.C, PathEndMode.Touch)); yield return(Toils_Haul.TakeToInventory(TargetIndex.C, () => job.takeExtraIngestibles - pawn.inventory.innerContainer.TotalStackCountOfDef(IngestibleSource.def))); yield return(findExtraFoodToCollect); }
protected override IEnumerable <Toil> MakeNewToils() { //FAIL CONDITIONS ToilFailConditions.FailOnDestroyedOrNull <JobDriver_Training>(this, TargetIndex.A); ToilFailConditions.FailOnDespawnedNullOrForbidden <JobDriver_Training>(this, TargetIndex.A); this.FailOn(() => { Pawn p = this.pawn; if (this.IsContinuation(this.job) && this.CurToilIndex > 1) { if ((double)p.needs.food.CurLevel < 0.25) { Messages.Message(p.LabelCap + " has stopped training due hunger.", (GlobalTargetInfo)p, MessageTypeDefOf.NeutralEvent); } else if ((double)p.needs.rest.CurLevel < 0.25) { Messages.Message(p.LabelCap + " has stopped training due lack of sleep.", (GlobalTargetInfo)p, MessageTypeDefOf.NeutralEvent); } } return((double)p.needs.food.CurLevel < 0.25 || (double)p.needs.rest.CurLevel < 0.25 || p.Drafted || p.jobs.jobQueue.Any()); }); //SEQUENZA AZIONI PAWN yield return(Toils_Reserve.Reserve(TargetIndex.A, 1)); yield return(Toils_Goto.GotoCell(TargetIndex.B, PathEndMode.OnCell)); Toil Train = Toils_Training(TargetIndex.B); yield return(Train); yield return(Toils_General.Wait(100)); yield return(Toils_Jump.Jump(Train)); }
private IEnumerable <Toil> PrepareToIngestToils_ToolUser(Toil chewToil) { yield return(ReserveFood()); Toil gotoToPickup = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.A); yield return(Toils_Jump.JumpIf(gotoToPickup, () => 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_WendigoIngest.PickupIngestible(TargetIndex.A, pawn)); if (job.takeExtraIngestibles > 0) { foreach (Toil item in TakeExtraIngestibles()) { yield return(item); } } if (!pawn.Drafted) { yield return(Toils_WendigoIngest.CarryIngestibleToChewSpot(pawn, TargetIndex.A).FailOnDestroyedOrNull(TargetIndex.A)); } yield return(Toils_WendigoIngest.FindAdjacentEatSurface(TargetIndex.B, TargetIndex.A)); }
protected override IEnumerable <Toil> MakeNewToils() { /// //Set fail conditions /// this.FailOnDestroyedOrNull(TargetIndex.A); this.AddEndCondition(() => { return(this.Deliveree.health.ShouldBeTendedNow ? JobCondition.Ongoing : JobCondition.Succeeded); }); //Note we only fail on forbidden if the target doesn't start that way //This helps haul-aside jobs on forbidden items /// //Define Toil /// /// //Toils Start /// //Reserve thing to be stored and storage cell yield return(Toils_Reserve.Reserve(TargetIndex.A)); StatWorker statWorker = new StatWorker(); statWorker.InitSetStat(StatDefOf.BaseHealingQuality); Toil toilApplyMedicine = new Toil(); toilApplyMedicine.initAction = () => { Thing dummy; Medicine.holder.TryDrop(Medicine, pawn.Position + IntVec3.North.RotatedBy(pawn.Rotation), ThingPlaceMode.Direct, out dummy); }; yield return(toilApplyMedicine); yield return(Toils_Tend.PickupMedicine(TargetIndex.B, Deliveree)); Toil toilGoTodeliveree = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch); yield return(toilGoTodeliveree); int duration = (int)(1.0 / (double)StatExtension.GetStatValue((Thing)pawn, StatDefOf.HealingSpeed, true) * 600.0); Toil toilDelivereeWait = new Toil(); toilDelivereeWait.initAction = () => { Deliveree.drafter.TakeOrderedJob(new Job(JobDefOf.Wait, duration)); }; yield return(Toils_General.Wait(duration)); yield return(Toils_Tend.FinalizeTend(Deliveree)); yield return(Toils_Jump.Jump(toilGoTodeliveree)); }
protected override IEnumerable <Toil> MakeNewToils() { this.FailOnDespawnedNullOrForbidden(TargetIndex.A); yield return(Toils_Reserve.Reserve(TargetIndex.A, 1)); var reserveSeeds = ReserveSeedsIfWillPlantWholeStack(); yield return(reserveSeeds); yield return(Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch) .FailOnDespawnedNullOrForbidden(TargetIndex.B) .FailOnSomeonePhysicallyInteracting(TargetIndex.B)); yield return(Toils_Haul.StartCarryThing(TargetIndex.B, false, false) .FailOnDestroyedNullOrForbidden(TargetIndex.B)); Toils_Haul.CheckForGetOpportunityDuplicate(reserveSeeds, TargetIndex.B, TargetIndex.None, false, null); var toil = Toils_Goto.GotoCell(TargetIndex.A, PathEndMode.Touch); yield return(toil); yield return(SowSeedToil()); yield return(Toils_Reserve.Release(TargetIndex.A)); yield return(TryToSetAdditionalPlantingSite()); yield return(Toils_Reserve.Reserve(TargetIndex.A, 1)); yield return(Toils_Jump.Jump(toil)); }
// Token: 0x06000095 RID: 149 RVA: 0x000059E9 File Offset: 0x00003BE9 protected override IEnumerable <Toil> MakeNewToils() { var count = 0; this.FailOn(() => job.GetTarget(TargetIndex.A).Thing.DestroyedOrNull()); this.FailOn(() => !HaywireData.IsHaywired(pawn)); var count1 = count; this.FailOn(() => count1 > 4); yield return(Toils_Combat.TrySetJobToUseAttackVerb(TargetIndex.A)); var gotoCastPos = Toils_Combat.GotoCastPosition(TargetIndex.A, TargetIndex.None, false, 0.95f); yield return(gotoCastPos); var count2 = count; count = count2 + 1; if (count > 8) { EndJobWith(JobCondition.Incompletable); } var jumpIfCannotHit = Toils_Jump.JumpIfTargetNotHittable(TargetIndex.A, gotoCastPos); yield return(jumpIfCannotHit); yield return(Toils_Combat.CastVerb(TargetIndex.A)); yield return(Toils_Jump.Jump(jumpIfCannotHit)); }
protected override IEnumerable <Toil> MakeNewToils() { this.FailOnDespawnedNullOrForbidden <JobDriver_StabilizeHere>(TargetIndex.A); this.FailOnAggroMentalState <JobDriver_StabilizeHere>(TargetIndex.A); this.AddEndCondition(() => { if (HealthAIUtility.ShouldBeTendedNowByPlayer(this.Patient) || this.Patient.health.HasHediffsNeedingTend(false)) { return(JobCondition.Ongoing); } return(JobCondition.Succeeded); }); Toil toil1 = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell); yield return(toil1); Toil toil2 = Toils_General.Wait((int)(1f / this.Doctor.GetStatValue(StatDefOf.MedicalTendSpeed, true) * 600f), TargetIndex.None).FailOnCannotTouch <Toil>(TargetIndex.A, PathEndMode.InteractionCell).WithProgressBarToilDelay(TargetIndex.A, false, -0.5f).PlaySustainerOrSound(SoundDefOf.Interact_Tend); toil2.activeSkill = () => SkillDefOf.Medicine; yield return(toil2); yield return(Toils_Tend.FinalizeTend(this.Patient)); yield return(Toils_Jump.Jump(toil1)); }
// Token: 0x0600000A RID: 10 RVA: 0x000029D9 File Offset: 0x00000BD9 protected override IEnumerable <Toil> MakeNewToils() { this.FailOn(delegate { if (job.ignoreDesignations) { return(false); } var victim = Victim; if (victim != null && !victim.Dead && Map.designationManager.DesignationOn(victim, DesignationDefOf.Hunt) == null) { return(true); } return(false); }); yield return(new Toil { initAction = delegate { jobStartTick = Find.TickManager.TicksGame; } }); yield return(Toils_Combat.TrySetJobToUseAttackVerb(TargetIndex.A)); var startCollectCorpse = StartCollectCorpseToil(); var gotoCastPos = MarvsGotoCastPosition(TargetIndex.A, true) .JumpIfDespawnedOrNull(TargetIndex.A, startCollectCorpse) .FailOn(() => Find.TickManager.TicksGame > jobStartTick + 5000); yield return(gotoCastPos); var moveIfCannotHit = MarvsJumpIfTargetNotHittable(TargetIndex.A, gotoCastPos); yield return(moveIfCannotHit); yield return(MarvsJumpIfTargetDownedDistant(TargetIndex.A, gotoCastPos)); yield return(Toils_Combat.CastVerb(TargetIndex.A, false) .JumpIfDespawnedOrNull(TargetIndex.A, startCollectCorpse) .FailOn(() => Find.TickManager.TicksGame > jobStartTick + 5000)); yield return(Toils_Jump.JumpIfTargetDespawnedOrNull(TargetIndex.A, startCollectCorpse)); yield return(Toils_Jump.Jump(moveIfCannotHit)); yield return(startCollectCorpse); yield return(Toils_Goto.GotoCell(TargetIndex.A, PathEndMode.ClosestTouch) .FailOnDespawnedNullOrForbidden(TargetIndex.A).FailOnSomeonePhysicallyInteracting(TargetIndex.A)); yield return(Toils_Haul.StartCarryThing(TargetIndex.A)); var carryToCell = Toils_Haul.CarryHauledThingToCell(TargetIndex.B); yield return(carryToCell); yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.B, carryToCell, true)); }
private IEnumerable <Toil> PrepareToIngestToils_ToolUser(Toil chewToil) { if (eatingFromInventory) { yield return(Toils_Misc.TakeItemFromInventoryToCarrier(pawn, TargetIndex.A)); } else { yield return(ReserveFoodIfWillIngestWholeStack()); Toil gotoToPickup = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.A); yield return(Toils_Jump.JumpIf(gotoToPickup, () => 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, pawn)); Toil reserveExtraFoodToCollect = Toils_Reserve.Reserve(TargetIndex.C); Toil findExtraFoodToCollect = new Toil(); findExtraFoodToCollect.initAction = delegate { if (pawn.inventory.innerContainer.TotalStackCountOfDef(IngestibleSource.def) < job.takeExtraIngestibles) { Predicate <Thing> validator = (Thing x) => pawn.CanReserve(x) && !x.IsForbidden(pawn) && x.IsSociallyProper(pawn); Thing thing = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, ThingRequest.ForDef(IngestibleSource.def), PathEndMode.Touch, TraverseParms.For(pawn), 12f, validator); if (thing != null) { pawn.CurJob.SetTarget(TargetIndex.C, thing); JumpToToil(reserveExtraFoodToCollect); } } }; findExtraFoodToCollect.defaultCompleteMode = ToilCompleteMode.Instant; yield return(Toils_Jump.Jump(findExtraFoodToCollect)); yield return(reserveExtraFoodToCollect); yield return(Toils_Goto.GotoThing(TargetIndex.C, PathEndMode.Touch)); yield return(Toils_Haul.TakeToInventory(TargetIndex.C, () => job.takeExtraIngestibles - pawn.inventory.innerContainer.TotalStackCountOfDef(IngestibleSource.def))); yield return(findExtraFoodToCollect); } yield return(Toils_Ingest.CarryIngestibleToChewSpot(pawn, TargetIndex.A).FailOnDestroyedOrNull(TargetIndex.A)); yield return(Toils_Ingest.FindAdjacentEatSurface(TargetIndex.B, TargetIndex.A)); }
protected override IEnumerable <Toil> MakeNewToils() { this.FailOn(() => Patient == null || Medicine == null); this.FailOnDespawnedNullOrForbidden(TargetIndex.A); this.FailOnDestroyedNullOrForbidden(TargetIndex.B); this.FailOnNotDowned(TargetIndex.A); this.AddEndCondition(delegate { if (Patient.health.hediffSet.GetHediffsTendable().Any(h => h.CanBeStabilized())) { return(JobCondition.Ongoing); } Medicine.Destroy(); return(JobCondition.Incompletable); }); // Pick up medicine and haul to patient yield return(Toils_Reserve.Reserve(TargetIndex.A)); yield return(Toils_Reserve.Reserve(TargetIndex.B)); yield return(Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch)); yield return(Toils_Haul.StartCarryThing(TargetIndex.B)); yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell)); yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.A, null, false)); // Stabilize patient int duration = (int)(1f / this.pawn.GetStatValue(StatDefOf.MedicalTendSpeed, true) * baseTendDuration); Toil waitToil = Toils_General.Wait(duration).WithProgressBarToilDelay(TargetIndex.A).PlaySustainerOrSound(SoundDefOf.Interact_Tend); yield return(waitToil); Toil stabilizeToil = new Toil(); stabilizeToil.initAction = delegate { float xp = (!Patient.RaceProps.Animal) ? 125f : 50f * Medicine.def.MedicineTendXpGainFactor; pawn.skills.Learn(SkillDefOf.Medicine, xp); foreach (Hediff curInjury in from x in Patient.health.hediffSet.GetHediffsTendable() orderby x.BleedRate descending select x) { if (curInjury.CanBeStabilized()) { HediffComp_Stabilize comp = curInjury.TryGetComp <HediffComp_Stabilize>(); comp.Stabilize(pawn, Medicine); break; } } }; stabilizeToil.defaultCompleteMode = ToilCompleteMode.Instant; yield return(stabilizeToil); yield return(Toils_Jump.Jump(waitToil)); }
protected override IEnumerable <Toil> MakeNewToils() { Toil waitLabel = Toils_General.Label(); Toil endLabel = Toils_General.Label(); yield return(Toils_Combat.TrySetJobToUseAttackVerb(TargetIndex.A)); Toil approach = new Toil(); approach.initAction = delegate { Job curJob = pawn.jobs.curJob; if (pawn == Victim || Victim == null) { pawn.pather.StopDead(); ReadyForNextToil(); } else { CastPositionRequest newReq = default(CastPositionRequest); newReq.caster = pawn; newReq.target = Victim; newReq.verb = curJob.verbToUse; newReq.maxRangeFromTarget = (!Victim.Downed ? Mathf.Max(curJob.verbToUse.verbProps.range * maxRangeFactor, 1.42f) : Mathf.Min(curJob.verbToUse.verbProps.range, Victim.RaceProps.executionRange)); newReq.wantCoverFromTarget = false; if (CastPositionFinder.TryFindCastPosition(newReq, out var dest)) { pawn.pather.StartPath(dest, PathEndMode.OnCell); pawn.Map.pawnDestinationReservationManager.Reserve(pawn, curJob, dest); } //else if (pawn.PositionHeld.DistanceTo(Victim.PositionHeld) <= waitRange) //{ // pawn.pather.StopDead(); // pawn.jobs.curDriver.JumpToToil(waitLabel); //} else { pawn.pather.StartPath(Victim, PathEndMode.Touch); } } }; approach.FailOnDespawnedOrNull(VictimIndex); approach.defaultCompleteMode = ToilCompleteMode.Delay; approach.defaultDuration = 60; yield return(approach); yield return(Toils_Jump.Jump(endLabel)); yield return(waitLabel); yield return(Toils_General.Wait(60)); yield return(endLabel); }
protected override IEnumerable <Toil> MakeNewToils() { this.EndOnDespawnedOrNull(TargetIndex.A); Toil chooseCell = Toils_Wrestling.FindRandomInsideReachableCell(TargetIndex.A, TargetIndex.B); yield return(chooseCell); yield return(Toils_Reserve.Reserve(TargetIndex.B)); yield return(Toils_Goto.GotoCell(TargetIndex.B, PathEndMode.OnCell)); Toil toil = new Toil(); toil.initAction = delegate { job.locomotionUrgency = LocomotionUrgency.Jog; }; toil.tickAction = delegate { pawn.rotationTracker.FaceCell(base.TargetA.Thing.OccupiedRect().CenterCell); if (ticksLeftThisToil == 150) { Random random = new System.Random(); if (random.NextDouble() > 0.7) { SoundDefOf.Corpse_Drop.PlayOneShot(new TargetInfo(pawn.Position, pawn.Map)); } else { SoundDefOf.Pawn_Melee_Punch_HitPawn.PlayOneShot(new TargetInfo(pawn.Position, pawn.Map)); } } if (Find.TickManager.TicksGame > startTick + job.def.joyDuration) { EndJobWith(JobCondition.Succeeded); } else { JoyUtility.JoyTickCheckEnd(pawn, JoyTickFullJoyAction.EndJob, 1f, (Building)base.TargetThingA); } }; toil.handlingFacing = true; toil.socialMode = RandomSocialMode.SuperActive; toil.defaultCompleteMode = ToilCompleteMode.Delay; toil.defaultDuration = MoveDuration; toil.AddFinishAction(delegate { JoyUtility.TryGainRecRoomThought(pawn); }); yield return(toil); yield return(Toils_Reserve.Release(TargetIndex.B)); yield return(Toils_Jump.Jump(chooseCell)); }
protected override IEnumerable <Toil> MakeNewToils() { var initExtractTargetFromQueue = Toils_JobTransforms.ClearDespawnedNullOrForbiddenQueuedTargets(FilthInd); yield return(initExtractTargetFromQueue); yield return(Toils_JobTransforms.SucceedOnNoTargetInQueue(FilthInd)); yield return(Toils_JobTransforms.ExtractNextTargetFromQueue(FilthInd)); yield return(Toils_Goto.GotoThing(FilthInd, PathEndMode.Touch) .JumpIfDespawnedOrNullOrForbidden(FilthInd, initExtractTargetFromQueue)); var clean = new Toil { initAction = delegate { cleaningWorkDone = 0f; totalCleaningWorkDone = 0f; totalCleaningWorkRequired = Filth.def.filth.cleaningWorkToReduceThickness * Filth.thickness; } }; clean.tickAction = delegate { var filth = Filth; cleaningWorkDone += 1f; totalCleaningWorkDone += 1f; if (!(cleaningWorkDone > filth.def.filth.cleaningWorkToReduceThickness)) { return; } filth.ThinFilth(); cleaningWorkDone = 0f; if (!filth.Destroyed) { return; } clean.actor.records.Increment(RecordDefOf.MessesCleaned); ReadyForNextToil(); }; clean.defaultCompleteMode = ToilCompleteMode.Never; clean.WithEffect(EffecterDefOf.Clean, FilthInd); clean.WithProgressBar(FilthInd, () => totalCleaningWorkDone / totalCleaningWorkRequired, true); clean.PlaySustainerOrSound(() => SoundDefOf.Interact_CleanFilth); clean.JumpIfDespawnedOrNullOrForbidden(FilthInd, initExtractTargetFromQueue); yield return(clean); yield return(Toils_Jump.Jump(initExtractTargetFromQueue)); }
protected override IEnumerable <Toil> MakeNewToils() { this.EndOnDespawnedOrNull(TargetIndex.A, JobCondition.Incompletable); Toil chooseCell = Toils_Misc.FindRandomAdjacentReachableCell(TargetIndex.A, TargetIndex.B); yield return(chooseCell); yield return(Toils_Reserve.Reserve(TargetIndex.B, 1, -1, null)); yield return(Toils_Goto.GotoCell(TargetIndex.B, PathEndMode.OnCell)); Toil play = new Toil(); play.initAction = delegate() { this.job.locomotionUrgency = LocomotionUrgency.Walk; }; play.tickAction = delegate() { this.pawn.rotationTracker.FaceCell(base.TargetA.Thing.OccupiedRect().ClosestCellTo(this.pawn.Position)); if (this.ticksLeftThisToil == 300) { SoundDefOf.PlayBilliards.PlayOneShot(new TargetInfo(this.pawn.Position, this.pawn.Map, false)); } if (Find.TickManager.TicksGame > this.startTick + this.job.def.joyDuration) { base.EndJobWith(JobCondition.Succeeded); } else { Pawn pawn = this.pawn; Building joySource = (Building)base.TargetThingA; JoyUtility.JoyTickCheckEnd(pawn, JoyTickFullJoyAction.EndJob, 1f, joySource); } }; play.handlingFacing = true; play.socialMode = RandomSocialMode.SuperActive; play.defaultCompleteMode = ToilCompleteMode.Delay; play.defaultDuration = 600; play.AddFinishAction(delegate { JoyUtility.TryGainRecRoomThought(this.pawn); }); yield return(play); yield return(Toils_Reserve.Release(TargetIndex.B)); yield return(Toils_Jump.Jump(chooseCell)); yield break; }
protected override IEnumerable <Toil> MakeNewToils() { Toil initExtractTargetFromQueue = Toils_JobTransforms.ClearDespawnedNullOrForbiddenQueuedTargets(TargetIndex.A); yield return(initExtractTargetFromQueue); yield return(Toils_JobTransforms.SucceedOnNoTargetInQueue(TargetIndex.A)); yield return(Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.A)); yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch).JumpIfDespawnedOrNullOrForbidden(TargetIndex.A, initExtractTargetFromQueue).JumpIfOutsideHomeArea(TargetIndex.A, initExtractTargetFromQueue)); Toil clean = new Toil(); clean.initAction = delegate { cleaningWorkDone = 0f; totalCleaningWorkDone = 0f; totalCleaningWorkRequired = Filth.def.filth.cleaningWorkToReduceThickness * (float)Filth.thickness; }; clean.tickAction = delegate { Filth filth = Filth; cleaningWorkDone += 1f; totalCleaningWorkDone += 1f; if (cleaningWorkDone > filth.def.filth.cleaningWorkToReduceThickness) { filth.ThinFilth(); cleaningWorkDone = 0f; if (filth.Destroyed) { clean.actor.records.Increment(RecordDefOf.MessesCleaned); ReadyForNextToil(); } } }; clean.defaultCompleteMode = ToilCompleteMode.Never; clean.WithEffect(EffecterDefOf.Clean, TargetIndex.A); clean.WithProgressBar(TargetIndex.A, () => totalCleaningWorkDone / totalCleaningWorkRequired, interpolateBetweenActorAndTarget: true); clean.PlaySustainerOrSound(delegate { ThingDef def = Filth.def; return((!def.filth.cleaningSound.NullOrUndefined()) ? def.filth.cleaningSound : SoundDefOf.Interact_CleanFilth); }); clean.JumpIfDespawnedOrNullOrForbidden(TargetIndex.A, initExtractTargetFromQueue); clean.JumpIfOutsideHomeArea(TargetIndex.A, initExtractTargetFromQueue); yield return(clean); yield return(Toils_Jump.Jump(initExtractTargetFromQueue)); }
//protected override IEnumerable<Toil> MakeNewToils() //{ // //these are the fail conditions. If at any time during this toil the cat becomes unavailable, our toil ends. // this.FailOnDespawnedNullOrForbidden(CatToPet); // this.FailOnDowned(CatToPet); // //this.FailOnNotCasualInterruptible(CatToPet); // //go to our cat. These are all vanilla Toils, which is easy to use. // yield return Toils_Goto.GotoThing(CatToPet, PathEndMode.Touch); // yield return Toils_Interpersonal.WaitToBeAbleToInteract(this.pawn); // yield return Toils_Interpersonal.GotoInteractablePosition(CatToPet); // //the RandomSocialMode is a special case for this part of our toil. // //While patting the cat, don't chat with others. We set this per toil. // //It's not possible to set the social mode in the yield return statement so, // //first we define the Toil, and then assign the mode while we return it. // Toil gotoTarget = Toils_Goto.GotoThing(CatToPet, PathEndMode.Touch); // gotoTarget.socialMode = RandomSocialMode.Off; // //There are two wait toils: Wait simply stops the pawn for an amount of ticks. // //The fancy WaitWith we're using has optional parameters like a progress bar and a TargetIndex. // Toil wait = Toils_General.WaitWith(CatToPet, NuzzleDuration, false, true); // wait.socialMode = RandomSocialMode.Off; // //sometimes a Toil must be converted into a delegate. // //Since we can't directly call non-Toil functions or methods inside the IEnumerable, // //we call on Toils_General.Do. There are other options for this, see the next chapter for more. // //yield return Toils_General.Do(delegate // //{ // // Pawn petter = this.pawn; // // Pawn pettee = (Pawn)this.pawn.CurJob.targetA.Thing; // // pettee.interactions.TryInteractWith(petter, InteractionDefOf.Nuzzle); // //}); // yield return new Toil // { // initAction = delegate // { // Pawn petter = this.pawn; // Pawn pettee = (Pawn)this.pawn.CurJob.targetA.Thing; // pettee.interactions.TryInteractWith(petter, InteractionDefOf.Nuzzle); // }, // defaultCompleteMode = ToilCompleteMode.Delay, // defaultDuration = this.job.def.joyDuration // }; //} protected override IEnumerable <Toil> MakeNewToils() { this.FailOnDespawnedNullOrForbidden(CatToPet); this.FailOnDowned(CatToPet); Toil gotoTarget = Toils_Goto.GotoThing(CatToPet, PathEndMode.Touch); yield return(gotoTarget); yield return(Toils_Reserve.Reserve(CatToPet, 1, -1, null)); Toil play = new Toil { initAction = delegate { this.job.locomotionUrgency = LocomotionUrgency.Jog; }, tickAction = delegate { if (Find.TickManager.TicksGame > this.startTick + this.job.def.joyDuration) { Pawn petter = this.pawn; Pawn pettee = (Pawn)this.pawn.CurJob.targetA.Thing; pettee.interactions.TryInteractWith(petter, InteractionDefOf.Nuzzle); this.EndJobWith(JobCondition.Succeeded); return; } JoyUtility.JoyTickCheckEnd(this.pawn, JoyTickFullJoyAction.EndJob); }, socialMode = RandomSocialMode.Off, defaultCompleteMode = ToilCompleteMode.Delay, defaultDuration = 60 }; play.AddFinishAction(delegate { JoyUtility.TryGainRecRoomThought(this.pawn); }); yield return(play); yield return(Toils_Reserve.Release(CatToPet)); yield return(Toils_Jump.Jump(gotoTarget)); }
static IEnumerable <Toil> prepToils(JobDriver_Ingest driver) { yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell).FailOnDespawnedNullOrForbidden(TargetIndex.A)); yield return(Toils_Ingest.TakeMealFromDispenser(TargetIndex.A, driver.pawn)); if (!driver.pawn.Drafted) { yield return(JobDriver_PrepareToIngestToils_ToolUser_CommonSensePatch.reserveChewSpot(TargetIndex.A, TargetIndex.B)); } Toil gotospot = JobDriver_PrepareToIngestToils_ToolUser_CommonSensePatch.gotoSpot(TargetIndex.B).FailOnDestroyedOrNull(TargetIndex.A); if (!Utility.IncapableOfCleaning(driver.pawn)) { TargetIndex filthListIndex = TargetIndex.B; TargetIndex progListIndex = TargetIndex.A; Toil FilthList = JobDriver_PrepareToIngestToils_ToolUser_CommonSensePatch.makeFilthListToil(filthListIndex); 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(progListIndex).Count == 0) { driver.job.GetTargetQueue(progListIndex).Add(new IntVec3(0, 0, 0)); } // Toil clean = JobDriver_PrepareToIngestToils_ToolUser_CommonSensePatch.makeCleanToil(progListIndex, filthListIndex, nextTarget); yield return(clean); yield return(Toils_Jump.Jump(nextTarget)); } yield return(gotospot); yield return(Toils_Ingest.FindAdjacentEatSurface(TargetIndex.B, TargetIndex.A)); }
protected override IEnumerable <Toil> MakeNewToils() { bool err = false; Toil error = Toils_General.Do(delegate { Log.Error("Error in Toils_Haul.PlaceHauledThingInCell. Breaking job."); Log.Error("eggInd = " + eggInd); Log.Error("bedInd = " + bedInd); Log.Error("bedCellInd = " + bedCellInd); err = true; }); this.FailOnDestroyedOrNull(eggInd); this.FailOnDespawnedOrNull(bedInd); yield return(Toils_Goto.GotoThing(eggInd, PathEndMode.Touch).FailOnDestroyedOrNull(eggInd).FailOnSomeonePhysicallyInteracting(eggInd)); if (!TargetA.Thing.IsForbidden(pawn) && TargetB.IsValid) { if (TargetA.Cell != TargetB.Cell) { yield return(Toils_Goto.GotoThing(eggInd, PathEndMode.Touch).FailOnDestroyedOrNull(eggInd).FailOnSomeonePhysicallyInteracting(eggInd)); yield return(Toils_Haul.StartCarryThing(eggInd, false, false, false)); yield return(Toils_Goto.GotoThing(bedInd, PathEndMode.Touch).FailOnDespawnedOrNull(bedInd)); yield return(Toils_Haul.PlaceHauledThingInCell(bedCellInd, Toils_Jump.Jump(error), false)); TargetA.Thing.SetForbidden(true, true); } } yield return(Toils_General.Wait(1000)); if (err) { yield return(error); } yield break; }
protected override IEnumerable <Toil> MakeNewToils() { this.EndOnDespawned(VictimInd, ResultOfDespawnedTarget()); yield return(Toils_Reserve.Reserve(VictimInd, ReservationType.Total)); Toil gotoCastPos = Toils_Combat.GotoCastPosition(VictimInd); yield return(gotoCastPos); Toil jumpIfCannotHit = Toils_Jump.JumpIfCannotHitTarget(VictimInd, gotoCastPos); yield return(jumpIfCannotHit); var verbtoil = Toils_Combat.CastVerb(VictimInd); var tool = (Tool)CurJob.verbToUse.ownerEquipment; verbtoil = verbtoil.WithEffect(tool.effecterDef, VictimInd); yield return(verbtoil); yield return(Toils_Jump.Jump(jumpIfCannotHit)); }
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); }
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; }
protected override IEnumerable <Toil> MakeNewToils() { Toil startCollectCorpse = Toils_General.Wait(10); yield return(Toils_Reserve.ReserveTarget(VictimInd, ReservationType.Total)); yield return(Toils_Combat.SetJobToUseToBestAttackVerb()); Toil gotoCastPos = Toils_Combat.GotoCastPosition(VictimInd) .JumpIfDespawned(VictimInd, startCollectCorpse); yield return(gotoCastPos); Toil jumpIfCannotHit = Toils_Jump.JumpIfCannotHitTarget(VictimInd, gotoCastPos); yield return(jumpIfCannotHit); yield return(Toils_General.Wait(2) .JumpIfDespawned(VictimInd, startCollectCorpse)); yield return(Toils_Combat.CastVerb(VictimInd) .JumpIfDespawned(VictimInd, startCollectCorpse)); yield return(Toils_Jump.Jump(jumpIfCannotHit)); //================================================ //============= Collect corpse =================== //================================================ yield return(startCollectCorpse); //---------------------------------------------------- //Rearrange the job so the bill doer goes and stores the product //---------------------------------------------------- Toil transformJobForCorpseStore = new Toil(); transformJobForCorpseStore.initAction = () => { Pawn actor = transformJobForCorpseStore.actor; //Hack way of finding a ref to the corpse Corpse corpse = null; Thing targPawn = actor.CurJob.GetTarget(VictimInd).Thing; foreach (Thing t in targPawn.Position) { corpse = t as Corpse; if (corpse != null && corpse.sourcePawn == targPawn) { break; } } corpse.SetForbidden(false); //Try find a store square IntVec3 storeSquare; if (corpse != null && StoreUtility.TryFindBestStoreSquareFor(corpse, StoragePriority.Unstored, out storeSquare)) { actor.CurJob.targetB = storeSquare; actor.CurJob.SetTarget(CorpseInd, corpse); actor.CurJob.maxNumToCarry = 1; actor.CurJob.haulMode = HaulMode.ToSquareStorage; } else { //No store square? We're done. actor.jobs.EndCurrentJob(JobCondition.Succeeded); return; } }; yield return(transformJobForCorpseStore); yield return(Toils_Goto.GotoLoc(CorpseInd, PathMode.ClosestTouch) .FailOnDespawnedOrForbidden(CorpseInd)); yield return(Toils_Haul.StartCarryThing(CorpseInd)); Toil carryToSquare = Toils_Haul.CarryHauledThingToSquare(TargetIndex.B); yield return(carryToSquare); yield return(Toils_Haul.PlaceHauledThingInSquare(TargetIndex.B, carryToSquare)); }
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; }
protected override IEnumerable <Toil> MakeNewToils() { Init(); yield return(Toils_JobTransforms.MoveCurrentTargetIntoQueue(TargetIndex.A)); Toil initExtractTargetFromQueue = Toils_JobTransforms.ClearDespawnedNullOrForbiddenQueuedTargets(TargetIndex.A, (RequiredDesignation != null) ? ((Func <Thing, bool>)((Thing t) => base.Map.designationManager.DesignationOn(t, RequiredDesignation) != null)) : null); yield return(initExtractTargetFromQueue); yield return(Toils_JobTransforms.SucceedOnNoTargetInQueue(TargetIndex.A)); yield return(Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.A)); Toil toil = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch).JumpIfDespawnedOrNullOrForbidden(TargetIndex.A, initExtractTargetFromQueue); if (RequiredDesignation != null) { toil.FailOnThingMissingDesignation(TargetIndex.A, RequiredDesignation); } yield return(toil); Toil cut = new Toil(); cut.tickAction = delegate { Pawn actor = cut.actor; if (actor.skills != null) { actor.skills.Learn(SkillDefOf.Plants, xpPerTick); } float statValue = actor.GetStatValue(StatDefOf.PlantWorkSpeed); Plant plant = Plant; statValue *= Mathf.Lerp(3.3f, 1f, plant.Growth); workDone += statValue; if (workDone >= plant.def.plant.harvestWork) { if (plant.def.plant.harvestedThingDef != null) { if (actor.RaceProps.Humanlike && plant.def.plant.harvestFailable && !plant.Blighted && Rand.Value > actor.GetStatValue(StatDefOf.PlantHarvestYield)) { MoteMaker.ThrowText((pawn.DrawPos + plant.DrawPos) / 2f, base.Map, "TextMote_HarvestFailed".Translate(), 3.65f); } else { int num = plant.YieldNow(); if (num > 0) { Thing thing = ThingMaker.MakeThing(plant.def.plant.harvestedThingDef); thing.stackCount = num; if (actor.Faction != Faction.OfPlayer) { thing.SetForbidden(value: true); } Find.QuestManager.Notify_PlantHarvested(actor, thing); GenPlace.TryPlaceThing(thing, actor.Position, base.Map, ThingPlaceMode.Near); actor.records.Increment(RecordDefOf.PlantsHarvested); } } } plant.def.plant.soundHarvestFinish.PlayOneShot(actor); plant.PlantCollected(); workDone = 0f; ReadyForNextToil(); } }; cut.FailOnDespawnedNullOrForbidden(TargetIndex.A); if (RequiredDesignation != null) { cut.FailOnThingMissingDesignation(TargetIndex.A, RequiredDesignation); } 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, interpolateBetweenActorAndTarget: true); cut.PlaySustainerOrSound(() => Plant.def.plant.soundHarvesting); cut.activeSkill = (() => SkillDefOf.Plants); yield return(cut); Toil toil2 = PlantWorkDoneToil(); if (toil2 != null) { yield return(toil2); } yield return(Toils_Jump.Jump(initExtractTargetFromQueue)); }
/// <summary> /// Find spot, reserve spot, pull thing out of inventory, go to spot, drop stuff, repeat. /// </summary> /// <returns></returns> protected override IEnumerable <Toil> MakeNewToils() { CompHauledToInventory takenToInventory = pawn.TryGetComp <CompHauledToInventory>(); HashSet <Thing> carriedThing = takenToInventory.GetHashSet(); if (ModCompatibilityCheck.ExtendedStorageIsActive) { //ES takes at least ~10 ticks to move from the feeder to the stockpile, so workaround ahoy UnloadDuration = 20; } Toil wait = Toils_General.Wait(UnloadDuration); Toil celebrate = Toils_General.Wait(UnloadDuration); yield return(wait); Toil findSpot = new Toil { initAction = () => { ThingCount unloadableThing = FirstUnloadableThing(pawn); if (unloadableThing.Count == 0 && carriedThing.Count == 0) { this.EndJobWith(JobCondition.Succeeded); } if (unloadableThing.Count != 0) { //StoragePriority currentPriority = StoreUtility.StoragePriorityAtFor(pawn.Position, unloadableThing.Thing); if (!StoreUtility.TryFindStoreCellNearColonyDesperate(unloadableThing.Thing, this.pawn, out IntVec3 c)) { this.pawn.inventory.innerContainer.TryDrop(unloadableThing.Thing, ThingPlaceMode.Near, unloadableThing.Thing.stackCount, out Thing thing); this.EndJobWith(JobCondition.Succeeded); } else { this.job.SetTarget(TargetIndex.A, unloadableThing.Thing); this.job.SetTarget(TargetIndex.B, c); this.countToDrop = unloadableThing.Thing.stackCount; } } } }; yield return(findSpot); yield return(Toils_Reserve.Reserve(TargetIndex.B)); yield return(new Toil { initAction = delegate { Thing thing = this.job.GetTarget(TargetIndex.A).Thing; if (thing == null || !this.pawn.inventory.innerContainer.Contains(thing)) { carriedThing.Remove(thing); pawn.jobs.curDriver.JumpToToil(wait); return; } if (!this.pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation) || !thing.def.EverStorable(false)) { this.pawn.inventory.innerContainer.TryDrop(thing, ThingPlaceMode.Near, this.countToDrop, out thing); this.EndJobWith(JobCondition.Succeeded); carriedThing.Remove(thing); } else { this.pawn.inventory.innerContainer.TryTransferToContainer(thing, this.pawn.carryTracker.innerContainer, this.countToDrop, out thing); this.job.count = this.countToDrop; this.job.SetTarget(TargetIndex.A, thing); carriedThing.Remove(thing); } try { ((Action)(() => { if (ModCompatibilityCheck.CombatExtendedIsActive) { //CombatExtended.CompInventory ceCompInventory = pawn.GetComp<CombatExtended.CompInventory>(); //ceCompInventory.UpdateInventory(); } }))(); } catch (TypeLoadException) { } thing.SetForbidden(false, false); } }); Toil carryToCell = Toils_Haul.CarryHauledThingToCell(TargetIndex.B); yield return(Toils_Goto.GotoCell(TargetIndex.B, PathEndMode.Touch)); yield return(carryToCell); yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.B, carryToCell, true)); //If the original cell is full, PlaceHauledThingInCell will set a different TargetIndex resulting in errors on yield return Toils_Reserve.Release. //We still gotta release though, mostly because of Extended Storage. Toil releaseReservation = new Toil { initAction = () => { if (pawn.Map.reservationManager.ReservedBy(this.job.targetB, pawn, pawn.CurJob) && !ModCompatibilityCheck.HCSKIsActive) { pawn.Map.reservationManager.Release(this.job.targetB, pawn, pawn.CurJob); } } }; yield return(releaseReservation); yield return(Toils_Jump.Jump(wait)); yield return(celebrate); }
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() { this.FailOnDespawnedNullOrForbidden(TargetIndex.A); this.FailOn(delegate { if (!WorkGiver_Tend.GoodLayingStatusForTend(this.$this.Deliveree, this.$this.pawn)) { return(true); } if (this.$this.MedicineUsed != null) { if (this.$this.Deliveree.playerSettings == null) { return(true); } if (!this.$this.Deliveree.playerSettings.medCare.AllowsMedicine(this.$this.MedicineUsed.def)) { return(true); } } return(this.$this.pawn == this.$this.Deliveree && (this.$this.pawn.playerSettings == null || !this.$this.pawn.playerSettings.selfTend)); }); base.AddEndCondition(delegate { if (HealthAIUtility.ShouldBeTendedNow(this.$this.Deliveree)) { return(JobCondition.Ongoing); } return(JobCondition.Succeeded); }); this.FailOnAggroMentalState(TargetIndex.A); Toil reserveMedicine = null; if (this.usesMedicine) { reserveMedicine = Toils_Reserve.Reserve(TargetIndex.B, 1, -1, null).FailOnDespawnedNullOrForbidden(TargetIndex.B); yield return(reserveMedicine); yield return(Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.B)); yield return(Toils_Tend.PickupMedicine(TargetIndex.B, this.Deliveree).FailOnDestroyedOrNull(TargetIndex.B)); yield return(Toils_Haul.CheckForGetOpportunityDuplicate(reserveMedicine, TargetIndex.B, TargetIndex.None, true, null)); } PathEndMode interactionCell = (this.Deliveree != this.pawn) ? PathEndMode.InteractionCell : PathEndMode.OnCell; Toil gotoToil = Toils_Goto.GotoThing(TargetIndex.A, interactionCell); yield return(gotoToil); int duration = (int)(1f / this.pawn.GetStatValue(StatDefOf.MedicalTendSpeed, true) * 600f); yield return(Toils_General.Wait(duration).FailOnCannotTouch(TargetIndex.A, interactionCell).WithProgressBarToilDelay(TargetIndex.A, false, -0.5f).PlaySustainerOrSound(SoundDefOf.Interact_Tend)); yield return(Toils_Tend.FinalizeTend(this.Deliveree)); if (this.usesMedicine) { yield return(new Toil { initAction = delegate { if (this.$this.MedicineUsed.DestroyedOrNull() && Medicine.GetMedicineCountToFullyHeal(this.$this.Deliveree) > 0) { Thing thing = HealthAIUtility.FindBestMedicine(this.$this.pawn, this.$this.Deliveree); if (thing != null) { this.$this.job.targetB = thing; this.$this.JumpToToil(reserveMedicine); } } } }); } yield return(Toils_Jump.Jump(gotoToil)); }
protected override IEnumerable <Toil> MakeNewToils() { //fail if can't do violence base.AddFailCondition(delegate { return(this.pawn.WorkTagIsDisabled(WorkTags.Violent)); }); this.jobStartTick = Find.TickManager.TicksGame; Func <bool> designationValidator = () => !( // Dummy must have the any designation TargetThingA.HasDesignation(CombatTrainingDefOf.TrainCombatDesignation) || // Dummy must have the melee designation, and the pawn has a melee weapon held TargetThingA.HasDesignation(CombatTrainingDefOf.TrainCombatDesignationMeleeOnly) && pawn.equipment.Primary.def.IsMeleeWeapon || // Dummy must have the ranged designation, and the pawn has a ranged weapon held TargetThingA.HasDesignation(CombatTrainingDefOf.TrainCombatDesignationRangedOnly) && pawn.equipment.Primary.def.IsRangedWeapon || // Dummy must have any designation, and the pawn is unarmed. (TargetThingA.HasDesignation(CombatTrainingDefOf.TrainCombatDesignation) || TargetThingA.HasDesignation(CombatTrainingDefOf.TrainCombatDesignationMeleeOnly) || TargetThingA.HasDesignation(CombatTrainingDefOf.TrainCombatDesignationRangedOnly)) && pawn.equipment.Primary == null); //make sure thing has train combat designation if (designationValidator()) { yield break; } // Make sure our dummy isn't already in use this.FailOnSomeonePhysicallyInteracting(TargetIndex.A); //fail if dummy is despawned null or forbidden this.FailOnDespawnedNullOrForbidden(TargetIndex.A); /**** START SWITCH TO TRAINING WEAPON ****/ //Pick up a training weapon if one is nearby. Remember previous weapon ThingWithComps startingEquippedWeapon = this.pawn.equipment.Primary; ThingWithComps trainingWeapon = null; if (startingEquippedWeapon == null || !startingEquippedWeapon.def.IsWithinCategory(CombatTrainingDefOf.TrainingWeapons)) { trainingWeapon = GetNearestTrainingWeapon(startingEquippedWeapon); if (trainingWeapon != null && !trainingWeapon.IsForbidden(pawn)) { //reserve training weapon, goto, and equip if (this.Map.reservationManager.CanReserve(this.pawn, trainingWeapon, 1, -1, null, false)) { this.pawn.Reserve(trainingWeapon, this.job, 1, -1, null, true); this.job.SetTarget(TargetIndex.B, trainingWeapon); yield return(Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.B)); yield return(CreateEquipToil(TargetIndex.B)); } //reserve previous weapon and set as target c if (this.Map.reservationManager.CanReserve(this.pawn, startingEquippedWeapon, 1, -1, null, false)) { this.pawn.Reserve(startingEquippedWeapon, this.job, 1, -1, null, true); this.job.SetTarget(TargetIndex.C, startingEquippedWeapon); } } } Toil reequipStartingWeaponLabel = Toils_General.Label(); /**** END SWITCH TO TRAINING WEAPON ****/ //set the job's attack verb to melee or shooting - needed to gotoCastPosition or stack overflow occurs yield return(Toils_Combat.TrySetJobToUseAttackVerb(TargetIndex.A)); //based on attack verb, go to cast position Toil gotoCastPos = Toils_Combat.GotoCastPosition(TargetIndex.A, true, 0.95f).EndOnDespawnedOrNull(TargetIndex.A); yield return(gotoCastPos); //try going to new cast position if the target can't be hit from current position yield return(Toils_Jump.JumpIfTargetNotHittable(TargetIndex.A, gotoCastPos)); //training loop - jump if done training -> cast verb -> jump to done training //if done training jumnp to reequipStartingWeaponLabel Toil doneTraining = Toils_Jump.JumpIf(reequipStartingWeaponLabel, delegate { if (LearningSaturated()) { return(true); } else { return(Dummy.Destroyed || Find.TickManager.TicksGame > this.jobStartTick + 5000 || designationValidator()); } }); yield return(doneTraining); Toil castVerb = Toils_Combat.CastVerb(TargetIndex.A, false); castVerb.AddFinishAction(delegate { LearnAttackSkill(); }); yield return(castVerb); yield return(Toils_Jump.Jump(doneTraining)); yield return(reequipStartingWeaponLabel); //gain room buff yield return(Toils_General.Do(delegate { TryGainCombatTrainingRoomThought(); })); //equip strating weapon if (trainingWeapon != null && startingEquippedWeapon != null) { yield return(Toils_Goto.GotoThing(TargetIndex.C, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.C)); yield return(CreateEquipToil(TargetIndex.C)); } 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; }
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); }