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); } } }
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); } } } }
private void FinalizeAndAddInjury(Pawn pawn, Hediff_Injury injury, DamageInfo dinfo, ref DamageWorker_AddInjuryCE.LocalInjuryResult result) { this.CalculateOldInjuryDamageThreshold(pawn, injury); result.totalDamageDealt += Mathf.Min(injury.Severity, pawn.health.hediffSet.GetPartHealth(injury.Part)); pawn.health.AddHediff(injury, null, new DamageInfo?(dinfo)); }
private void CheckDuplicateSmallPawnDamageToPartParent(DamageInfo dinfo, Pawn pawn, ref DamageWorker_AddInjuryCE.LocalInjuryResult result) { if (!dinfo.AllowDamagePropagation) { return; } if (result.lastHitPart != null && dinfo.Def.harmsHealth && result.lastHitPart != pawn.RaceProps.body.corePart && result.lastHitPart.parent != null && pawn.health.hediffSet.GetPartHealth(result.lastHitPart.parent) > 0f && dinfo.Amount >= 10 && pawn.HealthScale <= 0.5001f) { DamageInfo dinfo2 = dinfo; dinfo2.SetForcedHitPart(result.lastHitPart.parent); this.ApplyDamageToPart(dinfo2, pawn, ref result); } }