protected override IEnumerable <Toil> MakeNewToils() { // Set fail conditions this.EndOnDespawnedOrNull(TargetIndex.A, JobCondition.Incompletable); // Reference the tick manager so Find isn't constantly called TickManager tickMan = Find.TickManager; // Go to the bench yield return(Toils_Goto.GotoCell(BenchInd, PathEndMode.OnCell)); // Set up the toil JobDef joyJob = DefDatabase <JobDef> .GetNamed("ZEN_SitAtScenicBench"); Toil sitAtBench = new Toil() { socialMode = RandomSocialMode.Normal, initAction = () => { surroundingBeauty = BeautyUtility.AverageBeautyPerceptible(pawn.Position, Map); }, tickAction = () => { pawn.needs.joy.GainJoy(joyJob.joyGainRate * 0.000144f, joyJob.joyKind); pawn.needs.joy.GainJoy(Mathf.Min(Mathf.Max(surroundingBeauty / 2f, 0.3f), 2.5f) * 0.000144f, joyJob.joyKind); // Gain comfort from sitting on the bench pawn.GainComfortFromCellIfPossible(); // Occasionally look in a different direction, observing the surroundings if (tickMan.TicksGame % 250 == 0) { pawn.rotationTracker.FaceCell(GenAdj.RandomAdjacentCellCardinal(pawn.Position)); } // End this job once the pawn has maxed out their joy if (pawn.needs.joy.CurLevel > 0.9999f) { pawn.jobs.curDriver.EndJobWith(JobCondition.Succeeded); } }, defaultCompleteMode = ToilCompleteMode.Delay, defaultDuration = job.def.joyDuration }; sitAtBench.AddFinishAction(() => { Thought_Memory memory; // If the scenery was very beautiful, give a better memory, if (surroundingBeauty > 5f) { memory = (Thought_Memory)ThoughtMaker.MakeThought(ThoughtDef.Named("ZEN_EnjoyedBeautifulScenery")); } // or if the scenery was okay, give a normal memory, else if (surroundingBeauty > 0) { memory = (Thought_Memory)ThoughtMaker.MakeThought(ThoughtDef.Named("ZEN_EnjoyedScenery")); } // otherwise, give a bad memory else { memory = (Thought_Memory)ThoughtMaker.MakeThought(ThoughtDef.Named("ZEN_DidNotEnjoyScenery")); } pawn.needs.mood.thoughts.memories.TryGainMemory(memory); }); // Sit at the bench, enjoying the scenery yield return(sitAtBench); }