public static void Postfix(Pawn p, ref FloatRange __result) { if (p.InBed()) { Building_Bed bed = p.CurrentBed(); float InsulationCold = bed.GetStatValue(BedInsulationCold.Bed_Insulation_Cold, true); float InsulationHeat = bed.GetStatValue(BedInsulationHeat.Bed_Insulation_Heat, true); if (InsulationCold != 0 || InsulationHeat != 0) { ThingDef raceDef = p.kindDef.race; FloatRange altResult = new FloatRange(raceDef.GetStatValueAbstract(StatDefOf.ComfyTemperatureMin, null), raceDef.GetStatValueAbstract(StatDefOf.ComfyTemperatureMax, null)); altResult.min -= InsulationCold; altResult.max += InsulationHeat; if (__result.min > altResult.min) { __result.min = altResult.min; } if (__result.max < altResult.max) { __result.max = altResult.max; } //Log.Message(bed+" insulation cold is "+bed.GetStatValue(BedInsulationCold.Bed_Insulation_Cold, true)); //Log.Message("comfortable range modified for " + p + " by bed" + bed + ": " + __result.ToString()); } } }
private void TrySatisfyRestNeed(Pawn pawn, Need_Rest rest) { if (!this.caravan.pather.MovingNow || pawn.InCaravanBed() || pawn.CarriedByCaravan()) { Building_Bed building_Bed = pawn.CurrentCaravanBed(); float restEffectiveness = (building_Bed == null) ? 0.8f : building_Bed.GetStatValue(StatDefOf.BedRestEffectiveness, true); rest.TickResting(restEffectiveness); } }
public static void CalculateBaseTendQuality_Postfix(ref float __result, Pawn doctor, Pawn patient, float medicinePotency, float medicineQualityMax) { if (doctor?.story?.traits != null && doctor.story.traits.HasTrait(SyrTraitDefOf.SYR_SteadyHands)) { float num; if (doctor != null) { num = doctor.GetStatValue(StatDefOf.MedicalTendQuality, true); } else { num = 0.75f; } num *= medicinePotency; Building_Bed building_Bed = (patient != null) ? patient.CurrentBed() : null; if (building_Bed != null) { num += building_Bed.GetStatValue(StatDefOf.MedicalTendQualityOffset, true); } __result = Mathf.Clamp(num, 0f, medicineQualityMax); } }
public static bool Listener(Pawn doctor, Pawn patient, float medicinePotency, float medicineQualityMax, ref float __result) { if (!Settings.androidsCanOnlyBeHealedByCrafter || !patient.IsAndroidTier()) { return(true); } try { float num; if (doctor != null) { num = doctor.GetStatValue(Utils.statDefAndroidTending, true); } else { num = 0.75f; } num *= medicinePotency; Building_Bed building_Bed = (patient == null) ? null : patient.CurrentBed(); if (building_Bed != null) { num += building_Bed.GetStatValue(StatDefOf.MedicalTendQualityOffset, true); } if (doctor == patient && doctor != null) { num *= 0.7f; } __result = Mathf.Clamp(num, 0f, medicineQualityMax); return(false); } catch (Exception e) { Log.Message("[ATPP] TendUtility.CalculateBaseTendQuality " + e.Message + " " + e.StackTrace); 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) { 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); }
public static bool Prefix(object __instance, Pawn actor) { bool result; if (actor.needs.mood == null) { result = false; } else if (actor.CurrentBed() == null) { result = true; } else { //Log.Message("ApplyBedThoughts is relevant for " + actor); Building_Bed bed = new Building_Bed(); bed = actor.CurrentBed(); bool hospitalityIsGuest = false; if (isHospitalityLoaded) { //Correcting for Hospitality 1.0.25 hospitalityIsGuest = AddedBedIsOwned(__instance, actor, bed); // } actor.needs.mood.thoughts.memories.RemoveMemoriesOfDef(ThoughtDefOf.SleptInBedroom); actor.needs.mood.thoughts.memories.RemoveMemoriesOfDef(ThoughtDefOf.SleptInBarracks); actor.needs.mood.thoughts.memories.RemoveMemoriesOfDef(ThoughtDefOf.SleptOutside); actor.needs.mood.thoughts.memories.RemoveMemoriesOfDef(ThoughtDefOf.SleptOnGround); actor.needs.mood.thoughts.memories.RemoveMemoriesOfDef(ThoughtDefOf.SleptInCold); actor.needs.mood.thoughts.memories.RemoveMemoriesOfDef(ThoughtDefOf.SleptInHeat); if (actor.GetRoom(RegionType.Set_Passable).PsychologicallyOutdoors) { actor.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOf.SleptOutside, null); } if (bed == null || bed.CostListAdjusted().Count == 0) { actor.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOf.SleptOnGround, null); } //taking bed insulation into consideration: //Log.Message("bedStats: cold = " + bed.GetStatValue(BedInsulationCold.Bed_Insulation_Cold, true)+", heat ="+ bed.GetStatValue(BedInsulationHeat.Bed_Insulation_Heat)); float minTempInBed = actor.def.GetStatValueAbstract(StatDefOf.ComfyTemperatureMin, null) - bed.GetStatValue(BedInsulationCold.Bed_Insulation_Cold, true); float maxTempInBed = actor.def.GetStatValueAbstract(StatDefOf.ComfyTemperatureMax, null) + bed.GetStatValue(BedInsulationHeat.Bed_Insulation_Heat, true); if (actor.AmbientTemperature < minTempInBed) { actor.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOf.SleptInCold, null); //Log.Message("Temperature is " + actor.AmbientTemperature + " and bed insulation is " + minTempInBed + ", so " + actor + " gains cold memory"); } if (actor.AmbientTemperature > maxTempInBed) { actor.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOf.SleptInHeat, null); //Log.Message("Temperature is " + actor.AmbientTemperature + " and bed insulation is " + maxTempInBed + ", so " + actor + " gains heat memory"); } //adapted for hospitality: if (bed != null && (hospitalityIsGuest || bed == actor.ownership.OwnedBed) && !bed.ForPrisoners && !actor.story.traits.HasTrait(TraitDefOf.Ascetic)) { ThoughtDef thoughtDef = null; Room room = bed.GetRoom(); //Correcting for Hospitality 1.0.25 if (hospitalityIsGuest) { bool hospitalityOnlyOneBed = room.ContainedBeds.Count() == 1; if (room.Role == DefDatabase <RoomRoleDef> .GetNamed("GuestRoom", true))// easier to replicate GuestUtility.roleDefGuestRoom than reflecting it! { thoughtDef = hospitalityOnlyOneBed ? ThoughtDefOf.SleptInBedroom : ThoughtDefOf.SleptInBarracks; } } else if (room.Role == RoomRoleDefOf.Bedroom) { thoughtDef = ThoughtDefOf.SleptInBedroom; } else if (room.Role == RoomRoleDefOf.Barracks) { thoughtDef = ThoughtDefOf.SleptInBarracks; } if (thoughtDef != null) { int scoreStageIndex = RoomStatDefOf.Impressiveness.GetScoreStageIndex(bed.GetRoom(RegionType.Set_Passable).GetStat(RoomStatDefOf.Impressiveness)); if (thoughtDef.stages[scoreStageIndex] != null) { actor.needs.mood.thoughts.memories.TryGainMemory(ThoughtMaker.MakeThought(thoughtDef, scoreStageIndex), null); } } } result = false; } return(result); }
static bool Prefix(Toil ___layDown, TargetIndex ___bedOrRestSpotIndex) { Pawn patientPawn = ___layDown.actor; Job curJob = patientPawn.CurJob; JobDriver curDriver = patientPawn.jobs.curDriver; Building_Bed building_Bed = (Building_Bed)curJob.GetTarget(___bedOrRestSpotIndex).Thing; patientPawn.GainComfortFromCellIfPossible(); if (building_Bed is Building_BedMedPod bedMedPod && bedMedPod.powerComp.PowerOn && bedMedPod.IsForbidden(patientPawn) && MedPodHealthAIUtility.ShouldPawnSeekMedPod(patientPawn, bedMedPod.AlwaysTreatableHediffs, bedMedPod.NeverTreatableHediffs) && !bedMedPod.Aborted) { // Keep pawn asleep in MedPod as long as they need to use it curDriver.asleep = true; // Fulfil pawn's rest need while they are asleep in MedPod if they're not rest immune (e.g. Circadian Half-Cycler) if (patientPawn.needs.rest != null) { float restEffectiveness = !building_Bed.def.statBases.StatListContains(StatDefOf.BedRestEffectiveness) ? StatDefOf.BedRestEffectiveness.valueIfMissing : building_Bed.GetStatValue(StatDefOf.BedRestEffectiveness); patientPawn.needs.rest.TickResting(restEffectiveness); } return(false); // Skip original code } return(true); // Run original code }
internal static void _DoTend(Pawn doctor, Pawn patient, Medicine medicine) { if (!patient.health.HasHediffsNeedingTend(false)) { return; } if (medicine != null && medicine.Destroyed) { Log.Warning("Tried to use destroyed medicine."); medicine = null; } float num = (medicine == null) ? 0.2f : medicine.def.GetStatValueAbstract(StatDefOf.MedicalPotency, null); float num2 = num; Building_Bed building_Bed = patient.CurrentBed(); if (building_Bed != null) { num2 += building_Bed.GetStatValue(StatDefOf.MedicalTendQualityOffset, true); } if (doctor != null) { num2 *= doctor.GetStatValue(StatDefOf.HealingQuality, true); } num2 = Mathf.Clamp01(num2); if (patient.health.hediffSet.GetInjuriesTendable().Any <Hediff_Injury>()) { float num3 = 0f; int num4 = 0; foreach (Hediff_Injury current in from x in patient.health.hediffSet.GetInjuriesTendable() orderby x.Severity descending select x) { float num5 = Mathf.Min(current.Severity, 20f); if (num3 + num5 > 20f) { break; } num3 += num5; current.Tended(num2, num4); if (medicine == null) { break; } num4++; } } else { bleedingStumps.Clear(); List <Hediff_MissingPart> missingPartsCommonAncestors = patient.health.hediffSet.GetMissingPartsCommonAncestors(); for (int i = 0; i < missingPartsCommonAncestors.Count; i++) { if (missingPartsCommonAncestors[i].IsFresh) { bleedingStumps.Add(missingPartsCommonAncestors[i]); } } if (bleedingStumps.Count > 0) { bleedingStumps.RandomElement <Hediff_MissingPart>().IsFresh = false; bleedingStumps.Clear(); } else { otherHediffs.Clear(); otherHediffs.AddRange(patient.health.hediffSet.GetTendableNonInjuryNonMissingPartHediffs()); Hediff hediff; if (otherHediffs.TryRandomElement(out hediff)) { HediffCompProperties_TendDuration hediffCompProperties_TendDuration = hediff.def.CompProps <HediffCompProperties_TendDuration>(); if (hediffCompProperties_TendDuration != null && hediffCompProperties_TendDuration.tendAllAtOnce) { int num6 = 0; for (int j = 0; j < otherHediffs.Count; j++) { if (otherHediffs[j].def == hediff.def) { otherHediffs[j].Tended(num2, num6); num6++; } } } else { hediff.Tended(num2, 0); } } otherHediffs.Clear(); } } if (doctor != null && patient.HostFaction == null && patient.Faction != null && patient.Faction != doctor.Faction) { patient.Faction.AffectGoodwillWith(doctor.Faction, 0.3f); } if (doctor != null && doctor.RaceProps.Humanlike && patient.RaceProps.Animal && RelationsUtility.TryDevelopBondRelation(doctor, patient, 0.004f) && doctor.Faction != null && doctor.Faction != patient.Faction) { InteractionWorker_RecruitAttempt.DoRecruit(doctor, patient, 1f, false); } patient.records.Increment(RecordDefOf.TimesTendedTo); if (doctor != null) { doctor.records.Increment(RecordDefOf.TimesTendedOther); doctor.needs.mood.thoughts.memories.TryGainMemoryThought(ThoughtDefOfPsychology.DoctorBleedingHeart, patient); } if (medicine != null) { if ((patient.Spawned || (doctor != null && doctor.Spawned)) && num > 1f) { SoundDef.Named("TechMedicineUsed").PlayOneShot(new TargetInfo(patient.Position, patient.Map, false)); } if (medicine.stackCount > 1) { medicine.stackCount--; } else if (!medicine.Destroyed) { medicine.Destroy(DestroyMode.Vanish); } } }
private static float <RecalculateUsedBeds> m__1(Building_Bed x) { return(x.GetStatValue(StatDefOf.ImmunityGainSpeedFactor, true)); }
private static float <RecalculateUsedBeds> m__0(Building_Bed x) { return(x.GetStatValue(StatDefOf.BedRestEffectiveness, true)); }
public static void DoTend(Pawn doctor, Pawn patient, Medicine medicine) { if (!patient.health.HasHediffsNeedingTend(false)) { return; } if (medicine != null && medicine.Destroyed) { Log.Warning("Tried to use destroyed medicine."); medicine = null; } float num = (medicine == null) ? 0.2f : medicine.def.GetStatValueAbstract(StatDefOf.MedicalPotency, null); float quality = num; Building_Bed building_Bed = patient.CurrentBed(); if (building_Bed != null) { quality += building_Bed.GetStatValue(StatDefOf.MedicalTendQualityOffset, true); } if (doctor != null) { quality *= doctor.GetStatValue(StatDefOf.HealingQuality, true); } quality = Mathf.Clamp01(quality); if (patient.health.hediffSet.GetInjuriesTendable().Any <Hediff_Injury>()) { float maxSeverity = 0f; int batchPosition = 0; // added prio by bleeding, everything else vanilla foreach (Hediff_Injury current in from x in patient.health.hediffSet.GetInjuriesTendable().Where(x => x.BleedRate > 0) orderby x.BleedRate descending select x) { float severity = Mathf.Min(current.Severity, 20f); if (maxSeverity + severity > 20f) { break; } maxSeverity += severity; current.Tended(quality, batchPosition); if (medicine == null) { break; } batchPosition++; } foreach (Hediff_Injury current in from x in patient.health.hediffSet.GetInjuriesTendable() orderby x.Severity descending select x) { float severity = Mathf.Min(current.Severity, 20f); if (maxSeverity + severity > 20f) { break; } maxSeverity += severity; current.Tended(quality, batchPosition); if (medicine == null) { break; } batchPosition++; } } else { _TendUtility.bleedingStumps.Clear(); List <Hediff_MissingPart> missingPartsCommonAncestors = patient.health.hediffSet.GetMissingPartsCommonAncestors(); for (int i = 0; i < missingPartsCommonAncestors.Count; i++) { if (missingPartsCommonAncestors[i].IsFresh) { _TendUtility.bleedingStumps.Add(missingPartsCommonAncestors[i]); } } if (_TendUtility.bleedingStumps.Count > 0) { _TendUtility.bleedingStumps.RandomElement <Hediff_MissingPart>().IsFresh = false; _TendUtility.bleedingStumps.Clear(); } else { _TendUtility.otherHediffs.Clear(); _TendUtility.otherHediffs.AddRange(patient.health.hediffSet.GetTendableNonInjuryNonMissingPartHediffs()); Hediff hediff; if (_TendUtility.otherHediffs.TryRandomElement(out hediff)) { HediffCompProperties_TendDuration hediffCompProperties_TendDuration = hediff.def.CompProps <HediffCompProperties_TendDuration>(); if (hediffCompProperties_TendDuration != null && hediffCompProperties_TendDuration.tendAllAtOnce) { int num6 = 0; for (int j = 0; j < _TendUtility.otherHediffs.Count; j++) { if (_TendUtility.otherHediffs[j].def == hediff.def) { _TendUtility.otherHediffs[j].Tended(quality, num6); num6++; } } } else { hediff.Tended(quality, 0); } } _TendUtility.otherHediffs.Clear(); } } if (doctor != null && patient.HostFaction == null && patient.Faction != null && patient.Faction != doctor.Faction) { patient.Faction.AffectGoodwillWith(doctor.Faction, 0.3f); } if (doctor != null && doctor.RaceProps.Humanlike && patient.RaceProps.Animal && RelationsUtility.TryDevelopBondRelation(doctor, patient, ChanceToDevelopBondRelationOnTended) && doctor.Faction != null && doctor.Faction != patient.Faction) { InteractionWorker_RecruitAttempt.DoRecruit(doctor, patient, 1f, false); } patient.records.Increment(RecordDefOf.TimesTendedTo); if (doctor != null) { doctor.records.Increment(RecordDefOf.TimesTendedOther); } if (medicine != null) { if ((patient.Spawned || (doctor != null && doctor.Spawned)) && num > 1f) { SoundDef.Named("TechMedicineUsed").PlayOneShot(new TargetInfo(patient.Position, patient.Map, false)); } if (medicine.stackCount > 1) { medicine.stackCount--; } else if (!medicine.Destroyed) { medicine.Destroy(DestroyMode.Vanish); } } }