public static bool CanMakeBed(Pawn pawn, Building_Bed t, bool forced = false)
        {
            CompMakeableBed CompMakeableBed = t.TryGetComp <CompMakeableBed>();

            if (CompMakeableBed == null || CompMakeableBed.Loaded)
            {
                return(false);
            }
            if (!t.IsForbidden(pawn))
            {
                LocalTargetInfo target = t;
                if (pawn.CanReserve(target, 1, -1, null, forced))
                {
                    if (t.Faction != pawn.Faction)
                    {
                        return(false);
                    }
                    if (FindBestBedding(pawn, t) == null)
                    {
                        ThingFilter beddingFilter = new ThingFilter();
                        beddingFilter.SetAllow(t.TryGetComp <CompMakeableBed>().allowedBedding, true);
                        JobFailReason.Is("NoSuitableBedding".Translate(beddingFilter.Summary), null);
                        return(false);
                    }
                    return(true);
                }
            }
            return(false);
        }
Beispiel #2
0
            private static FloatMenuOption GetFailureReason(Building_Bed bed, Pawn myPawn)
            {
                if (!myPawn.CanReach(bed, PathEndMode.InteractionCell, Danger.Some))
                {
                    return(new FloatMenuOption("CannotUseNoPath".Translate(), null));
                }
                if (bed.Spawned && bed.Map.gameConditionManager.ConditionIsActive(GameConditionDefOf.SolarFlare))
                {
                    return(new FloatMenuOption("CannotUseSolarFlare".Translate(), null));
                }
                if (!bed.TryGetComp <CompPowerTrader>().PowerOn)
                {
                    return(new FloatMenuOption("CannotUseNoPower".Translate(), null));
                }
                if (!Utils.ExceptionAndroidList.Contains(myPawn.def.defName))
                {
                    return(new FloatMenuOption("ATPP_CanOnlyBeUsedByAndroid".Translate(), null));
                }

                var ca = myPawn.TryGetComp <CompAndroidState>();

                if (ca == null || !ca.UseBattery)
                {
                    return(new FloatMenuOption("ATPP_CannotUseBecauseNotInBatteryMode".Translate(), null));
                }

                return(null);
            }
Beispiel #3
0
        public static void Postfix(PawnRenderer __instance, Pawn ___pawn, Vector3 drawLoc)
        {
            Building_Bed    softWarmBed = ___pawn.CurrentBed();
            CompMakeableBed bedComp     = softWarmBed.TryGetComp <CompMakeableBed>();

            if (___pawn.RaceProps.Humanlike && bedComp != null)//___pawn.CurrentBed() is Building_SoftWarmBed)
            {
                if (!bedComp.Loaded)
                {
                    // Thanks to @Zamu & @Mehni!
                    var        rotDrawMode  = (RotDrawMode)AccessTools.Property(typeof(PawnRenderer), "CurRotDrawMode").GetGetMethod(true).Invoke(__instance, new object[0]);
                    MethodInfo layingFacing = AccessTools.Method(type: typeof(PawnRenderer), name: "LayingFacing");
                    Rot4       rot          = (Rot4)layingFacing.Invoke(__instance, new object[0]);
                    float      angle;
                    Vector3    rootLoc;
                    Rot4       rotation = softWarmBed.Rotation;
                    rotation.AsInt += 2;
                    angle           = rotation.AsAngle;
                    AltitudeLayer altLayer = (AltitudeLayer)Mathf.Max((int)softWarmBed.def.altitudeLayer, 15);
                    Vector3       vector2  = ___pawn.Position.ToVector3ShiftedWithAltitude(altLayer);
                    Vector3       vector3  = vector2;
                    vector3.y += 0.02734375f;
                    float   d = -__instance.BaseHeadOffsetAt(Rot4.South).z;
                    Vector3 a = rotation.FacingCell.ToVector3();
                    rootLoc    = vector2 + a * d;
                    rootLoc.y += 0.0078125f;
                    MethodInfo renderPawnInternal = AccessTools.Method(type: typeof(PawnRenderer), name: "RenderPawnInternal", parameters: new[] { typeof(Vector3), typeof(float), typeof(bool), typeof(Rot4), typeof(Rot4), typeof(RotDrawMode), typeof(bool), typeof(bool), typeof(bool) });
                    renderPawnInternal.Invoke(__instance, new object[] { rootLoc, angle, true, rot, rot, rotDrawMode, false, false, false });
                }
            }
        }
        private static Thing FindBestBedding(Pawn pawn, Building_Bed bed)
        {
            //Log.Message(pawn + " is looking for a bedding type " + bed.TryGetComp<CompMakeableBed>().blanketDef + " for " + bed);
            ThingFilter beddingFilter = new ThingFilter();

            beddingFilter.SetAllow(bed.TryGetComp <CompMakeableBed>().allowedBedding, true);
            ThingFilter stuffFilter = new ThingFilter();

            stuffFilter = bed.TryGetComp <CompMakeableBed>().settings.filter;
            Predicate <Thing> predicate        = (Thing x) => !x.IsForbidden(pawn) && pawn.CanReserve(x, 1, -1, null, false) && beddingFilter.Allows(x) && stuffFilter.Allows(x.Stuff);
            IntVec3           position         = pawn.Position;
            Map               map              = pawn.Map;
            ThingRequest      bestThingRequest = beddingFilter.BestThingRequest;
            PathEndMode       peMode           = PathEndMode.ClosestTouch;
            TraverseParms     traverseParams   = TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false);
            Predicate <Thing> validator        = predicate;

            return(GenClosest.ClosestThingReachable(position, map, bestThingRequest, peMode, traverseParams, 9999f, validator, null, 0, -1, false, RegionType.Set_Passable, false));
        }
        public static void Postfix(Pawn ___pawn, ref bool showBody)
        {
            if (showBody)
            {
                return;
            }
            Building_Bed    softWarmBed = ___pawn.CurrentBed();
            CompMakeableBed bedComp     = softWarmBed.TryGetComp <CompMakeableBed>();

            showBody = ___pawn.RaceProps.Humanlike && bedComp != null && !bedComp.Loaded;
        }
Beispiel #6
0
        public static bool SwapPatch(object __instance, Building_Bed bed)
        {
            CompMakeableBed bedComp = bed.TryGetComp <CompMakeableBed>();

            if (bedComp != null)
            {
                bedComp.NotTheBlanket = false;
                Swap(__instance, bed, bedComp.settings, bedComp);
                return(false);
            }
            return(true);
        }
        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);
        }