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); }
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); }
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; }
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); }