public static Building_AIPawnRechargeStation FindRechargeStationFor(AIPawn sleeper, AIPawn traveler, bool sleeperWillBePrisoner, bool checkSocialProperness, bool forceCheckMedBed = false) { Predicate <Thing> bedValidator = (Thing t) => { Building_AIPawnRechargeStation foundRechargeStation = t as Building_AIPawnRechargeStation; if (foundRechargeStation == null) { return(false); } if (!traveler.CanReserveAndReach(t, PathEndMode.OnCell, Danger.Some, foundRechargeStation.SleepingSlotsCount)) { return(false); } if (!foundRechargeStation.AnyUnoccupiedSleepingSlot && (!sleeper.InBed() || sleeper.CurrentBed() != foundRechargeStation)) { foreach (Pawn owner in foundRechargeStation.owners) { if (owner as AIPawn != null) { return(false); } } } if (sleeperWillBePrisoner) { if (!foundRechargeStation.ForPrisoners) { return(false); } if (!foundRechargeStation.Position.IsInPrisonCell(sleeper.Map)) { return(false); } } else { if (foundRechargeStation.Faction != traveler.Faction) { return(false); } if (foundRechargeStation.ForPrisoners) { return(false); } } if (foundRechargeStation.Medical) { if (!HealthAIUtility.ShouldEverReceiveMedicalCareFromPlayer(sleeper)) { return(false); } if (!HealthAIUtility.ShouldSeekMedicalRest(sleeper)) { return(false); } if (!foundRechargeStation.AnyUnoccupiedSleepingSlot && (!sleeper.InBed() || sleeper.CurrentBed() != foundRechargeStation)) { return(false); } } else if (foundRechargeStation.owners.Any <Pawn>() && !foundRechargeStation.owners.Contains(sleeper)) { // The pawn in the recharge station is not an AIPawn. UnassignPawn! foreach (Pawn owner in foundRechargeStation.owners) { if (owner as AIPawn == null) { if (foundRechargeStation.owners.Find((Pawn x) => LovePartnerRelationUtility.LovePartnerRelationExists(sleeper, x)) == null) { foundRechargeStation.TryUnassignPawn(owner); break; } } } // Now recheck if there is a free place if (!foundRechargeStation.AnyUnownedSleepingSlot) { return(false); } } return((!checkSocialProperness || foundRechargeStation.IsSociallyProper(sleeper, sleeperWillBePrisoner, false)) && !foundRechargeStation.IsForbidden(traveler) && !foundRechargeStation.IsBurning()); }; if (sleeper.ownership != null && sleeper.ownership.OwnedBed != null && bedValidator(sleeper.ownership.OwnedBed)) { Building_AIPawnRechargeStation rStation = sleeper.ownership.OwnedBed as Building_AIPawnRechargeStation; if (rStation != null) { return(rStation); } else { sleeper.ownership.UnclaimBed(); } } DirectPawnRelation directPawnRelation = LovePartnerRelationUtility.ExistingMostLikedLovePartnerRel(sleeper, false); if (directPawnRelation != null) { Building_AIPawnRechargeStation ownedBed = directPawnRelation.otherPawn.ownership.OwnedBed as Building_AIPawnRechargeStation; if (ownedBed != null && bedValidator(ownedBed)) { return(ownedBed); } } for (int j = 0; j < RestUtility.AllBedDefBestToWorst.Count; j++) { ThingDef thingDef = RestUtility.AllBedDefBestToWorst[j]; if (RestUtility.CanUseBedEver(sleeper, thingDef)) { Predicate <Thing> validator = (Thing b) => bedValidator(b) && (b as Building_AIPawnRechargeStation != null) && !((Building_AIPawnRechargeStation)b).Medical; Building_AIPawnRechargeStation building_Bed2 = GenClosest.ClosestThingReachable(sleeper.Position, sleeper.Map, ThingRequest.ForDef(thingDef), PathEndMode.OnCell, TraverseParms.For(traveler, Danger.Deadly, TraverseMode.ByPawn, false), 9999f, validator, null, 0, -1, false) as Building_AIPawnRechargeStation; if (building_Bed2 != null) { if (sleeper.ownership != null) { sleeper.ownership.UnclaimBed(); } return(building_Bed2); } } } return(null); }