protected override IEnumerable <Toil> MakeNewToils() { this.EndOnDespawnedOrNull(TargetIndex.A, JobCondition.Incompletable); bool hasBed = base.TargetC.HasThing && base.TargetC.Thing is Building_Bed; Toil watch; if (hasBed) { this.KeepLyingDown(TargetIndex.C); yield return(Toils_Bed.ClaimBedIfNonMedical(TargetIndex.C, TargetIndex.None)); yield return(Toils_Bed.GotoBed(TargetIndex.C)); watch = Toils_LayDown.LayDown(TargetIndex.C, true, false, true, true); watch.AddFailCondition(() => !watch.actor.Awake()); } else { yield return(Toils_Goto.GotoCell(TargetIndex.B, PathEndMode.OnCell)); watch = new Toil(); } watch.AddPreTickAction(delegate { this.$this.WatchTickAction(); }); watch.AddFinishAction(delegate { JoyUtility.TryGainRecRoomThought(this.$this.pawn); }); watch.defaultCompleteMode = ToilCompleteMode.Delay; watch.defaultDuration = this.job.def.joyDuration; watch.handlingFacing = true; yield return(watch); }
protected override IEnumerable <Toil> MakeNewToils() { this.FailOnDespawnedOrNull(BedInd); this.FailOnDespawnedOrNull(PartnerInd); this.FailOn(() => !Partner.health.capacities.CanBeAwake); this.KeepLyingDown(BedInd); yield return(Toils_Bed.ClaimBedIfNonMedical(BedInd)); yield return(Toils_Bed.GotoBed(BedInd)); Toil toil = new Toil(); toil.initAction = delegate { if (Partner.CurJob == null || Partner.CurJob.def != JobDefOf.Lovin) { Job newJob = JobMaker.MakeJob(JobDefOf.Lovin, pawn, Bed); Partner.jobs.StartJob(newJob, JobCondition.InterruptForced); ticksLeft = (int)(2500f * Mathf.Clamp(Rand.Range(0.1f, 1.1f), 0.1f, 2f)); } else { ticksLeft = 9999999; } }; toil.defaultCompleteMode = ToilCompleteMode.Instant; yield return(toil); Toil toil2 = Toils_LayDown.LayDown(BedInd, hasBed: true, lookForOtherJobs: false, canSleep: false, gainRestAndHealth: false); toil2.FailOn(() => Partner.CurJob == null || Partner.CurJob.def != JobDefOf.Lovin); toil2.AddPreTickAction(delegate { ticksLeft--; if (ticksLeft <= 0) { ReadyForNextToil(); } else if (pawn.IsHashIntervalTick(100)) { MoteMaker.ThrowMetaIcon(pawn.Position, pawn.Map, ThingDefOf.Mote_Heart); } }); toil2.AddFinishAction(delegate { Thought_Memory thought_Memory = (Thought_Memory)ThoughtMaker.MakeThought(ThoughtDefOf.GotSomeLovin); if ((pawn.health != null && pawn.health.hediffSet != null && pawn.health.hediffSet.hediffs.Any((Hediff h) => h.def == HediffDefOf.LoveEnhancer)) || (Partner.health != null && Partner.health.hediffSet != null && Partner.health.hediffSet.hediffs.Any((Hediff h) => h.def == HediffDefOf.LoveEnhancer))) { thought_Memory.moodPowerFactor = 1.5f; } if (pawn.needs.mood != null) { pawn.needs.mood.thoughts.memories.TryGainMemory(thought_Memory, Partner); } pawn.mindState.canLovinTick = Find.TickManager.TicksGame + GenerateRandomMinTicksToNextLovin(pawn); }); toil2.socialMode = RandomSocialMode.Off; yield return(toil2); }
protected override IEnumerable <Toil> MakeNewToils() { this.FailOnDespawnedOrNull(this.BedInd); this.FailOnDespawnedOrNull(this.PartnerInd); this.FailOn(() => !this.Partner.health.capacities.CanBeAwake); this.KeepLyingDown(this.BedInd); yield return(Toils_Bed.ClaimBedIfNonMedical(this.BedInd, TargetIndex.None)); yield return(Toils_Bed.GotoBed(this.BedInd)); yield return(new Toil { initAction = delegate() { if (this.Partner.CurJob == null || this.Partner.CurJob.def != JobDefOf.Lovin) { Job newJob = new Job(JobDefOf.Lovin, this.pawn, this.Bed); this.Partner.jobs.StartJob(newJob, JobCondition.InterruptForced, null, false, true, null, null, false); this.ticksLeft = (int)(2500f * Mathf.Clamp(Rand.Range(0.1f, 1.1f), 0.1f, 2f)); } else { this.ticksLeft = 9999999; } }, defaultCompleteMode = ToilCompleteMode.Instant }); Toil doLovin = Toils_LayDown.LayDown(this.BedInd, true, false, false, false); doLovin.FailOn(() => this.Partner.CurJob == null || this.Partner.CurJob.def != JobDefOf.Lovin); doLovin.AddPreTickAction(delegate { this.ticksLeft--; if (this.ticksLeft <= 0) { base.ReadyForNextToil(); } else if (this.pawn.IsHashIntervalTick(100)) { MoteMaker.ThrowMetaIcon(this.pawn.Position, this.pawn.Map, ThingDefOf.Mote_Heart); } }); doLovin.AddFinishAction(delegate { Thought_Memory newThought = (Thought_Memory)ThoughtMaker.MakeThought(ThoughtDefOf.GotSomeLovin); this.pawn.needs.mood.thoughts.memories.TryGainMemory(newThought, this.Partner); this.pawn.mindState.canLovinTick = Find.TickManager.TicksGame + this.GenerateRandomMinTicksToNextLovin(this.pawn); }); doLovin.socialMode = RandomSocialMode.Off; yield return(doLovin); yield break; }
internal void <> m__2() { Pawn actor = this.layDown.actor; JobDriver curDriver = actor.jobs.curDriver; if (actor.mindState.applyBedThoughtsOnLeave) { Toils_LayDown.ApplyBedThoughts(actor); } curDriver.asleep = false; }
protected override IEnumerable <Toil> MakeNewToils() { bool hasBed = this.job.GetTarget(TargetIndex.A).HasThing; if (hasBed) { yield return(Toils_Bed.ClaimBedIfNonMedical(TargetIndex.A, TargetIndex.None)); yield return(Toils_Bed.GotoBed(TargetIndex.A)); } else { yield return(Toils_Goto.GotoCell(TargetIndex.A, PathEndMode.OnCell)); } yield return(Toils_LayDown.LayDown(TargetIndex.A, hasBed, true, true, true)); }
protected override IEnumerable <Toil> MakeNewToils() { this.EndOnDespawnedOrNull(TargetIndex.A); Toil watch; if (base.TargetC.HasThing && base.TargetC.Thing is Building_Bed) { this.KeepLyingDown(TargetIndex.C); yield return(Toils_Bed.ClaimBedIfNonMedical(TargetIndex.C)); yield return(Toils_Bed.GotoBed(TargetIndex.C)); watch = Toils_LayDown.LayDown(TargetIndex.C, hasBed: true, lookForOtherJobs: false); watch.AddFailCondition(() => !watch.actor.Awake()); } else { yield return(Toils_Goto.GotoCell(TargetIndex.B, PathEndMode.OnCell)); watch = new Toil(); } watch.AddPreTickAction(delegate { WatchTickAction(); }); watch.AddFinishAction(delegate { JoyUtility.TryGainRecRoomThought(pawn); }); watch.defaultCompleteMode = ToilCompleteMode.Delay; watch.defaultDuration = job.def.joyDuration; watch.handlingFacing = true; if (base.TargetA.Thing.def.building != null && base.TargetA.Thing.def.building.effectWatching != null) { watch.WithEffect(() => base.TargetA.Thing.def.building.effectWatching, EffectTargetGetter); } yield return(watch); LocalTargetInfo EffectTargetGetter() { return(base.TargetA.Thing.OccupiedRect().RandomCell + IntVec3.North.RotatedBy(base.TargetA.Thing.Rotation)); } }
protected override IEnumerable <Toil> MakeNewToils() { Toil relax; if (this.FromBed) { this.KeepLyingDown(TargetIndex.A); yield return(Toils_Bed.ClaimBedIfNonMedical(TargetIndex.A, TargetIndex.None)); yield return(Toils_Bed.GotoBed(TargetIndex.A)); relax = Toils_LayDown.LayDown(TargetIndex.A, true, false, true, true); relax.AddFailCondition(() => !this.pawn.Awake()); } else { yield return(Toils_Goto.GotoCell(TargetIndex.A, PathEndMode.OnCell)); relax = new Toil(); relax.initAction = delegate() { this.faceDir = ((!this.job.def.faceDir.IsValid) ? Rot4.Random : this.job.def.faceDir); }; relax.handlingFacing = true; } relax.defaultCompleteMode = ToilCompleteMode.Delay; relax.defaultDuration = this.job.def.joyDuration; relax.AddPreTickAction(delegate { if (this.faceDir.IsValid) { this.pawn.rotationTracker.FaceCell(this.pawn.Position + this.faceDir.FacingCell); } this.pawn.GainComfortFromCellIfPossible(); JoyUtility.JoyTickCheckEnd(this.pawn, JoyTickFullJoyAction.EndJob, 1f, null); }); yield return(relax); yield break; }
protected override IEnumerable <Toil> MakeNewToils() { Toil toil; if (FromBed) { this.KeepLyingDown(TargetIndex.A); yield return(Toils_Bed.ClaimBedIfNonMedical(TargetIndex.A)); yield return(Toils_Bed.GotoBed(TargetIndex.A)); toil = Toils_LayDown.LayDown(TargetIndex.A, hasBed: true, lookForOtherJobs: false, CanSleep); toil.AddFailCondition(() => !pawn.Awake()); } else { yield return(Toils_Goto.GotoCell(TargetIndex.A, PathEndMode.OnCell)); toil = new Toil(); toil.initAction = delegate { faceDir = (job.def.faceDir.IsValid ? job.def.faceDir : Rot4.Random); }; toil.handlingFacing = true; } toil.defaultCompleteMode = ToilCompleteMode.Delay; toil.defaultDuration = job.def.joyDuration; toil.AddPreTickAction(delegate { if (faceDir.IsValid) { pawn.rotationTracker.FaceCell(pawn.Position + faceDir.FacingCell); } pawn.GainComfortFromCellIfPossible(); JoyUtility.JoyTickCheckEnd(pawn); }); yield return(toil); }
public static Toil LayDown(TargetIndex bedOrRestSpotIndex, bool hasBed, bool lookForOtherJobs, bool canSleep = true, bool gainRestAndHealth = true) { Toil layDown = new Toil(); layDown.initAction = delegate { Pawn actor = layDown.actor; actor.pather.StopDead(); JobDriver curDriver = actor.jobs.curDriver; if (hasBed) { Building_Bed t = (Building_Bed)actor.CurJob.GetTarget(bedOrRestSpotIndex).Thing; if (!t.OccupiedRect().Contains(actor.Position)) { Log.Error("Can't start LayDown toil because pawn is not in the bed. pawn=" + actor); actor.jobs.EndCurrentJob(JobCondition.Errored, true); return; } curDriver.layingDown = LayingDownState.LayingInBed; } else { curDriver.layingDown = LayingDownState.LayingSurface; } curDriver.asleep = false; if (actor.mindState.applyBedThoughtsTick == 0) { actor.mindState.applyBedThoughtsTick = Find.TickManager.TicksGame + Rand.Range(2500, 10000); actor.mindState.applyBedThoughtsOnLeave = false; } if (actor.ownership != null && actor.CurrentBed() != actor.ownership.OwnedBed) { ThoughtUtility.RemovePositiveBedroomThoughts(actor); } }; layDown.tickAction = delegate { Pawn actor = layDown.actor; Job curJob = actor.CurJob; JobDriver curDriver = actor.jobs.curDriver; Building_Bed building_Bed = (Building_Bed)curJob.GetTarget(bedOrRestSpotIndex).Thing; actor.GainComfortFromCellIfPossible(); if (!curDriver.asleep) { if (canSleep && ((actor.needs.rest != null && actor.needs.rest.CurLevel < RestUtility.FallAsleepMaxLevel(actor)) || curJob.forceSleep)) { curDriver.asleep = true; } } else if (!canSleep) { curDriver.asleep = false; } else if ((actor.needs.rest == null || actor.needs.rest.CurLevel >= RestUtility.WakeThreshold(actor)) && !curJob.forceSleep) { curDriver.asleep = false; } if (curDriver.asleep && gainRestAndHealth && actor.needs.rest != null) { float num; if (building_Bed != null && building_Bed.def.statBases.StatListContains(StatDefOf.BedRestEffectiveness)) { num = building_Bed.GetStatValue(StatDefOf.BedRestEffectiveness, true); } else { num = 0.8f; } float num2 = RestUtility.PawnHealthRestEffectivenessFactor(actor); num = 0.7f * num + 0.3f * num * num2; actor.needs.rest.TickResting(num); } if (actor.mindState.applyBedThoughtsTick != 0 && actor.mindState.applyBedThoughtsTick <= Find.TickManager.TicksGame) { Toils_LayDown.ApplyBedThoughts(actor); actor.mindState.applyBedThoughtsTick += 60000; actor.mindState.applyBedThoughtsOnLeave = true; } if (actor.IsHashIntervalTick(100) && !actor.Position.Fogged(actor.Map)) { if (curDriver.asleep) { MoteMaker.ThrowMetaIcon(actor.Position, actor.Map, ThingDefOf.Mote_SleepZ); } if (gainRestAndHealth && actor.health.hediffSet.GetNaturallyHealingInjuredParts().Any <BodyPartRecord>()) { MoteMaker.ThrowMetaIcon(actor.Position, actor.Map, ThingDefOf.Mote_HealingCross); } } if (actor.ownership != null && building_Bed != null && !building_Bed.Medical && !building_Bed.owners.Contains(actor)) { if (actor.Downed) { actor.Position = CellFinder.RandomClosewalkCellNear(actor.Position, actor.Map, 1, null); } actor.jobs.EndCurrentJob(JobCondition.Incompletable, true); return; } if (lookForOtherJobs && actor.IsHashIntervalTick(211)) { actor.jobs.CheckForJobOverride(); return; } }; layDown.defaultCompleteMode = ToilCompleteMode.Never; if (hasBed) { layDown.FailOnBedNoLongerUsable(bedOrRestSpotIndex); } layDown.AddFinishAction(delegate { Pawn actor = layDown.actor; JobDriver curDriver = actor.jobs.curDriver; if (actor.mindState.applyBedThoughtsOnLeave) { Toils_LayDown.ApplyBedThoughts(actor); } curDriver.layingDown = LayingDownState.NotLaying; curDriver.asleep = false; }); return(layDown); }
public bool MoveNext() { uint num = (uint)this.$PC; this.$PC = -1; switch (num) { case 0u: this.FailOnDespawnedOrNull(this.BedInd); this.FailOnDespawnedOrNull(this.PartnerInd); this.FailOn(() => !base.Partner.health.capacities.CanBeAwake); this.KeepLyingDown(this.BedInd); this.$current = Toils_Bed.ClaimBedIfNonMedical(this.BedInd, TargetIndex.None); if (!this.$disposing) { this.$PC = 1; } return(true); case 1u: this.$current = Toils_Bed.GotoBed(this.BedInd); if (!this.$disposing) { this.$PC = 2; } return(true); case 2u: { Toil preparePartner = new Toil(); preparePartner.initAction = delegate() { if (base.Partner.CurJob == null || base.Partner.CurJob.def != JobDefOf.Lovin) { Job newJob = new Job(JobDefOf.Lovin, this.pawn, base.Bed); base.Partner.jobs.StartJob(newJob, JobCondition.InterruptForced, null, false, true, null, null, false); this.ticksLeft = (int)(2500f * Mathf.Clamp(Rand.Range(0.1f, 1.1f), 0.1f, 2f)); } else { this.ticksLeft = 9999999; } }; preparePartner.defaultCompleteMode = ToilCompleteMode.Instant; this.$current = preparePartner; if (!this.$disposing) { this.$PC = 3; } return(true); } case 3u: doLovin = Toils_LayDown.LayDown(this.BedInd, true, false, false, false); doLovin.FailOn(() => base.Partner.CurJob == null || base.Partner.CurJob.def != JobDefOf.Lovin); doLovin.AddPreTickAction(delegate { this.ticksLeft--; if (this.ticksLeft <= 0) { base.ReadyForNextToil(); } else if (this.pawn.IsHashIntervalTick(100)) { MoteMaker.ThrowMetaIcon(this.pawn.Position, this.pawn.Map, ThingDefOf.Mote_Heart); } }); doLovin.AddFinishAction(delegate { Thought_Memory newThought = (Thought_Memory)ThoughtMaker.MakeThought(ThoughtDefOf.GotSomeLovin); this.pawn.needs.mood.thoughts.memories.TryGainMemory(newThought, base.Partner); this.pawn.mindState.canLovinTick = Find.TickManager.TicksGame + base.GenerateRandomMinTicksToNextLovin(this.pawn); }); doLovin.socialMode = RandomSocialMode.Off; this.$current = doLovin; if (!this.$disposing) { this.$PC = 4; } return(true); case 4u: this.$PC = -1; break; } return(false); }
public bool MoveNext() { uint num = (uint)this.$PC; this.$PC = -1; switch (num) { case 0u: if (base.FromBed) { this.KeepLyingDown(TargetIndex.A); this.$current = Toils_Bed.ClaimBedIfNonMedical(TargetIndex.A, TargetIndex.None); if (!this.$disposing) { this.$PC = 1; } return(true); } this.$current = Toils_Goto.GotoCell(TargetIndex.A, PathEndMode.OnCell); if (!this.$disposing) { this.$PC = 3; } return(true); case 1u: this.$current = Toils_Bed.GotoBed(TargetIndex.A); if (!this.$disposing) { this.$PC = 2; } return(true); case 2u: relax = Toils_LayDown.LayDown(TargetIndex.A, true, false, true, true); relax.AddFailCondition(() => !this.pawn.Awake()); break; case 3u: relax = new Toil(); relax.initAction = delegate() { this.faceDir = ((!this.job.def.faceDir.IsValid) ? Rot4.Random : this.job.def.faceDir); }; relax.handlingFacing = true; break; case 4u: this.$PC = -1; return(false); default: return(false); } relax.defaultCompleteMode = ToilCompleteMode.Delay; relax.defaultDuration = this.job.def.joyDuration; relax.AddPreTickAction(delegate { if (this.faceDir.IsValid) { this.pawn.rotationTracker.FaceCell(this.pawn.Position + this.faceDir.FacingCell); } this.pawn.GainComfortFromCellIfPossible(); JoyUtility.JoyTickCheckEnd(this.pawn, JoyTickFullJoyAction.EndJob, 1f, null); }); this.$current = relax; if (!this.$disposing) { this.$PC = 4; } return(true); }
internal void <> m__1() { Pawn actor = this.layDown.actor; Job curJob = actor.CurJob; JobDriver curDriver = actor.jobs.curDriver; Building_Bed building_Bed = (Building_Bed)curJob.GetTarget(this.bedOrRestSpotIndex).Thing; actor.GainComfortFromCellIfPossible(); if (!curDriver.asleep) { if (this.canSleep && ((actor.needs.rest != null && actor.needs.rest.CurLevel < RestUtility.FallAsleepMaxLevel(actor)) || curJob.forceSleep)) { curDriver.asleep = true; } } else if (!this.canSleep) { curDriver.asleep = false; } else if ((actor.needs.rest == null || actor.needs.rest.CurLevel >= RestUtility.WakeThreshold(actor)) && !curJob.forceSleep) { curDriver.asleep = false; } if (curDriver.asleep && this.gainRestAndHealth && actor.needs.rest != null) { float restEffectiveness; if (building_Bed != null && building_Bed.def.statBases.StatListContains(StatDefOf.BedRestEffectiveness)) { restEffectiveness = building_Bed.GetStatValue(StatDefOf.BedRestEffectiveness, true); } else { restEffectiveness = 0.8f; } actor.needs.rest.TickResting(restEffectiveness); } if (actor.mindState.applyBedThoughtsTick != 0 && actor.mindState.applyBedThoughtsTick <= Find.TickManager.TicksGame) { Toils_LayDown.ApplyBedThoughts(actor); actor.mindState.applyBedThoughtsTick += 60000; actor.mindState.applyBedThoughtsOnLeave = true; } if (actor.IsHashIntervalTick(100) && !actor.Position.Fogged(actor.Map)) { if (curDriver.asleep) { MoteMaker.ThrowMetaIcon(actor.Position, actor.Map, ThingDefOf.Mote_SleepZ); } if (this.gainRestAndHealth && actor.health.hediffSet.GetNaturallyHealingInjuredParts().Any <BodyPartRecord>()) { MoteMaker.ThrowMetaIcon(actor.Position, actor.Map, ThingDefOf.Mote_HealingCross); } } if (actor.ownership != null && building_Bed != null && !building_Bed.Medical && !building_Bed.owners.Contains(actor)) { if (actor.Downed) { actor.Position = CellFinder.RandomClosewalkCellNear(actor.Position, actor.Map, 1, null); } actor.jobs.EndCurrentJob(JobCondition.Incompletable, true); return; } if (this.lookForOtherJobs && actor.IsHashIntervalTick(211)) { actor.jobs.CheckForJobOverride(); return; } }
protected override IEnumerable <Toil> MakeNewToils() { Toil meditate = new Toil { socialMode = RandomSocialMode.Off }; if (FromBed) { this.KeepLyingDown(TargetIndex.B); meditate = Toils_LayDown.LayDown(TargetIndex.B, job.GetTarget(TargetIndex.B).Thing is Building_Bed, lookForOtherJobs: false, canSleep: false); } else { yield return(Toils_Goto.GotoCell(TargetIndex.A, PathEndMode.OnCell)); meditate.initAction = delegate { LocalTargetInfo target = job.GetTarget(TargetIndex.C); if (target.IsValid) { faceDir = target.Cell - pawn.Position; } else { faceDir = (job.def.faceDir.IsValid ? job.def.faceDir : Rot4.Random).FacingCell; } }; if (Focus != null) { meditate.FailOnDespawnedNullOrForbidden(TargetIndex.C); if (pawn.HasPsylink && Focus.Thing != null) { meditate.FailOn(() => Focus.Thing.GetStatValueForPawn(StatDefOf.MeditationFocusStrength, pawn) < float.Epsilon); } } meditate.handlingFacing = true; } meditate.defaultCompleteMode = ToilCompleteMode.Delay; meditate.defaultDuration = job.def.joyDuration; meditate.FailOn(() => !MeditationUtility.CanMeditateNow(pawn) || !MeditationUtility.SafeEnvironmentalConditions(pawn, base.TargetLocA, base.Map)); meditate.AddPreTickAction(delegate { bool flag = pawn.GetTimeAssignment() == TimeAssignmentDefOf.Meditate; if (job.ignoreJoyTimeAssignment) { Pawn_PsychicEntropyTracker psychicEntropy = pawn.psychicEntropy; if (!flag && psychicEntropy.TargetPsyfocus < psychicEntropy.CurrentPsyfocus && (psychicEntropy.TargetPsyfocus < job.psyfocusTargetLast || job.wasOnMeditationTimeAssignment)) { EndJobWith(JobCondition.InterruptForced); return; } job.psyfocusTargetLast = psychicEntropy.TargetPsyfocus; job.wasOnMeditationTimeAssignment = flag; } if (faceDir.IsValid && !FromBed) { pawn.rotationTracker.FaceCell(pawn.Position + faceDir); } MeditationTick(); if (ModLister.RoyaltyInstalled && MeditationFocusDefOf.Natural.CanPawnUse(pawn)) { int num = GenRadial.NumCellsInRadius(MeditationUtility.FocusObjectSearchRadius); for (int i = 0; i < num; i++) { IntVec3 c = pawn.Position + GenRadial.RadialPattern[i]; if (c.InBounds(pawn.Map)) { Plant plant = c.GetPlant(pawn.Map); if (plant != null && plant.def == ThingDefOf.Plant_TreeAnima) { plant.TryGetComp <CompSpawnSubplant>()?.AddProgress_NewTmp(AnimaTreeSubplantProgressPerTick); } } } } }); yield return(meditate); }
protected override IEnumerable <Toil> MakeNewToils() { Toil meditate = new Toil { socialMode = RandomSocialMode.Off }; if (FromBed) { this.KeepLyingDown(TargetIndex.B); meditate = Toils_LayDown.LayDown(TargetIndex.B, job.GetTarget(TargetIndex.B).Thing is Building_Bed, lookForOtherJobs: false, canSleep: false); } else { yield return(Toils_Goto.GotoCell(TargetIndex.A, PathEndMode.OnCell)); meditate.initAction = delegate { LocalTargetInfo target = job.GetTarget(TargetIndex.C); if (target.IsValid) { faceDir = target.Cell - pawn.Position; } else { faceDir = (job.def.faceDir.IsValid ? job.def.faceDir : Rot4.Random).FacingCell; } }; if (Focus != null) { meditate.FailOnDespawnedNullOrForbidden(TargetIndex.C); } meditate.handlingFacing = true; } meditate.defaultCompleteMode = ToilCompleteMode.Delay; meditate.defaultDuration = job.def.joyDuration; meditate.FailOn(() => !MeditationUtility.CanMeditateNow(pawn) || !MeditationUtility.SafeEnvironmentalConditions(pawn, base.TargetLocA, base.Map)); meditate.AddPreTickAction(delegate { if (faceDir.IsValid && !FromBed) { pawn.rotationTracker.FaceCell(pawn.Position + faceDir); } pawn.GainComfortFromCellIfPossible(); MeditationTick(); if (ModLister.RoyaltyInstalled && MeditationFocusDefOf.Natural.CanPawnUse(pawn)) { int num = GenRadial.NumCellsInRadius(MeditationUtility.FocusObjectSearchRadius); for (int i = 0; i < num; i++) { IntVec3 c = pawn.Position + GenRadial.RadialPattern[i]; if (c.InBounds(pawn.Map)) { Plant plant = c.GetPlant(pawn.Map); if (plant != null && plant.def == ThingDefOf.Plant_TreeAnima) { plant.TryGetComp <CompSpawnSubplant>()?.AddProgress(AnimaTreeSubplantProgressPerTick); } } } } }); meditate.AddFinishAction(delegate { if (sustainer != null) { sustainer.End(); } }); yield return(meditate); }