private static void DoTendPrefix(Pawn doctor, Pawn patient, ref Medicine medicine, Medicine __state) { if (QOLTweaksPack.BruiseWalkingOff.Value == false) { return; } //Log.Message("tending prefix"); if (medicine == null || doctor == null || patient == null || doctor.Faction.IsPlayer == false) { return; } List <Hediff> tmpHediffsToTend = new List <Hediff>(); TendUtility.GetOptimalHediffsToTendWithSingleTreatment(patient, true, tmpHediffsToTend, null); foreach (Hediff tendable in tmpHediffsToTend) { //Log.Message("tending " + tendable.GetType().ToString()); if (!(tendable is Hediff_Injury)) { return; } Hediff_Injury injury = (tendable as Hediff_Injury); if (injury.Bleeding) { //Log.Message("is bleeding"); return; } if (injury.TryGetComp <HediffComp_Infecter>() != null) { //Log.Message("has infecter"); return; } if (injury.TryGetComp <HediffComp_GetsOld>() != null) { //Log.Message("has scarring"); return; } //Log.Message("match"); } __state = medicine; medicine = null; }
public virtual void Repair(Building_RepairStation repairStation) { List <Hediff_Injury> allInjuries = health.hediffSet.GetHediffs <Hediff_Injury>().ToList(); List <Hediff_MissingPart> allMissingParts = health.hediffSet.GetHediffs <Hediff_MissingPart>().ToList(); float num = Rand.Value; if ((allInjuries.Count == 0 || num > 0.6) && allMissingParts.Count > 0 && repairStation != null && repairStation.HasEnoughOf(repairStation.Def.repairThingDef, repairStation.Def.repairCostAmount)) { Hediff_MissingPart hediff = allMissingParts.RandomElement(); if (repairStation.TakeSomeOf(repairStation.Def.repairThingDef, repairStation.Def.repairCostAmount)) { health.hediffSet.RestorePart(hediff.Part.HighestMissingPart(this)); } } else if (allInjuries.Count > 0) { Hediff_Injury hediff = allInjuries.RandomElement(); if (hediff.def.injuryProps.fullyHealableOnlyByTreatment) { HediffComp_Treatable treatable = hediff.TryGetComp <HediffComp_Treatable>(); if (treatable != null && !treatable.treatedWithMedicine) { treatable.NewlyTreated(1f, ThingDefOf.Medicine); } } hediff.DirectHeal(repairStation.Def.repairAmount); } }
// 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)); }
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; } } }
private void CalculateOldInjuryDamageThreshold(Pawn pawn, Hediff_Injury injury) { HediffComp_GetsOld comp = injury.TryGetComp <HediffComp_GetsOld>(); if (comp == null) { return; } // No permanent injuries on solid parts, prosthetics or injuries that are already old if (injury.Part.def.IsSolid(injury.Part, pawn.health.hediffSet.hediffs) || pawn.health.hediffSet.PartOrAnyAncestorHasDirectlyAddedParts(injury.Part) || injury.IsOld()) { return; } // Delicate parts get old instantly if (injury.Part.def.IsDelicate) { comp.oldDamageThreshold = injury.Severity; comp.IsOld = true; } // Check if injury is at least 10% of part health and make a random roll else if (injury.Severity >= injury.Part.def.GetMaxHealth(pawn) * 0.1f && injury.Severity > 1) { float getOldChance = injury.Part.def.oldInjuryBaseChance * comp.Props.becomeOldChance * Mathf.Pow((injury.Severity / injury.Part.def.GetMaxHealth(pawn)), 2); if (Rand.Value < getOldChance) { comp.oldDamageThreshold = Rand.Range(1, injury.Severity); } } }
// // 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; } } }
// Self healing //private int timerRepairDamage = 0; private void TryHealDamagedBodyPartOfRobot(X2_AIRobot robot) { //timerRepairDamage--; //if (timerRepairDamage > 0) // return; //timerRepairDamage = 300; if (robot == null || !Verse.Gen.IsHashIntervalTick(robot, 300)) { return; } IEnumerable <Hediff_Injury> hediff_injuries = (from x in robot.health.hediffSet.GetHediffs <Hediff_Injury>() where x.CanHealFromTending() || x.CanHealNaturally() select x); // Apply Treated, but not healing! if (robot.health.HasHediffsNeedingTend(false)) { float quality = (Rand.Value); int batchPosition = 0; foreach (Hediff_Injury injury in from x in robot.health.hediffSet.GetInjuriesTendable() orderby x.Severity descending select x) { injury.Tended(quality, batchPosition); batchPosition++; if (batchPosition >= 1) { break; } } } // Apply healing if (hediff_injuries != null && hediff_injuries.Count() > 0) { Hediff_Injury hediff_Injury2 = hediff_injuries.RandomElement(); float tendQuality = hediff_Injury2.TryGetComp <HediffComp_TendDuration>().tendQuality; float num2 = GenMath.LerpDouble(0f, 1f, 0.5f, 1.5f, Mathf.Clamp01(tendQuality)); ////hediff_Injury2.Heal(22f * num2 * robot.HealthScale * 0.01f); -> At quality 0.5 --> 0.066 healed. //Log.Error("Calculation: " + (GenMath.LerpDouble(0f, 1f, 0.5f, 1.5f, Mathf.Clamp01(tendQuality)).ToString())); //Log.Error("Healing: " + (22f * num2 * robot.HealthScale * 0.1f).ToString()); //Log.Error("PRE:" + hediff_Injury2.Severity.ToString()); //hediff_Injury2.Heal(1f); hediff_Injury2.Heal(22f * num2 * robot.HealthScale * 0.1f * 0.5f); //Log.Error("POST:" + hediff_Injury2.Severity.ToString()); // Throw Healing Mote MoteMaker.ThrowMetaIcon(this.Position, this.Map, ThingDefOf.Mote_HealingCross); } }
// Self healing private void DoHealDamagedBodyPart(bool enhancedAI) { IEnumerable <Hediff> notTendedBodyParts = (from x in this.health.hediffSet.hediffs where (x is Hediff_Injury) && x.TendableNow(false) //!(x is Hediff_MissingPart) && x.CanHealFromTending() && !x.IsTended() select x); IEnumerable <Hediff_Injury> hediff_injuries = (from x in this.health.hediffSet.GetHediffs <Hediff_Injury>() where x.CanHealFromTending() || x.CanHealNaturally() select x); if (notTendedBodyParts.Count() == 0) // && hediff_injuries.Count() == 0) { // Nothing to heal/tend, check for missing body parts next DoHealMissingBodyPart(enhancedAI); return; } // Apply Treated, but not healing! if (this.health.HasHediffsNeedingTend(false)) { float quality = (enhancedAI ? 1.0f : Rand.Value); int batchPosition = 0; foreach (Hediff_Injury injury in from x in this.health.hediffSet.GetInjuriesTendable() orderby x.Severity descending select x) { injury.Tended(quality, 1f, batchPosition); batchPosition++; if (batchPosition >= (IsInBed(Map) ? 3 : 1)) { break; } } } // No additional healing while in bed (it heals by itself here) if (IsInBed(Map)) { return; } if (hediff_injuries != null && hediff_injuries.Count() > 0) { Hediff_Injury hediff_Injury2 = hediff_injuries.RandomElement <Hediff_Injury>(); float tendQuality = hediff_Injury2.TryGetComp <HediffComp_TendDuration>().tendQuality; float num2 = GenMath.LerpDouble(0f, 1f, 0.5f, 1.5f, Mathf.Clamp01(tendQuality)); hediff_Injury2.Heal(22f * num2 * this.HealthScale * 0.01f * (enhancedAI ? 2 : 1)); } }
// Token: 0x06004B8A RID: 19338 RVA: 0x0023489C File Offset: 0x00232C9C protected float FinalizeAndAddInjury(Pawn pawn, Hediff_Injury injury, DamageInfo dinfo, DamageWorker.DamageResult result) { HediffComp_GetsPermanent hediffComp_GetsPermanent = injury.TryGetComp <HediffComp_GetsPermanent>(); if (hediffComp_GetsPermanent != null) { hediffComp_GetsPermanent.PreFinalizeInjury(); } pawn.health.AddHediff(injury, null, new DamageInfo?(dinfo), result); float num = Mathf.Min(injury.Severity, pawn.health.hediffSet.GetPartHealth(injury.Part)); result.totalDamageDealt += num; result.wounded = true; result.AddPart(pawn, injury.Part); result.AddHediff(injury); return(num); }
// // 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); } } }
public bool RegenerateInjury(Pawn pawn, float amount) { var injuries = pawn.health.hediffSet.hediffs.OfType <Hediff_Injury>().Where(x => x.Severity > 0 && x.Part != null); Hediff_Injury injury = injuries.RandomElementWithFallback(); if (injury == null) { return(false); } HediffComp_GetsPermanent hediffComp_GetsPermanent = injury.TryGetComp <HediffComp_GetsPermanent>(); if (hediffComp_GetsPermanent != null) { hediffComp_GetsPermanent.IsPermanent = false; } injury.Severity = Mathf.Max(injury.Severity - amount); pawn.health.hediffSet.DirtyCache(); RadiologyEffectSpawnerDef.Spawn(effectRegeneration, pawn); return(true); }
public bool RegenerateInjury() { var permanentInjuries = pawn.health.hediffSet.hediffs.OfType <Hediff_Injury>().Where(x => x.IsPermanent() && x.Part != null); Hediff_Injury injury = permanentInjuries.RandomElementWithFallback(); if (injury == null) { return(false); } HediffComp_GetsPermanent hediffComp_GetsPermanent = injury.TryGetComp <HediffComp_GetsPermanent>(); if (hediffComp_GetsPermanent == null) { return(false); } hediffComp_GetsPermanent.IsPermanent = false; injury.Severity = injury.Part.def.hitPoints - 1; pawn.health.hediffSet.DirtyCache(); RadiologyEffectSpawnerDef.Spawn(def.effectRegeneration, pawn); return(true); }
/// <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); }
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 flag = injury.Part.def.oldInjuryBaseChance >= 0.8f; if ((Rand.Value <= injury.Part.def.oldInjuryBaseChance * hediffCompProperties.becomeOldChance && injury.Severity >= injury.Part.def.GetMaxHealth(pawn) * 0.25f && injury.Severity >= 7f) || flag) { 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 (flag) { hediffComp_GetsOld.oldDamageThreshold = injury.Severity; hediffComp_GetsOld.isOld = true; } } }
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 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; } } }
public static bool HealthTick(Pawn_HealthTracker __instance) { if (__instance.Dead) { return(false); } for (int index = __instance.hediffSet.hediffs.Count - 1; index >= 0; --index) { Hediff hediff = __instance.hediffSet.hediffs[index]; try { hediff.Tick(); hediff.PostTick(); } catch (Exception ex1) { Log.Error("Exception ticking hediff " + hediff.ToStringSafe <Hediff>() + " for pawn " + __instance.pawn.ToStringSafe <Pawn>() + ". Removing hediff... Exception: " + (object)ex1); try { __instance.RemoveHediff(hediff); } catch (Exception ex2) { Log.Error("Error while removing hediff: " + (object)ex2); } } if (__instance.Dead) { return(false); } } bool flag1 = false; lock (__instance.hediffSet) //added { List <Hediff> newHediffs = new List <Hediff>(__instance.hediffSet.hediffs); //added for (int index = newHediffs.Count - 1; index >= 0; --index) //changed { Hediff hediff = newHediffs[index]; if (hediff.ShouldRemove) { newHediffs.RemoveAt(index); //changed __instance.hediffSet.hediffs = newHediffs; //added hediff.PostRemoved(); flag1 = true; } } } if (flag1) { __instance.Notify_HediffChanged((Hediff)null); } if (__instance.Dead) { return(false); } __instance.immunity.ImmunityHandlerTick(); if (__instance.pawn.RaceProps.IsFlesh && __instance.pawn.IsHashIntervalTick(600) && (__instance.pawn.needs.food == null || !__instance.pawn.needs.food.Starving)) { bool flag2 = false; if (__instance.hediffSet.HasNaturallyHealingInjury()) { float num = 8f; if (__instance.pawn.GetPosture() != PawnPosture.Standing) { num += 4f; Building_Bed buildingBed = __instance.pawn.CurrentBed(); if (buildingBed != null) { num += buildingBed.def.building.bed_healPerDay; } } foreach (Hediff hediff in __instance.hediffSet.hediffs) { HediffStage curStage = hediff.CurStage; if (curStage != null && (double)curStage.naturalHealingFactor != -1.0) { num *= curStage.naturalHealingFactor; } } __instance.hediffSet.GetHediffs <Hediff_Injury>().Where <Hediff_Injury>((Func <Hediff_Injury, bool>)(x => x.CanHealNaturally())).RandomElement <Hediff_Injury>().Heal((float)((double)num * (double)__instance.pawn.HealthScale * 0.00999999977648258) * __instance.pawn.GetStatValue(StatDefOf.InjuryHealingFactor)); flag2 = true; } if (__instance.hediffSet.HasTendedAndHealingInjury() && (__instance.pawn.needs.food == null || !__instance.pawn.needs.food.Starving)) { Hediff_Injury hd = __instance.hediffSet.GetHediffs <Hediff_Injury>().Where <Hediff_Injury>((Func <Hediff_Injury, bool>)(x => x.CanHealFromTending())).RandomElement <Hediff_Injury>(); hd.Heal((float)(8.0 * (double)GenMath.LerpDouble(0.0f, 1f, 0.5f, 1.5f, Mathf.Clamp01(hd.TryGetComp <HediffComp_TendDuration>().tendQuality)) * (double)__instance.pawn.HealthScale * 0.00999999977648258) * __instance.pawn.GetStatValue(StatDefOf.InjuryHealingFactor)); flag2 = true; } if (flag2 && !__instance.HasHediffsNeedingTendByPlayer() && (!HealthAIUtility.ShouldSeekMedicalRest(__instance.pawn) && !__instance.hediffSet.HasTendedAndHealingInjury()) && PawnUtility.ShouldSendNotificationAbout(__instance.pawn)) { Messages.Message((string)"MessageFullyHealed".Translate((NamedArgument)__instance.pawn.LabelCap, (NamedArgument)(Thing)__instance.pawn), (LookTargets)(Thing)__instance.pawn, MessageTypeDefOf.PositiveEvent); } } if (__instance.pawn.RaceProps.IsFlesh && (double)__instance.hediffSet.BleedRateTotal >= 0.100000001490116) { float num = __instance.hediffSet.BleedRateTotal * __instance.pawn.BodySize; if ((double)Rand.Value < (__instance.pawn.GetPosture() != PawnPosture.Standing ? (double)(num * 0.0004f) : (double)(num * 0.004f))) { __instance.DropBloodFilth(); } } if (!__instance.pawn.IsHashIntervalTick(60)) { return(false); } List <HediffGiverSetDef> hediffGiverSets = __instance.pawn.RaceProps.hediffGiverSets; if (hediffGiverSets != null) { for (int index1 = 0; index1 < hediffGiverSets.Count; ++index1) { List <HediffGiver> hediffGivers = hediffGiverSets[index1].hediffGivers; for (int index2 = 0; index2 < hediffGivers.Count; ++index2) { hediffGivers[index2].OnIntervalPassed(__instance.pawn, (Hediff)null); if (__instance.pawn.Dead) { return(false); } } } } if (__instance.pawn.story == null) { return(false); } List <Trait> allTraits = __instance.pawn.story.traits.allTraits; for (int index = 0; index < allTraits.Count; ++index) { TraitDegreeData currentData = allTraits[index].CurrentData; if ((double)currentData.randomDiseaseMtbDays > 0.0 && Rand.MTBEventOccurs(currentData.randomDiseaseMtbDays, 60000f, 60f)) { BiomeDef biome = __instance.pawn.Tile == -1 ? DefDatabase <BiomeDef> .GetRandom() : Find.WorldGrid[__instance.pawn.Tile].biome; IncidentDef incidentDef = DefDatabase <IncidentDef> .AllDefs.Where <IncidentDef>((Func <IncidentDef, bool>)(d => d.category == IncidentCategoryDefOf.DiseaseHuman)).RandomElementByWeightWithFallback <IncidentDef>((Func <IncidentDef, float>)(d => biome.CommonalityOfDisease(d))); if (incidentDef != null) { string blockedInfo; List <Pawn> pawns = ((IncidentWorker_Disease)incidentDef.Worker).ApplyToPawns(Gen.YieldSingle <Pawn>(__instance.pawn), out blockedInfo); if (PawnUtility.ShouldSendNotificationAbout(__instance.pawn)) { if (pawns.Contains(__instance.pawn)) { Find.LetterStack.ReceiveLetter("LetterLabelTraitDisease".Translate((NamedArgument)incidentDef.diseaseIncident.label), "LetterTraitDisease".Translate((NamedArgument)__instance.pawn.LabelCap, (NamedArgument)incidentDef.diseaseIncident.label, __instance.pawn.Named("PAWN")).AdjustedFor(__instance.pawn), LetterDefOf.NegativeEvent, (LookTargets)(Thing)__instance.pawn); } else if (!blockedInfo.NullOrEmpty()) { Messages.Message(blockedInfo, (LookTargets)(Thing)__instance.pawn, MessageTypeDefOf.NeutralEvent); } } } } } 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); } } } }