Ejemplo n.º 1
0
        public static float JamChance(IAdvancedVerb verbEntry, Thing gun)
        {
            float result = 0f;

            switch (verbEntry.Reliability)
            {
            case Reliability.UR:
                result = 50f;
                break;

            case Reliability.ST:
                result = 30f;
                break;

            case Reliability.VR:
                result = 10f;
                break;

            default:
                return(0);
            }
            if (gun != null)
            {
                result += GetQualityFactor(gun);
                result  = result * 100 / gun.HitPoints / 100;
            }
            result = (float)(Math.Truncate((double)result * 100.0) / 100.0);
            return(result);
        }
Ejemplo n.º 2
0
        public static bool GetsHot(this Verb verb, out bool GetsHotCrit, out float GetsHotCritChance, out bool GetsHotCritExplosion, out float GetsHotCritExplosionChance, out bool canDamageWeapon, out float extraWeaponDamage)
        {
            IAdvancedVerb entry   = verb.verbProps as IAdvancedVerb;
            bool          GetsHot = false;

            if (entry == null || !AMSettings.Instance.AllowGetsHot)
            {
                GetsHotCrit                = false;
                GetsHotCritChance          = 0f;
                GetsHotCritExplosion       = false;
                GetsHotCritExplosionChance = 0f;
                canDamageWeapon            = false;
                extraWeaponDamage          = 0f;
                //    Log.Message("no SpecialRules detected");
                return(GetsHot);
            }
            GetsHot                    = entry.GetsHot;
            GetsHotCrit                = entry.GetsHotCrit;
            GetsHotCritChance          = entry.GetsHotCritChance;
            GetsHotCritExplosion       = entry.GetsHotCritExplosion;
            GetsHotCritExplosionChance = entry.GetsHotCritExplosionChance;
            canDamageWeapon            = entry.HotDamageWeapon;
            extraWeaponDamage          = entry.HotDamage;
            return(GetsHot);
        }
        public static void Postfix(VerbProperties __instance, IntVec3 center)
        {
            IAdvancedVerb verbProperties = __instance as IAdvancedVerb;

            if (AMAMod.settings.AllowRapidFire && verbProperties != null)
            {
                verbProperties.DrawExtraRadiusRings(center);
            }
        }
        public static void Postfix(VerbProperties __instance, IntVec3 center)
        {
            IAdvancedVerb verbProperties = __instance as IAdvancedVerb;

            if (verbProperties != null)
            {
                verbProperties.DrawExtraRadiusRings(center);
            }
        }
Ejemplo n.º 5
0
        public static void Postfix(ref Verb_ShootCE __instance, float __state)
        {
            IAdvancedVerb entry = __instance.SpecialRules();

            if (entry != null)
            {
                __instance.verbProps.warmupTime = __state;
                //    Log.Message("Postfix original warmup " + __state + " " + __instance.verbProps.label + " fired by " + __instance.CasterPawn.LabelShortCap + "\nwarmup " + __instance.verbProps.warmupTime + " Cooldown " + __instance.verbProps.AdjustedCooldown(__instance, __instance.CasterPawn) + " Burst " + ((__instance.verbProps.burstShotCount - 1) * __instance.verbProps.ticksBetweenBurstShots).TicksToSeconds());
            }
        }
Ejemplo n.º 6
0
        public void Setup(Thing launcher, Vector3 origin, Vector3 destination, Verb verb = null, Thing hitThing = null, Effecter effecter = null, EffecterDef effecterDef = null)
        {
            //SetColor(launcher);
            this.launcher    = launcher;
            this.verb        = verb;
            this.a           = origin;
            this.b           = destination;
            this.hitThing    = hitThing ?? null;
            this.effecter    = effecter ?? null;
            this.effecterDef = effecterDef ?? null;
            Map     map = verb?.Caster?.Map ?? launcher.Map;
            Vector3 dir = (destination - origin).normalized;

            dir.y = 0;

            Vector3 a = origin;// += dir * (defWeapon == null ? 0.9f : defWeapon.barrelLength);

            if (verb != null)
            {
                if (verb.Muzzle(out float barrelLength, out float barrelOffset, out float bulletOffset, out FleckDef flareDef, out float flareSize, out FleckDef smokeDef, out float smokeSize))
                {
                    a    = origin -= dir * (barrelOffset * (verb.EquipmentSource.def.graphicData.drawSize.magnitude / 4));
                    a.y += 0.0367346928f;
                    if (flareDef != null)
                    {
                        IAdvancedVerb properties = verb.verbProps as IAdvancedVerb;
                        Rand.PushState();
                        AdeptusFleckMaker.Static(a, map, flareDef, flareSize, properties?.MuzzleFlareColor, properties != null && properties.MuzzleFlareRotates ? (float?)Rand.Range(0, 350) : null, projDef.lifetime);
                        Rand.PopState();
                    }
                    if (smokeDef != null)
                    {
                        AdeptusFleckMaker.ThrowSmoke(a, smokeSize, map, smokeDef);
                    }
                }

                FleckMaker.Static(a, launcher.Map, FleckDefOf.ShotFlash, verb.verbProps.muzzleFlashScale);
            }
            if (effecter == null)
            {
                TriggerEffect(effecterDef, b, hitThing);
            }
            ProjectileVFX ext = this.projDef.GetModExtensionFast <ProjectileVFX>();

            if (ext != null && destination.InBounds(launcher.Map))
            {
                Vector3  pos = destination;
                ThingDef explosionMoteDef = ext.ExplosionMoteDef ?? projDef.projectile.damageDef.explosionCellMote ?? null;
                SoundDef sound            = projDef.projectile.damageDef.soundExplosion;
                Color?   color            = ext.useGraphicColor ? projDef.graphic.color : (ext.useGraphicColorTwo ? projDef.graphic.colorTwo : projDef.projectile.damageDef.explosionColorCenter);
                float    scale            = ext.scaleWithProjectile ? projDef.graphic.drawSize.magnitude : 1f;
                ext.ImpactEffects(pos, map, explosionMoteDef, ext.ExplosionMoteSize * scale, color, sound, ext.ImpactMoteDef, ext.ImpactMoteSize * scale, ext.ImpactGlowMoteDef, ext.ImpactGlowMoteSize * scale, hitThing, null, (int)((projDef.lifetime - ticks) * 1.1f));
                //    ext.ImpactEffects(destination, launcher.Map, ext.ExplosionMoteDef ?? this.projDef.projectile.damageDef.explosionCellMote, ext.ExplosionMoteSize, this.projDef.projectile.damageDef.explosionColorCenter, this.projDef.projectile.damageDef.soundExplosion, ext.ImpactMoteDef, ext.ImpactMoteSize, ext.ImpactGlowMoteDef, ext.ImpactGlowMoteSize, hitThing);
            }
        }
        public static bool Prefix(VerbProperties __instance, Thing equipment, float dist, ref float __result)
        {
            IAdvancedVerb verbProperties = __instance as IAdvancedVerb;

            if (verbProperties != null)
            {
                __result = verbProperties.GetHitChanceFactor(equipment, dist);
                return(false);
            }
            return(true);
        }
Ejemplo n.º 8
0
        public static void ExtraProjectiles(Projectile projectile2, Thing launcher, Vector3 origin, LocalTargetInfo usedTarget, LocalTargetInfo intendedTarget, ProjectileHitFlags hitFlags, bool preventFriendlyFire, Thing equipment, ThingDef targetCoverDef, ShootLine shootLine, Verb_LaunchProjectile instance)
        {
            IDrawnWeaponWithRotation weapon = null;
            Pawn pawn = launcher as Pawn;

            if (pawn != null && pawn.equipment != null)
            {
                weapon = pawn.equipment.Primary as IDrawnWeaponWithRotation;
            }
            if (weapon == null)
            {
                Building_LaserGun turret = launcher as Building_LaserGun;
                if (turret != null)
                {
                    weapon = turret.gun as IDrawnWeaponWithRotation;
                }
            }
            if (weapon != null)
            {
                float angle = (usedTarget.CenterVector3 - origin).AngleFlat() - (intendedTarget.CenterVector3 - origin).AngleFlat();
                weapon.RotationOffset = (angle + 180) % 360 - 180;
            }
            projectile2.Launch(launcher, origin, usedTarget, intendedTarget, hitFlags, preventFriendlyFire, equipment, targetCoverDef);
            int           extras = 0;
            IAdvancedVerb Props  = instance.verbProps as IAdvancedVerb;

            if (Props != null)
            {
                extras = Props.ScattershotCount;
            }
            else
            {
                ScattershotProjectileExtension ext = projectile2.def.GetModExtensionFast <ScattershotProjectileExtension>();
                if (ext != null && ext.projectileCount.HasValue)
                {
                    extras = ext.projectileCount.Value;
                }
            }
            if (extras > 0)
            {
                for (int i = 0; i < extras; i++)
                {
                    Projectile projectile3 = (Projectile)GenSpawn.Spawn(projectile2.def, shootLine.Source, launcher.Map, WipeMode.Vanish);
                    projectile3.Launch(launcher, origin, usedTarget, intendedTarget, hitFlags, preventFriendlyFire, equipment, targetCoverDef);
                }
            }
        }
Ejemplo n.º 9
0
        public static void Prefix(ref Verb_Shoot __instance, ref float?__state)
        {
            __state = __instance.verbProps.warmupTime;
            IAdvancedVerb entry = __instance.SpecialRules();

            if (entry != null)
            {
                if (__instance.RapidFire(__state.Value, out bool InRange, out float modified))
                {
                    if (InRange)
                    {
                        __instance.verbProps.warmupTime = modified;
                    }
                }
                //    Log.Message("Prefix original warmup " + __state  + " "+ __instance.verbProps.label + " fired by " + __instance.CasterPawn.LabelShortCap + "\nwarmup " + __instance.verbProps.warmupTime + " Cooldown " + __instance.verbProps.AdjustedCooldown(__instance, __instance.CasterPawn) + " Burst " + ((__instance.verbProps.burstShotCount - 1) * __instance.verbProps.ticksBetweenBurstShots).TicksToSeconds());
            }
        }
Ejemplo n.º 10
0
        public static bool Jams(this Verb verb, out bool canDamageWeapon, out float extraWeaponDamage)
        {
            IAdvancedVerb entry = verb.verbProps as IAdvancedVerb;
            bool          Jams  = false;

            if (entry == null || !AMSettings.Instance.AllowJams)
            {
                canDamageWeapon   = false;
                extraWeaponDamage = 0f;
                //     Log.Message("no SpecialRules detected");
                return(Jams);
            }
            Jams              = entry.Jams;
            canDamageWeapon   = entry.JamsDamageWeapon;
            extraWeaponDamage = entry.JamDamage;
            return(Jams);
        }
Ejemplo n.º 11
0
 public static void GetReliability(IAdvancedVerb verbEntry, Thing gun, out string rel, out float jamsOn)
 {
     rel    = string.Empty;
     jamsOn = JamChance(verbEntry, gun);
     if (jamsOn < 0.25)
     {
         rel = "Extremely Reliable";
     }
     else if (jamsOn < 0.5)
     {
         rel = "Very Reliable";
     }
     else if (jamsOn < 1)
     {
         rel = "Standard";
     }
     else
     {
         rel = "Unreliable";
     }
 }
Ejemplo n.º 12
0
        public static float AdjustedWarmup(float warmUpTime, Verb verb, LocalTargetInfo castTarg)
        {
            if (AdeptusIntergrationUtility.enabled_CombatExtended)
            {
                if (!CE(verb))
                {
                    return(warmUpTime);
                }
            }
            else
            {
                if (!(verb is Verb_Shoot) && !(verb is AbilitesExtended.Verb_ShootEquipment))
                {
                    return(warmUpTime);
                }
            }
            float result = warmUpTime;
            //    AdvancedVerbProperties props = verb.verbProps as AdvancedVerbProperties;
            IAdvancedVerb  props      = verb.verbProps as IAdvancedVerb;
            ThingWithComps gun        = verb.EquipmentSource;
            CompEquippable compeq     = verb.EquipmentCompSource;
            Thing          caster     = verb.caster;
            Pawn           CasterPawn = verb.CasterPawn;

            if (props != null)
            {
                if (verb.GetsHot(out bool GetsHotCrit, out float GetsHotCritChance, out bool GetsHotCritExplosion, out float GetsHotCritExplosionChance, out bool canDamageWeapon, out float extraWeaponDamage))
                {
                }

                if (props.RapidFire)
                {
                    //    log.message(string.Format("RapidFire prefix pre-modified Values, Warmup: {0}", gun.def.Verbs[0].warmupTime, cooldown));
                    if (caster.Position.InHorDistOf(castTarg.Cell, verb.verbProps.range * props.RapidFireRange))
                    {
                        float reduction = ((verb.verbProps.burstShotCount - 1) * verb.verbProps.ticksBetweenBurstShots).TicksToSeconds() / 4;
                        reduction += warmUpTime / 2;
                        result    -= reduction;
                    }
                    //    log.message(string.Format("RapidFire prefix post-modified Values, Warmup: {0}", gun.def.Verbs[0].warmupTime, cooldown));
                }
                else if (props.HeavyWeapon && verb.CasterIsPawn)
                {
                    CompWeapon_GunSpecialRules GunExt = gun.TryGetCompFast <CompWeapon_GunSpecialRules>();
                    if (GunExt.ticksHere < (props.HeavyWeaponSetupTime.SecondsToTicks()))
                    {
                        float extra = props.HeavyWeaponSetupTime;
                        if (CasterPawn.story?.bodyType == BodyTypeDefOf.Hulk)
                        {
                            extra *= 0.5f;
                        }
                        extra = Math.Max(0, extra - GunExt.ticksHere.TicksToSeconds());
                        //    Log.Message(string.Format("HeavyWeapon prefix pre-modified Values, Warmup: {0} + {1}, last move tick: {2}", __instance.verbProps.warmupTime, extra, GunExt.LastMovedTick));
                        result += extra;
                    }
                    //    log.message(string.Format("HeavyWeapon prefix post-modified Values, Warmup: {0}, last move tick: {1}", gun.def.Verbs[0].warmupTime, GunExt.LastMovedTick));
                }
                if (compeq != null)
                {
                    if (verb.GetProjectile().projectile.Conversion())
                    {
                        float distance = caster.Position.DistanceTo(castTarg.Cell);
                        result = (float)warmUpTime + (distance / 30);
                    }
                }
            }
            //    Log.Message("Testing return result" + result + " warmUpTime: " + warmUpTime + " for verb: " + verb + " casting at " + castTarg);
            return(result);
        }
Ejemplo n.º 13
0
        public static bool Prefix(ref Verb_Shoot __instance)
        {
            //    Log.Warning("TryCastShot");
            IAdvancedVerb entry = __instance.SpecialRules();

            if (entry == null)
            {
                //    Log.Message("no SpecialRules detected");
                return(true);
            }
            bool          UserEffect      = entry.EffectsUser;
            HediffDef     UserHediff      = entry.UserEffect;
            float         AddHediffChance = entry.EffectsUserChance;
            List <string> Immunitylist    = entry.UserEffectImmuneList;
            string        msg             = string.Format("");
            float         failChance      = entry.FailChance(__instance.EquipmentSource, out string reliabilityString);

            bool failed = false;

            if (failChance > 0f)
            {
                if (entry.Debug)
                {
                    Log.Message("failChance: " + failChance);
                }
                Rand.PushState();
                failed = Rand.Chance(failChance);
                Rand.PopState();
                if (entry.Debug)
                {
                    Log.Message((entry.GetsHot ? "Overheat" : "Jam") + " Chance: " + failChance + "% Result: " + (failed ? (entry.GetsHot ? "Overheated" : "Jamed") : "Passed"));
                }
                //    Log.Message("failed: "+failed);
            }
            if (failed)
            {
                bool           stillFire         = true;
                bool           canDamageWeapon   = entry.HotDamageWeapon || entry.JamsDamageWeapon;
                MessageTypeDef msgDef            = entry.GetsHot ? MessageTypeDefOf.NegativeHealthEvent : MessageTypeDefOf.SilentInput;
                float          extraWeaponDamage = entry.HotDamageWeapon ? entry.HotDamage : entry.JamDamage;
                if (entry.GetsHot)
                {
                    string    overheat     = "overheated";
                    string    causing      = "causing";
                    DamageDef damageDef    = __instance.Projectile.projectile.damageDef;
                    HediffDef HediffToAdd  = damageDef.hediff;
                    Pawn      launcherPawn = __instance.caster as Pawn;
                    Rand.PushState();
                    bool crit = Rand.Chance(entry.GetsHotCritChance);
                    Rand.PopState();
                    bool critExplode = false;
                    if (crit)
                    {
                        overheat = "critically overheated";
                        if (entry.GetsHotCritExplosion)
                        {
                            critExplode = Rand.Chance(entry.GetsHotCritExplosionChance);
                            if (critExplode)
                            {
                                causing = "causing an explosion";
                                CriticalOverheatExplosion(__instance);
                            }
                        }
                    }
                    float ArmorPenetration = __instance.Projectile.projectile.GetArmorPenetration(__instance.EquipmentSource, null) * (crit ? 1f : 0.25f);
                    float DamageAmount     = __instance.Projectile.projectile.GetDamageAmount(__instance.EquipmentSource, null) * (crit ? 1f : 0.25f);
                    msg = string.Format("{0}'s {1} " + overheat + ". ({2} chance) " + causing + " {3} damage", __instance.caster.LabelCap, __instance.EquipmentSource.LabelCap, failChance.ToStringPercent(), DamageAmount);
                    float damageLeft = DamageAmount;
                    List <BodyPartTagDef> tagDefs = new List <BodyPartTagDef>()
                    {
                        BodyPartTagDefOf.ManipulationLimbDigit, BodyPartTagDefOf.ManipulationLimbSegment
                    };
                    List <BodyPartRecord> list = launcherPawn.health.hediffSet.GetNotMissingParts(BodyPartHeight.Undefined, BodyPartDepth.Outside, tagDefs).ToList <BodyPartRecord>();
                    if (list.NullOrEmpty())
                    {
                        list = launcherPawn.health.hediffSet.GetNotMissingParts().Where(x => x.def.defName.Contains("Arm") || x.parent.def.defName.Contains("Arm")).ToList <BodyPartRecord>();
                    }
                    if (list.NullOrEmpty())
                    {
                        list = launcherPawn.health.hediffSet.GetNotMissingParts().Where(x => x.def.tags.Contains(BodyPartTagDefOf.ManipulationLimbCore) || x.def.tags.Contains(BodyPartTagDefOf.ManipulationLimbSegment) || x.def.tags.Contains(BodyPartTagDefOf.ManipulationLimbDigit)).ToList <BodyPartRecord>();
                    }
                    if (!list.NullOrEmpty())
                    {
                        while (damageLeft > 0f && !list.NullOrEmpty())
                        {
                            Rand.PushState();
                            BodyPartRecord part = list.RandomElement();
                            list.Remove(part);
                            float maxPartDamage = Math.Min(damageLeft, launcherPawn.health.hediffSet.GetPartHealth(part));
                            float amount        = Rand.Range(1f, Math.Min(damageLeft, maxPartDamage));
                            Rand.PopState();
                            if (amount > 0)
                            {
                                /*
                                 * Hediff hediff = HediffMaker.MakeHediff(HediffToAdd, launcherPawn, part);
                                 * hediff.Severity = severity;
                                 * launcherPawn.health.AddHediff(hediff, part, null);
                                 */
                                DamageInfo info = new DamageInfo(damageDef, amount, ArmorPenetration, -1, __instance.EquipmentSource, part, __instance.EquipmentSource.def, DamageInfo.SourceCategory.ThingOrUnknown, __instance.CurrentTarget.Thing ?? null);
                                launcherPawn.TakeDamage(info);
                                damageLeft -= amount;
                            }
                        }
                    }
                    else
                    {
                    }
                    Messages.Message(msg, MessageTypeDefOf.NegativeHealthEvent);
                }
                if (entry.Jams)
                {
                    if (!__instance.GetsHot())
                    {
                        msg = string.Format("{0}'s {1} had a weapon jam. ({2} chance)", __instance.caster.LabelCap, __instance.EquipmentSource.LabelCap, failChance.ToStringPercent());
                        Messages.Message(msg, MessageTypeDefOf.SilentInput);
                    }
                    float defaultCooldownTime = __instance.verbProps.defaultCooldownTime * 2;
                    __instance.verbProps.defaultCooldownTime = defaultCooldownTime;
                    if (canDamageWeapon)
                    {
                        if (extraWeaponDamage != 0f)
                        {
                            if (__instance.EquipmentSource != null)
                            {
                                if (__instance.EquipmentSource.HitPoints - (int)extraWeaponDamage >= 0)
                                {
                                    __instance.EquipmentSource.HitPoints = __instance.EquipmentSource.HitPoints - (int)extraWeaponDamage;
                                }
                                else if (__instance.EquipmentSource.HitPoints - (int)extraWeaponDamage < 0)
                                {
                                    __instance.EquipmentSource.HitPoints = 0;
                                    __instance.EquipmentSource.Destroy();
                                }
                            }
                            if (__instance.HediffCompSource != null)
                            {
                                /*
                                 * if (__instance.HediffCompSource.parent.Part.HitPoints - (int)extraWeaponDamage >= 0)
                                 * {
                                 *  __instance.HediffCompSource.HitPoints = __instance.HediffCompSource.HitPoints - (int)extraWeaponDamage;
                                 * }
                                 * else if (__instance.HediffCompSource.HitPoints - (int)extraWeaponDamage < 0)
                                 * {
                                 *  __instance.HediffCompSource.HitPoints = 0;
                                 *  __instance.HediffCompSource.Destroy();
                                 * }
                                 */
                            }
                        }
                        else
                        {
                            if (__instance.EquipmentSource != null)
                            {
                                if (__instance.EquipmentSource.HitPoints > 0)
                                {
                                    __instance.EquipmentSource.HitPoints--;
                                }
                            }
                        }
                    }
                    if (__instance.EquipmentSource != null)
                    {
                        SpinningLaserGun spinner = __instance.EquipmentSource as SpinningLaserGun;
                        if (spinner != null)
                        {
                            spinner.state = SpinningLaserGunBase.State.Idle;
                            spinner.ReachRotationSpeed(0, 0);
                        }
                    }
                    return(false);
                }
            }
            if (__instance.UserEffect(out float Chance, out HediffDef Effect, out StatDef ResistStat, out List <string> ImmuneList))
            {
                bool Immunityflag = false;
                Pawn launcherPawn = __instance.caster as Pawn;
                if (!Immunitylist.NullOrEmpty())
                {
                    foreach (var item in Immunitylist)
                    {
                        Immunityflag = launcherPawn.def.defName.Contains(item);
                        if (Immunityflag)
                        {
                            //    Log.Message(string.Format("{0} is immune to their {1}'s UseEffect", launcherPawn.LabelShortCap, __instance.EquipmentSource.LabelShortCap));
                        }
                    }

                    /*
                     * List<string> list = GunExt.UserEffectImmuneList.Where(x => DefDatabase<ThingDef>.GetNamedSilentFail(x) != null).ToList();
                     * bool Immunityflag = list.Contains(launcherPawn.def.defName);
                     * if (Immunityflag)
                     * {
                     *  return;
                     * }
                     */
                }
                if (!Immunityflag)
                {
                    Rand.PushState();
                    var rand = Rand.Value; // This is a random percentage between 0% and 100%
                    Rand.PopState();
                    //    Log.Message(string.Format("GunExt.EffectsUser Effect: {0}, Chance: {1}, Roll: {2}, Result: {3}" + GunExt.ResistEffectStat != null ? ", Resist Stat: "+GunExt.ResistEffectStat.LabelCap+", Resist Amount"+ __instance.caster.GetStatValue(GunExt.ResistEffectStat, true) : null, GunExt.UserEffect.LabelCap, AddHediffChance, rand, rand <= AddHediffChance));
                    if (rand <= AddHediffChance) // If the percentage falls under the chance, success!
                    {
                        Rand.PushState();
                        var randomSeverity = Rand.Range(0.05f, 0.15f);
                        Rand.PopState();
                        var effectOnPawn = launcherPawn?.health?.hediffSet?.GetFirstHediffOfDef(UserHediff);
                        if (effectOnPawn != null)
                        {
                            effectOnPawn.Severity += randomSeverity;
                        }
                        else
                        {
                            Hediff hediff = HediffMaker.MakeHediff(UserHediff, launcherPawn, null);
                            hediff.Severity = randomSeverity;
                            launcherPawn.health.AddHediff(hediff, null, null);
                        }
                    }
                }
            }
            return(true);
        }
Ejemplo n.º 14
0
        public static bool Prefix(ref Verb_ShootCE __instance)
        {
            //    Log.Warning("CE_TryCastShot_WeaponSpecialRules_Patch WarmupComplete ");
            IAdvancedVerb entry = __instance.SpecialRules();

            if (entry == null)
            {
                //    Log.Message("no SpecialRules detected");
                return(true);
            }
            bool          canDamageWeapon;
            float         extraWeaponDamage;
            bool          TwinLinked       = entry.TwinLinked;
            bool          Multishot        = entry.Multishot;
            int           ScattershotCount = entry.ScattershotCount;
            bool          UserEffect       = entry.EffectsUser;
            HediffDef     UserHediff       = entry.UserEffect;
            float         AddHediffChance  = entry.EffectsUserChance;
            List <string> Immunitylist     = entry.UserEffectImmuneList;
            string        msg = string.Format("");
            string        reliabilityString;
            float         failChance;

            StatPart_Reliability.GetReliability(entry, __instance.EquipmentSource, out reliabilityString, out failChance);
            failChance = (__instance.GetsHot()) ? (failChance / 10) : (failChance / 100);
            bool failed = false;

            if (__instance.GetsHot() || __instance.Jams())
            {
                //    Log.Message("failChance: "+failChance);
                Rand.PushState();
                failed = Rand.Chance(failChance);
                Rand.PopState();
                //    Log.Message("failed: "+failed);
            }
            if (__instance.GetsHot(out bool GetsHotCrit, out float GetsHotCritChance, out bool GetsHotCritExplosion, out float GetsHotCritExplosionChance, out canDamageWeapon, out extraWeaponDamage))
            {
                if (failed)
                {
                    DamageDef damageDef        = __instance.Projectile.projectile.damageDef;
                    HediffDef HediffToAdd      = damageDef.hediff;
                    float     ArmorPenetration = __instance.Projectile.projectile.GetArmorPenetration(__instance.EquipmentSource, null);
                    float     DamageAmount     = 0;
                    Pawn      launcherPawn     = __instance.caster as Pawn;
                    Rand.PushState();
                    if (Rand.Chance(GetsHotCritChance))
                    {
                        DamageAmount = __instance.Projectile.projectile.GetDamageAmount(__instance.EquipmentSource, null);
                        msg          = string.Format("{0}'s {1} critically overheated. ({2} chance) causing {3} damage", __instance.caster.LabelCap, __instance.EquipmentSource.LabelCap, failChance.ToStringPercent(), DamageAmount);
                        if (GetsHotCritExplosion && Rand.Chance(GetsHotCritExplosionChance))
                        {
                            CriticalOverheatExplosion(ref __instance);
                        }
                    }
                    else
                    {
                        DamageAmount = __instance.Projectile.projectile.GetDamageAmount(__instance.EquipmentSource, null);
                        msg          = string.Format("{0}'s {1} overheated. ({2} chance) causing {3} damage", __instance.caster.LabelCap, __instance.EquipmentSource.LabelCap, failChance.ToStringPercent(), DamageAmount);
                    }
                    Rand.PopState();
                    float maxburndmg = DamageAmount / 10;
                    while (DamageAmount > 0f)
                    {
                        List <BodyPartRecord> list = launcherPawn.health.hediffSet.GetNotMissingParts().Where(x => x.def.defName.Contains("Finger") || x.def.defName.Contains("Hand")).ToList <BodyPartRecord>();
                        if (list.NullOrEmpty())
                        {
                            list = launcherPawn.health.hediffSet.GetNotMissingParts().Where(x => x.def.defName.Contains("Arm") || x.parent.def.defName.Contains("Arm")).ToList <BodyPartRecord>();
                        }
                        if (list.NullOrEmpty())
                        {
                            list = launcherPawn.health.hediffSet.GetNotMissingParts().Where(x => x.def.tags.Contains(BodyPartTagDefOf.ManipulationLimbCore) || x.def.tags.Contains(BodyPartTagDefOf.ManipulationLimbSegment) || x.def.tags.Contains(BodyPartTagDefOf.ManipulationLimbDigit)).ToList <BodyPartRecord>();
                        }
                        if (list.NullOrEmpty())
                        {
                            break;
                        }
                        else
                        {
                            BodyPartRecord part = list.RandomElement();
                            Hediff         hediff;
                            Rand.PushState();
                            float severity = Rand.Range(Math.Min(0.1f, DamageAmount), Math.Min(DamageAmount, maxburndmg));
                            Rand.PopState();
                            hediff          = HediffMaker.MakeHediff(HediffToAdd, launcherPawn, part);
                            hediff.Severity = severity;
                            launcherPawn.health.AddHediff(hediff, part, null);
                            DamageAmount -= severity;
                        }
                    }
                    Messages.Message(msg, MessageTypeDefOf.NegativeHealthEvent);
                }
            }
            if (__instance.Jams(out canDamageWeapon, out extraWeaponDamage))
            {
                if (failed)
                {
                    if (!__instance.GetsHot())
                    {
                        msg = string.Format("{0}'s {1} had a weapon jam. ({2} chance)", __instance.caster.LabelCap, __instance.EquipmentSource.LabelCap, failChance.ToStringPercent());
                        Messages.Message(msg, MessageTypeDefOf.SilentInput);
                    }
                    float defaultCooldownTime = __instance.verbProps.defaultCooldownTime * 2;
                    __instance.verbProps.defaultCooldownTime = defaultCooldownTime;
                    if (canDamageWeapon)
                    {
                        if (extraWeaponDamage != 0f)
                        {
                            if (__instance.EquipmentSource != null)
                            {
                                if (__instance.EquipmentSource.HitPoints - (int)extraWeaponDamage >= 0)
                                {
                                    __instance.EquipmentSource.HitPoints = __instance.EquipmentSource.HitPoints - (int)extraWeaponDamage;
                                }
                                else if (__instance.EquipmentSource.HitPoints - (int)extraWeaponDamage < 0)
                                {
                                    __instance.EquipmentSource.HitPoints = 0;
                                    __instance.EquipmentSource.Destroy();
                                }
                            }
                            if (__instance.HediffCompSource != null)
                            {
                                /*
                                 * if (__instance.HediffCompSource.parent.Part..HitPoints - (int)extraWeaponDamage >= 0)
                                 * {
                                 *  __instance.HediffCompSource.HitPoints = __instance.HediffCompSource.HitPoints - (int)extraWeaponDamage;
                                 * }
                                 * else if (__instance.HediffCompSource.HitPoints - (int)extraWeaponDamage < 0)
                                 * {
                                 *  __instance.HediffCompSource.HitPoints = 0;
                                 *  __instance.HediffCompSource.Destroy();
                                 * }
                                 */
                            }
                        }
                        else
                        {
                            if (__instance.EquipmentSource != null)
                            {
                                if (__instance.EquipmentSource.HitPoints > 0)
                                {
                                    __instance.EquipmentSource.HitPoints--;
                                }
                            }
                        }
                    }
                    if (__instance.EquipmentSource != null)
                    {
                        SpinningLaserGun spinner = (SpinningLaserGun)__instance.EquipmentSource;
                        if (spinner != null)
                        {
                            spinner.state = SpinningLaserGunBase.State.Idle;
                            spinner.ReachRotationSpeed(0, 0);
                        }
                    }
                    return(false);
                }
            }

            if (__instance.MultiShot() || __instance.TwinLinked())
            {
                if (__instance.TwinLinked())
                {
                }
                else
                {
                }
            }

            if (__instance.UserEffect(out float Chance, out HediffDef Effect, out StatDef ResistStat, out List <string> ImmuneList))
            {
                bool Immunityflag = false;
                Pawn launcherPawn = __instance.caster as Pawn;
                if (!Immunitylist.NullOrEmpty())
                {
                    foreach (var item in Immunitylist)
                    {
                        Immunityflag = launcherPawn.def.defName.Contains(item);
                        if (Immunityflag)
                        {
                            //    Log.Message(string.Format("{0} is immune to their {1}'s UseEffect", launcherPawn.LabelShortCap, __instance.EquipmentSource.LabelShortCap));
                        }
                    }

                    /*
                     * List<string> list = GunExt.UserEffectImmuneList.Where(x => DefDatabase<ThingDef>.GetNamedSilentFail(x) != null).ToList();
                     * bool Immunityflag = list.Contains(launcherPawn.def.defName);
                     * if (Immunityflag)
                     * {
                     *  return;
                     * }
                     */
                }
                if (!Immunityflag)
                {
                    Rand.PushState();
                    var rand = Rand.Value; // This is a random percentage between 0% and 100%
                    Rand.PopState();
                    //    Log.Message(string.Format("GunExt.EffectsUser Effect: {0}, Chance: {1}, Roll: {2}, Result: {3}" + GunExt.ResistEffectStat != null ? ", Resist Stat: "+GunExt.ResistEffectStat.LabelCap+", Resist Amount"+ __instance.caster.GetStatValue(GunExt.ResistEffectStat, true) : null, GunExt.UserEffect.LabelCap, AddHediffChance, rand, rand <= AddHediffChance));
                    if (rand <= AddHediffChance) // If the percentage falls under the chance, success!
                    {
                        Rand.PushState();
                        var randomSeverity = Rand.Range(0.05f, 0.15f);
                        Rand.PopState();
                        var effectOnPawn = launcherPawn?.health?.hediffSet?.GetFirstHediffOfDef(UserHediff);
                        if (effectOnPawn != null)
                        {
                            effectOnPawn.Severity += randomSeverity;
                        }
                        else
                        {
                            Hediff hediff = HediffMaker.MakeHediff(UserHediff, launcherPawn, null);
                            hediff.Severity = randomSeverity;
                            launcherPawn.health.AddHediff(hediff, null, null);
                        }
                    }
                }
            }
            return(true);
        }