public static bool Prefix(ProjectileCE __instance, Thing ___launcher, IntVec3 ___originInt, Vector2 ___origin, Vector2 ___destinationInt, int ___startingTicksToImpactInt, int ___ticksToImpact, int ___intTicksToImpact, ThingDef ___equipmentDef, ref float ___suppressionAmount, Thing hitThing)
        {
            if (hitThing != null)
            {
                bool  Rending       = false;
                float RendingChance = 0.167f;
                Pawn  caster        = ___launcher as Pawn;
                Thing Launcher      = ___launcher;
                if (caster != null)
                {
                    if (caster.equipment != null)
                    {
                        //    Log.Warning(string.Format("___launcher: {0}", ___launcher));
                        if (caster.equipment.Primary != null)
                        {
                            //    Log.Warning(string.Format("caster.equipment != null"));
                            Launcher = caster.equipment.Primary;
                            //    Log.Warning(string.Format("Launcher = caster.equipment.Primary"));
                            CompWeapon_GunSpecialRules _GunSpecialRules = Launcher.TryGetCompFast <CompWeapon_GunSpecialRules>();
                            if (_GunSpecialRules != null)
                            {
                                //    Log.Warning(string.Format("_GunSpecialRules != null"));
                                Rending       = _GunSpecialRules.Rending;
                                RendingChance = _GunSpecialRules.RendingChance;
                            }
                        }
                        else
                        {
                            //    Log.Warning(string.Format("caster.equipment == null"));
                            if (caster.health.hediffSet.hediffs.Any(x => x.TryGetCompFast <HediffComp_VerbGiverExtra>() != null))
                            {
                                //    Log.Warning(string.Format("HediffComp_VerbGiverExtra: {0}", ___launcher));
                                HediffComp_VerbGiverExtra _VGE = caster.health.hediffSet.hediffs.Find(x => x.TryGetCompFast <HediffComp_VerbGiverExtra>() is HediffComp_VerbGiverExtra z && z.verbTracker.AllVerbs.Any(y => y.verbProps.defaultProjectile == __instance.def)).TryGetCompFast <HediffComp_VerbGiverExtra>();
                                if (_VGE != null)
                                {
                                    //    Log.Warning(string.Format("_VGE != null: {0}", _VGE.parent.LabelCap));
                                    GunVerbEntry entry = _VGE.Props.verbEntrys.Find(x => x.VerbProps.defaultProjectile == __instance.def);
                                    if (entry != null)
                                    {
                                        //    Log.Warning(string.Format("{0}, Rending: {1}, Chance: {2}", entry.VerbProps.label, entry.Rending, entry.RendingChance));
                                        Rending       = entry.Rending;
                                        RendingChance = entry.RendingChance;
                                    }
                                }
                            }
                        }
                    }
                }
                if (Rending)
                {
                    //    Log.Warning(string.Format("Rending: {0}", ___launcher));
                    Rand.PushState();
                    bool RendingEffect = Rand.Chance(RendingChance);
                    Rand.PopState();
                    if (RendingEffect)
                    {
                        DamageDef damageDef = __instance.def.projectile.damageDef;
                        DamageArmorCategoryDef armorCategory = damageDef.armorCategory != null ? damageDef.armorCategory: null;
                        StatDef armorcatdef = damageDef.armorCategory != null ? armorCategory.armorRatingStat : null;
                        float   num         = 0f;
                        float   num2        = Mathf.Clamp01((armorcatdef != null ? hitThing.GetStatValue(armorcatdef, true) : 0f) / 2f);
                        if (hitThing is Pawn hitPawn)
                        {
                            List <BodyPartRecord> allParts = hitPawn.RaceProps.body.AllParts;
                            List <Apparel>        list     = (hitPawn.apparel == null) ? null : hitPawn.apparel.WornApparel;
                            for (int i = 0; i < allParts.Count; i++)
                            {
                                float num3 = 1f - num2;
                                if (list != null)
                                {
                                    for (int j = 0; j < list.Count; j++)
                                    {
                                        if (list[j].def.apparel.CoversBodyPart(allParts[i]))
                                        {
                                            float num4 = Mathf.Clamp01((armorcatdef != null ? list[j].GetStatValue(armorcatdef, true) : 0f) / 2f);
                                            num3 *= 1f - num4;
                                        }
                                    }
                                }
                                num += allParts[i].coverageAbs * (1f - num3);
                            }
                        }
                        num = Mathf.Clamp(num * 2f, 0f, 2f);
                        float armorPenetration = num;

                        MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, "AdeptusMechanicus.Rending_Shot".Translate(__instance.LabelCap, hitThing.LabelShortCap), 3f);
                        //    Log.Warning(string.Format("ArmorPenetration: {0}", ArmorPenetration));

                        bool flag = ___launcher is AmmoThing;
                        Map  map  = __instance.Map;
                        LogEntry_DamageResult logEntry_DamageResult = null;
                        bool flag2 = __instance.logMisses || (!__instance.logMisses && hitThing != null && (hitThing is Pawn || hitThing is Building_Turret));
                        if (flag2)
                        {
                            bool flag3 = !flag;
                            if (flag3)
                            {
                                LogImpact(__instance, ___launcher, ___equipmentDef, hitThing, out logEntry_DamageResult);
                            }
                        }
                        bool flag4 = hitThing != null;
                        if (flag4)
                        {
                            int damageAmount = __instance.def.projectile.GetDamageAmount(1f, null);
                            DamageDefExtensionCE   damageDefExtensionCE   = __instance.def.projectile.damageDef.GetModExtension <DamageDefExtensionCE>() ?? new DamageDefExtensionCE();
                            ProjectilePropertiesCE projectilePropertiesCE = (ProjectilePropertiesCE)__instance.def.projectile;
                            //    float armorPenetration = (this.def.projectile.damageDef.armorCategory == DamageArmorCategoryDefOf.Sharp) ? projectilePropertiesCE.armorPenetrationSharp : projectilePropertiesCE.armorPenetrationBlunt;
                            DamageInfo     damageInfo          = new DamageInfo(__instance.def.projectile.damageDef, (float)damageAmount, armorPenetration, __instance.ExactRotation.eulerAngles.y, ___launcher, null, __instance.def, DamageInfo.SourceCategory.ThingOrUnknown, null);
                            BodyPartDepth  depth               = (damageDefExtensionCE != null && damageDefExtensionCE.harmOnlyOutsideLayers) ? BodyPartDepth.Outside : BodyPartDepth.Undefined;
                            BodyPartHeight collisionBodyHeight = new CollisionVertical(hitThing).GetCollisionBodyHeight(__instance.ExactPosition.y);
                            damageInfo.SetBodyRegion(collisionBodyHeight, depth);
                            bool flag5 = damageDefExtensionCE != null && damageDefExtensionCE.harmOnlyOutsideLayers;
                            if (flag5)
                            {
                                damageInfo.SetBodyRegion(BodyPartHeight.Undefined, BodyPartDepth.Outside);
                            }
                            bool flag6 = flag && hitThing is Pawn;
                            if (flag6)
                            {
                                logEntry_DamageResult = new BattleLogEntry_DamageTaken((Pawn)hitThing, DefDatabase <RulePackDef> .GetNamed("DamageEvent_CookOff", true), null);
                                Find.BattleLog.Add(logEntry_DamageResult);
                            }
                            try
                            {
                                hitThing.TakeDamage(damageInfo).AssociateWithLog(logEntry_DamageResult);
                                bool flag7 = !(hitThing is Pawn) && projectilePropertiesCE != null && !projectilePropertiesCE.secondaryDamage.NullOrEmpty <SecondaryDamage>();
                                if (flag7)
                                {
                                    foreach (SecondaryDamage secondaryDamage in projectilePropertiesCE.secondaryDamage)
                                    {
                                        bool destroyed = hitThing.Destroyed;
                                        if (destroyed)
                                        {
                                            break;
                                        }
                                        DamageInfo dinfo = secondaryDamage.GetDinfo(damageInfo);
                                        hitThing.TakeDamage(dinfo).AssociateWithLog(logEntry_DamageResult);
                                    }
                                }
                            }
                            catch (Exception ex)
                            {
                                Log.Error("CombatExtended :: BulletCE impacting thing " + hitThing.LabelCap + " of def " + hitThing.def.LabelCap + " added by mod " + hitThing.def.modContentPack.Name + ". See following stacktrace for information.", false);
                                throw ex;
                            }
                            finally
                            {
                                Impact(__instance, ___launcher, ___equipmentDef, hitThing, ___originInt, ___origin, ___destinationInt, ___startingTicksToImpactInt, ___ticksToImpact, ___intTicksToImpact, ref ___suppressionAmount);
                            }
                        }
                        else
                        {
                            SoundDefOf.BulletImpact_Ground.PlayOneShot(new TargetInfo(__instance.Position, map, false));
                            bool castShadow = __instance.castShadow;
                            if (castShadow)
                            {
                                FleckMaker.Static(__instance.ExactPosition, map, FleckDefOf.ShotHit_Dirt, 1f);
                                bool takeSplashes = __instance.Position.GetTerrain(map).takeSplashes;
                                if (takeSplashes)
                                {
                                    FleckMaker.WaterSplash(__instance.ExactPosition, map, Mathf.Sqrt((float)__instance.def.projectile.GetDamageAmount(___launcher, null)) * 1f, 4f);
                                }
                            }
                            Impact(__instance, ___launcher, ___equipmentDef, hitThing, ___originInt, ___origin, ___destinationInt, ___startingTicksToImpactInt, ___ticksToImpact, ___intTicksToImpact, ref ___suppressionAmount);
                        }
                        NotifyImpact(__instance, ___launcher, hitThing, map, __instance.Position);
                    }
                    return(false);
                }
            }
            return(true);
        }
Ejemplo n.º 2
0
        public static IEnumerable <BodyPartRecord> GetNotMissingParts(this HediffSet set, BodyPartHeight height = BodyPartHeight.Undefined, BodyPartDepth depth = BodyPartDepth.Undefined, List <BodyPartTagDef> tags = null, BodyPartRecord partParent = null)
        {
            List <BodyPartRecord> allPartsList = set.pawn.def.race.body.AllParts;
            int num;

            for (int i = 0; i < allPartsList.Count; i = num + 1)
            {
                BodyPartRecord bodyPartRecord = allPartsList[i];
                if (!set.PartIsMissing(bodyPartRecord) && (height == BodyPartHeight.Undefined || bodyPartRecord.height == height) && (depth == BodyPartDepth.Undefined || bodyPartRecord.depth == depth) && (tags == null || bodyPartRecord.def.tags.Any(x => tags.Contains(x))) && (partParent == null || bodyPartRecord.parent == partParent))
                {
                    yield return(bodyPartRecord);
                }
                num = i;
            }
            yield break;
        }
Ejemplo n.º 3
0
        protected override void Impact(Thing hitThing)
        {
            bool cookOff = (launcher is AmmoThing);

            Map map = base.Map;
            LogEntry_DamageResult logEntry = null;

            if (logMisses
                ||
                (!logMisses &&
                 hitThing != null &&
                 (hitThing is Pawn ||
                  hitThing is Building_Turret)
                ))
            {
                if (!cookOff)
                {
                    LogImpact(hitThing, out logEntry);
                }
            }

            if (hitThing != null)
            {
                // launcher being the pawn equipping the weapon, not the weapon itself
                int damageAmountBase          = def.projectile.GetDamageAmount(1);
                DamageDefExtensionCE damDefCE = def.projectile.damageDef.GetModExtension <DamageDefExtensionCE>() ?? new DamageDefExtensionCE();
                var projectilePropsCE         = (ProjectilePropertiesCE)def.projectile;
                var isSharpDmg  = def.projectile.damageDef.armorCategory == DamageArmorCategoryDefOf.Sharp;
                var penetration = isSharpDmg ? projectilePropsCE.armorPenetrationSharp : projectilePropsCE.armorPenetrationBlunt;

                DamageInfo dinfo = new DamageInfo(
                    def.projectile.damageDef,
                    damageAmountBase,
                    penetration, //Armor Penetration
                    ExactRotation.eulerAngles.y,
                    launcher,
                    null,
                    def);

                // Set impact height
                BodyPartDepth partDepth = damDefCE != null && damDefCE.harmOnlyOutsideLayers ? BodyPartDepth.Outside : BodyPartDepth.Undefined;
                //NOTE: ExactPosition.y isn't always Height at the point of Impact!
                BodyPartHeight partHeight = new CollisionVertical(hitThing).GetCollisionBodyHeight(ExactPosition.y);
                dinfo.SetBodyRegion(partHeight, partDepth);
                if (damDefCE != null && damDefCE.harmOnlyOutsideLayers)
                {
                    dinfo.SetBodyRegion(BodyPartHeight.Undefined, BodyPartDepth.Outside);
                }

                //The following code excludes turrets etcetera from having cook off projectile impacts recorded in their combat log.
                //If it is necessary to add cook off to turret logs, a new BattleLogEntry_ must be created, because BattleLogEntry_DamageTaken,
                //which is the only method capable of handling cookoff and only using pawns, can not take !(hitThing is Pawn).
                if (cookOff && hitThing is Pawn)
                {
                    logEntry =
                        new BattleLogEntry_DamageTaken(
                            (Pawn)hitThing,
                            DefDatabase <RulePackDef> .GetNamed("DamageEvent_CookOff"));
                    Find.BattleLog.Add(logEntry);
                }

                try
                {
                    // Apply primary damage
                    hitThing.TakeDamage(dinfo).AssociateWithLog(logEntry);

                    // Apply secondary to non-pawns (pawn secondary damage is handled in the damage worker)
                    // The !(hitThing is Pawn) already excludes non-pawn cookoff projectiles from being logged, as logEntry == null
                    if (!(hitThing is Pawn) && projectilePropsCE != null && !projectilePropsCE.secondaryDamage.NullOrEmpty())
                    {
                        foreach (SecondaryDamage cur in projectilePropsCE.secondaryDamage)
                        {
                            if (hitThing.Destroyed)
                            {
                                break;
                            }

                            var secDinfo = cur.GetDinfo(dinfo);
                            hitThing.TakeDamage(secDinfo).AssociateWithLog(logEntry);
                        }
                    }
                }
                catch (Exception e)
                {
                    Log.Error("CombatExtended :: BulletCE impacting thing " + hitThing.LabelCap + " of def " + hitThing.def.LabelCap + " added by mod " + hitThing.def.modContentPack.Name + ". See following stacktrace for information.");
                    throw e;
                }
                finally
                {
                    base.Impact(hitThing);
                }
            }
            else
            {
                SoundDefOf.BulletImpact_Ground.PlayOneShot(new TargetInfo(base.Position, map, false));

                //Only display a dirt/water hit for projectiles with a dropshadow
                if (base.castShadow)
                {
                    MoteMaker.MakeStaticMote(this.ExactPosition, map, ThingDefOf.Mote_ShotHit_Dirt, 1f);
                    if (base.Position.GetTerrain(map).takeSplashes)
                    {
                        MoteMaker.MakeWaterSplash(this.ExactPosition, map, Mathf.Sqrt(def.projectile.GetDamageAmount(this.launcher)) * 1f, 4f);
                    }
                }
                base.Impact(hitThing);
            }
        }
Ejemplo n.º 4
0
 public void SetBodyRegion(BodyPartHeight height = BodyPartHeight.Undefined, BodyPartDepth depth = BodyPartDepth.Undefined)
 {
     heightInt = height;
     depthInt  = depth;
 }
Ejemplo n.º 5
0
 public static BodyPartRecord RerollBodyPart(TargetingModeDef targetingMode, BodyPartRecord bodyPart, DamageDef damDef, BodyPartHeight height, BodyPartDepth depth, Pawn pawn, Thing instigator)
 {
     for (int i = 0; i < targetingMode.RerollCount(pawn, instigator); i++)
     {
         BodyPartRecord newPart = pawn.health.hediffSet.GetRandomNotMissingPart(damDef, height, depth);
         if (newPart.IsPrioritizedPart(targetingMode))
         {
             return(newPart);
         }
     }
     return(bodyPart);
 }
Ejemplo n.º 6
0
        public IEnumerable <BodyPartRecord> GetNotMissingParts(BodyPartHeight height = BodyPartHeight.Undefined, BodyPartDepth depth = BodyPartDepth.Undefined)
        {
            List <BodyPartRecord> allPartsList = this.pawn.def.race.body.AllParts;

            for (int i = 0; i < allPartsList.Count; i++)
            {
                BodyPartRecord part = allPartsList[i];
                if (!this.PartIsMissing(part))
                {
                    if (height == BodyPartHeight.Undefined || part.height == height)
                    {
                        if (depth == BodyPartDepth.Undefined || part.depth == depth)
                        {
                            yield return(part);
                        }
                    }
                }
            }
        }
Ejemplo n.º 7
0
        public BodyPartRecord GetRandomNotMissingPart(DamageDef damDef, BodyPartHeight height = BodyPartHeight.Undefined, BodyPartDepth depth = BodyPartDepth.Undefined)
        {
            IEnumerable <BodyPartRecord> notMissingParts;

            if (this.GetNotMissingParts(height, depth).Any <BodyPartRecord>())
            {
                notMissingParts = this.GetNotMissingParts(height, depth);
            }
            else
            {
                if (!this.GetNotMissingParts(BodyPartHeight.Undefined, depth).Any <BodyPartRecord>())
                {
                    return(null);
                }
                notMissingParts = this.GetNotMissingParts(BodyPartHeight.Undefined, depth);
            }
            BodyPartRecord result;

            if (notMissingParts.TryRandomElementByWeight((BodyPartRecord x) => x.coverageAbs * x.def.GetHitChanceFactorFor(damDef), out result))
            {
                return(result);
            }
            if (notMissingParts.TryRandomElementByWeight((BodyPartRecord x) => x.coverageAbs, out result))
            {
                return(result);
            }
            throw new InvalidOperationException();
        }
Ejemplo n.º 8
0
        public BodyPartRecord GetRandomNotMissingPart(DamageDef damDef, BodyPartHeight height = BodyPartHeight.Undefined, BodyPartDepth depth = BodyPartDepth.Undefined, BodyPartRecord partParent = null)
        {
            IEnumerable <BodyPartRecord> enumerable = null;

            if (GetNotMissingParts(height, depth, null, partParent).Any())
            {
                enumerable = GetNotMissingParts(height, depth, null, partParent);
            }
            else
            {
                if (!GetNotMissingParts(BodyPartHeight.Undefined, depth, null, partParent).Any())
                {
                    return(null);
                }
                enumerable = GetNotMissingParts(BodyPartHeight.Undefined, depth, null, partParent);
            }
            if (enumerable.TryRandomElementByWeight((BodyPartRecord x) => x.coverageAbs * x.def.GetHitChanceFactorFor(damDef), out var result))
            {
                return(result);
            }
            if (enumerable.TryRandomElementByWeight((BodyPartRecord x) => x.coverageAbs, out result))
            {
                return(result);
            }
            throw new InvalidOperationException();
        }
Ejemplo n.º 9
0
        public IEnumerable <BodyPartRecord> GetNotMissingParts(BodyPartHeight height = BodyPartHeight.Undefined, BodyPartDepth depth = BodyPartDepth.Undefined, BodyPartTagDef tag = null, BodyPartRecord partParent = null)
        {
            List <BodyPartRecord> allPartsList = pawn.def.race.body.AllParts;

            for (int i = 0; i < allPartsList.Count; i++)
            {
                BodyPartRecord bodyPartRecord = allPartsList[i];
                if (!PartIsMissing(bodyPartRecord) && (height == BodyPartHeight.Undefined || bodyPartRecord.height == height) && (depth == BodyPartDepth.Undefined || bodyPartRecord.depth == depth) && (tag == null || bodyPartRecord.def.tags.Contains(tag)) && (partParent == null || bodyPartRecord.parent == partParent))
                {
                    yield return(bodyPartRecord);
                }
            }
        }
Ejemplo n.º 10
0
        protected override void Impact(Thing hitThing)
        {
            Map map = base.Map;

            if (hitThing != null)
            {
                int                  damageAmountBase = def.projectile.damageAmountBase;
                ThingDef             equipmentDef     = this.equipmentDef;
                DamageDefExtensionCE damDefCE         = def.projectile.damageDef.GetModExtension <DamageDefExtensionCE>() ?? new DamageDefExtensionCE();

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

                // Set impact height
                BodyPartDepth partDepth = damDefCE != null && damDefCE.harmOnlyOutsideLayers ? BodyPartDepth.Outside : BodyPartDepth.Undefined;
                //NOTE: ExactPosition.y isn't always Height at the point of Impact!
                BodyPartHeight partHeight = new CollisionVertical(hitThing).GetCollisionBodyHeight(ExactPosition.y);
                dinfo.SetBodyRegion(partHeight, partDepth);
                if (damDefCE != null && damDefCE.harmOnlyOutsideLayers)
                {
                    dinfo.SetBodyRegion(BodyPartHeight.Undefined, BodyPartDepth.Outside);
                }

                // Apply primary damage
                hitThing.TakeDamage(dinfo);

                // Apply secondary to non-pawns (pawn secondary damage is handled in the damage worker)
                var projectilePropsCE = def.projectile as ProjectilePropertiesCE;
                if (!(hitThing is Pawn) && projectilePropsCE != null && !projectilePropsCE.secondaryDamage.NullOrEmpty())
                {
                    foreach (SecondaryDamage cur in projectilePropsCE.secondaryDamage)
                    {
                        if (hitThing.Destroyed)
                        {
                            break;
                        }
                        var secDinfo = new DamageInfo(
                            cur.def,
                            cur.amount,
                            ExactRotation.eulerAngles.y,
                            launcher,
                            null,
                            def);
                        hitThing.TakeDamage(secDinfo);
                    }
                }
            }
            else
            {
                SoundDefOf.BulletImpactGround.PlayOneShot(new TargetInfo(base.Position, map, false));

                //Only display a dirt hit for projectiles with a dropshadow
                if (base.castShadow)
                {
                    MoteMaker.MakeStaticMote(ExactPosition, map, ThingDefOf.Mote_ShotHit_Dirt, 1f);
                }
            }
            base.Impact(hitThing);
        }
Ejemplo n.º 11
0
        public BodyPartRecord GetRandomNotMissingPart(DamageDef damDef, BodyPartHeight height = BodyPartHeight.Undefined, BodyPartDepth depth = BodyPartDepth.Undefined)
        {
            IEnumerable <BodyPartRecord> enumerable = null;

            if (this.GetNotMissingParts(height, depth).Any())
            {
                enumerable = this.GetNotMissingParts(height, depth);
                goto IL_0053;
            }
            if (this.GetNotMissingParts(BodyPartHeight.Undefined, depth).Any())
            {
                enumerable = this.GetNotMissingParts(BodyPartHeight.Undefined, depth);
                goto IL_0053;
            }
            return(null);

IL_0053:
            BodyPartRecord result = default(BodyPartRecord);

            if (enumerable.TryRandomElementByWeight <BodyPartRecord>((Func <BodyPartRecord, float>)((BodyPartRecord x) => x.coverageAbs * x.def.GetHitChanceFactorFor(damDef)), out result))
            {
                return(result);
            }
            if (enumerable.TryRandomElementByWeight <BodyPartRecord>((Func <BodyPartRecord, float>)((BodyPartRecord x) => x.coverageAbs), out result))
            {
                return(result);
            }
            throw new InvalidOperationException();
        }
Ejemplo n.º 12
0
        public IEnumerable <BodyPartRecord> GetNotMissingParts(BodyPartHeight height = BodyPartHeight.Undefined, BodyPartDepth depth = BodyPartDepth.Undefined)
        {
            List <BodyPartRecord> allPartsList = this.pawn.def.race.body.AllParts;
            int            i = 0;
            BodyPartRecord part;

            while (true)
            {
                if (i < allPartsList.Count)
                {
                    part = allPartsList[i];
                    if (!this.PartIsMissing(part) && (height == BodyPartHeight.Undefined || part.height == height))
                    {
                        if (depth == BodyPartDepth.Undefined)
                        {
                            break;
                        }
                        if (part.depth == depth)
                        {
                            break;
                        }
                    }
                    i++;
                    continue;
                }
                yield break;
            }
            yield return(part);

            /*Error: Unable to find new state assignment for yield return*/;
        }