public static void DamageUntilDowned(Pawn p) { if (p.health.Downed) { return; } HediffSet hediffSet = p.health.hediffSet; p.health.forceIncap = true; IEnumerable <BodyPartRecord> source = from x in HealthUtility.HittablePartsViolence(hediffSet) where !p.health.hediffSet.hediffs.Any((Hediff y) => y.Part == x && y.CurStage != null && y.CurStage.partEfficiencyOffset < 0f) select x; int num = 0; while (num < 300 && !p.Downed && source.Any <BodyPartRecord>()) { num++; BodyPartRecord bodyPartRecord = source.RandomElementByWeight((BodyPartRecord x) => x.coverageAbs); int num2 = Mathf.RoundToInt(hediffSet.GetPartHealth(bodyPartRecord)) - 3; if (num2 >= 8) { DamageDef damageDef; if (bodyPartRecord.depth == BodyPartDepth.Outside) { damageDef = HealthUtility.RandomViolenceDamageType(); } else { damageDef = DamageDefOf.Blunt; } int num3 = Rand.RangeInclusive(Mathf.RoundToInt((float)num2 * 0.65f), num2); HediffDef hediffDefFromDamage = HealthUtility.GetHediffDefFromDamage(damageDef, p, bodyPartRecord); if (!p.health.WouldDieAfterAddingHediff(hediffDefFromDamage, bodyPartRecord, (float)num3)) { DamageDef def = damageDef; int amount = num3; BodyPartRecord hitPart = bodyPartRecord; DamageInfo dinfo = new DamageInfo(def, amount, -1f, null, hitPart, null, DamageInfo.SourceCategory.ThingOrUnknown); dinfo.SetAllowDamagePropagation(false); p.TakeDamage(dinfo); } } } if (p.Dead) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine(p + " died during GiveInjuriesToForceDowned"); for (int i = 0; i < p.health.hediffSet.hediffs.Count; i++) { stringBuilder.AppendLine(" -" + p.health.hediffSet.hediffs[i].ToString()); } Log.Error(stringBuilder.ToString()); } p.health.forceIncap = false; }
public static void DamageUntilDowned(Pawn p, bool allowBleedingWounds = true) { if (!p.health.Downed) { HediffSet hediffSet = p.health.hediffSet; p.health.forceIncap = true; IEnumerable <BodyPartRecord> source = from x in HittablePartsViolence(hediffSet) where !p.health.hediffSet.hediffs.Any((Hediff y) => y.Part == x && y.CurStage != null && y.CurStage.partEfficiencyOffset < 0f) select x; int num = 0; while (num < 300 && !p.Downed && source.Any()) { num++; BodyPartRecord bodyPartRecord = source.RandomElementByWeight((BodyPartRecord x) => x.coverageAbs); int num2 = Mathf.RoundToInt(hediffSet.GetPartHealth(bodyPartRecord)) - 3; if (num2 >= 8) { DamageDef damageDef = (bodyPartRecord.depth != BodyPartDepth.Outside) ? DamageDefOf.Blunt : ((allowBleedingWounds || !(bodyPartRecord.def.bleedRate > 0f)) ? RandomViolenceDamageType() : DamageDefOf.Blunt); int num3 = Rand.RangeInclusive(Mathf.RoundToInt((float)num2 * 0.65f), num2); HediffDef hediffDefFromDamage = GetHediffDefFromDamage(damageDef, p, bodyPartRecord); if (!p.health.WouldDieAfterAddingHediff(hediffDefFromDamage, bodyPartRecord, (float)num3)) { DamageDef def = damageDef; float amount = (float)num3; float armorPenetration = 999f; BodyPartRecord hitPart = bodyPartRecord; DamageInfo dinfo = new DamageInfo(def, amount, armorPenetration, -1f, null, hitPart); dinfo.SetAllowDamagePropagation(val: false); p.TakeDamage(dinfo); } } } if (p.Dead) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine(p + " died during GiveInjuriesToForceDowned"); for (int i = 0; i < p.health.hediffSet.hediffs.Count; i++) { stringBuilder.AppendLine(" -" + p.health.hediffSet.hediffs[i].ToString()); } Log.Error(stringBuilder.ToString()); } p.health.forceIncap = false; } }
public static float CalculatePartEfficiency(HediffSet diffSet, BodyPartRecord part, bool ignoreAddedParts = false, List <CapacityImpactor> impactors = null) { BodyPartRecord rec; for (rec = part.parent; rec != null; rec = rec.parent) { if (diffSet.HasDirectlyAddedPartFor(rec)) { Hediff_AddedPart hediff_AddedPart = (from x in diffSet.GetHediffs <Hediff_AddedPart>() where x.Part == rec select x).First(); impactors?.Add(new CapacityImpactorHediff { hediff = hediff_AddedPart }); return(hediff_AddedPart.def.addedPartProps.partEfficiency); } } if (part.parent != null && diffSet.PartIsMissing(part.parent)) { return(0f); } float num = 1f; if (!ignoreAddedParts) { for (int i = 0; i < diffSet.hediffs.Count; i++) { Hediff_AddedPart hediff_AddedPart2 = diffSet.hediffs[i] as Hediff_AddedPart; if (hediff_AddedPart2 != null && hediff_AddedPart2.Part == part) { num *= hediff_AddedPart2.def.addedPartProps.partEfficiency; if (hediff_AddedPart2.def.addedPartProps.partEfficiency != 1f) { impactors?.Add(new CapacityImpactorHediff { hediff = hediff_AddedPart2 }); } } } } float b = -1f; float num2 = 0f; bool flag = false; for (int j = 0; j < diffSet.hediffs.Count; j++) { if (diffSet.hediffs[j].Part == part && diffSet.hediffs[j].CurStage != null) { HediffStage curStage = diffSet.hediffs[j].CurStage; num2 += curStage.partEfficiencyOffset; flag |= curStage.partIgnoreMissingHP; if (curStage.partEfficiencyOffset != 0f && curStage.becomeVisible) { impactors?.Add(new CapacityImpactorHediff { hediff = diffSet.hediffs[j] }); } } } if (!flag) { float num3 = diffSet.GetPartHealth(part) / part.def.GetMaxHealth(diffSet.pawn); if (num3 != 1f) { if (DamageWorker_AddInjury.ShouldReduceDamageToPreservePart(part)) { num3 = Mathf.InverseLerp(0.1f, 1f, num3); } impactors?.Add(new CapacityImpactorBodyPartHealth { bodyPart = part }); num *= num3; } } num += num2; if (num > 0.0001f) { num = Mathf.Max(num, b); } return(Mathf.Max(num, 0f)); }
public void Notify_Resurrected() { healthState = PawnHealthState.Mobile; hediffSet.hediffs.RemoveAll((Hediff x) => x.def.everCurableByItem && x.TryGetComp <HediffComp_Immunizable>() != null); hediffSet.hediffs.RemoveAll((Hediff x) => x.def.everCurableByItem && x is Hediff_Injury && !x.IsPermanent()); hediffSet.hediffs.RemoveAll((Hediff x) => x.def.everCurableByItem && (x.def.lethalSeverity >= 0f || (x.def.stages != null && x.def.stages.Any((HediffStage y) => y.lifeThreatening)))); hediffSet.hediffs.RemoveAll((Hediff x) => x.def.everCurableByItem && x is Hediff_Injury && x.IsPermanent() && hediffSet.GetPartHealth(x.Part) <= 0f); while (true) { Hediff_MissingPart hediff_MissingPart = (from x in hediffSet.GetMissingPartsCommonAncestors() where !hediffSet.PartOrAnyAncestorHasDirectlyAddedParts(x.Part) select x).FirstOrDefault(); if (hediff_MissingPart == null) { break; } RestorePart(hediff_MissingPart.Part, null, checkStateChange: false); } hediffSet.DirtyCache(); if (ShouldBeDead()) { hediffSet.hediffs.Clear(); } Notify_HediffChanged(null); }
private HashSet <Hediff> CalculateMissingPartHediffsFromInjury(Hediff hediff) { HashSet <Hediff> missing = null; if (hediff.Part != null && hediff.Part != pawn.RaceProps.body.corePart && hediff.Severity >= hediffSet.GetPartHealth(hediff.Part)) { missing = new HashSet <Hediff>(); AddAllParts(hediff.Part); } return(missing); void AddAllParts(BodyPartRecord part) { Hediff_MissingPart hediff_MissingPart = (Hediff_MissingPart)HediffMaker.MakeHediff(HediffDefOf.MissingBodyPart, pawn); hediff_MissingPart.lastInjury = hediff.def; hediff_MissingPart.Part = part; missing.Add(hediff_MissingPart); foreach (BodyPartRecord part in part.parts) { AddAllParts(part); } } }