private void CalculateOldInjuryDamageThreshold(Pawn pawn, Hediff_Injury injury) { HediffCompProperties hediffCompProperties = injury.def.CompPropsFor(typeof(HediffComp_GetsOld)); if (hediffCompProperties == null) { return; } if (injury.Part.def.IsSolid(injury.Part, pawn.health.hediffSet.hediffs) || pawn.health.hediffSet.PartOrAnyAncestorHasDirectlyAddedParts(injury.Part) || injury.IsOld() || injury.Part.def.oldInjuryBaseChance < 1E-05f) { return; } bool isDelicate = injury.Part.def.IsDelicate; if ((Rand.Value <= injury.Part.def.oldInjuryBaseChance * hediffCompProperties.becomeOldChance && injury.Severity >= injury.Part.def.GetMaxHealth(pawn) * 0.25f && injury.Severity >= 7f) || isDelicate) { HediffComp_GetsOld hediffComp_GetsOld = injury.TryGetComp <HediffComp_GetsOld>(); float num = 1f; float num2 = injury.Severity / 2f; if (num <= num2) { hediffComp_GetsOld.oldDamageThreshold = Rand.Range(num, num2); } if (isDelicate) { hediffComp_GetsOld.oldDamageThreshold = injury.Severity; hediffComp_GetsOld.IsOld = true; } } }
public void InitializeOptions() { // Add long-term chronic conditions from the giver that adds new hediffs as pawns age. HediffGiverSetDef giverSetDef = DefDatabase <HediffGiverSetDef> .GetNamedSilentFail("OrganicStandard"); HashSet <HediffDef> addedDefs = new HashSet <HediffDef>(); if (giverSetDef != null) { foreach (var g in giverSetDef.hediffGivers) { if (g.GetType() == typeof(HediffGiver_Birthday)) { InjuryOption option = new InjuryOption(); option.Chronic = true; option.HediffDef = g.hediff; option.Label = g.hediff.LabelCap; option.Giver = g; if (!g.canAffectAnyLivePart) { option.ValidParts = new List <BodyPartDef>(); option.ValidParts.AddRange(g.partsToAffect); } options.Add(option); if (!addedDefs.Contains(g.hediff)) { addedDefs.Add(g.hediff); } } } } // Get all of the hediffs that can be added via the "forced hediff" scenario part and // add them to a hash set so that we can quickly look them up. ScenPart_ForcedHediff scenPart = new ScenPart_ForcedHediff(); IEnumerable <HediffDef> scenPartDefs = (IEnumerable <HediffDef>) typeof(ScenPart_ForcedHediff).GetMethod("PossibleHediffs", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(scenPart, null); HashSet <HediffDef> scenPartDefSet = new HashSet <HediffDef>(scenPartDefs); // Add injury options. List <InjuryOption> oldInjuries = new List <InjuryOption>(); foreach (var hd in DefDatabase <HediffDef> .AllDefs) { // TODO: Missing body part seems to be a special case. The hediff giver doesn't itself remove // limbs, so disable it until we can add special-case handling. if (hd.defName == "MissingBodyPart") { continue; } // Filter out defs that were already added as a chronic condition. if (addedDefs.Contains(hd)) { continue; } // Filter out implants. if (hd.hediffClass == typeof(Hediff_AddedPart)) { continue; } // If it's old injury, use the old injury properties to get the label. HediffCompProperties getsOldProperties = hd.CompPropsFor(typeof(HediffComp_GetsOld)); String label; if (getsOldProperties != null) { if (getsOldProperties.oldLabel != null) { label = getsOldProperties.oldLabel.CapitalizeFirst(); } else { Log.Warning("Could not find label for old injury: " + hd.defName); continue; } } // If it's not an old injury, make sure it's one of the available hediffs that can // be added via ScenPart_ForcedHediff. If it's not, filter it out. else { if (!scenPartDefSet.Contains(hd)) { continue; } label = hd.LabelCap; } // Add the injury option. InjuryOption option = new InjuryOption(); option.HediffDef = hd; option.Label = label; if (getsOldProperties != null) { option.IsOldInjury = true; } else { option.ValidParts = new List <BodyPartDef>(); } oldInjuries.Add(option); } // Disambiguate duplicate injury labels. HashSet <string> labels = new HashSet <string>(); HashSet <string> duplicateLabels = new HashSet <string>(); foreach (var option in oldInjuries) { if (labels.Contains(option.Label)) { duplicateLabels.Add(option.Label); } else { labels.Add(option.Label); } } foreach (var option in oldInjuries) { HediffCompProperties props = option.HediffDef.CompPropsFor(typeof(HediffComp_GetsOld)); if (props != null) { if (duplicateLabels.Contains(option.Label)) { string label = "EdB.PrepareCarefully.InjuryLabel".Translate(new string[] { props.oldLabel.CapitalizeFirst(), option.HediffDef.LabelCap }); option.Label = label; } } } // Add old injuries to the full list of injury options options.AddRange(oldInjuries); // Sort by name. options.Sort((InjuryOption x, InjuryOption y) => { return(string.Compare(x.Label, y.Label)); }); }
protected void InitializeInjuryOptions(OptionsHealth options, ThingDef pawnThingDef) { HashSet <HediffDef> addedDefs = new HashSet <HediffDef>(); // Go through all of the hediff giver sets for the pawn's race and intialize injuries from // each giver. if (pawnThingDef.race.hediffGiverSets != null) { foreach (var giverSetDef in pawnThingDef.race.hediffGiverSets) { foreach (var giver in giverSetDef.hediffGivers) { InitializeHediffGiverInjuries(options, giver); } } } // Go through all hediff stages, looking for hediff givers. foreach (var hd in DefDatabase <HediffDef> .AllDefs) { if (hd.stages != null) { foreach (var stage in hd.stages) { if (stage.hediffGivers != null) { foreach (var giver in stage.hediffGivers) { InitializeHediffGiverInjuries(options, giver); } } } } } // Go through all of the chemical defs, looking for hediff givers. foreach (var chemicalDef in DefDatabase <ChemicalDef> .AllDefs) { if (chemicalDef.onGeneratedAddictedEvents != null) { foreach (var giver in chemicalDef.onGeneratedAddictedEvents) { InitializeHediffGiverInjuries(options, giver); } } } // Get all of the hediffs that can be added via the "forced hediff" scenario part and // add them to a hash set so that we can quickly look them up. ScenPart_ForcedHediff scenPart = new ScenPart_ForcedHediff(); IEnumerable <HediffDef> scenPartDefs = Reflection.ScenPart_ForcedHediff.PossibleHediffs(scenPart); HashSet <HediffDef> scenPartDefSet = new HashSet <HediffDef>(scenPartDefs); // Add injury options. foreach (var hd in DefDatabase <HediffDef> .AllDefs) { // TODO: Missing body part seems to be a special case. The hediff giver doesn't itself remove // limbs, so disable it until we can add special-case handling. if (hd.defName == "MissingBodyPart") { continue; } // Filter out defs that were already added via the hediff giver sets. if (addedDefs.Contains(hd)) { continue; } // Filter out implants. if (hd.hediffClass == typeof(Hediff_AddedPart)) { continue; } // If it's an old injury, use the old injury properties to get the label. HediffCompProperties p = hd.CompPropsFor(typeof(HediffComp_GetsPermanent)); HediffCompProperties_GetsPermanent getsPermanentProperties = p as HediffCompProperties_GetsPermanent; String label; if (getsPermanentProperties != null) { if (getsPermanentProperties.permanentLabel != null) { label = getsPermanentProperties.permanentLabel.CapitalizeFirst(); } else { Log.Warning("Prepare Carefully could not find label for old injury: " + hd.defName); continue; } } // If it's not an old injury, make sure it's one of the available hediffs that can // be added via ScenPart_ForcedHediff. If it's not, filter it out. else { if (!scenPartDefSet.Contains(hd)) { continue; } label = hd.LabelCap; } // Add the injury option.. InjuryOption option = new InjuryOption(); option.HediffDef = hd; option.Label = label; if (getsPermanentProperties != null) { option.IsOldInjury = true; } else { option.ValidParts = new List <BodyPartDef>(); } options.AddInjury(option); } // Disambiguate duplicate injury labels. HashSet <string> labels = new HashSet <string>(); HashSet <string> duplicateLabels = new HashSet <string>(); foreach (var option in options.InjuryOptions) { if (labels.Contains(option.Label)) { duplicateLabels.Add(option.Label); } else { labels.Add(option.Label); } } foreach (var option in options.InjuryOptions) { HediffCompProperties p = option.HediffDef.CompPropsFor(typeof(HediffComp_GetsPermanent)); HediffCompProperties_GetsPermanent props = p as HediffCompProperties_GetsPermanent; if (props != null) { if (duplicateLabels.Contains(option.Label)) { string label = "EdB.PC.Dialog.Injury.OldInjury.Label".Translate(props.permanentLabel.CapitalizeFirst(), option.HediffDef.LabelCap); option.Label = label; } } } }
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 = (Medicine)null; } float num1 = medicine == null ? 0.0f : medicine.def.GetStatValueAbstract(StatDefOf.MedicalPotency, (ThingDef)null); float quality = medicine == null ? 0.5f : num1; if (doctor != null) { quality *= doctor.GetStatValue(StatDefOf.BaseHealingQuality, true); } if (patient.InBed()) { quality *= patient.CurrentBed().GetStatValue(StatDefOf.MedicalTreatmentQualityFactor, true); } if (patient.health.hediffSet.GetInjuriesTendable().Any <Hediff_Injury>()) { float num2 = 0.0f; int batchPosition = 0; foreach (Hediff_Injury hediffInjury in (IEnumerable <Hediff_Injury>)patient.health.hediffSet.GetInjuriesTendable().OrderByDescending <Hediff_Injury, float>((Func <Hediff_Injury, float>)(x => x.Severity))) { float num3 = Mathf.Min(hediffInjury.Severity, 20f); if ((double)num2 + (double)num3 <= 20.0) { num2 += num3; hediffInjury.Tended(quality, batchPosition); if (medicine != null) { ++batchPosition; } else { break; } } else { break; } } } else { bleedingStumps.Clear(); List <Hediff_MissingPart> partsCommonAncestors = patient.health.hediffSet.GetMissingPartsCommonAncestors(); for (int index = 0; index < partsCommonAncestors.Count; ++index) { if (partsCommonAncestors[index].IsFresh) { bleedingStumps.Add(partsCommonAncestors[index]); } } if (bleedingStumps.Count > 0) { bleedingStumps.RandomElement <Hediff_MissingPart>().IsFresh = false; bleedingStumps.Clear(); } else { otherHediffs.Clear(); otherHediffs.AddRange(patient.health.hediffSet.GetTendableNonInjuryNonMissingPartHediffs()); Hediff result; if (otherHediffs.TryRandomElement <Hediff>(out result)) { HediffCompProperties hediffCompProperties = result.def.CompPropsFor(typeof(HediffComp_Tendable)); if (hediffCompProperties != null && hediffCompProperties.tendAllAtOnce) { int batchPosition = 0; for (int index = 0; index < otherHediffs.Count; ++index) { if (otherHediffs[index].def == result.def) { otherHediffs[index].Tended(quality, batchPosition); ++batchPosition; } } } else { result.Tended(quality, 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.01f)) && (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) { return; } if ((patient.Spawned || doctor != null && doctor.Spawned) && (double)num1 > 0.899999976158142) { SoundDef.Named("TechMedicineUsed").PlayOneShot((SoundInfo)patient.Position); } if (medicine.stackCount > 1) { --medicine.stackCount; } else { if (medicine.Destroyed) { return; } medicine.Destroy(DestroyMode.Vanish); } }