public static Toil GotoBed(TargetIndex bedIndex)
        {
            Toil gotoBed = new Toil();

            gotoBed.initAction = delegate
            {
                Pawn         actor2 = gotoBed.actor;
                Building_Bed bed    = (Building_Bed)actor2.CurJob.GetTarget(bedIndex).Thing;
                IntVec3      bedSleepingSlotPosFor = RestUtility.GetBedSleepingSlotPosFor(actor2, bed);
                if (actor2.Position == bedSleepingSlotPosFor)
                {
                    actor2.jobs.curDriver.ReadyForNextToil();
                }
                else
                {
                    actor2.pather.StartPath(RestUtility.GetBedSleepingSlotPosFor(actor2, bed), PathEndMode.OnCell);
                }
            };
            gotoBed.tickAction = delegate
            {
                Pawn         actor         = gotoBed.actor;
                Building_Bed building_Bed  = (Building_Bed)actor.CurJob.GetTarget(bedIndex).Thing;
                Pawn         curOccupantAt = building_Bed.GetCurOccupantAt(actor.pather.Destination.Cell);
                if (curOccupantAt != null && curOccupantAt != actor)
                {
                    actor.pather.StartPath(RestUtility.GetBedSleepingSlotPosFor(actor, building_Bed), PathEndMode.OnCell);
                }
            };
            gotoBed.defaultCompleteMode = ToilCompleteMode.PatherArrival;
            gotoBed.FailOnBedNoLongerUsable(bedIndex);
            return(gotoBed);
        }
示例#2
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            // Claim bed if possible.
            if (this.job.GetTarget(TargetIndex.A).HasThing)
            {
                yield return(Toils_Bed.ClaimBedIfNonMedical(TargetIndex.A, TargetIndex.None));
            }

            Toil toil = new Toil
            {
                defaultCompleteMode = ToilCompleteMode.Never,
                actor = pawn,

                // ...

                initAction =
                    delegate
                {
                    // Check if our pawn is even in the bed.
                    if (!TargetA.Thing.OccupiedRect().Contains(pawn.Position))
                    {       // Nope.
                        base.ReadyForNextToil();
                    }

                    // Set our posture to laying in bed so we aren't downed.
                    pawn.jobs.posture = PawnPosture.LayingInBed;
                    this.asleep       = false;
                },

                // ...

                tickAction =
                    delegate
                {
                    // If the pawn is in bed spawn a healing mote.
                    #region Original RW Code

                    if (pawn.IsHashIntervalTick(100) && !pawn.Position.Fogged(pawn.Map))
                    {
                        if (pawn.health.hediffSet.GetNaturallyHealingInjuredParts().Any <BodyPartRecord>())
                        {
                            MoteMaker.ThrowMetaIcon(pawn.Position, pawn.Map, ThingDefOf.Mote_HealingCross);
                        }
                    }

                    #endregion Original RW Code
                }
            };

            toil.FailOnBedNoLongerUsable(TargetIndex.A);

            yield return(toil);

            yield break;
        }
示例#3
0
        public static Toil LayDown(TargetIndex bedOrRestSpotIndex, bool hasBed, bool lookForOtherJobs, bool canSleep = true, bool gainRestAndHealth = true)
        {
            Toil layDown = new Toil();

            layDown.initAction = delegate()
            {
                Pawn actor = layDown.actor;
                actor.pather.StopDead();
                JobDriver curDriver = actor.jobs.curDriver;
                if (hasBed)
                {
                    if (!((Building_Bed)actor.CurJob.GetTarget(bedOrRestSpotIndex).Thing).OccupiedRect().Contains(actor.Position))
                    {
                        Log.Error("Can't start LayDown toil because pawn is not in the bed. pawn=" + actor, false);
                        actor.jobs.EndCurrentJob(JobCondition.Errored, true, true);
                        return;
                    }
                    actor.jobs.posture = PawnPosture.LayingInBed;
                }
                else
                {
                    actor.jobs.posture = PawnPosture.LayingOnGroundNormal;
                }
                curDriver.asleep = false;
                if (actor.mindState.applyBedThoughtsTick == 0)
                {
                    actor.mindState.applyBedThoughtsTick    = Find.TickManager.TicksGame + Rand.Range(2500, 10000);
                    actor.mindState.applyBedThoughtsOnLeave = false;
                }
                if (actor.ownership != null && actor.CurrentBed() != actor.ownership.OwnedBed)
                {
                    ThoughtUtility.RemovePositiveBedroomThoughts(actor);
                }
                CompCanBeDormant comp = actor.GetComp <CompCanBeDormant>();
                if (comp != null)
                {
                    comp.ToSleep();
                }
            };
            layDown.tickAction = delegate()
            {
                Pawn         actor        = layDown.actor;
                Job          curJob       = actor.CurJob;
                JobDriver    curDriver    = actor.jobs.curDriver;
                Building_Bed building_Bed = (Building_Bed)curJob.GetTarget(bedOrRestSpotIndex).Thing;
                actor.GainComfortFromCellIfPossible(false);
                if (!curDriver.asleep)
                {
                    if (canSleep && ((actor.needs.rest != null && actor.needs.rest.CurLevel < RestUtility.FallAsleepMaxLevel(actor)) || curJob.forceSleep))
                    {
                        curDriver.asleep = true;
                    }
                }
                else if (!canSleep)
                {
                    curDriver.asleep = false;
                }
                else if ((actor.needs.rest == null || actor.needs.rest.CurLevel >= RestUtility.WakeThreshold(actor)) && !curJob.forceSleep)
                {
                    curDriver.asleep = false;
                }
                if (curDriver.asleep && gainRestAndHealth && actor.needs.rest != null)
                {
                    float restEffectiveness;
                    if (building_Bed != null && building_Bed.def.statBases.StatListContains(StatDefOf.BedRestEffectiveness))
                    {
                        restEffectiveness = building_Bed.GetStatValue(StatDefOf.BedRestEffectiveness, true);
                    }
                    else
                    {
                        restEffectiveness = StatDefOf.BedRestEffectiveness.valueIfMissing;
                    }
                    actor.needs.rest.TickResting(restEffectiveness);
                }
                if (actor.IsHashIntervalTick(100) && !actor.Position.Fogged(actor.Map))
                {
                    if (curDriver.asleep)
                    {
                        MoteMaker.ThrowMetaIcon(actor.Position, actor.Map, ThingDefOf.Mote_SleepZ);
                    }
                    if (gainRestAndHealth && actor.health.hediffSet.GetNaturallyHealingInjuredParts().Any <BodyPartRecord>())
                    {
                        MoteMaker.ThrowMetaIcon(actor.Position, actor.Map, ThingDefOf.Mote_HealingCross);
                    }
                }
                if (actor.ownership != null && building_Bed != null && !building_Bed.Medical && !building_Bed.OwnersForReading.Contains(actor))
                {
                    if (actor.Downed)
                    {
                        actor.Position = CellFinder.RandomClosewalkCellNear(actor.Position, actor.Map, 1, null);
                    }
                    actor.jobs.EndCurrentJob(JobCondition.Incompletable, true, true);
                    return;
                }
                if (lookForOtherJobs && actor.IsHashIntervalTick(211))
                {
                    actor.jobs.CheckForJobOverride();
                    return;
                }
            };
            layDown.AddEndCondition(delegate()
            {
                Pawn actor = layDown.actor;
                if (!actor.health.hediffSet.HasHediff(HediffDefOf.Hypothermia))
                {
                    return(JobCondition.Succeeded);
                }
                else
                {
                    return(JobCondition.Ongoing);
                }
            });
            layDown.defaultCompleteMode = ToilCompleteMode.Never;
            if (hasBed)
            {
                layDown.FailOnBedNoLongerUsable(bedOrRestSpotIndex);
            }
            layDown.AddFinishAction(delegate
            {
                Pawn actor          = layDown.actor;
                JobDriver curDriver = actor.jobs.curDriver;

                curDriver.asleep = false;
            });
            return(layDown);
        }
        // A: TargetThing
        protected override IEnumerable <Toil> MakeNewToils()
        {
            yield return(Toils_Bed.ClaimBedIfNonMedical(TargetIndex.A, TargetIndex.None));

            yield return(Toils_Bed.GotoBed(TargetIndex.A));

            this.goalNeedRest = napRestRate + (1 - napRestRate) * pawn.needs.rest.CurLevelPercentage;


            Toil nap = new Toil();

            nap.defaultCompleteMode = ToilCompleteMode.Never;
            nap.FailOnBedNoLongerUsable(TargetIndex.A);
            nap.socialMode = RandomSocialMode.Off;
            nap.initAction = () =>
            {
                pawn.pather.StopDead();
                if (!Bed.OccupiedRect().Contains(pawn.Position))
                {
                    Log.Error("Can't start LayDown toil because pawn is not in the bed. pawn=" + pawn, false);
                    pawn.jobs.EndCurrentJob(JobCondition.Errored, true);
                    return;
                }

                pawn.jobs.posture = PawnPosture.LayingInBed;

                this.asleep = false;
                if (pawn.mindState.applyBedThoughtsTick == 0)
                {
                    pawn.mindState.applyBedThoughtsTick    = Find.TickManager.TicksGame + Rand.Range(2500, 10000);
                    pawn.mindState.applyBedThoughtsOnLeave = false;
                }

                if (pawn.ownership != null && pawn.CurrentBed() != pawn.ownership.OwnedBed)
                {
                    ThoughtUtility.RemovePositiveBedroomThoughts(pawn);
                }
            };

            nap.tickAction = () =>
            {
                pawn.GainComfortFromCellIfPossible();

                if (!this.asleep)
                {
                    if (pawn.needs.rest != null && pawn.needs.rest.CurLevel < RestUtility.FallAsleepMaxLevel(pawn))
                    {
                        this.asleep = true;
                    }
                }
                else if (pawn.needs.rest == null || pawn.needs.rest.CurLevelPercentage >= this.goalNeedRest)
                {
                    this.asleep = false;
                }

                if (this.asleep && pawn.needs.rest != null)
                {
                    float restEffectiveness;
                    if (Bed != null && Bed.def.statBases.StatListContains(StatDefOf.BedRestEffectiveness))
                    {
                        restEffectiveness = Bed.GetStatValue(StatDefOf.BedRestEffectiveness, true);
                    }
                    else
                    {
                        restEffectiveness = 0.8f;
                    }

                    pawn.needs.rest.TickResting(restEffectiveness);
                }

                if (pawn.mindState.applyBedThoughtsTick != 0 && pawn.mindState.applyBedThoughtsTick <= Find.TickManager.TicksGame)
                {
                    ApplyBedThoughts(pawn);
                    pawn.mindState.applyBedThoughtsTick   += 60000;
                    pawn.mindState.applyBedThoughtsOnLeave = true;
                }

                if (pawn.IsHashIntervalTick(100) && !pawn.Position.Fogged(pawn.Map))
                {
                    if (this.asleep)
                    {
                        FleckMaker.ThrowMetaIcon(pawn.Position, pawn.Map, FleckDefOf.SleepZ);
                    }

                    if (pawn.health.hediffSet.GetNaturallyHealingInjuredParts().Any <BodyPartRecord>())
                    {
                        FleckMaker.ThrowMetaIcon(pawn.Position, pawn.Map, FleckDefOf.HealingCross);
                    }
                }

                if (pawn.ownership != null && Bed != null && !Bed.Medical && !Bed.OwnersForReading.Contains(pawn))
                {
                    if (pawn.Downed)
                    {
                        pawn.Position = CellFinder.RandomClosewalkCellNear(pawn.Position, pawn.Map, 1, null);
                    }

                    pawn.jobs.EndCurrentJob(JobCondition.Incompletable, true);
                    return;
                }

                if (pawn.IsHashIntervalTick(211))
                {
                    pawn.jobs.CheckForJobOverride();
                    return;
                }
            };

            nap.AddFinishAction(() =>
            {
                if (pawn.mindState.applyBedThoughtsOnLeave)
                {
                    ApplyBedThoughts(pawn);
                }

                this.asleep = false;
            });

            yield return(nap);

            yield break;
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            setup_ticks();

            this.FailOnDespawnedOrNull(iTarget);
            this.FailOnDespawnedNullOrForbidden(iBed);
            this.FailOn(() => !pawn.CanReserveAndReach(Partner, PathEndMode.Touch, Danger.Deadly));
            this.FailOn(() => pawn.Drafted);
            this.FailOn(() => Partner.IsFighting());
            this.FailOn(() => !Partner.CanReach(pawn, PathEndMode.Touch, Danger.Deadly));

            yield return(Toils_Reserve.Reserve(iTarget, 1, 0));

            Toil gotoAnimal = Toils_Goto.GotoThing(iTarget, PathEndMode.Touch);

            yield return(gotoAnimal);

            Toil gotoBed = new Toil();

            gotoBed.defaultCompleteMode = ToilCompleteMode.PatherArrival;
            gotoBed.FailOnBedNoLongerUsable(iBed);
            gotoBed.AddFailCondition(() => Partner.Downed);
            gotoBed.initAction = delegate
            {
                pawn.pather.StartPath(SleepSpot, PathEndMode.OnCell);
                Partner.jobs.StopAll();
                Job job = JobMaker.MakeJob(JobDefOf.GotoMindControlled, SleepSpot);
                Partner.jobs.StartJob(job, JobCondition.InterruptForced);
            };
            yield return(gotoBed);

            Toil waitInBed = new Toil();

            waitInBed.FailOn(() => pawn.GetRoom(RegionType.Set_Passable) == null);
            waitInBed.defaultCompleteMode = ToilCompleteMode.Delay;
            waitInBed.initAction          = delegate
            {
                ticksLeftThisToil = 5000;
            };
            waitInBed.tickAction = delegate
            {
                pawn.GainComfortFromCellIfPossible();
                if (IsInOrByBed(Bed, Partner) && pawn.PositionHeld == Partner.PositionHeld)
                {
                    ReadyForNextToil();
                }
            };
            yield return(waitInBed);

            Toil StartPartnerJob = new Toil();

            StartPartnerJob.defaultCompleteMode = ToilCompleteMode.Instant;
            StartPartnerJob.socialMode          = RandomSocialMode.Off;
            StartPartnerJob.initAction          = delegate
            {
                var gettin_loved = JobMaker.MakeJob(xxx.gettin_loved, pawn, Bed);
                Partner.jobs.StartJob(gettin_loved, JobCondition.InterruptForced);
            };
            yield return(StartPartnerJob);

            Toil loveToil = new Toil();

            loveToil.AddFailCondition(() => Partner.Dead || !IsInOrByBed(Bed, Partner));
            loveToil.socialMode          = RandomSocialMode.Off;
            loveToil.defaultCompleteMode = ToilCompleteMode.Never;
            loveToil.handlingFacing      = true;
            loveToil.initAction          = delegate
            {
                usedCondom = CondomUtility.TryUseCondom(pawn);
                Start();
            };
            loveToil.AddPreTickAction(delegate
            {
                --ticks_left;
                if (pawn.IsHashIntervalTick(ticks_between_hearts))
                {
                    if (xxx.is_zoophile(pawn))
                    {
                        ThrowMetaIcon(pawn.Position, pawn.Map, ThingDefOf.Mote_Heart);
                    }
                    else
                    {
                        ThrowMetaIcon(pawn.Position, pawn.Map, xxx.mote_noheart);
                    }
                }
                SexTick(pawn, Partner);
                SexUtility.reduce_rest(pawn, 1);
                SexUtility.reduce_rest(Partner, 2);
                if (ticks_left <= 0)
                {
                    ReadyForNextToil();
                }
            });
            loveToil.AddFinishAction(delegate
            {
                End();
            });
            yield return(loveToil);

            Toil afterSex = new Toil
            {
                initAction = delegate
                {
                    //Log.Message("JobDriver_BestialityForFemale::MakeNewToils() - Calling aftersex");
                    SexUtility.ProcessSex(Partner, pawn, usedCondom: usedCondom, sextype: sexType);
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            };

            yield return(afterSex);
        }
        public static Toil LayDown(TargetIndex bedOrRestSpotIndex, bool hasBed, bool lookForOtherJobs, bool canSleep = true, bool gainRestAndHealth = true)
        {
            Toil layDown = new Toil();

            layDown.initAction = delegate
            {
                Pawn actor = layDown.actor;
                actor.pather.StopDead();
                JobDriver curDriver = actor.jobs.curDriver;
                if (hasBed)
                {
                    Building_Bed t = (Building_Bed)actor.CurJob.GetTarget(bedOrRestSpotIndex).Thing;
                    if (!t.OccupiedRect().Contains(actor.Position))
                    {
                        Log.Error("Can't start LayDown toil because pawn is not in the bed. pawn=" + actor, false);
                        actor.jobs.EndCurrentJob(JobCondition.Errored, true);
                        return;
                    }
                    actor.jobs.posture = PawnPosture.LayingInBed;
                }
                else
                {
                    actor.jobs.posture = PawnPosture.LayingOnGroundNormal;
                }
                curDriver.asleep = false;
                if (actor.mindState.applyBedThoughtsTick == 0)
                {
                    actor.mindState.applyBedThoughtsTick    = Find.TickManager.TicksGame + Rand.Range(2500, 10000);
                    actor.mindState.applyBedThoughtsOnLeave = false;
                }
                if (actor.ownership != null && actor.CurrentBed() != actor.ownership.OwnedBed)
                {
                    ThoughtUtility.RemovePositiveBedroomThoughts(actor);
                }
            };

            layDown.tickAction = delegate
            {
                Pawn         actor        = layDown.actor;
                Job          curJob       = actor.CurJob;
                JobDriver    curDriver    = actor.jobs.curDriver;
                Building_Bed building_Bed = (Building_Bed)curJob.GetTarget(bedOrRestSpotIndex).Thing;
                actor.GainComfortFromCellIfPossible();

                if (actor.IsHashIntervalTick(100) && !actor.Position.Fogged(actor.Map))
                {
                    if (curDriver.asleep)
                    {
                        MoteMaker.ThrowMetaIcon(actor.Position, actor.Map, ThingDefOf.Mote_SleepZ);
                    }
                    if (gainRestAndHealth && actor.health.hediffSet.GetNaturallyHealingInjuredParts().Any <BodyPartRecord>())
                    {
                        MoteMaker.ThrowMetaIcon(actor.Position, actor.Map, ThingDefOf.Mote_HealingCross);
                    }
                }
                if (actor.ownership != null && building_Bed != null && !building_Bed.Medical && !building_Bed.OwnersForReading.Contains(actor))
                {
                    if (actor.Downed)
                    {
                        actor.Position = CellFinder.RandomClosewalkCellNear(actor.Position, actor.Map, 1, null);
                    }
                    actor.jobs.EndCurrentJob(JobCondition.Incompletable, true);
                    return;
                }
                if (lookForOtherJobs && actor.IsHashIntervalTick(211))
                {
                    actor.jobs.CheckForJobOverride();
                    return;
                }

                //Fin recharche ou pod non alimenté ou non operationel
                if (actor.needs.food.CurLevelPercentage >= 1.0f ||
                    building_Bed.Destroyed || building_Bed.IsBrokenDown() ||
                    !building_Bed.TryGetComp <CompPowerTrader>().PowerOn)
                {
                    actor.jobs.EndCurrentJob(JobCondition.Succeeded, true);
                }
            };
            layDown.defaultCompleteMode = ToilCompleteMode.Never;
            if (hasBed)
            {
                layDown.FailOnBedNoLongerUsable(bedOrRestSpotIndex);
            }
            layDown.AddFinishAction(delegate
            {
                Pawn actor          = layDown.actor;
                JobDriver curDriver = actor.jobs.curDriver;
                curDriver.asleep    = false;
            });
            return(layDown);
        }
示例#7
0
    public static Toil BrrrLayDown(TargetIndex bedOrRestSpotIndex, bool hasBed, bool lookForOtherJobs = false,
                                   bool canSleep = true, bool gainRestAndHealth = true)
    {
        var layDown = new Toil();

        layDown.initAction = delegate
        {
            var actor3 = layDown.actor;
            actor3.pather.StopDead();
            var curDriver3 = actor3.jobs.curDriver;
            if (hasBed)
            {
                if (!((Building_Bed)actor3.CurJob.GetTarget(bedOrRestSpotIndex).Thing).OccupiedRect()
                    .Contains(actor3.Position))
                {
                    Log.Error("Can't start LayDown toil because pawn is not in the bed. pawn=" + actor3);
                    actor3.jobs.EndCurrentJob(JobCondition.Errored);
                    return;
                }

                actor3.jobs.posture = PawnPosture.LayingInBed;
            }
            else
            {
                actor3.jobs.posture = PawnPosture.LayingOnGroundNormal;
            }

            curDriver3.asleep = false;
            if (actor3.mindState.applyBedThoughtsTick == 0)
            {
                actor3.mindState.applyBedThoughtsTick    = Find.TickManager.TicksGame + Rand.Range(2500, 10000);
                actor3.mindState.applyBedThoughtsOnLeave = false;
            }

            if (actor3.ownership != null && actor3.CurrentBed() != actor3.ownership.OwnedBed)
            {
                ThoughtUtility.RemovePositiveBedroomThoughts(actor3);
            }
        };
        layDown.tickAction = delegate
        {
            var actor2       = layDown.actor;
            var curJob       = actor2.CurJob;
            var curDriver2   = actor2.jobs.curDriver;
            var building_Bed = (Building_Bed)curJob.GetTarget(bedOrRestSpotIndex).Thing;
            actor2.GainComfortFromCellIfPossible();
            if (!curDriver2.asleep)
            {
                if (canSleep &&
                    (actor2.needs.rest != null &&
                     actor2.needs.rest.CurLevel < RestUtility.FallAsleepMaxLevel(actor2) || curJob.forceSleep))
                {
                    curDriver2.asleep = true;
                }
            }
            else if (!canSleep)
            {
                curDriver2.asleep = false;
            }
            else if ((actor2.needs.rest == null ||
                      actor2.needs.rest.CurLevel >= RestUtility.WakeThreshold(actor2)) && !curJob.forceSleep)
            {
                curDriver2.asleep = false;
            }

            if (curDriver2.asleep & gainRestAndHealth && actor2.needs.rest != null)
            {
                var restEffectiveness =
                    building_Bed == null ||
                    !building_Bed.def.statBases.StatListContains(StatDefOf.BedRestEffectiveness)
                        ? 0.8f
                        : building_Bed.GetStatValue(StatDefOf.BedRestEffectiveness);
                actor2.needs.rest.TickResting(restEffectiveness);
            }

            if (actor2.mindState.applyBedThoughtsTick != 0 &&
                actor2.mindState.applyBedThoughtsTick <= Find.TickManager.TicksGame)
            {
                ApplyBedThoughts(actor2);
                actor2.mindState.applyBedThoughtsTick   += 60000;
                actor2.mindState.applyBedThoughtsOnLeave = true;
            }

            if (actor2.IsHashIntervalTick(TicksBetweenSleepZs) && !actor2.Position.Fogged(actor2.Map))
            {
                if (curDriver2.asleep)
                {
                    FleckMaker.ThrowMetaIcon(actor2.Position, actor2.Map, FleckDefOf.SleepZ);
                }

                if (gainRestAndHealth && actor2.health.hediffSet.GetNaturallyHealingInjuredParts().Any())
                {
                    FleckMaker.ThrowMetaIcon(actor2.Position, actor2.Map, FleckDefOf.HealingCross);
                }
            }

            if (actor2.ownership != null && building_Bed != null && !building_Bed.Medical &&
                !building_Bed.OwnersForReading.Contains(actor2))
            {
                if (actor2.Downed)
                {
                    actor2.Position = CellFinder.RandomClosewalkCellNear(actor2.Position, actor2.Map, 1);
                }

                actor2.jobs.EndCurrentJob(JobCondition.Incompletable);
                return;
            }

            if (lookForOtherJobs && actor2.IsHashIntervalTick(GetUpOrStartJobWhileInBedCheckInterval))
            {
                actor2.jobs.CheckForJobOverride();
            }
        };
        layDown.defaultCompleteMode = ToilCompleteMode.Never;
        if (hasBed)
        {
            layDown.FailOnBedNoLongerUsable(bedOrRestSpotIndex);
        }

        layDown.AddFailCondition(delegate
        {
            var actor = layDown.actor;
            var needs = actor.needs;
            if (needs?.food != null &&
                actor.needs.food.CurLevelPercentage < actor.needs.food.PercentageThreshHungry)
            {
                return(true);
            }

            var needs2 = actor.needs;
            return(needs2?.joy != null && !actor.RaceProps.Animal &&
                   actor.needs.joy.CurLevelPercentage < Settings.JoySev / 100f && Settings.AllowJoy);
        });
        layDown.AddFailCondition(delegate
        {
            var actor     = layDown.actor;
            var hypoHed   = actor.health.hediffSet.GetFirstHediffOfDef(HediffDefOf.Hypothermia);
            var heatHed   = actor.health.hediffSet.GetFirstHediffOfDef(HediffDefOf.Heatstroke);
            var ToxHed    = actor.health.hediffSet.GetFirstHediffOfDef(HediffDefOf.ToxicBuildup);
            var BreathHed =
                actor.health.hediffSet.GetFirstHediffOfDef(
                    DefDatabase <HediffDef> .GetNamed("OxygenStarvation", false));
            return(hypoHed == null && heatHed == null && ToxHed == null && BreathHed == null);
        });
        layDown.AddFinishAction(delegate
        {
            var actor     = layDown.actor;
            var curDriver = actor.jobs.curDriver;
            if (actor.mindState.applyBedThoughtsOnLeave)
            {
                ApplyBedThoughts(actor);
            }

            curDriver.asleep = false;
        });
        return(layDown);
    }
        public static Toil LayDown(TargetIndex bedOrRestSpotIndex, bool hasBed, bool lookForOtherJobs, bool canSleep = true, bool gainRestAndHealth = true)
        {
            Toil layDown = new Toil();

            layDown.initAction = delegate
            {
                Pawn actor3 = layDown.actor;
                actor3.pather.StopDead();
                JobDriver curDriver3 = actor3.jobs.curDriver;
                if (hasBed)
                {
                    Building_Bed t = (Building_Bed)actor3.CurJob.GetTarget(bedOrRestSpotIndex).Thing;
                    if (!t.OccupiedRect().Contains(actor3.Position))
                    {
                        Log.Error("Can't start LayDown toil because pawn is not in the bed. pawn=" + actor3);
                        actor3.jobs.EndCurrentJob(JobCondition.Errored, true);
                        return;
                    }
                    curDriver3.layingDown = LayingDownState.LayingInBed;
                }
                else
                {
                    curDriver3.layingDown = LayingDownState.LayingSurface;
                }
                curDriver3.asleep = false;
                if (actor3.mindState.applyBedThoughtsTick == 0)
                {
                    actor3.mindState.applyBedThoughtsTick    = Find.TickManager.TicksGame + Rand.Range(2500, 10000);
                    actor3.mindState.applyBedThoughtsOnLeave = false;
                }
                if (actor3.ownership != null && actor3.CurrentBed() != actor3.ownership.OwnedBed)
                {
                    ThoughtUtility.RemovePositiveBedroomThoughts(actor3);
                }
            };
            layDown.tickAction = delegate
            {
                Pawn         actor2       = layDown.actor;
                Job          curJob       = actor2.CurJob;
                JobDriver    curDriver2   = actor2.jobs.curDriver;
                Building_Bed building_Bed = (Building_Bed)curJob.GetTarget(bedOrRestSpotIndex).Thing;
                actor2.GainComfortFromCellIfPossible();
                if (!curDriver2.asleep)
                {
                    if (canSleep)
                    {
                        if (actor2.needs.rest != null && actor2.needs.rest.CurLevel < RestUtility.FallAsleepMaxLevel(actor2))
                        {
                            goto IL_008c;
                        }
                        if (curJob.forceSleep)
                        {
                            goto IL_008c;
                        }
                    }
                }
                else if (!canSleep)
                {
                    curDriver2.asleep = false;
                }
                else if ((actor2.needs.rest == null || actor2.needs.rest.CurLevel >= RestUtility.WakeThreshold(actor2)) && !curJob.forceSleep)
                {
                    curDriver2.asleep = false;
                }
                goto IL_00ec;
IL_00ec:
                if (curDriver2.asleep && gainRestAndHealth && actor2.needs.rest != null)
                {
                    float num  = (float)((building_Bed == null || !building_Bed.def.statBases.StatListContains(StatDefOf.BedRestEffectiveness)) ? 0.800000011920929 : building_Bed.GetStatValue(StatDefOf.BedRestEffectiveness, true));
                    float num2 = RestUtility.PawnHealthRestEffectivenessFactor(actor2);
                    num = (float)(0.699999988079071 * num + 0.30000001192092896 * num * num2);
                    actor2.needs.rest.TickResting(num);
                }
                if (actor2.mindState.applyBedThoughtsTick != 0 && actor2.mindState.applyBedThoughtsTick <= Find.TickManager.TicksGame)
                {
                    Toils_LayDown.ApplyBedThoughts(actor2);
                    actor2.mindState.applyBedThoughtsTick   += 60000;
                    actor2.mindState.applyBedThoughtsOnLeave = true;
                }
                if (actor2.IsHashIntervalTick(100) && !actor2.Position.Fogged(actor2.Map))
                {
                    if (curDriver2.asleep)
                    {
                        MoteMaker.ThrowMetaIcon(actor2.Position, actor2.Map, ThingDefOf.Mote_SleepZ);
                    }
                    if (gainRestAndHealth && actor2.health.hediffSet.GetNaturallyHealingInjuredParts().Any())
                    {
                        MoteMaker.ThrowMetaIcon(actor2.Position, actor2.Map, ThingDefOf.Mote_HealingCross);
                    }
                }
                if (actor2.ownership != null && building_Bed != null && !building_Bed.Medical && !building_Bed.owners.Contains(actor2))
                {
                    if (actor2.Downed)
                    {
                        actor2.Position = CellFinder.RandomClosewalkCellNear(actor2.Position, actor2.Map, 1, null);
                    }
                    actor2.jobs.EndCurrentJob(JobCondition.Incompletable, true);
                }
                else if (lookForOtherJobs && actor2.IsHashIntervalTick(211))
                {
                    actor2.jobs.CheckForJobOverride();
                }
                return;

IL_008c:
                curDriver2.asleep = true;
                goto IL_00ec;
            };
            layDown.defaultCompleteMode = ToilCompleteMode.Never;
            if (hasBed)
            {
                layDown.FailOnBedNoLongerUsable(bedOrRestSpotIndex);
            }
            layDown.AddFinishAction(delegate
            {
                Pawn actor          = layDown.actor;
                JobDriver curDriver = actor.jobs.curDriver;
                if (actor.mindState.applyBedThoughtsOnLeave)
                {
                    Toils_LayDown.ApplyBedThoughts(actor);
                }
                curDriver.layingDown = LayingDownState.NotLaying;
                curDriver.asleep     = false;
            });
            return(layDown);
        }
示例#9
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnDespawnedOrNull(PartnerInd);
            this.FailOnDespawnedNullOrForbidden(BedInd);
            this.FailOn(() => Actor is null || !Actor.CanReserveAndReach(Partner, PathEndMode.Touch, Danger.Deadly));
            this.FailOn(() => pawn.Drafted);
            yield return(Toils_Reserve.Reserve(PartnerInd, 1, 0));

            //yield return Toils_Reserve.Reserve(BedInd, Bed.SleepingSlotsCount, 0);
            Toil gotoAnimal = Toils_Goto.GotoThing(PartnerInd, PathEndMode.Touch);

            yield return(gotoAnimal);

            bool partnerHasPenis = Genital_Helper.has_penis(Partner) || Genital_Helper.has_penis_infertile(Partner);

            Toil gotoBed = new Toil
            {
                initAction = delegate
                {
                    Actor.pather.StartPath(SleepSpot, PathEndMode.OnCell);
                    Partner.pather.StartPath(SleepSpot, PathEndMode.OnCell);
                },
                defaultCompleteMode = ToilCompleteMode.PatherArrival
            };

            gotoBed.FailOnBedNoLongerUsable(BedInd);
            gotoBed.AddFailCondition(() => Partner.Downed);
            yield return(gotoBed);

            gotoBed.AddFinishAction(delegate
            {
                var gettin_loved = new Job(xxx.gettin_loved, Actor, Bed);
                Partner.jobs.StartJob(gettin_loved, JobCondition.InterruptForced, null, false, true, null);
            });

            Toil waitInBed = new Toil
            {
                initAction = delegate
                {
                    //Rand.PopState();
                    //Rand.PushState(RJW_Multiplayer.PredictableSeed());
                    ticksLeftThisToil = 5000;
                    ticks_left        = (int)(2000.0f * Rand.Range(0.30f, 1.30f));
                },
                tickAction = delegate
                {
                    Actor.GainComfortFromCellIfPossible();
                    if (IsInOrByBed(Bed, Partner))
                    {
                        ticksLeftThisToil = 0;
                    }
                },
                defaultCompleteMode = ToilCompleteMode.Delay,
            };

            waitInBed.FailOn(() => pawn.GetRoom(RegionType.Set_Passable) == null);
            yield return(waitInBed);

            Toil loveToil = new Toil
            {
                initAction = delegate
                {
                    if (!partnerHasPenis)
                    {
                        Actor.rotationTracker.Face(Partner.DrawPos);
                    }
                },
                defaultCompleteMode = ToilCompleteMode.Never,                 //Changed from Delay
            };

            loveToil.AddPreTickAction(delegate
            {
                //Actor.Reserve(Partner, 1, 0);
                --ticks_left;
                xxx.reduce_rest(Actor, 1);
                xxx.reduce_rest(Partner, 2);
                if (ticks_left <= 0)
                {
                    ReadyForNextToil();
                }
                else if (pawn.IsHashIntervalTick(ticks_between_hearts))
                {
                    MoteMaker.ThrowMetaIcon(Actor.Position, Actor.Map, ThingDefOf.Mote_Heart);
                }
                Actor.GainComfortFromCellIfPossible();
                Partner.GainComfortFromCellIfPossible();
            });
            loveToil.AddFailCondition(() => Partner.Dead || !IsInOrByBed(Bed, Partner));
            loveToil.socialMode = RandomSocialMode.Off;
            yield return(loveToil);

            Toil afterSex = new Toil
            {
                initAction = delegate
                {
                    //Log.Message("JobDriver_BestialityForFemale::MakeNewToils() - Calling aftersex");
                    // Trying to add some interactions and social logs
                    SexUtility.ProcessSex(Partner, pawn);
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            };

            yield return(afterSex);
        }