Skip to content

1b) Job Assignment via WorkGiver

Mehni edited this page Feb 25, 2018 · 4 revisions

Much the same as the JobGiver. In fact, it's JobGiver_Work that defers to a WorkGiver. Almost all WorkGivers derive from WorkGiver_Scanner which in turn derives from WorkGiver. WorkGiver provides a few basic checks for an early-out before the WorkGiver_Scanner. Depending on the implementation of your WorkGiver, you can use its PotentialWorkThingRequest as a filter, use that to override the HasJobOnThing boolean, or simply override JobOnThing and return a new Job.

Pawns must do a .CanReserve() check before being assigned the job. They'll do the actual reservation in the JobDriver, but this preliminary check will avoid issues.

Below is a truncated early version of Pick Up And Haul. This old version was quite buggy in practice, but for illustration purposes it works fine.

namespace PickUpThatCan
{
    //inheriting from WorkGiver_HaulGeneral gives us the opportunity to re-use its WorkGiver_Scanner, lessening the load.
    public class WorkGiver_HaulToInventory : WorkGiver_HaulGeneral
    {
        //provide an early out using the results from the PotentialWorkThingsGlobal from the parent, and some simple checks.
        public override bool ShouldSkip(Pawn pawn)
        {
            return base.ShouldSkip(pawn) && (pawn.Faction != Faction.OfPlayer) && (!pawn.RaceProps.Humanlike);
        }

        //override JobOnThing, return a new Job if you find something. 
        //This WorkGiver is special, in that it returns different Jobs depending on the state.
        public override Job JobOnThing(Pawn pawn, Thing t, bool forced = false)
        {
            //we don't want colonists stuffing corpses in their inventory.
            if (t is Corpse) 
            {
                return null;
            }

            //PawnCanAutomaticallyHaulFast contains a CanReserve.
            if (!HaulAIUtility.PawnCanAutomaticallyHaulFast(pawn, t, forced)) 
            {
                return null;
            }
            
            //if pawns are heavily encumbered, they need to haul.
            if (MassUtility.EncumbrancePercent(pawn) >= 0.90f) 
            {
                Job haul = HaulAIUtility.HaulToStorageJob(pawn, t);
                pawn.inventory.UnloadEverything = true;
                return haul;
            }

            //this flag got set when the colonist hauled one last item.
            if (pawn.inventory.UnloadEverything == true) 
            {
                return new Job(JobDefOf.UnloadYourInventory);
            }

            pawn.inventory.UnloadEverything = false;
            Job job = new Job(JobDefOf.TakeInventory, t);
            job.count = MassUtility.CountToPickUpUntilOverEncumbered(pawn, t);
            return job;
        }
    }
}
Clone this wiki locally