I have a simple JobGiver which makes a pawn either haul something to a stockpile, or find the nearest filth and clean it:
namespace RimWorld
{
public class JobGiver_Compulsion: ThinkNode_JobGiver
{
protected bool IgnoreForbid(Pawn pawn)
{
return pawn.InMentalState;
}
protected override Job TryGiveJob(Pawn pawn)
{
if (pawn.jobs.jobQueue.Count > 3 || pawn.CurJobDef == JobDefOf.Clean || pawn.CurJobDef == JobDefOf.HaulToCell || pawn.CurJobDef == JobDefOf.HaulToContainer)
{
return null;
}
if (Rand.Range(0f, 1f) < 0.5f)
{
List<Thing> filth = pawn.Map.listerFilthInHomeArea.FilthInHomeArea;
Filth t = GetClosestFilth(pawn, filth);
if (CanClean(pawn, t))
{
LocalTargetInfo lt = new LocalTargetInfo(t);
return new Job(JobDefOf.Clean, lt);
}
}
if (Rand.Range(0f, 1f) < 0.5f)
{
Predicate<Thing> validator = (Thing t) => !t.IsForbidden(pawn) && HaulAIUtility.PawnCanAutomaticallyHaulFast(pawn, t, true);
Thing thing = GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map, pawn.Map.listerHaulables.ThingsPotentiallyNeedingHauling(), PathEndMode.OnCell, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), 9999f, validator, null);
if (thing != null)
{
return HaulAIUtility.HaulToStorageJob(pawn, thing);
}
}
return null;
}
Filth GetClosestFilth(Pawn pawn, List<Thing> filth)
{
Thing result = null;
int minDist = int.MaxValue;
foreach (Thing t in filth)
{
int dist = IntVec3Utility.ManhattanDistanceFlat(pawn.PositionHeld, t.PositionHeld);
if (dist < minDist)
{
minDist = dist;
result = t;
}
}
return result as Filth;
}
bool CanClean(Pawn pawn, Thing t)
{
Filth filth = t as Filth;
return filth != null && pawn.Map.areaManager.Home[filth.Position] && pawn.CanReserveAndReach(t, PathEndMode.ClosestTouch, Danger.Deadly, 1);
}
}
}
However, it seems that the cleaning job which worked fine in 0.9 does not work fine in 1.0. Maybe something got changed? The hauling job works fine.
Here's what i see when i'm debugging:
25594 Burton: StartJob [Clean (Job_12335) A=Thing_Filth_RubbleRock28550] lastJobEndCondition=None, jobGiver=RimWorld.JobGiver_Compulsion, cancelBusyStances=False
25594 Burton: JobDriver_CleanFilth ends current job Clean (Job_12335) A=Thing_Filth_RubbleRock28550 because of toils[1].endConditions[0]
My decompiler won't show me the toils associated to JobDriver_CleanFilth. Can anyone tell me why the toil is failing?
The pawn clearly has a path to all of the filth in the home area in my test map (and my job giver also verifies that a path is available). So it's not an issue of impossible-to-reach filth. Some other end condition is being met before the pawn can clean the filth.
Anyone? :(
The only exit condition I see in JobDriver_CleanFilth is not having anything left to clean. I've copied the pre toil reservation code and the first few lines of make new toils. This is the only place I see a success condition and the defaultcompletemode is never. Perhaps the target queue is not having a job added to it? Did you consider inheriting from WorkGiver_Scanner instead of ThinkNode_JobGiver or is this supposed to be for a mental state?
public override bool TryMakePreToilReservations(bool errorOnFailed)
{
this.pawn.ReserveAsManyAsPossible(this.job.GetTargetQueue(TargetIndex.A), this.job, 1, -1, null);
return true;
}
protected override IEnumerable<Toil> MakeNewToils()
{
Toil initExtractTargetFromQueue = Toils_JobTransforms.ClearDespawnedNullOrForbiddenQueuedTargets(TargetIndex.A, null);
yield return initExtractTargetFromQueue;
yield return Toils_JobTransforms.SucceedOnNoTargetInQueue(TargetIndex.A);
This is meant to be a mental state.... This code worked fine in 0.9, the 1.0 update caused it to stop working. I assume maybe the cleaning jobs were altered in the 1.0 update?