// Token: 0x06004B8B RID: 19339 RVA: 0x00234924 File Offset: 0x00232D24 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); } }
// // Static Methods // public static void GenerateRandomOldAgeInjuries(Pawn pawn, bool tryNotToKillPawn) { int num = 0; for (int i = 10; i < Mathf.Min(pawn.ageTracker.AgeBiologicalYears, 120); i += 10) { if (Rand.Value < 0.15f) { num++; } } for (int j = 0; j < num; j++) { IEnumerable <BodyPartRecord> source = from x in pawn.health.hediffSet.GetNotMissingParts(BodyPartHeight.Undefined, BodyPartDepth.Undefined) where x.depth == BodyPartDepth.Outside && !Mathf.Approximately(x.def.oldInjuryBaseChance, 0f) && !pawn.health.hediffSet.PartOrAnyAncestorHasDirectlyAddedParts(x) select x; if (source.Any <BodyPartRecord>()) { BodyPartRecord bodyPartRecord = source.RandomElementByWeight((BodyPartRecord x) => x.coverageAbs); DamageDef dam = AgeInjuryUtility.RandomOldInjuryDamageType(bodyPartRecord.def.frostbiteVulnerability > 0f && pawn.RaceProps.ToolUser); HediffDef hediffDefFromDamage = HealthUtility.GetHediffDefFromDamage(dam, pawn, bodyPartRecord); if (bodyPartRecord.def.oldInjuryBaseChance > 0f && hediffDefFromDamage.CompPropsFor(typeof(HediffComp_GetsOld)) != null) { if (Rand.Chance(bodyPartRecord.def.amputateIfGeneratedInjuredChance)) { Hediff_MissingPart hediff_MissingPart = (Hediff_MissingPart)HediffMaker.MakeHediff(HediffDefOf.MissingBodyPart, pawn, null); hediff_MissingPart.lastInjury = hediffDefFromDamage; hediff_MissingPart.TryGetComp <HediffComp_GetsOld>().IsOld = true; pawn.health.AddHediff(hediff_MissingPart, bodyPartRecord, null); if (pawn.RaceProps.Humanlike && (bodyPartRecord.def == BodyPartDefOf.LeftLeg || bodyPartRecord.def == BodyPartDefOf.RightLeg) && Rand.Chance(0.5f)) { RecipeDefOf.InstallPegLeg.Worker.ApplyOnPawn(pawn, bodyPartRecord, null, AgeInjuryUtility.emptyIngredientsList, null); } } else { Hediff_Injury hediff_Injury = (Hediff_Injury)HediffMaker.MakeHediff(hediffDefFromDamage, pawn, null); hediff_Injury.Severity = (float)Rand.RangeInclusive(2, 6); hediff_Injury.TryGetComp <HediffComp_GetsOld>().IsOld = true; pawn.health.AddHediff(hediff_Injury, bodyPartRecord, null); } } } } for (int k = 1; k < pawn.ageTracker.AgeBiologicalYears; k++) { foreach (HediffGiver_Birthday current in AgeInjuryUtility.RandomHediffsToGainOnBirthday(pawn, k)) { current.TryApplyAndSimulateSeverityChange(pawn, (float)k, tryNotToKillPawn); if (pawn.Dead) { break; } } if (pawn.Dead) { break; } } }
// Token: 0x06004B89 RID: 19337 RVA: 0x002347B4 File Offset: 0x00232BB4 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 roll_for_syphilis_damage(Pawn p) { var syp = p.health.hediffSet.GetFirstHediffOfDef(syphilis.hediff_def); if ((syp != null) && (syp.Severity >= 0.60f) && (!syp.FullyImmune())) { // A 30% chance per day of getting any permanent damage works out to ~891 in 1 million for each roll // The equation is (1-x)^(60000/150)=.7 // Important Note: // this function is called from Need_Sex::NeedInterval(), where it involves a needsex_tick and a std_tick to actually trigger this roll_for_syphilis_damage. // j(this is not exactly the same as the value in Need_Sex, that value is 0, but here j should be 1) std_ticks per this function called, k needsex_ticks per std_tick, 150 ticks per needsex_tick, and x is the chance per 150 ticks, // The new equation should be .7 = (1-x)^(400/kj) // 1-x = .7^(kj/400), x =1-.7^(kj/400) // Since k=10,j=1, so kj=10, new x is 1-.7^(10/400)=0.0088772362, let it be 888/100000 if (Rand.RangeInclusive(1, 100000) <= 888) { BodyPartRecord part; float sev; { var rv = Rand.Value; if (rv < 0.10f) { part = BodyDefOf.Human.AllParts.Find((BodyPartRecord bpr) => String.Equals(bpr.def.defName, "Brain")); sev = 1.0f; } else if (rv < 0.50f) { part = BodyDefOf.Human.AllParts.Find((BodyPartRecord bpr) => String.Equals(bpr.def.defName, "Liver")); sev = (float)Rand.RangeInclusive(1, 3); } else if (rv < 0.75f) { part = BodyDefOf.Human.AllParts.Find((BodyPartRecord bpr) => String.Equals(bpr.def.defName, "LeftKidney")); sev = (float)Rand.RangeInclusive(1, 2); } else { part = BodyDefOf.Human.AllParts.Find((BodyPartRecord bpr) => String.Equals(bpr.def.defName, "RightKidney")); sev = (float)Rand.RangeInclusive(1, 2); } } if ((part != null) && (!p.health.hediffSet.PartIsMissing(part)) && (!p.health.hediffSet.HasDirectlyAddedPartFor(part))) { var vir_dam = DefDatabase <DamageDef> .GetNamed("ViralDamage"); var dam_def = HealthUtility.GetHediffDefFromDamage(vir_dam, p, part); var inj = (Hediff_Injury)HediffMaker.MakeHediff(dam_def, p, null); inj.Severity = sev; inj.TryGetComp <HediffComp_GetsOld>().IsOld = true; p.health.AddHediff(inj, part, null); Find.LetterStack.ReceiveLetter(syphilis.label + " Damage", "RJW_Syphilis_Damage_Message".Translate(new object[] { p.NameStringShort, (p.gender == Gender.Male ? "Prohis".Translate() : "Proher".Translate()), part.def.label, syphilis.label }), LetterDefOf.ThreatSmall, p); } } } }
public static void DamagePart(Pawn p, int damage, BodyPartRecord part) { HediffDef hediffDefFromDamage = HealthUtility.GetHediffDefFromDamage(DamageDefOf.SurgicalCut, p, part); Hediff_Injury injury = (Hediff_Injury)HediffMaker.MakeHediff(hediffDefFromDamage, p, part); injury.Severity = damage; p.health.AddHediff(injury, part, new DamageInfo(DamageDefOf.SurgicalCut, damage, 999f, -1f, null, part)); GenLeaving.DropFilthDueToDamage(p, damage); }
// Applies permanent damage to a randomly chosen colonist, to test that this works public static void damage_virally(Map m) { var vir_dam = DefDatabase <DamageDef> .GetNamed("ViralDamage"); var p = m.mapPawns.FreeColonists.RandomElement(); var lun = BodyDefOf.Human.AllParts.Find((BodyPartRecord bpr) => String.Equals(bpr.def.defName, "LeftLung")); var dam_def = HealthUtility.GetHediffDefFromDamage(vir_dam, p, lun); var inj = (Hediff_Injury)HediffMaker.MakeHediff(dam_def, p, null); inj.Severity = 2.0f; inj.TryGetComp <HediffComp_GetsOld>().IsOld = true; p.health.AddHediff(inj, lun, null); }
// Token: 0x06004B87 RID: 19335 RVA: 0x00234638 File Offset: 0x00232A38 private void ApplyDamageToPart(DamageInfo dinfo, Pawn pawn, DamageWorker.DamageResult result) { BodyPartRecord exactPartFromDamageInfo = this.GetExactPartFromDamageInfo(dinfo, pawn); if (exactPartFromDamageInfo == null) { return; } dinfo.SetHitPart(exactPartFromDamageInfo); float num = dinfo.Amount; bool flag = !dinfo.InstantPermanentInjury; bool deflectedByMetalArmor = false; if (flag) { DamageDef def = dinfo.Def; num = ArmorUtility.GetPostArmorDamage(pawn, num, dinfo.ArmorPenetrationInt, dinfo.HitPart, ref def, out deflectedByMetalArmor, out bool 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; return; } if (DamageWorker_CombiPin.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.permanentInjuryChanceFactor == 0f || pawn.health.hediffSet.PartOrAnyAncestorHasDirectlyAddedParts(dinfo.HitPart)) { return; } } if (!dinfo.AllowDamagePropagation) { this.FinalizeAndAddInjury(pawn, num, dinfo, result); return; } this.ApplySpecialEffectsToPart(pawn, num, dinfo, result); }
private void CheckDuplicateDamageToOuterParts(DamageInfo dinfo, Pawn pawn, Hediff_Injury injury, bool involveArmor, ref DamageWorker_AddInjuryCE.LocalInjuryResult result) { if (!dinfo.AllowDamagePropagation) { return; } if (dinfo.Def.harmAllLayersUntilOutside && injury.Part.depth == BodyPartDepth.Inside) { BodyPartRecord parent = injury.Part.parent; do { if (pawn.health.hediffSet.GetPartHealth(parent) != 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 = injury.source; hediff_Injury.sourceBodyPartGroup = injury.sourceBodyPartGroup; hediff_Injury.Severity = (float)dinfo.Amount; /* * if (involveArmor) * { * //hediff_Injury.Severity = (float)ArmorUtility.GetAfterArmorDamage(pawn, dinfo.Amount, parent, dinfo.Def); * } */ if (hediff_Injury.Severity <= 0f) { hediff_Injury.Severity = 1f; } result.lastHitPart = hediff_Injury.Part; this.FinalizeAndAddInjury(pawn, hediff_Injury, dinfo, ref result); } if (parent.depth == BodyPartDepth.Outside) { break; } parent = parent.parent; }while (parent != null); } }
private void CheckPropagateDamageToInnerSolidParts(DamageInfo dinfo, Pawn pawn, Hediff_Injury injury, bool involveArmor, ref DamageWorker_AddInjuryCE.LocalInjuryResult result) { if (!dinfo.AllowDamagePropagation) { return; } if (Rand.Value >= HealthTunings.ChanceToAdditionallyDamageInnerSolidPart) { return; } if (dinfo.Def.hasChanceToAdditionallyDamageInnerSolidParts && !injury.Part.def.IsSolid(injury.Part, pawn.health.hediffSet.hediffs) && injury.Part.depth == BodyPartDepth.Outside) { IEnumerable <BodyPartRecord> source = from x in pawn.health.hediffSet.GetNotMissingParts(BodyPartHeight.Undefined, BodyPartDepth.Undefined) where x.parent == injury.Part && x.def.IsSolid(x, pawn.health.hediffSet.hediffs) && x.depth == BodyPartDepth.Inside select x; BodyPartRecord part; if (source.TryRandomElementByWeight((BodyPartRecord x) => x.coverageAbs, out part)) { HediffDef hediffDefFromDamage = HealthUtility.GetHediffDefFromDamage(dinfo.Def, pawn, part); Hediff_Injury hediff_Injury = (Hediff_Injury)HediffMaker.MakeHediff(hediffDefFromDamage, pawn, null); hediff_Injury.Part = part; hediff_Injury.source = injury.source; hediff_Injury.sourceBodyPartGroup = injury.sourceBodyPartGroup; hediff_Injury.Severity = (float)(dinfo.Amount / 2); /* * if (involveArmor) * { * hediff_Injury.Severity = (float)ArmorUtility.GetAfterArmorDamage(pawn, dinfo.Amount / 2, part, dinfo.Def); * } */ if (hediff_Injury.Severity <= 0f) { return; } result.lastHitPart = hediff_Injury.Part; this.FinalizeAndAddInjury(pawn, hediff_Injury, dinfo, ref result); } } }
// // Static Methods // public static void GenerateRandomOldAgeInjuries(Pawn pawn, bool tryNotToKillPawn) { int num = 0; for (int i = 10; i < pawn.ageTracker.AgeBiologicalYears; i += 10) { if (Rand.Value < 0.15) { num++; } } for (int j = 0; j < num; j++) { DamageDef dam = AgeInjuryUtility.RandomOldInjuryDamageType(); int num2 = Rand.RangeInclusive(2, 6); IEnumerable <BodyPartRecord> source = from x in pawn.health.hediffSet.GetNotMissingParts(BodyPartHeight.Undefined, BodyPartDepth.Undefined) where x.depth == BodyPartDepth.Outside && !Mathf.Approximately(x.def.oldInjuryBaseChance, 0) && !pawn.health.hediffSet.PartOrAnyAncestorHasDirectlyAddedParts(x) select x; if (source.Any <BodyPartRecord>()) { BodyPartRecord bodyPartRecord = source.RandomElementByWeight((BodyPartRecord x) => x.absoluteFleshCoverage); HediffDef hediffDefFromDamage = HealthUtility.GetHediffDefFromDamage(dam, pawn, bodyPartRecord); if (bodyPartRecord.def.oldInjuryBaseChance > 0 && hediffDefFromDamage.CompPropsFor(typeof(HediffComp_GetsOld)) != null) { Hediff_Injury hediff_Injury = (Hediff_Injury)HediffMaker.MakeHediff(hediffDefFromDamage, pawn, null); hediff_Injury.Severity = (float)num2; hediff_Injury.TryGetComp <HediffComp_GetsOld>().IsOld = true; pawn.health.AddHediff(hediff_Injury, bodyPartRecord, null); } } } for (int k = 1; k < pawn.ageTracker.AgeBiologicalYears; k++) { foreach (HediffGiver_Birthday current in AgeInjuryUtility.RandomHediffsToGainOnBirthday(pawn, k)) { current.TryApplyAndSimulateSeverityChange(pawn, (float)k, tryNotToKillPawn); } } }
private void CheckPropagateDamageToInnerSolidParts(DamageInfo dinfo, Pawn pawn, Hediff_Injury injury, bool involveArmor, int postArmorDamage, ref DamageWorker_AddInjuryCR.LocalInjuryResult result) { if (!dinfo.AllowDamagePropagation) { return; } if (Rand.Value >= HealthTunings.ChanceToAdditionallyDamageInnerSolidPart) { return; } if (dinfo.Def.hasChanceToAdditionallyDamageInnerSolidParts && !injury.Part.def.IsSolid(injury.Part, pawn.health.hediffSet.hediffs) && injury.Part.depth == BodyPartDepth.Outside) { IEnumerable <BodyPartRecord> enumerable = pawn.health.hediffSet.GetNotMissingParts(null, null).Where(x => x.parent == injury.Part && x.def.IsSolid(x, pawn.health.hediffSet.hediffs) && x.depth == BodyPartDepth.Inside); BodyPartRecord part; if (DamageWorker_AddInjuryCR.cache0 == null) { DamageWorker_AddInjuryCR.cache0 = delegate(BodyPartRecord x) { return(x.absoluteFleshCoverage); }; } if (enumerable.TryRandomElementByWeight(DamageWorker_AddInjuryCR.cache0, out part)) { HediffDef hediffDefFromDamage = HealthUtility.GetHediffDefFromDamage(dinfo.Def, pawn, part); Hediff_Injury hediff_Injury = (Hediff_Injury)HediffMaker.MakeHediff(hediffDefFromDamage, pawn, null); hediff_Injury.Part = part; hediff_Injury.source = injury.source; hediff_Injury.sourceBodyPartGroup = injury.sourceBodyPartGroup; hediff_Injury.Severity = (float)(dinfo.Amount / 2); if (involveArmor) { hediff_Injury.Severity = (float)postArmorDamage; } if (hediff_Injury.Severity <= 0f) { return; } result.lastHitPart = hediff_Injury.Part; this.FinalizeAndAddInjury(pawn, hediff_Injury, dinfo, ref result); } } }
private void ApplyDamagePartial(DamageInfo dinfo, Pawn pawn, ref DamageWorker_AddInjuryCR.LocalInjuryResult result) { BodyPartRecord exactPartFromDamageInfo = DamageWorker_AddInjuryCR.GetExactPartFromDamageInfo(dinfo, pawn); if (exactPartFromDamageInfo == null) { return; } // Only apply armor if we propagate damage to the outside or the body part itself is outside, secondary damage types should directly damage organs, bypassing armor bool involveArmor = !dinfo.InstantOldInjury && !result.deflected && (dinfo.Def.harmAllLayersUntilOutside || exactPartFromDamageInfo.depth == BodyPartDepth.Outside); int damageAmount = dinfo.Amount; if (involveArmor) { damageAmount = Utility.GetAfterArmorDamage(pawn, dinfo.Amount, exactPartFromDamageInfo, dinfo, true, ref result.deflected); } if ((double)damageAmount < 0.001) { result.absorbed = true; return; } // Shot absorbed and converted into blunt DamageDef_CR damageDefCR = dinfo.Def as DamageDef_CR; if (damageDefCR != null && damageDefCR.deflectable && result.deflected && dinfo.Def != Utility.absorbDamageDef) { // Get outer parent of struck part BodyPartRecord currentPart = exactPartFromDamageInfo; while (currentPart != null && currentPart.parent != null && currentPart.depth != BodyPartDepth.Outside) { currentPart = currentPart.parent; } DamageInfo dinfo2 = new DamageInfo(Utility.absorbDamageDef, damageAmount, dinfo.Instigator, new BodyPartDamageInfo(currentPart, false), dinfo.Source); this.ApplyDamagePartial(dinfo2, pawn, ref result); return; } //Creating the Hediff HediffDef hediffDefFromDamage = HealthUtility.GetHediffDefFromDamage(dinfo.Def, pawn, exactPartFromDamageInfo); Hediff_Injury hediff_Injury = (Hediff_Injury)HediffMaker.MakeHediff(hediffDefFromDamage, pawn, null); hediff_Injury.Part = exactPartFromDamageInfo; hediff_Injury.source = dinfo.Source; hediff_Injury.sourceBodyPartGroup = dinfo.LinkedBodyPartGroup; hediff_Injury.sourceHediffDef = dinfo.LinkedHediffDef; hediff_Injury.Severity = (float)damageAmount; if (dinfo.InstantOldInjury) { HediffComp_GetsOld hediffComp_GetsOld = hediff_Injury.TryGetComp <HediffComp_GetsOld>(); if (hediffComp_GetsOld != null) { hediffComp_GetsOld.IsOld = true; } else { Log.Error(string.Concat(new object[] { "Tried to create instant old injury on Hediff without a GetsOld comp: ", hediffDefFromDamage, " on ", pawn })); } } result.wounded = true; result.lastHitPart = hediff_Injury.Part; if (DamageWorker_AddInjuryCR.IsHeadshot(dinfo, hediff_Injury, pawn)) { result.headshot = true; } if (dinfo.InstantOldInjury && (hediff_Injury.def.CompPropsFor(typeof(HediffComp_GetsOld)) == null || hediff_Injury.Part.def.oldInjuryBaseChance == 0f || hediff_Injury.Part.def.IsSolid(hediff_Injury.Part, pawn.health.hediffSet.hediffs) || pawn.health.hediffSet.PartOrAnyAncestorHasDirectlyAddedParts(hediff_Injury.Part))) { return; } this.FinalizeAndAddInjury(pawn, hediff_Injury, dinfo, ref result); this.CheckPropagateDamageToInnerSolidParts(dinfo, pawn, hediff_Injury, !dinfo.InstantOldInjury, damageAmount, ref result); this.CheckDuplicateDamageToOuterParts(dinfo, pawn, hediff_Injury, !dinfo.InstantOldInjury, damageAmount, ref result); }
public static void roll_for_syphilis_damage(Pawn p) { Hediff syp = p.health.hediffSet.GetFirstHediffOfDef(std.syphilis.hediff_def); if (syp == null || !(syp.Severity >= 0.60f) || syp.FullyImmune()) { return; } // A 30% chance per day of getting any permanent damage works out to ~891 in 1 million for each roll // The equation is (1-x)^(60000/150)=.7 // Important Note: // this function is called from Need_Sex::NeedInterval(), where it involves a needsex_tick and a std_tick to actually trigger this roll_for_syphilis_damage. // j(this is not exactly the same as the value in Need_Sex, that value is 0, but here j should be 1) std_ticks per this function called, k needsex_ticks per std_tick, 150 ticks per needsex_tick, and x is the chance per 150 ticks, // The new equation should be .7 = (1-x)^(400/kj) // 1-x = .7^(kj/400), x =1-.7^(kj/400) // Since k=10,j=1, so kj=10, new x is 1-.7^(10/400)=0.0088772362, let it be 888/100000 //Rand.PopState(); //Rand.PushState(RJW_Multiplayer.PredictableSeed()); if (Rand.RangeInclusive(1, 100000) <= 888) { BodyPartRecord part; float sev; var parts = p.RaceProps.body.AllParts; float rv = Rand.Value; if (rv < 0.10f) { part = parts.Find(bpr => string.Equals(bpr.def.defName, "Brain")); sev = 1.0f; } else if (rv < 0.50f) { part = parts.Find(bpr => string.Equals(bpr.def.defName, "Liver")); sev = Rand.RangeInclusive(1, 3); } else if (rv < 0.75f) { //LeftKidney, probably part = parts.Find(bpr => string.Equals(bpr.def.defName, "Kidney")); sev = Rand.RangeInclusive(1, 2); } else { //RightKidney, probably part = parts.FindLast(bpr => string.Equals(bpr.def.defName, "Kidney")); sev = Rand.RangeInclusive(1, 2); } if (part != null && !p.health.hediffSet.PartIsMissing(part) && !p.health.hediffSet.HasDirectlyAddedPartFor(part)) { DamageDef vir_dam = DefDatabase <DamageDef> .GetNamed("ViralDamage"); HediffDef dam_def = HealthUtility.GetHediffDefFromDamage(vir_dam, p, part); Hediff_Injury inj = (Hediff_Injury)HediffMaker.MakeHediff(dam_def, p, null); inj.Severity = sev; inj.TryGetComp <HediffComp_GetsPermanent>().IsPermanent = true; p.health.AddHediff(inj, part, null); string message_title = std.syphilis.label + " Damage"; string baby_pronoun = p.gender == Gender.Male ? "his" : "her"; string message_text = "RJW_Syphilis_Damage_Message".Translate(xxx.get_pawnname(p), baby_pronoun, part.def.label, std.syphilis.label); Find.LetterStack.ReceiveLetter(message_title, message_text, LetterDefOf.ThreatSmall, p); } } }
public static void DamageUntilDownedWithSpecialOptions(Pawn p, bool allowBleedingWounds = true, DamageDef damageDef = null, ThingDef weapon = null) { if (!p.health.Downed) { if (p.apparel != null) { foreach (Apparel apparel in p.apparel.WornApparel) { if (apparel.def.StatBaseDefined(StatDefOf.SmokepopBeltRadius)) { p.apparel.Remove(apparel); break; } } } HediffSet hediffSet = p.health.hediffSet; p.health.forceIncap = true; IEnumerable <BodyPartRecord> source = HittablePartsViolence(hediffSet).Where(x => !p.health.hediffSet.hediffs .Any(y => y.Part == x && y.CurStage?.partEfficiencyOffset < 0f)).ToList(); 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) { if (bodyPartRecord.depth == BodyPartDepth.Outside) { if (!allowBleedingWounds && bodyPartRecord.def.bleedRate > 0f) { damageDef = DamageDefOf.Blunt; } else { if (damageDef == null || damageDef == DamageDefOf.Flame) { 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; float amount = (float)num3; float armorPenetration = 999f; BodyPartRecord hitPart = bodyPartRecord; DamageInfo dinfo = new DamageInfo(def, amount, armorPenetration, -1f, null, hitPart, weapon); 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; } }
static bool Prefix(DamageWorker_AddInjury __instance, DamageInfo dinfo, Pawn pawn, float totalDamage, DamageWorker.DamageResult result) { var hitPart = dinfo.HitPart; if (hitPart.IsInGroup(CE_BodyPartGroupDefOf.OutsideSquishy)) { var parent = hitPart.parent; if (parent != null) { dinfo.SetHitPart(parent); if (pawn.health.hediffSet.GetPartHealth(parent) != 0f && parent.coverageAbs > 0f) { Hediff_Injury hediff_Injury = (Hediff_Injury)HediffMaker.MakeHediff(HealthUtility.GetHediffDefFromDamage(dinfo.Def, pawn, parent), 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; } FinalizeAndAddInjury.Invoke(__instance, new object[] { pawn, hediff_Injury, dinfo, result }); } } } return(true); }
public static bool AddDirect(HediffSet __instance, Hediff hediff, DamageInfo?dinfo = null, DamageWorker.DamageResult damageResult = null) { if (hediff.def == null) { Log.Error("Tried to add health diff with null def. Canceling."); return(false); } if (hediff.Part != null && !__instance.GetNotMissingParts().Contains(hediff.Part)) { Log.Error("Tried to add health diff to missing part " + hediff.Part); return(false); } hediff.ageTicks = 0; hediff.pawn = __instance.pawn; bool flag = false; for (int i = 0; i < __instance.hediffs.Count; i++) { if (__instance.hediffs[i].TryMergeWith(hediff)) { flag = true; } } if (!flag) { lock (__instance) { //List<Hediff> newHediffs = new List<Hediff>(__instance.hediffs) { hediff }; //__instance.hediffs = newHediffs; __instance.hediffs.Add(hediff); } hediff.PostAdd(dinfo); if (__instance.pawn.needs != null && __instance.pawn.needs.mood != null) { __instance.pawn.needs.mood.thoughts.situational.Notify_SituationalThoughtsDirty(); } } bool flag2 = hediff is Hediff_MissingPart; if (!(hediff is Hediff_MissingPart) && hediff.Part != null && hediff.Part != __instance.pawn.RaceProps.body.corePart && __instance.GetPartHealth(hediff.Part) == 0f && hediff.Part != __instance.pawn.RaceProps.body.corePart) { bool flag3 = __instance.HasDirectlyAddedPartFor(hediff.Part); Hediff_MissingPart hediff_MissingPart = (Hediff_MissingPart)HediffMaker.MakeHediff(HediffDefOf.MissingBodyPart, __instance.pawn); hediff_MissingPart.IsFresh = !flag3; hediff_MissingPart.lastInjury = hediff.def; __instance.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, __instance.pawn, hediff.Part); } else { hediff_MissingPart.lastInjury = null; } } flag2 = true; } __instance.DirtyCache(); if (flag2 && __instance.pawn.apparel != null) { __instance.pawn.apparel.Notify_LostBodyPart(); } if (hediff.def.causesNeed != null && !__instance.pawn.Dead) { __instance.pawn.needs.AddOrRemoveNeedsAsAppropriate(); } return(false); }
private void ApplyDamageToPart(DamageInfo dinfo, Pawn pawn, ref DamageWorker_AddInjuryCE.LocalInjuryResult result) { BodyPartRecord exactPartFromDamageInfo = GetExactPartFromDamageInfo(dinfo, pawn); if (exactPartFromDamageInfo == null) { return; } bool involveArmor = !dinfo.InstantOldInjury; DamageInfo postArmorDinfo = dinfo; bool shieldAbsorbed = false; if (involveArmor) { postArmorDinfo = ArmorUtilityCE.GetAfterArmorDamage(dinfo, pawn, exactPartFromDamageInfo, out shieldAbsorbed); if (dinfo.ForceHitPart == null && postArmorDinfo.ForceHitPart != null && exactPartFromDamageInfo != postArmorDinfo.ForceHitPart) { exactPartFromDamageInfo = postArmorDinfo.ForceHitPart; // If the shot was deflected, update our body part if (pawn.Spawned) { LessonAutoActivator.TeachOpportunity(CE_ConceptDefOf.CE_ArmorSystem, OpportunityType.Critical); // Inform the player about armor deflection } } } // Vanilla code - apply hediff if ((double)postArmorDinfo.Amount < 0.001) { result.deflected = true; return; } HediffDef hediffDefFromDamage = HealthUtility.GetHediffDefFromDamage(postArmorDinfo.Def, pawn, exactPartFromDamageInfo); Hediff_Injury hediff_Injury = (Hediff_Injury)HediffMaker.MakeHediff(hediffDefFromDamage, pawn, null); hediff_Injury.Part = exactPartFromDamageInfo; hediff_Injury.source = postArmorDinfo.WeaponGear; hediff_Injury.sourceBodyPartGroup = postArmorDinfo.WeaponBodyPartGroup; hediff_Injury.sourceHediffDef = postArmorDinfo.WeaponLinkedHediff; hediff_Injury.Severity = (float)postArmorDinfo.Amount; if (postArmorDinfo.InstantOldInjury) { HediffComp_GetsOld hediffComp_GetsOld = hediff_Injury.TryGetComp <HediffComp_GetsOld>(); if (hediffComp_GetsOld != null) { hediffComp_GetsOld.IsOld = true; } else { Log.Error(string.Concat(new object[] { "Tried to create instant old injury on Hediff without a GetsOld comp: ", hediffDefFromDamage, " on ", pawn })); } } result.wounded = true; result.lastHitPart = hediff_Injury.Part; if (DamageWorker_AddInjuryCE.IsHeadshot(postArmorDinfo, hediff_Injury, pawn)) { result.headshot = true; } if (postArmorDinfo.InstantOldInjury && (hediff_Injury.def.CompPropsFor(typeof(HediffComp_GetsOld)) == null || hediff_Injury.Part.def.oldInjuryBaseChance == 0f || hediff_Injury.Part.def.IsSolid(hediff_Injury.Part, pawn.health.hediffSet.hediffs) || pawn.health.hediffSet.PartOrAnyAncestorHasDirectlyAddedParts(hediff_Injury.Part))) { return; } this.FinalizeAndAddInjury(pawn, hediff_Injury, postArmorDinfo, ref result); this.CheckPropagateDamageToInnerSolidParts(postArmorDinfo, pawn, hediff_Injury, involveArmor, ref result); this.CheckDuplicateDamageToOuterParts(postArmorDinfo, pawn, hediff_Injury, involveArmor, ref result); // Apply secondary damage if (!shieldAbsorbed) { var props = dinfo.WeaponGear?.projectile as ProjectilePropertiesCE; if (props != null && !props.secondaryDamage.NullOrEmpty() && dinfo.Def == props.damageDef) { foreach (SecondaryDamage sec in props.secondaryDamage) { if (pawn.Dead) { return; } var secDinfo = sec.GetDinfo(postArmorDinfo); secDinfo.SetForcedHitPart(exactPartFromDamageInfo); pawn.TakeDamage(secDinfo); } } } }
public static void GenerateRandomOldAgeInjuries(Pawn pawn, bool tryNotToKillPawn) { float num = (!pawn.RaceProps.IsMechanoid) ? pawn.RaceProps.lifeExpectancy : 2500f; float num2 = num / 8f; float b = num * 1.5f; float chance = (!pawn.RaceProps.Humanlike) ? 0.03f : 0.15f; int num3 = 0; for (float num4 = num2; num4 < Mathf.Min((float)pawn.ageTracker.AgeBiologicalYears, b); num4 += num2) { if (Rand.Chance(chance)) { num3++; } } for (int i = 0; i < num3; i++) { IEnumerable <BodyPartRecord> source = from x in pawn.health.hediffSet.GetNotMissingParts(BodyPartHeight.Undefined, BodyPartDepth.Undefined, null, null) where x.depth == BodyPartDepth.Outside && (x.def.permanentInjuryChanceFactor != 0f || x.def.pawnGeneratorCanAmputate) && !pawn.health.hediffSet.PartOrAnyAncestorHasDirectlyAddedParts(x) select x; if (source.Any <BodyPartRecord>()) { BodyPartRecord bodyPartRecord = source.RandomElementByWeight((BodyPartRecord x) => x.coverageAbs); DamageDef dam = AgeInjuryUtility.RandomPermanentInjuryDamageType(bodyPartRecord.def.frostbiteVulnerability > 0f && pawn.RaceProps.ToolUser); HediffDef hediffDefFromDamage = HealthUtility.GetHediffDefFromDamage(dam, pawn, bodyPartRecord); if (bodyPartRecord.def.pawnGeneratorCanAmputate && Rand.Chance(0.3f)) { Hediff_MissingPart hediff_MissingPart = (Hediff_MissingPart)HediffMaker.MakeHediff(HediffDefOf.MissingBodyPart, pawn, null); hediff_MissingPart.lastInjury = hediffDefFromDamage; hediff_MissingPart.Part = bodyPartRecord; hediff_MissingPart.IsFresh = false; if (!tryNotToKillPawn || !pawn.health.WouldDieAfterAddingHediff(hediff_MissingPart)) { pawn.health.AddHediff(hediff_MissingPart, bodyPartRecord, null, null); if (pawn.RaceProps.Humanlike && bodyPartRecord.def == BodyPartDefOf.Leg && Rand.Chance(0.5f)) { RecipeDefOf.InstallPegLeg.Worker.ApplyOnPawn(pawn, bodyPartRecord, null, AgeInjuryUtility.emptyIngredientsList, null); } } } else if (bodyPartRecord.def.permanentInjuryChanceFactor > 0f && hediffDefFromDamage.HasComp(typeof(HediffComp_GetsPermanent))) { Hediff_Injury hediff_Injury = (Hediff_Injury)HediffMaker.MakeHediff(hediffDefFromDamage, pawn, null); hediff_Injury.Severity = (float)Rand.RangeInclusive(2, 6); hediff_Injury.TryGetComp <HediffComp_GetsPermanent>().IsPermanent = true; hediff_Injury.Part = bodyPartRecord; if (!tryNotToKillPawn || !pawn.health.WouldDieAfterAddingHediff(hediff_Injury)) { pawn.health.AddHediff(hediff_Injury, bodyPartRecord, null, null); } } } } for (int j = 1; j < pawn.ageTracker.AgeBiologicalYears; j++) { foreach (HediffGiver_Birthday hediffGiver_Birthday in AgeInjuryUtility.RandomHediffsToGainOnBirthday(pawn, j)) { hediffGiver_Birthday.TryApplyAndSimulateSeverityChange(pawn, (float)j, tryNotToKillPawn); if (pawn.Dead) { break; } } if (pawn.Dead) { break; } } }
/// <summary> /// Handles damage and armor calculations /// </summary> /// <param name="dinfo"></param> /// <param name="pawn"></param> /// <param name="result"></param> private void ApplyDamagePartial(DamageInfo dinfo, Pawn pawn, ref DamageWorker_AddInjuryCR.LocalInjuryResult result) { BodyPartRecord exactPartFromDamageInfo = DamageWorker_AddInjuryCR.GetExactPartFromDamageInfo(dinfo, pawn); if (exactPartFromDamageInfo == null) { return; } bool flag = true; if (dinfo.InstantOldInjury) { flag = false; } int damageAmount = dinfo.Amount; bool shotAbsorbed = false; if (!result.deflected && flag) { //damageAmount = ArmorUtility.GetAfterArmorDamage(pawn, dinfo.Amount, exactPartFromDamageInfo, dinfo.Def); damageAmount = Utility.GetAfterArmorDamage(pawn, dinfo.Amount, exactPartFromDamageInfo, dinfo, true, ref shotAbsorbed); } if ((double)damageAmount < 0.001) { result.deflected = true; return; } //Shot absorbed and converted into blunt if (shotAbsorbed) { result.deflected = true; if (dinfo.Def != Utility.absorbDamageDef) { //Get outer parent of struck part BodyPartRecord parentPart = exactPartFromDamageInfo; while (parentPart != null && parentPart.parent != null && parentPart.depth != BodyPartDepth.Outside) { parentPart = parentPart.parent; } DamageInfo dinfo2 = new DamageInfo(Utility.absorbDamageDef, damageAmount, dinfo.Instigator, new BodyPartDamageInfo(parentPart, false), dinfo.Source); this.ApplyDamagePartial(dinfo2, pawn, ref result); return; } } //Creating the Hediff HediffDef hediffDefFromDamage = HealthUtility.GetHediffDefFromDamage(dinfo.Def, pawn, exactPartFromDamageInfo); Hediff_Injury hediff_Injury = (Hediff_Injury)HediffMaker.MakeHediff(hediffDefFromDamage, pawn, null); hediff_Injury.Part = exactPartFromDamageInfo; hediff_Injury.source = dinfo.Source; hediff_Injury.sourceBodyPartGroup = dinfo.LinkedBodyPartGroup; hediff_Injury.sourceHediffDef = dinfo.LinkedHediffDef; hediff_Injury.Severity = (float)damageAmount; if (dinfo.InstantOldInjury) { HediffComp_GetsOld hediffComp_GetsOld = hediff_Injury.TryGetComp <HediffComp_GetsOld>(); if (hediffComp_GetsOld != null) { hediffComp_GetsOld.isOld = dinfo.InstantOldInjury; } else { Log.Error(string.Concat(new object[] { "Tried to create instant old injury on Hediff without a GetsOld comp: ", hediffDefFromDamage, " on ", pawn })); } } result.wounded = true; result.lastHitPart = hediff_Injury.Part; if (DamageWorker_AddInjuryCR.IsHeadshot(dinfo, hediff_Injury, pawn)) { result.headshot = true; } if (dinfo.InstantOldInjury && (hediff_Injury.def.CompPropsFor(typeof(HediffComp_GetsOld)) == null || hediff_Injury.Part.def.oldInjuryBaseChance == 0f || hediff_Injury.Part.def.IsSolid(hediff_Injury.Part, pawn.health.hediffSet.hediffs) || pawn.health.hediffSet.PartOrAnyAncestorHasDirectlyAddedParts(hediff_Injury.Part))) { return; } this.FinalizeAndAddInjury(pawn, hediff_Injury, dinfo, ref result); this.CheckPropagateDamageToInnerSolidParts(dinfo, pawn, hediff_Injury, flag, ref result); this.CheckDuplicateDamageToOuterParts(dinfo, pawn, hediff_Injury, flag, ref result); }