How can I get the pawn working at a "building"

Started by svend, September 02, 2021, 07:13:17 PM

Previous topic - Next topic

svend

Hello,

I have a student's desk that's linked to a teacher's desk. Both extend Building_WorkTable.
I can get pawns to study and teach (new work types, etc) at the stations, but I want to do the following:
QuoteOnly allow a pawn X to study subject N at a student's desk A if A is linked to a teacher's desk B where pawn Y is teaching subject N.
I'm able to get the linked teacher's desk (as the Building_TeacherDesk type extending Building_WorkTable), but is there a way to get the pawn working at the Building_WorkTable?
I've tried using GetAssignedPawn, but that return null regardless of whether a pawn is working there, so I presume this isn't (AssignableUtility1) isn't applicable to Building_WorkTable?

Does anyone know if/how it would be possible to get the pawn?

Cheers,
Svend

1 I've just worked out that this is for assigning like you assign beds, so not applicable for this situation.

svend

I've found a way to do this using

Map.reservationManager.ReservationsReadOnly.Where(reservation => reservation.Target.HasThing && reservation.Target.Thing == teacherDesk)

This works. Is it the best way of doing it? :)

RawCode

you should study logic behind jobs, start from "JobDriver_Research" and follow around.

most effective way will be "disabling and enabling" student desks based on state of teacher desk (that is always enabled)

your current code will trigger as soon as pawn took job, ever if he is on other part of map and not actually doing job (and will take few hours of walking to reach it)

svend

Thank yoiu RawCode! That sounds like good advice :)

I did notice that the pawns start studying as soon as a teacher is heading the teachers desk, and they might get there before him. This isn't so much of a problem as they only actually learn anything when the teacher is teaching (it might even be preferrable as it means the class will gather as soon as the teacher is on his way, which seems to mimic normal behaviour more, instead of having the teacher go in first and start working at the desk and _then_ students heading there... anyway, that's a lot to consider :) ).

However, I'd also like have the students stop studying if the teacher stops teaching for any reason. Currently they will continue studying until they get hungry, tired or need recreation :P Maybe I can also do that through my JobDriver :)

svend

#4
I've worked out how to do the second part as well, by adding this inside the tickAction setup in my JobDriver's MakeNewToils:

if (!desk.CanStudy(TeachingSubjectDef.FromJobDef(job.def))){
    EndJobWith(JobCondition.InterruptForced);
}


(Where the CanStudy is checking if the teacher is teaching the required subject) :)

Edit:

Actually, I think I've found an even nicer way of doing it, by setting a FailOn callback on the Toil:

studying.FailOn(() => !desk.CanStudy(TeachingSubjectDef.FromJobDef(job.def)));

RawCode

it will be helpful (for other people) if you post entire code or leave workshop\git hub link to your mod.

also you may want to check syntax sugar behind your lambda, because real code is very different compared to what you see in IDE.
(any decompiler in IL mode will work)

svend

Sure, if you think it might be helpful :)

This is my MakeNewToils at the moment... it's still WIP :)


        protected override IEnumerable<Toil> MakeNewToils()
        {
            this.FailOnDespawnedNullOrForbidden(TargetIndex.A);
            yield return Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell);
            Toil teaching = new Toil();
            int progress = 0;
            Building_TeacherDesk desk = TeachersTable;
            teaching.tickAction = () =>
            {
                Pawn actor = teaching.actor;
                MyFind.teachingManager.TeachingPerformed(actor.GetStatValue(StatDefOf.ResearchSpeed) * TargetThingA.GetStatValue(StatDefOf.ResearchSpeedFactor), actor, desk);
                actor.skills.Learn(SkillDefOf.Intellectual, 0.05f);
                actor.skills.Learn(SkillDefOf.Social, 0.05f);
                actor.GainComfortFromCellIfPossible(true);
                TeachStudents(desk);
                ++progress;
            };
            teaching.FailOnCannotTouch(TargetIndex.A, PathEndMode.InteractionCell);
            teaching.WithEffect(EffecterDefOf.Research, TargetIndex.A);
            teaching.WithProgressBar(TargetIndex.A, () =>
            {
                return progress / 1000f;
            });
            teaching.defaultCompleteMode = ToilCompleteMode.Delay;
            teaching.defaultDuration = 4000;
            teaching.activeSkill = () => SkillDefOf.Intellectual;
            yield return teaching;
            yield return Toils_General.Wait(2);
        }