Exemplo n.º 1
0
        static bool Prefix(ref Pawn ___pawn, ref Building_Bed ___intOwnedBed)
        {
            UnassignAllBedsIfDead(___pawn);
            if (!Helpers.ShouldRunForPawn(___pawn))
            {
                return(true);
            }

            var isInShuttle = !___pawn.Spawned && ___pawn.SpawnedParentOrMe?.Label?.Contains("shuttle") == true;

            if (isInShuttle)
            {
                ___intOwnedBed = null;
                ThoughtUtility.RemovePositiveBedroomThoughts(___pawn);
                return(true);
            }

            // NOTE: If the bed is unclaimed (typically deconstructed/replaced) on another map this will cause the pawn
            // to unclaim the bed on CurrentMap. Since UnclaimBed doesn't specify bed we have to guess, and since it's
            // called from a bunch of places in vanilla (plus whatever from mods) I'd rather just take the occasional
            // unwanted unclaim instead of trying to patch everywhere.

            // Temporarily replace pawns owned bed on their map with the bed owned on the current map
            ClaimBedOnMapIfExists(___pawn, Find.CurrentMap, ref ___intOwnedBed);
            return(true);
        }
Exemplo n.º 2
0
 public static void UnclaimBeds(Pawn pawn, IEnumerable <Building_Bed> beds, ref Building_Bed ___intOwnedBed)
 {
     foreach (var bed in beds)
     {
         bed?.CompAssignableToPawn?.ForceRemovePawn(pawn);
         if (pawn.ownership?.OwnedBed == bed)
         {
             ___intOwnedBed = null;
             ThoughtUtility.RemovePositiveBedroomThoughts(pawn);
         }
     }
 }
Exemplo n.º 3
0
        private static void ClaimBedOnMapIfExists(Pawn ___pawn, Map map, ref Building_Bed ___intOwnedBed)
        {
            var pawnBedsOnMap = Helpers.PawnBedsOnMap(___pawn, map);

            if (pawnBedsOnMap.Any())
            {
                var bed = pawnBedsOnMap.First();
                ___intOwnedBed = bed;
                if (bed.CompAssignableToPawn != null && !bed.CompAssignableToPawn.AssignedPawnsForReading.Contains(___pawn))
                {
                    bed.CompAssignableToPawn.ForceAddPawn(___pawn);
                }
                ThoughtUtility.RemovePositiveBedroomThoughts(___pawn);
            }
        }
Exemplo n.º 4
0
        static bool Prefix(Building_Bed newBed, Pawn_Ownership __instance, ref Pawn ___pawn, ref Building_Bed ___intOwnedBed)
        {
            if (newBed == null ||
                newBed.Medical ||
                !Helpers.ShouldRunForPawn(___pawn) ||
                (newBed.OwnersForReading != null && newBed.OwnersForReading.Contains(___pawn) && ___pawn.ownership?.OwnedBed == newBed))
            {
                return(true);
            }

            // Remove other pawn to make room in bed
            var pawn = ___pawn;

            if (newBed.OwnersForReading?.Count == newBed.SleepingSlotsCount &&
                !newBed.OwnersForReading.Any(p => p == pawn) &&
                newBed.OwnersForReading.Count > 0)
            {
                var pawnToRemove = newBed.OwnersForReading.LastOrDefault();
                pawnToRemove?.ownership?.UnclaimBed();
            }

            // Unclaim bed if pawn already has one on the map of the new bed
            var pawnBeds = Helpers.PawnBedsOnMap(___pawn, newBed.Map);

            if (pawnBeds.Any())
            {
                Helpers.UnclaimBeds(___pawn, pawnBeds, ref ___intOwnedBed);
            }

            // Claim new bed
            newBed.CompAssignableToPawn.ForceAddPawn(___pawn);
            // ... but only assign it if the pawn is on the same map
            if (___pawn.Map == newBed.Map)
            {
                ___intOwnedBed = newBed;
                ThoughtUtility.RemovePositiveBedroomThoughts(___pawn);
            }

            return(false);
        }
Exemplo n.º 5
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);
        }
Exemplo n.º 6
0
        // 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()
        {
            Toil  layDown = new Toil();
            float num     = 1.25f;

            layDown.initAction = delegate
            {
                Pawn actor = layDown.actor;
                actor.pather.StopDead();
                JobDriver curDriver = actor.jobs.curDriver;
                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;
                actor.GainComfortFromCellIfPossible();
                if (!curDriver.asleep)
                {
                    if (actor.needs.rest != null && actor.needs.rest.CurLevel < .99f * RestUtility.WakeThreshold(actor))
                    {
                        curDriver.asleep = true;
                    }
                }
                else if (actor.needs.rest == null || actor.needs.rest.CurLevel >= RestUtility.WakeThreshold(actor))
                {
                    actor.mindState.priorityWork.ClearPrioritizedWorkAndJobQueue();
                    this.EndJobWith(JobCondition.Incompletable);
                }

                if (curDriver.asleep && actor.needs.rest != null)
                {
                    num = (0.7f * num) + (0.3f * num);  //talk about convoluted calculations...
                    actor.needs.rest.TickResting(num);
                    if (actor.needs.rest.CurLevel >= .99f * RestUtility.WakeThreshold(actor))
                    {
                        curDriver.asleep = false;
                        actor.mindState.priorityWork.ClearPrioritizedWorkAndJobQueue();
                        this.EndJobWith(JobCondition.Succeeded);
                    }
                }

                if (actor.mindState.applyBedThoughtsTick != 0 && actor.mindState.applyBedThoughtsTick <= Find.TickManager.TicksGame)
                {
                    ApplyBedThoughts(actor);
                    actor.mindState.applyBedThoughtsTick   += 60000;
                    actor.mindState.applyBedThoughtsOnLeave = true;
                }
                if (actor.IsHashIntervalTick(100) && !actor.Position.Fogged(actor.Map))
                {
                    if (curDriver.asleep)
                    {
                        MoteMaker.ThrowMetaIcon(actor.Position, actor.Map, ThingDefOf.Mote_SleepZ);
                    }
                    if (actor.health.hediffSet.GetNaturallyHealingInjuredParts().Any <BodyPartRecord>())
                    {
                        MoteMaker.ThrowMetaIcon(actor.Position, actor.Map, ThingDefOf.Mote_HealingCross);
                    }
                }
            };
            layDown.defaultCompleteMode = ToilCompleteMode.Never;
            layDown.AddFinishAction(delegate
            {
                Pawn actor          = layDown.actor;
                JobDriver curDriver = actor.jobs.curDriver;
                if (actor.mindState.applyBedThoughtsOnLeave)
                {
                    ApplyBedThoughts(actor);
                }
                actor.jobs.posture = PawnPosture.Standing;
                curDriver.asleep   = false;
            });
            yield 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 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);
        }
Exemplo n.º 9
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);
    }