-
Notifications
You must be signed in to change notification settings - Fork 1
4) JobDriver
The JobDriver contains the step by step instructions for doing the job. A JobDrivers contain at least these two functions:
public override bool TryMakePreToilReservations()
protected override IEnumerable<Toil> MakeNewToils()
By default, the game save the current Toil. If it's important to save the state or progress of the Toil, use the scribe
in public override void ExposeData()
to store your variables.
If your Job should report a different inspect string based on conditions, use public override string GetReport()
, as seen in JobDriver_Skygaze
(watching eclipse/sunset/aurora).
The Toils
are evaluated only once, when the job is started. That means that when your job loops, it doesn't re-evaluate any if
statements in the IEnumerable
. You have to treat yielded toils like a set of unchanging building blocks, and the logic that happens needs to happen in conditional toil jumps. If your job doesn't loop, this is no problem. If it does loop, read the chapter on Toils.
namespace CatsAreJerks
{
class JobDriver_PetTheCat : JobDriver
{
//we'll be defining CatToPet as TargetIndex.A
//It shows up as TargetIndex.A in decompiled code, but this is easy to mistype
//This also prevents confusion when our TargetIndex.A contains both a List and a Thing.
//Likewise, we define our NuzzleDuration in here too, since that'll be easier to change.
private const TargetIndex CatToPet = TargetIndex.A;
private const int NuzzleDuration = 500;
//reserve the cat, so other pawns can't pet it. This is OUR cat!
public override bool TryMakePreToilReservations()
{
return this.pawn.Reserve(this.job.GetTarget(CatToPet), this.job, 1, -1, null);
}
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);
});
}
}
}