internal static IEnumerable <Toil> _MakeNewToils(this JobDriver_SocialRelax obj)
        {
            obj.EndOnDespawnedOrNull(GatherSpotParentInd, JobCondition.Incompletable);

            if (obj.HasChair())
            {
                obj.EndOnDespawnedOrNull(ChairOrSpotInd, JobCondition.Incompletable);
            }
            yield return(Toils_Reserve.Reserve(ChairOrSpotInd, 1));

            if (obj.HasDrinkOrDispenser())
            {
                obj.FailOnDestroyedNullOrForbidden(OptionalDrinkInd);
                yield return(Toils_Reserve.Reserve(OptionalDrinkInd, 1));

                if (obj.IsDispenser())
                {
                    yield return(Toils_Goto.GotoThing(OptionalDrinkInd, PathEndMode.InteractionCell));

                    yield return(Toils_FoodSynthesizer.TakeAlcoholFromSynthesizer(OptionalDrinkInd, obj.pawn));
                }
                else
                {
                    yield return(Toils_Goto.GotoThing(OptionalDrinkInd, PathEndMode.OnCell));

                    yield return(Toils_Haul.StartCarryThing(OptionalDrinkInd));
                }
            }

            yield return(Toils_Goto.GotoCell(ChairOrSpotInd, PathEndMode.OnCell));

            var relax = new Toil()
            {
                defaultCompleteMode = ToilCompleteMode.Delay,
                defaultDuration     = obj.pawn.CurJob.def.joyDuration,
                tickAction          = () =>
                {
                    var pawnDrawer     = obj.pawn.GetPawnDrawTracker();
                    var pawnFaceTarget = obj.ClosestGatherSpotParentCell();
                    pawnDrawer.rotator.FaceCell(pawnFaceTarget);
                    obj.pawn.GainComfortFromCellIfPossible();
                    JoyUtility.JoyTickCheckEnd(obj.pawn, JoyTickFullJoyAction.GoToNextToil, 1f);
                }
            };

            relax.AddFinishAction(() =>
                                  JoyUtility.TryGainRecRoomThought(obj.pawn)
                                  );
            relax.socialMode = RandomSocialMode.SuperActive;
            yield return(relax);

            if (obj.IsDrink())
            {
                yield return(Toils_Ingest.FinalizeIngest(obj.pawn, OptionalDrinkInd));
            }
        }
Exemplo n.º 2
0
        static IEnumerable <Toil> _MakeToils(this JobDriver_SocialRelax driver)
        {
            //driver.EndOnDespawnedOrNull(TargetIndex.A, JobCondition.Incompletable);
            driver.AddEndCondition(delegate
            {
                LocalTargetInfo target = driver.GetActor().jobs.curJob.GetTarget(TargetIndex.A);
                Thing thing            = target.Thing;
                if (thing == null && target.IsValid || thing is Filth)
                {
                    return(JobCondition.Ongoing);
                }
                if (thing == null || !thing.Spawned || thing.Map != driver.GetActor().Map)
                {
                    return(JobCondition.Incompletable);
                }
                return(JobCondition.Ongoing);
            });

            if (driver.HasChair())
            {
                driver.EndOnDespawnedOrNull(TargetIndex.B, JobCondition.Incompletable);
            }
            if (driver.HasDrink())
            {
                driver.FailOnDestroyedNullOrForbidden(TargetIndex.C);
                yield return(Toils_Goto.GotoThing(TargetIndex.C, PathEndMode.OnCell).FailOnSomeonePhysicallyInteracting(TargetIndex.C));

                yield return(Toils_Haul.StartCarryThing(TargetIndex.C, false, false, false));
            }

            //cleaning patch
            Toil GoToRelaxPlace = Toils_Goto.GotoCell(TargetIndex.B, PathEndMode.OnCell);

            if (Settings.adv_cleaning_ingest && !Utility.IncapableOfCleaning(driver.pawn))
            {
                Toil FilthList = new Toil();
                FilthList.initAction = delegate()
                {
                    Job curJob = FilthList.actor.jobs.curJob;
                    if (curJob.GetTargetQueue(TargetIndex.A).NullOrEmpty())
                    {
                        LocalTargetInfo     A = curJob.GetTarget(TargetIndex.A);
                        IEnumerable <Filth> l = Utility.SelectAllFilth(FilthList.actor, A, Settings.adv_clean_num);
                        Utility.AddFilthToQueue(curJob, TargetIndex.A, l, FilthList.actor);
                        FilthList.actor.ReserveAsManyAsPossible(curJob.GetTargetQueue(TargetIndex.A), curJob);
                        curJob.targetQueueA.Add(A);
                    }
                };
                yield return(FilthList);

                yield return(Toils_Jump.JumpIf(GoToRelaxPlace, () => driver.job.GetTargetQueue(TargetIndex.A).NullOrEmpty()));

                Toil CleanFilthList = Toils_JobTransforms.ClearDespawnedNullOrForbiddenQueuedTargets(TargetIndex.A, null);
                yield return(CleanFilthList);

                yield return(Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.A, true));

                yield return(Toils_Jump.JumpIf(GoToRelaxPlace, () => driver.job.GetTargetQueue(TargetIndex.A).NullOrEmpty()));

                yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch).JumpIfDespawnedOrNullOrForbidden(TargetIndex.A, CleanFilthList).JumpIfOutsideHomeArea(TargetIndex.A, CleanFilthList));

                //
                driver.job.GetTargetQueue(TargetIndex.B).Add(new IntVec3(0, 0, 0));
                Toil clean = new Toil();
                clean.initAction = delegate()
                {
                    Filth filth   = clean.actor.jobs.curJob.GetTarget(TargetIndex.A).Thing as Filth;
                    var   progQue = clean.actor.jobs.curJob.GetTargetQueue(TargetIndex.B);
                    progQue[0] = new IntVec3(0, 0, (int)filth.def.filth.cleaningWorkToReduceThickness * filth.thickness);
                };
                clean.tickAction = delegate()
                {
                    Filth   filth   = clean.actor.jobs.curJob.GetTarget(TargetIndex.A).Thing as Filth;
                    var     progQue = clean.actor.jobs.curJob.GetTargetQueue(TargetIndex.B);
                    IntVec3 iv      = progQue[0].Cell;
                    iv.x += 1;
                    iv.y += 1;
                    if (iv.x > filth.def.filth.cleaningWorkToReduceThickness)
                    {
                        filth.ThinFilth();
                        iv.x = 0;
                        if (filth.Destroyed)
                        {
                            clean.actor.records.Increment(RecordDefOf.MessesCleaned);
                            driver.ReadyForNextToil();
                            return;
                        }
                    }
                    progQue[0] = iv;
                };
                clean.defaultCompleteMode = ToilCompleteMode.Never;
                clean.WithEffect(EffecterDefOf.Clean, TargetIndex.A);
                clean.WithProgressBar(TargetIndex.A,
                                      delegate()
                {
                    var q        = driver.job.GetTargetQueue(TargetIndex.B)[0];
                    float result = (float)q.Cell.y / q.Cell.z;
                    return(result);
                }
                                      , true, -0.5f);
                clean.PlaySustainerOrSound(() => SoundDefOf.Interact_CleanFilth);
                clean.JumpIfDespawnedOrNullOrForbidden(TargetIndex.A, CleanFilthList);
                clean.JumpIfOutsideHomeArea(TargetIndex.A, CleanFilthList);
                yield return(clean);

                yield return(Toils_Jump.Jump(CleanFilthList));
            }

            yield return(GoToRelaxPlace);

            //
            float    joyoffset;
            ThingDef def = driver.job.GetTarget(TargetIndex.C).HasThing ? driver.job.GetTarget(TargetIndex.C).Thing.def : null;

            if (Settings.social_relax_economy && def != null && def.IsIngestible)
            {
                joyoffset = def.ingestible.joy * driver.pawn.needs.joy.tolerances.JoyFactorFromTolerance(def.ingestible.JoyKind);
                //minimum amount of time for action to perform
                float baseoffset = Mathf.Max(0.36f / 2500f * def.ingestible.baseIngestTicks, 0.36f / 2500f * 60f * 4f);
                float expected   = 1f - driver.pawn.needs.joy.CurLevel - joyoffset;
                if (expected < baseoffset)
                {
                    float expected2 = 1f - driver.pawn.needs.joy.CurLevel - baseoffset;
                    if (expected2 < 0f)
                    {
                        joyoffset = 0f;
                    }
                    else if (expected2 < baseoffset)
                    {
                        joyoffset = baseoffset - expected2;
                    }
                    else
                    {
                        joyoffset += expected - baseoffset;
                    }
                }
            }
            else
            {
                joyoffset = 0f;
            }

            Toil toil = new Toil();

            toil.tickAction = delegate()
            {
                driver.pawn.rotationTracker.FaceCell(driver.ClosestGatherSpotParentCell());
                driver.pawn.GainComfortFromCellIfPossible(false);
                JoyTickCheckEndOffset(driver.pawn, joyoffset, JoyTickFullJoyAction.GoToNextToil);
            };
            toil.handlingFacing      = true;
            toil.defaultCompleteMode = ToilCompleteMode.Delay;
            toil.defaultDuration     = driver.job.def.joyDuration;
            toil.AddFinishAction(delegate
            {
                JoyUtility.TryGainRecRoomThought(driver.pawn);
            });
            toil.socialMode = RandomSocialMode.SuperActive;
            Toils_Ingest.AddIngestionEffects(toil, driver.pawn, TargetIndex.C, TargetIndex.None);
            yield return(toil);

            if (driver.HasDrink())
            {
                yield return(Toils_Ingest.FinalizeIngest(driver.pawn, TargetIndex.C));
            }
            yield break;
        }