private void CheckDuplicateDamageToOuterParts(DamageInfo dinfo, Pawn pawn, float totalDamage, DamageWorker.DamageResult result) { if (!dinfo.AllowDamagePropagation) { return; } if (dinfo.Def.harmAllLayersUntilOutside && dinfo.HitPart.depth == BodyPartDepth.Inside) { BodyPartRecord parent = dinfo.HitPart.parent; do { if (pawn.health.hediffSet.GetPartHealth(parent) != 0f && parent.coverageAbs > 0f) { HediffDef hediffDefFromDamage = HealthUtility.GetHediffDefFromDamage(dinfo.Def, pawn, parent); Hediff_Injury hediff_Injury = (Hediff_Injury)HediffMaker.MakeHediff(hediffDefFromDamage, pawn, null); hediff_Injury.Part = parent; hediff_Injury.source = dinfo.Weapon; hediff_Injury.sourceBodyPartGroup = dinfo.WeaponBodyPartGroup; hediff_Injury.Severity = totalDamage; if (hediff_Injury.Severity <= 0f) { hediff_Injury.Severity = 1f; } this.FinalizeAndAddInjury(pawn, hediff_Injury, dinfo, result); } if (parent.depth == BodyPartDepth.Outside) { break; } parent = parent.parent; }while (parent != null); } }
protected float FinalizeAndAddInjury(Pawn pawn, float totalDamage, DamageInfo dinfo, ref DamageResult result) { if (pawn.health.hediffSet.PartIsMissing(dinfo.HitPart)) { return(0f); } HediffDef hediffDefFromDamage = HealthUtility.GetHediffDefFromDamage(dinfo.Def, pawn, dinfo.HitPart); Hediff_Injury hediff_Injury = (Hediff_Injury)HediffMaker.MakeHediff(hediffDefFromDamage, pawn, null); hediff_Injury.Part = dinfo.HitPart; hediff_Injury.source = dinfo.Weapon; hediff_Injury.sourceBodyPartGroup = dinfo.WeaponBodyPartGroup; hediff_Injury.sourceHediffDef = dinfo.WeaponLinkedHediff; hediff_Injury.Severity = totalDamage; if (dinfo.InstantOldInjury) { HediffComp_GetsOld hediffComp_GetsOld = hediff_Injury.TryGetComp <HediffComp_GetsOld>(); if (hediffComp_GetsOld != null) { hediffComp_GetsOld.IsOld = true; } else { Log.Error("Tried to create instant old injury on Hediff without a GetsOld comp: " + hediffDefFromDamage + " on " + pawn); } } return(this.FinalizeAndAddInjury(pawn, hediff_Injury, dinfo, ref result)); }
protected float FinalizeAndAddInjury(Pawn pawn, float totalDamage, DamageInfo dinfo, DamageWorker.DamageResult result) { if (pawn.health.hediffSet.PartIsMissing(dinfo.HitPart)) { return(0f); } HediffDef hediffDefFromDamage = HealthUtility.GetHediffDefFromDamage(dinfo.Def, pawn, dinfo.HitPart); Hediff_Injury hediff_Injury = (Hediff_Injury)HediffMaker.MakeHediff(hediffDefFromDamage, pawn, null); hediff_Injury.Part = dinfo.HitPart; hediff_Injury.source = dinfo.Weapon; hediff_Injury.sourceBodyPartGroup = dinfo.WeaponBodyPartGroup; hediff_Injury.sourceHediffDef = dinfo.WeaponLinkedHediff; hediff_Injury.Severity = totalDamage; if (dinfo.InstantPermanentInjury) { HediffComp_GetsPermanent hediffComp_GetsPermanent = hediff_Injury.TryGetComp <HediffComp_GetsPermanent>(); if (hediffComp_GetsPermanent != null) { hediffComp_GetsPermanent.IsPermanent = true; } else { Log.Error(string.Concat(new object[] { "Tried to create instant permanent injury on Hediff without a GetsPermanent comp: ", hediffDefFromDamage, " on ", pawn }), false); } } return(this.FinalizeAndAddInjury(pawn, hediff_Injury, dinfo, result)); }
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; }
private void ApplyDamageToPart(DamageInfo dinfo, Pawn pawn, ref DamageResult result) { BodyPartRecord exactPartFromDamageInfo = this.GetExactPartFromDamageInfo(dinfo, pawn); if (exactPartFromDamageInfo != null) { dinfo.SetHitPart(exactPartFromDamageInfo); int num = dinfo.Amount; if (!dinfo.InstantOldInjury) { num = ArmorUtility.GetPostArmorDamage(pawn, dinfo.Amount, dinfo.HitPart, dinfo.Def); } if (num <= 0) { result.deflected = true; } else { if (DamageWorker_AddInjury.IsHeadshot(dinfo, pawn)) { result.headshot = true; } if (dinfo.InstantOldInjury) { HediffDef hediffDefFromDamage = HealthUtility.GetHediffDefFromDamage(dinfo.Def, pawn, dinfo.HitPart); if (hediffDefFromDamage.CompPropsFor(typeof(HediffComp_GetsOld)) == null) { return; } if (dinfo.HitPart.def.oldInjuryBaseChance == 0.0) { return; } if (dinfo.HitPart.def.IsSolid(dinfo.HitPart, pawn.health.hediffSet.hediffs)) { return; } if (pawn.health.hediffSet.PartOrAnyAncestorHasDirectlyAddedParts(dinfo.HitPart)) { return; } } if (!dinfo.AllowDamagePropagation) { this.FinalizeAndAddInjury(pawn, (float)num, dinfo, ref result); } else { this.ApplySpecialEffectsToPart(pawn, (float)num, dinfo, ref result); } } } }
private void ApplyDamageToPart(DamageInfo dinfo, Pawn pawn, DamageWorker.DamageResult result) { BodyPartRecord exactPartFromDamageInfo = this.GetExactPartFromDamageInfo(dinfo, pawn); if (exactPartFromDamageInfo != null) { dinfo.SetHitPart(exactPartFromDamageInfo); float num = dinfo.Amount; bool flag = !dinfo.InstantPermanentInjury; bool deflectedByMetalArmor = false; if (flag) { DamageDef def = dinfo.Def; bool diminishedByMetalArmor; num = ArmorUtility.GetPostArmorDamage(pawn, num, dinfo.ArmorPenetrationInt, dinfo.HitPart, ref def, out deflectedByMetalArmor, out diminishedByMetalArmor); dinfo.Def = def; if (num < dinfo.Amount) { result.diminished = true; result.diminishedByMetalArmor = diminishedByMetalArmor; } } if (num <= 0f) { result.AddPart(pawn, dinfo.HitPart); result.deflected = true; result.deflectedByMetalArmor = deflectedByMetalArmor; } else { if (DamageWorker_AddInjury.IsHeadshot(dinfo, pawn)) { result.headshot = true; } if (dinfo.InstantPermanentInjury) { HediffDef hediffDefFromDamage = HealthUtility.GetHediffDefFromDamage(dinfo.Def, pawn, dinfo.HitPart); if (hediffDefFromDamage.CompPropsFor(typeof(HediffComp_GetsPermanent)) == null || dinfo.HitPart.def.permanentInjuryBaseChance == 0f || dinfo.HitPart.def.IsSolid(dinfo.HitPart, pawn.health.hediffSet.hediffs) || pawn.health.hediffSet.PartOrAnyAncestorHasDirectlyAddedParts(dinfo.HitPart)) { return; } } if (!dinfo.AllowDamagePropagation) { this.FinalizeAndAddInjury(pawn, num, dinfo, result); } else { this.ApplySpecialEffectsToPart(pawn, num, dinfo, result); } } } }
private void ApplyDamageToPart(DamageInfo dinfo, Pawn pawn, DamageResult result) { BodyPartRecord exactPartFromDamageInfo = GetExactPartFromDamageInfo(dinfo, pawn); if (exactPartFromDamageInfo == null) { return; } dinfo.SetHitPart(exactPartFromDamageInfo); float num = dinfo.Amount; bool num2 = !dinfo.InstantPermanentInjury && !dinfo.IgnoreArmor; bool deflectedByMetalArmor = false; if (num2) { DamageDef damageDef = dinfo.Def; num = ArmorUtility.GetPostArmorDamage(pawn, num, dinfo.ArmorPenetrationInt, dinfo.HitPart, ref damageDef, out deflectedByMetalArmor, out bool diminishedByMetalArmor); dinfo.Def = damageDef; if (num < dinfo.Amount) { result.diminished = true; result.diminishedByMetalArmor = diminishedByMetalArmor; } } if (dinfo.Def.ExternalViolenceFor(pawn)) { num *= pawn.GetStatValue(StatDefOf.IncomingDamageFactor); } if (num <= 0f) { result.AddPart(pawn, dinfo.HitPart); result.deflected = true; result.deflectedByMetalArmor = deflectedByMetalArmor; return; } if (IsHeadshot(dinfo, pawn)) { result.headshot = true; } if (!dinfo.InstantPermanentInjury || (HealthUtility.GetHediffDefFromDamage(dinfo.Def, pawn, dinfo.HitPart).CompPropsFor(typeof(HediffComp_GetsPermanent)) != null && dinfo.HitPart.def.permanentInjuryChanceFactor != 0f && !pawn.health.hediffSet.PartOrAnyAncestorHasDirectlyAddedParts(dinfo.HitPart))) { if (!dinfo.AllowDamagePropagation) { FinalizeAndAddInjury(pawn, num, dinfo, result); } else { ApplySpecialEffectsToPart(pawn, num, dinfo, result); } } }
public static void DamageLegsUntilIncapableOfMoving(Pawn p, bool allowBleedingWounds = true) { int num = 0; p.health.forceIncap = true; while (p.health.capacities.CapableOf(PawnCapacityDefOf.Moving) && num < 300) { num++; IEnumerable <BodyPartRecord> source = from x in p.health.hediffSet.GetNotMissingParts(BodyPartHeight.Undefined, BodyPartDepth.Undefined, null, null) where x.def.tags.Contains(BodyPartTagDefOf.MovingLimbCore) && p.health.hediffSet.GetPartHealth(x) >= 2f select x; if (!source.Any <BodyPartRecord>()) { break; } BodyPartRecord bodyPartRecord = source.RandomElement <BodyPartRecord>(); float maxHealth = bodyPartRecord.def.GetMaxHealth(p); float partHealth = p.health.hediffSet.GetPartHealth(bodyPartRecord); int min = Mathf.Clamp(Mathf.RoundToInt(maxHealth * 0.12f), 1, (int)partHealth - 1); int max = Mathf.Clamp(Mathf.RoundToInt(maxHealth * 0.27f), 1, (int)partHealth - 1); int num2 = Rand.RangeInclusive(min, max); DamageDef damageDef; if (!allowBleedingWounds && bodyPartRecord.def.bleedRate > 0f) { damageDef = DamageDefOf.Blunt; } else { damageDef = HealthUtility.RandomViolenceDamageType(); } HediffDef hediffDefFromDamage = HealthUtility.GetHediffDefFromDamage(damageDef, p, bodyPartRecord); if (p.health.WouldDieAfterAddingHediff(hediffDefFromDamage, bodyPartRecord, (float)num2)) { break; } DamageDef def = damageDef; float amount = (float)num2; float armorPenetration = 999f; BodyPartRecord hitPart = bodyPartRecord; DamageInfo dinfo = new DamageInfo(def, amount, armorPenetration, -1f, null, hitPart, null, DamageInfo.SourceCategory.ThingOrUnknown, null); dinfo.SetAllowDamagePropagation(false); p.TakeDamage(dinfo); } p.health.forceIncap = false; }
public void AddDirect(Hediff hediff, DamageInfo?dinfo = default(DamageInfo?), DamageWorker.DamageResult damageResult = null) { if (hediff.def == null) { Log.Error("Tried to add health diff with null def. Canceling."); } else if (hediff.Part != null && !GetNotMissingParts().Contains(hediff.Part)) { Log.Error("Tried to add health diff to missing part " + hediff.Part); } else { hediff.ageTicks = 0; hediff.pawn = pawn; bool flag = false; for (int i = 0; i < hediffs.Count; i++) { if (hediffs[i].TryMergeWith(hediff)) { flag = true; } } if (!flag) { hediffs.Add(hediff); hediff.PostAdd(dinfo); if (pawn.needs != null && pawn.needs.mood != null) { pawn.needs.mood.thoughts.situational.Notify_SituationalThoughtsDirty(); } } bool flag2 = hediff is Hediff_MissingPart; if (!(hediff is Hediff_MissingPart) && hediff.Part != null && hediff.Part != pawn.RaceProps.body.corePart && GetPartHealth(hediff.Part) == 0f && hediff.Part != pawn.RaceProps.body.corePart) { bool flag3 = HasDirectlyAddedPartFor(hediff.Part); Hediff_MissingPart hediff_MissingPart = (Hediff_MissingPart)HediffMaker.MakeHediff(HediffDefOf.MissingBodyPart, pawn); hediff_MissingPart.IsFresh = !flag3; hediff_MissingPart.lastInjury = hediff.def; pawn.health.AddHediff(hediff_MissingPart, hediff.Part, dinfo); damageResult?.AddHediff(hediff_MissingPart); if (flag3) { if (dinfo.HasValue) { hediff_MissingPart.lastInjury = HealthUtility.GetHediffDefFromDamage(dinfo.Value.Def, pawn, hediff.Part); } else { hediff_MissingPart.lastInjury = null; } } flag2 = true; } DirtyCache(); if (flag2 && pawn.apparel != null) { pawn.apparel.Notify_LostBodyPart(); } if (hediff.def.causesNeed != null && !pawn.Dead) { pawn.needs.AddOrRemoveNeedsAsAppropriate(); } } }