示例#1
0
        private static bool ApplyArmor(ref float damAmount, ref float pierceAmount, float armorRating, Thing armorThing, DamageDef damageDef)
        {
            float        originalDamage    = damAmount;
            bool         deflected         = false;
            DamageDef_CE damageDefCE       = damageDef as DamageDef_CE;
            float        penetrationChance = 1;

            if (damageDefCE != null && damageDefCE.deflectable)
            {
                penetrationChance = Mathf.Clamp((pierceAmount - armorRating) * 6, 0, 1);
            }
            //Shot is deflected
            if (penetrationChance == 0 || Rand.Value > penetrationChance)
            {
                deflected = true;
            }
            //Damage calculations
            float dMult = 1;

            if (damageDefCE != null)
            {
                if (damageDefCE.absorbable && deflected)
                {
                    dMult = 0;
                }
                else if (damageDefCE.deflectable)
                {
                    dMult = Mathf.Clamp01(0.5f + (pierceAmount - armorRating) * 3);
                }
            }
            else
            {
                dMult = Mathf.Clamp01(1 - armorRating);
            }
            damAmount *= dMult;

            //Damage armor
            if (armorThing != null && armorThing as Pawn == null)
            {
                float absorbedDamage = (originalDamage - damAmount) * Mathf.Min(pierceAmount, 1f);
                if (deflected)
                {
                    absorbedDamage *= 0.5f;
                }
                armorThing.TakeDamage(new DamageInfo(damageDef, Mathf.CeilToInt(absorbedDamage), -1, null, null, null));
            }

            pierceAmount *= dMult;
            return(deflected);
        }
示例#2
0
        protected override void Impact(Thing hitThing)
        {
            Map map = base.Map;

            base.Impact(hitThing);
            if (hitThing != null)
            {
                int          damageAmountBase = def.projectile.damageAmountBase;
                ThingDef     equipmentDef     = this.equipmentDef;
                DamageDef_CE damDefCE         = def.projectile.damageDef as DamageDef_CE;

                DamageInfo dinfo = new DamageInfo(
                    def.projectile.damageDef,
                    damageAmountBase,
                    ExactRotation.eulerAngles.y,
                    launcher,
                    null,
                    equipmentDef);

                //  if (damDefCE != null && damDefCE.harmOnlyOutsideLayers) dinfo.ForceHitPart.depth = BodyPartDepth.Outside;

                ProjectilePropertiesCE propsCE = def.projectile as ProjectilePropertiesCE;
                if (propsCE != null && !propsCE.secondaryDamage.NullOrEmpty())
                {
                    // Log.Message("propsCE: " + propsCE.ToString());
                    // Get the correct body part
                    Pawn pawn = hitThing as Pawn;
                    if (pawn != null && def.projectile.damageDef.workerClass == typeof(DamageWorker_AddInjuryCE))
                    {
                        BodyPartRecord exactPartFromDamageInfo = DamageWorker_AddInjuryCE.GetExactPartFromDamageInfo(dinfo, pawn);
                        dinfo = new DamageInfo(
                            dinfo.Def,
                            dinfo.Amount,
                            dinfo.Angle,
                            dinfo.Instigator,
                            exactPartFromDamageInfo = (DamageWorker_AddInjuryCE.GetExactPartFromDamageInfo(dinfo, pawn)),
                            dinfo.WeaponGear);
                    }
                    List <DamageInfo> dinfoList = new List <DamageInfo>()
                    {
                        dinfo
                    };
                    foreach (SecondaryDamage secDamage in propsCE.secondaryDamage)
                    {
                        dinfoList.Add(new DamageInfo(
                                          secDamage.def,
                                          secDamage.amount,
                                          dinfo.Angle,
                                          dinfo.Instigator,
                                          dinfo.ForceHitPart,
                                          dinfo.WeaponGear));
                    }
                    foreach (DamageInfo curDinfo in dinfoList)
                    {
                        hitThing.TakeDamage(curDinfo);
                    }
                }
                else
                {
                    hitThing.TakeDamage(dinfo);
                }
            }
            else
            {
                SoundDefOf.BulletImpactGround.PlayOneShot(new TargetInfo(base.Position, map, false));
                MoteMaker.MakeStaticMote(ExactPosition, map, ThingDefOf.Mote_ShotHit_Dirt, 1f);
            }
        }
        private void ApplyDamagePartial(DamageInfo dinfo, Pawn pawn, ref LocalInjuryResult result)
        {
            BodyPartRecord exactPartFromDamageInfo = 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 = CE_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_CE damageDefCE = dinfo.Def as DamageDef_CE;

            if (damageDefCE != null &&
                damageDefCE.deflectable &&
                result.deflected &&
                dinfo.Def != CE_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(CE_Utility.absorbDamageDef, damageAmount, dinfo.Angle, dinfo.Instigator, currentPart, dinfo.WeaponGear);
                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.WeaponGear;
            hediff_Injury.sourceBodyPartGroup = dinfo.WeaponBodyPartGroup;
            hediff_Injury.sourceHediffDef     = dinfo.WeaponLinkedHediff;
            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 (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;
            }
            FinalizeAndAddInjury(pawn, hediff_Injury, dinfo, ref result);
            CheckPropagateDamageToInnerSolidParts(dinfo, pawn, hediff_Injury, !dinfo.InstantOldInjury, damageAmount, ref result);
            CheckDuplicateDamageToOuterParts(dinfo, pawn, hediff_Injury, !dinfo.InstantOldInjury, damageAmount, ref result);
        }