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);
     }
 }