private void DiagnosePatient(Pawn patientPawn) { // List all of the patient's hediffs/injuries, sorted by body part hierarchy then severity // Hediffs with no body part defined (i.e. "Whole Body" hediffs) are moved to the bottom of the list) patientTreatableHediffs = patientPawn.health.hediffSet.hediffs.OrderBy((Hediff x) => x.Part == null ? 9999 : x.Part.Index).ThenByDescending((Hediff x) => x.Severity).ToList(); // Ignore missing child parts of limbs and other body parts that have been replaced with // implants or prosthetics // This is a multi-step process: // - Find the hediffs (and the associated body parts) corresponding to implants/prosthetics // - Identify the child parts affected by the implants/prosthetics // - Remove the hediffs from the treatment list by body part List <Hediff> artificialPartHediffs = patientTreatableHediffs.FindAll((Hediff x) => x.def.hediffClass.Equals(typeof(Hediff_AddedPart))); List <BodyPartRecord> childPartsToSkip = new List <BodyPartRecord>(); foreach (Hediff currentArtificialPartHediff in artificialPartHediffs) { childPartsToSkip.AddRange(GetBodyPartDescendants(currentArtificialPartHediff.part)); } // Only ignore Missing part Hediffs from body parts that have been replaced patientTreatableHediffs.RemoveAll((Hediff x) => childPartsToSkip.Any(p => x.part == p) && x.def.hediffClass == typeof(Hediff_MissingPart)); // Ignore hediffs/injuries that are: // - Not explicitly whitelisted as always treatable // - Blacklisted as never treatable // - Not bad (i.e isBad = false) and not treatable patientTreatableHediffs.RemoveAll((Hediff x) => !AlwaysTreatableHediffs.Contains(x.def) && (NeverTreatableHediffs.Contains(x.def) || (!x.def.isBad && !x.TendableNow()))); // Induce coma in the patient so that they don't run off during treatment // (Pawns tend to get up as soon as they are "no longer incapable of walking") AnesthesizePatient(patientPawn); // Calculate individual and total cumulative treatment time for each hediff/injury foreach (Hediff currentHediff in patientTreatableHediffs) { float currentSeverity = currentHediff.Severity; // currentHediff.Part will throw an error if a hediff is applied to the whole body (e.g. malnutrition), as part == null float currentBodyPartMaxHealth = (currentHediff.Part != null) ? CompatibilityWrapper.GetMaxHealth(currentHediff.Part.def, patientPawn, currentHediff.Part) : 1; float currentNormalizedSeverity = (currentSeverity < 1) ? currentSeverity : currentSeverity / currentBodyPartMaxHealth; totalNormalizedSeverities += currentNormalizedSeverity; TotalHealingTicks += (int)Math.Ceiling(GetHediffNormalizedSeverity(currentHediff) * MaxHealingTicks); // Tend all bleeding hediffs immediately so the pawn doesn't die after being anesthetized by the MedPod // The Hediff will be completely removed once the Medpod is done with the Healing process if (currentHediff.Bleeding) { currentHediff.Tended(1); // TODO - Replace with new method name once it no longer has a temporary name } } }
private float GetHediffNormalizedSeverity(Hediff specificHediff = null) { Hediff currentHediff = (specificHediff == null) ? patientTreatableHediffs.First() : specificHediff; float currentHediffSeverity = currentHediff.Severity; float currentHediffBodyPartMaxHealth = (currentHediff.Part != null) ? CompatibilityWrapper.GetMaxHealth(currentHediff.Part.def, PatientPawn, currentHediff.Part) : 1; float currentHediffNormalizedSeverity = (currentHediffSeverity < 1) ? currentHediffSeverity : currentHediffSeverity / currentHediffBodyPartMaxHealth; return(currentHediffNormalizedSeverity); }