protected virtual void Explode()
        {
            this.Destroy(DestroyMode.Vanish);
            ProjectilePropertiesCR propsCR     = def.projectile as ProjectilePropertiesCR;
            ThingDef preExplosionSpawnThingDef = this.def.projectile.preExplosionSpawnThingDef;
            float    explosionSpawnChance      = this.def.projectile.explosionSpawnChance;

            GenExplosion.DoExplosion(base.Position,
                                     this.def.projectile.explosionRadius,
                                     this.def.projectile.damageDef,
                                     this.launcher,
                                     this.def.projectile.soundExplode,
                                     this.def,
                                     this.equipmentDef,
                                     this.def.projectile.postExplosionSpawnThingDef,
                                     this.def.projectile.explosionSpawnChance,
                                     1,
                                     propsCR == null ? false : propsCR.damageAdjacentTiles,
                                     preExplosionSpawnThingDef,
                                     this.def.projectile.explosionSpawnChance,
                                     1);
            ThrowBigExplode(base.Position.ToVector3Shifted() + Gen.RandomHorizontalVector(def.projectile.explosionRadius * 0.7f), def.projectile.explosionRadius * 0.6f);
            CompExplosiveCR comp = this.TryGetComp <CompExplosiveCR>();

            if (comp != null)
            {
                comp.Explode(launcher, this.Position);
            }
        }
        protected virtual void Explode()
        {
            this.Destroy(DestroyMode.Vanish);
            ProjectilePropertiesCR propsCR     = def.projectile as ProjectilePropertiesCR;
            ThingDef preExplosionSpawnThingDef = this.def.projectile.preExplosionSpawnThingDef;

            GenExplosion.DoExplosion(base.Position,
                                     this.def.projectile.explosionRadius,
                                     this.def.projectile.damageDef,
                                     this.launcher,
                                     this.def.projectile.soundExplode,
                                     this.def,
                                     this.equipmentDef,
                                     this.def.projectile.postExplosionSpawnThingDef,
                                     this.def.projectile.explosionSpawnChance,
                                     propsCR == null ? false : propsCR.damageAdjacentTiles,
                                     preExplosionSpawnThingDef,
                                     this.def.projectile.explosionSpawnChance);

            CompExplosiveCR comp = this.TryGetComp <CompExplosiveCR>();

            if (comp != null)
            {
                comp.Explode(launcher);
            }
        }
Ejemplo n.º 3
0
        protected override void Impact(Thing hitThing)
        {
            base.Impact(hitThing);
            if (hitThing != null)
            {
                int damageAmountBase = this.def.projectile.damageAmountBase;

                BodyPartDamageInfo value;
                DamageDef_CR       damDefCR = def.projectile.damageDef as DamageDef_CR;
                if (damDefCR != null && damDefCR.harmOnlyOutsideLayers)
                {
                    value = new BodyPartDamageInfo(null, BodyPartDepth.Outside);
                }
                else
                {
                    value = new BodyPartDamageInfo(null, null);
                }

                DamageInfo dinfo = new DamageInfo(this.def.projectile.damageDef, damageAmountBase, this.launcher, this.ExactRotation.eulerAngles.y, new BodyPartDamageInfo?(value), this.def);

                ProjectilePropertiesCR propsCR = def.projectile as ProjectilePropertiesCR;
                if (propsCR != null && !propsCR.secondaryDamage.NullOrEmpty())
                {
                    // Get the correct body part
                    Pawn pawn = hitThing as Pawn;
                    if (pawn != null && def.projectile.damageDef.workerClass == typeof(DamageWorker_AddInjuryCR))
                    {
                        dinfo = new DamageInfo(dinfo.Def,
                                               dinfo.Amount,
                                               dinfo.Instigator,
                                               dinfo.Angle,
                                               new BodyPartDamageInfo(DamageWorker_AddInjuryCR.GetExactPartFromDamageInfo(dinfo, pawn), false, (HediffDef)null),
                                               dinfo.Source);
                    }
                    List <DamageInfo> dinfoList = new List <DamageInfo>()
                    {
                        dinfo
                    };
                    foreach (SecondaryDamage secDamage in propsCR.secondaryDamage)
                    {
                        dinfoList.Add(new DamageInfo(secDamage.def, secDamage.amount, dinfo.Instigator, dinfo.Part, dinfo.Source));
                    }
                    foreach (DamageInfo curDinfo in dinfoList)
                    {
                        hitThing.TakeDamage(curDinfo);
                    }
                }
                else
                {
                    hitThing.TakeDamage(dinfo);
                }
            }
            else
            {
                SoundDefOf.BulletImpactGround.PlayOneShot(base.Position);
                MoteThrower.ThrowStatic(this.ExactPosition, ThingDefOf.Mote_ShotHit_Dirt, 1f);
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Takes into account the target being downed and the projectile having been fired while the target was downed, and the target's bodySize
        /// </summary>
        private bool ImpactThroughBodySize(Thing thing, float height)
        {
            Pawn pawn = thing as Pawn;

            if (pawn != null)
            {
                //Add suppression
                CompSuppressable compSuppressable = pawn.TryGetComp <CompSuppressable>();
                if (compSuppressable != null)
                {
                    float suppressionAmount        = this.def.projectile.damageAmountBase;
                    ProjectilePropertiesCR propsCR = def.projectile as ProjectilePropertiesCR;
                    float penetrationAmount        = propsCR == null ? 0f : propsCR.armorPenetration;
                    suppressionAmount *= 1 - Mathf.Clamp(compSuppressable.parentArmor - penetrationAmount, 0, 1);
                    compSuppressable.AddSuppression(suppressionAmount, this.origin.ToIntVec3());
                }

                //Check horizontal distance
                Vector3 dest              = this.destination;
                Vector3 orig              = this.origin;
                Vector3 pawnPos           = pawn.DrawPos;
                float   closestDistToPawn = Math.Abs((dest.z - orig.z) * pawnPos.x - (dest.x - orig.x) * pawnPos.z + dest.x * orig.z - dest.z * orig.x)
                                            / (float)Math.Sqrt((dest.z - orig.z) * (dest.z - orig.z) + (dest.x - orig.x) * (dest.x - orig.x));
                if (closestDistToPawn <= Utility.GetCollisionWidth(pawn))
                {
                    //Check vertical distance
                    float pawnHeight = Utility.GetCollisionHeight(pawn);
                    if (height < pawnHeight)
                    {
                        this.Impact(thing);
                        return(true);
                    }
                }
            }
            if (thing.def.fillPercent > 0 || thing.def.Fillage == FillCategory.Full)
            {
                if (height < Utility.GetCollisionHeight(thing) || thing.def.Fillage == FillCategory.Full)
                {
                    this.Impact(thing);
                    return(true);
                }
            }
            return(false);
        }
Ejemplo n.º 5
0
        protected virtual void Explode()
        {
            Map map = base.Map;

            this.Destroy(DestroyMode.Vanish);
            ProjectilePropertiesCR propsCR     = def.projectile as ProjectilePropertiesCR;
            ThingDef preExplosionSpawnThingDef = this.def.projectile.preExplosionSpawnThingDef;
            float    explosionSpawnChance      = this.def.projectile.explosionSpawnChance;

            GenExplosion.DoExplosion(base.Position,
                                     map,
                                     this.def.projectile.explosionRadius,
                                     this.def.projectile.damageDef,
                                     this.launcher,
                                     this.def.projectile.soundExplode,
                                     this.def,
                                     this.equipmentDef,
                                     this.def.projectile.postExplosionSpawnThingDef,
                                     this.def.projectile.explosionSpawnChance,
                                     1,
                                     false, // propsCR == null ? false : propsCR.damageAdjacentTiles,
                                     preExplosionSpawnThingDef,
                                     explosionSpawnChance,
                                     1);

            if (map != null && base.Position.IsValid)
            {
                ThrowBigExplode(base.Position.ToVector3Shifted() + Gen.RandomHorizontalVector(def.projectile.explosionRadius * 0.5f), base.Map, def.projectile.explosionRadius * 0.4f);
            }

            CompExplosiveCR comp = this.TryGetComp <CompExplosiveCR>();

            if (comp != null && this.launcher != null && this.Position.IsValid)
            {
                comp.Explode(launcher, this.Position, Find.VisibleMap);
            }
        }
Ejemplo n.º 6
0
        public override string GetDescription()
        {
            if (ammoDef != null && ammoDef.ammoClass != null && ammoDef.linkedProjectile != null)
            {
                StringBuilder stringBuilder = new StringBuilder();
                stringBuilder.AppendLine(base.GetDescription());

                // Append ammo class description
                if (!string.IsNullOrEmpty(ammoDef.ammoClass.description))
                {
                    stringBuilder.AppendLine("\n" +
                                             (string.IsNullOrEmpty(ammoDef.ammoClass.LabelCap) ? "" : ammoDef.ammoClass.LabelCap + ":\n") +
                                             ammoDef.ammoClass.description);
                }

                // Append ammo stats
                ProjectilePropertiesCR props = ammoDef.linkedProjectile.projectile as ProjectilePropertiesCR;
                if (props != null)
                {
                    // Damage type/amount
                    stringBuilder.AppendLine("\n" + "CR_DescDamage".Translate() + ": ");
                    stringBuilder.AppendLine("   " + GenText.ToStringByStyle(props.damageAmountBase, ToStringStyle.Integer) + " (" + props.damageDef.LabelCap + ")");
                    if (!props.secondaryDamage.NullOrEmpty())
                    {
                        foreach (SecondaryDamage sec in props.secondaryDamage)
                        {
                            stringBuilder.AppendLine("   " + GenText.ToStringByStyle(sec.amount, ToStringStyle.Integer) + " (" + sec.def.LabelCap + ")");
                        }
                    }
                    // Explosion radius
                    if (props.explosionRadius > 0)
                    {
                        stringBuilder.AppendLine("CR_DescExplosionRadius".Translate() + ": " + GenText.ToStringByStyle(props.explosionRadius, ToStringStyle.FloatOne));
                    }

                    // Secondary explosion
                    CompProperties_ExplosiveCR secExpProps = ammoDef.linkedProjectile.GetCompProperties <CompProperties_ExplosiveCR>();
                    if (secExpProps != null)
                    {
                        if (secExpProps.explosionRadius > 0)
                        {
                            stringBuilder.AppendLine("CR_DescSecondaryExplosion".Translate() + ":");
                            stringBuilder.AppendLine("   " + "CR_DescExplosionRadius".Translate() + ": " + GenText.ToStringByStyle(secExpProps.explosionRadius, ToStringStyle.FloatOne));
                            stringBuilder.AppendLine("   " + "CR_DescDamage".Translate() + ": " +
                                                     GenText.ToStringByStyle(secExpProps.explosionDamage, ToStringStyle.Integer) + " (" + secExpProps.explosionDamageDef.LabelCap + ")");
                        }
                        if (secExpProps.fragRange > 0)
                        {
                            stringBuilder.AppendLine("CR_DescFragRange".Translate() + ": " + GenText.ToStringByStyle(secExpProps.fragRange, ToStringStyle.FloatTwo));
                        }
                    }

                    // CR stats
                    stringBuilder.AppendLine("CR_DescArmorPenetration".Translate() + ": " + GenText.ToStringByStyle(props.armorPenetration, ToStringStyle.PercentOne));
                    if (props.pelletCount > 1)
                    {
                        stringBuilder.AppendLine("CR_DescPelletCount".Translate() + ": " + GenText.ToStringByStyle(props.pelletCount, ToStringStyle.Integer));
                    }
                    if (props.spreadMult != 1)
                    {
                        stringBuilder.AppendLine("CR_DescSpreadMult".Translate() + ": " + GenText.ToStringByStyle(props.spreadMult, ToStringStyle.PercentZero));
                    }
                }

                return(stringBuilder.ToString());
            }
            return(base.GetDescription());
        }
Ejemplo n.º 7
0
        public static readonly DamageDef absorbDamageDef = DamageDefOf.Blunt;   //The damage def to convert absorbed shots into

        /// <summary>
        /// Calculates deflection chance and damage through armor
        /// </summary>
        public static int GetAfterArmorDamage(Pawn pawn, int damAmountInt, BodyPartRecord part, DamageInfo dinfo, bool damageArmor, ref bool deflected)
        {
            DamageDef damageDef = dinfo.Def;

            if (damageDef.armorCategory == DamageArmorCategory.IgnoreArmor)
            {
                return(damAmountInt);
            }

            float   damageAmount   = (float)damAmountInt;
            StatDef deflectionStat = damageDef.armorCategory.DeflectionStat();

            // Get armor penetration value
            float pierceAmount = 0f;

            if (dinfo.Source != null)
            {
                ProjectilePropertiesCR projectileProps = dinfo.Source.projectile as ProjectilePropertiesCR;
                if (projectileProps != null)
                {
                    pierceAmount = projectileProps.armorPenetration;
                }
                else if (dinfo.Instigator != null)
                {
                    Pawn instigatorPawn = dinfo.Instigator as Pawn;
                    if (instigatorPawn != null)
                    {
                        if (instigatorPawn.equipment != null && instigatorPawn.equipment.Primary != null)
                        {
                            pierceAmount = instigatorPawn.equipment.Primary.GetStatValue(StatDef.Named("ArmorPenetration"));
                        }
                        else
                        {
                            pierceAmount = instigatorPawn.GetStatValue(StatDef.Named("ArmorPenetration"));
                        }
                    }
                }
            }

            // Run armor calculations on all apparel
            if (pawn.apparel != null)
            {
                List <Apparel> wornApparel = new List <Apparel>(pawn.apparel.WornApparel);
                for (int i = wornApparel.Count - 1; i >= 0; i--)
                {
                    if (wornApparel[i].def.apparel.CoversBodyPart(part))
                    {
                        Thing armorThing = damageArmor ? wornApparel[i] : null;

                        //Check for deflection
                        if (Utility.ApplyArmor(ref damageAmount, ref pierceAmount, wornApparel[i].GetStatValue(deflectionStat, true), armorThing, damageDef))
                        {
                            deflected = true;
                            if (damageDef != absorbDamageDef)
                            {
                                damageDef      = absorbDamageDef;
                                deflectionStat = damageDef.armorCategory.DeflectionStat();
                                i++;
                            }
                        }
                        if (damageAmount < 0.001)
                        {
                            return(0);
                        }
                    }
                }
            }
            float pawnArmorAmount    = 0f;
            bool  partCoveredByArmor = false;

            if (part.IsInGroup(DefDatabase <BodyPartGroupDef> .GetNamed("CoveredByNaturalArmor")))
            {
                partCoveredByArmor = true;
            }
            else
            {
                BodyPartRecord outerPart = part;
                while (outerPart.parent != null && outerPart.depth != BodyPartDepth.Outside)
                {
                    outerPart = outerPart.parent;
                }
                partCoveredByArmor = outerPart != part && outerPart.IsInGroup(DefDatabase <BodyPartGroupDef> .GetNamed("CoveredByNaturalArmor"));
            }
            if (partCoveredByArmor)
            {
                pawnArmorAmount = pawn.GetStatValue(deflectionStat);
            }

            if (pawnArmorAmount > 0 && Utility.ApplyArmor(ref damageAmount, ref pierceAmount, pawnArmorAmount, null, damageDef))
            {
                deflected = true;
                if (damageAmount < 0.001)
                {
                    return(0);
                }
                damageDef      = absorbDamageDef;
                deflectionStat = damageDef.armorCategory.DeflectionStat();
                Utility.ApplyArmor(ref damageAmount, ref pierceAmount, pawn.GetStatValue(deflectionStat, true), pawn, damageDef);
            }
            return(Mathf.RoundToInt(damageAmount));
        }
Ejemplo n.º 8
0
        /// <summary>
        ///     Takes into account the target being downed and the projectile having been fired while the target was downed, and
        ///     the target's bodySize
        /// </summary>
        private bool ImpactThroughBodySize(Thing thing, float height)
        {
            Pawn pawn = thing as Pawn;

            if (pawn != null)
            {
                PersonalShield shield = null;
                if (pawn.RaceProps.Humanlike)
                {
                    // check for shield user

                    List <Apparel> wornApparel = pawn.apparel.WornApparel;
                    for (int i = 0; i < wornApparel.Count; i++)
                    {
                        if (wornApparel[i] is PersonalShield)
                        {
                            shield = (PersonalShield)wornApparel[i];
                            break;
                        }
                    }
                }
                //Add suppression
                CompSuppressable compSuppressable = pawn.TryGetComp <CompSuppressable>();
                if (compSuppressable != null)
                {
                    if (shield == null || (shield != null && shield?.ShieldState == ShieldState.Resetting))
                    {
                        /*
                         * if (pawn.skills.GetSkill(SkillDefOf.Shooting).level >= 1)
                         * {
                         *  suppressionAmount = (def.projectile.damageAmountBase * (1f - ((pawn.skills.GetSkill(SkillDefOf.Shooting).level) / 100) * 3));
                         * }
                         * else suppressionAmount = def.projectile.damageAmountBase;
                         */
                        suppressionAmount = def.projectile.damageAmountBase;
                        ProjectilePropertiesCR propsCR = def.projectile as ProjectilePropertiesCR;
                        float penetrationAmount        = propsCR == null ? 0f : propsCR.armorPenetration;
                        suppressionAmount *= 1 - Mathf.Clamp(compSuppressable.parentArmor - penetrationAmount, 0, 1);
                        compSuppressable.AddSuppression(suppressionAmount, origin.ToIntVec3());
                    }
                }

                //Check horizontal distance
                Vector3 dest              = destination;
                Vector3 orig              = origin;
                Vector3 pawnPos           = pawn.DrawPos;
                float   closestDistToPawn = Math.Abs((dest.z - orig.z) * pawnPos.x - (dest.x - orig.x) * pawnPos.z +
                                                     dest.x * orig.z - dest.z * orig.x)
                                            /
                                            (float)
                                            Math.Sqrt((dest.z - orig.z) * (dest.z - orig.z) +
                                                      (dest.x - orig.x) * (dest.x - orig.x));
                if (closestDistToPawn <= CR_Utility.GetCollisionWidth(pawn))
                {
                    //Check vertical distance
                    float pawnHeight = CR_Utility.GetCollisionHeight(pawn);
                    if (height < pawnHeight)
                    {
                        Impact(thing);
                        return(true);
                    }
                }
            }
            if (thing.def.fillPercent > 0 || thing.def.Fillage == FillCategory.Full)
            {
                if (height < CR_Utility.GetCollisionHeight(thing) || thing.def.Fillage == FillCategory.Full)
                {
                    Impact(thing);
                    return(true);
                }
            }
            return(false);
        }
Ejemplo n.º 9
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_CR damDefCR         = def.projectile.damageDef as DamageDef_CR;

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

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

                ProjectilePropertiesCR propsCR = def.projectile as ProjectilePropertiesCR;
                if (propsCR != null && !propsCR.secondaryDamage.NullOrEmpty())
                {
                    // Log.Message("propsCR: " + propsCR.ToString());
                    // Get the correct body part
                    Pawn pawn = hitThing as Pawn;
                    if (pawn != null && def.projectile.damageDef.workerClass == typeof(DamageWorker_AddInjuryCR))
                    {
                        BodyPartRecord exactPartFromDamageInfo = DamageWorker_AddInjuryCR.GetExactPartFromDamageInfo(dinfo, pawn);
                        dinfo = new DamageInfo(
                            dinfo.Def,
                            dinfo.Amount,
                            dinfo.Angle,
                            dinfo.Instigator,
                            exactPartFromDamageInfo = (DamageWorker_AddInjuryCR.GetExactPartFromDamageInfo(dinfo, pawn)),
                            dinfo.WeaponGear);
                    }
                    List <DamageInfo> dinfoList = new List <DamageInfo>()
                    {
                        dinfo
                    };
                    foreach (SecondaryDamage secDamage in propsCR.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);
            }
        }