Ejemplo n.º 1
0
 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);
     }
 }
Ejemplo n.º 2
0
        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));
        }
Ejemplo n.º 3
0
        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));
        }
Ejemplo n.º 4
0
        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;
        }
Ejemplo n.º 5
0
        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);
                    }
                }
            }
        }
Ejemplo n.º 6
0
        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);
                    }
                }
            }
        }
Ejemplo n.º 7
0
        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);
                }
            }
        }
Ejemplo n.º 8
0
        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;
        }
Ejemplo n.º 9
0
 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();
         }
     }
 }