コード例 #1
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)
                {
                    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);
                        actor.jobs.EndCurrentJob(JobCondition.Errored, true);
                        return;
                    }
                    curDriver.layingDown = LayingDownState.LayingInBed;
                }
                else
                {
                    curDriver.layingDown = LayingDownState.LayingSurface;
                }
                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 (!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 num;
                    if (building_Bed != null && building_Bed.def.statBases.StatListContains(StatDefOf.BedRestEffectiveness))
                    {
                        num = building_Bed.GetStatValue(StatDefOf.BedRestEffectiveness, true);
                    }
                    else
                    {
                        num = 0.8f;
                    }
                    float num2 = RestUtility.PawnHealthRestEffectivenessFactor(actor);
                    num = 0.7f * num + 0.3f * num * num2;
                    actor.needs.rest.TickResting(num);
                }
                if (actor.mindState.applyBedThoughtsTick != 0 && actor.mindState.applyBedThoughtsTick <= Find.TickManager.TicksGame)
                {
                    Toils_LayDown.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 (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.owners.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;
                }
            };
            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);
        }
コード例 #2
0
 public override void NeedInterval()
 {
     if (!base.IsFrozen)
     {
         if (this.Resting)
         {
             float num  = this.lastRestEffectiveness;
             float num2 = RestUtility.PawnHealthRestEffectivenessFactor(this.pawn);
             num  = 0.7f * num + 0.3f * num * num2;
             num *= this.pawn.GetStatValue(StatDefOf.RestRateMultiplier, true);
             if (num > 0f)
             {
                 this.CurLevel += 0.00571428565f * num;
             }
         }
         else
         {
             this.CurLevel -= this.RestFallPerTick * 150f;
         }
     }
     if (this.CurLevel < 0.0001f)
     {
         this.ticksAtZero += 150;
     }
     else
     {
         this.ticksAtZero = 0;
     }
     if (this.ticksAtZero > 1000 && this.pawn.Spawned)
     {
         float mtb;
         if (this.ticksAtZero < 15000)
         {
             mtb = 0.25f;
         }
         else if (this.ticksAtZero < 30000)
         {
             mtb = 0.125f;
         }
         else if (this.ticksAtZero < 45000)
         {
             mtb = 0.0833333358f;
         }
         else
         {
             mtb = 0.0625f;
         }
         if (Rand.MTBEventOccurs(mtb, 60000f, 150f) && (this.pawn.CurJob == null || this.pawn.CurJob.def != JobDefOf.LayDown))
         {
             this.pawn.jobs.StartJob(new Job(JobDefOf.LayDown, this.pawn.Position), JobCondition.InterruptForced, null, false, true, null, new JobTag?(JobTag.SatisfyingNeeds), false);
             if (this.pawn.InMentalState)
             {
                 this.pawn.mindState.mentalStateHandler.CurState.RecoverFromState();
             }
             if (PawnUtility.ShouldSendNotificationAbout(this.pawn))
             {
                 Messages.Message("MessageInvoluntarySleep".Translate(new object[]
                 {
                     this.pawn.LabelShort
                 }), this.pawn, MessageTypeDefOf.NegativeEvent, true);
             }
             TaleRecorder.RecordTale(TaleDefOf.Exhausted, new object[]
             {
                 this.pawn
             });
         }
     }
 }