Exemplo n.º 1
0
        public static bool TryCastShot_Prefix(ref Verb_Shoot __instance)
        {
            //    Log.Warning("TryCastShot");
            bool          GetsHot                    = false;
            bool          Jams                       = false;
            bool          GetsHotCrit                = false;
            float         GetsHotCritChance          = 0f;
            bool          GetsHotCritExplosion       = false;
            float         GetsHotCritExplosionChance = 0f;
            bool          canDamageWeapon            = false;
            float         extraWeaponDamage          = 0f;
            bool          TwinLinked                 = false;
            bool          Multishot                  = false;
            int           ScattershotCount           = 0;
            bool          UserEffect                 = false;
            HediffDef     UserHediff                 = null;
            float         AddHediffChance            = 0f;
            List <string> Immunitylist               = new List <string>();

            if (__instance.EquipmentSource != null)
            {
                if (!__instance.EquipmentSource.AllComps.NullOrEmpty())
                {
                    if (__instance.EquipmentSource.GetComp <CompWeapon_GunSpecialRules>() != null)
                    {
                        if (__instance.EquipmentSource.GetComp <CompWeapon_GunSpecialRules>() is CompWeapon_GunSpecialRules GunExt)
                        {
                            GetsHot                    = GunExt.GetsHot;
                            Jams                       = GunExt.Jams;
                            GetsHotCrit                = GunExt.GetsHotCrit;
                            GetsHotCritChance          = GunExt.GetsHotCritChance;
                            GetsHotCritExplosion       = GunExt.GetsHotCritExplosion;
                            GetsHotCritExplosionChance = GunExt.GetsHotCritExplosionChance;
                            canDamageWeapon            = (Jams && GunExt.JamsDamageWeapon) || (GetsHot && GunExt.HotDamageWeapon);
                            extraWeaponDamage          = (Jams && GunExt.JamsDamageWeapon) ? GunExt.JamDamage : (GetsHot && GunExt.HotDamageWeapon) ? GunExt.HotDamage : 0f;

                            Multishot        = GunExt.Multishot;
                            ScattershotCount = GunExt.ScattershotCount;

                            TwinLinked      = GunExt.TwinLinked;
                            UserEffect      = GunExt.EffectsUser;
                            UserHediff      = GunExt.UserEffect;
                            Immunitylist    = GunExt.UserEffectImmuneList;
                            AddHediffChance = GunExt.ResistEffectStat != null?GunExt.EffectsUserChance *__instance.caster.GetStatValue(GunExt.ResistEffectStat, true) : GunExt.EffectsUserChance;
                        }
                    }
                }
            }
            if (__instance.HediffCompSource != null)
            {
                HediffComp_VerbGiverExtra _VGE = (HediffComp_VerbGiverExtra)__instance.HediffCompSource;

                GetsHot                    = _VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].GetsHot;
                Jams                       = _VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].Jams;
                GetsHotCrit                = _VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].GetsHotCrit;
                GetsHotCritChance          = _VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].GetsHotCritChance;
                GetsHotCritExplosion       = _VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].GetsHotCritExplosion;
                GetsHotCritExplosionChance = _VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].GetsHotCritExplosionChance;
                canDamageWeapon            = (_VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].Jams && _VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].JamsDamageWeapon) || (GetsHot && _VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].HotDamageWeapon);
                extraWeaponDamage          = (_VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].Jams && _VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].JamsDamageWeapon) ? _VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].JamDamage : (GetsHot && _VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].HotDamageWeapon) ? _VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].HotDamage : 0f;

                Multishot        = _VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].Multishot;
                ScattershotCount = _VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].ScattershotCount;

                TwinLinked      = _VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].TwinLinked;
                UserEffect      = _VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].EffectsUser;
                UserHediff      = _VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].UserEffect;
                Immunitylist    = _VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].UserEffectImmuneList;
                AddHediffChance = _VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].ResistEffectStat != null ? _VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].EffectsUserChance * __instance.caster.GetStatValue(_VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].ResistEffectStat, true) : _VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].EffectsUserChance;
            }
            if ((GetsHot && AMASettings.Instance.AllowGetsHot) || (Jams && AMASettings.Instance.AllowJams))
            {
                string msg = string.Format("");
                string reliabilityString;
                float  failChance;
                StatPart_Reliability.GetReliability(__instance.EquipmentSource.TryGetComp <CompWeapon_GunSpecialRules>(), out reliabilityString, out failChance);
                failChance = GetsHot ? (failChance / 10) : (failChance / 100);
                if (Rand.Chance(failChance))
                {
                    if (GetsHot)
                    {
                        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;
                        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);
                        }
                        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.def.defName.Contains("Shoulder")).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;
                                float          severity = Rand.Range(Math.Min(0.1f, DamageAmount), Math.Min(DamageAmount, maxburndmg));
                                hediff          = HediffMaker.MakeHediff(HediffToAdd, launcherPawn, null);
                                hediff.Severity = severity;
                                launcherPawn.health.AddHediff(hediff, part, null);
                                DamageAmount -= severity;
                            }
                        }
                        Messages.Message(msg, MessageTypeDefOf.NegativeHealthEvent);
                    }
                    else
                    {
                        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 (Jams)
                    {
                        if (__instance.EquipmentSource != null)
                        {
                            SpinningLaserGun spinner = (SpinningLaserGun)__instance.EquipmentSource;
                            if (spinner != null)
                            {
                                spinner.state = SpinningLaserGunBase.State.Idle;
                                spinner.ReachRotationSpeed(0, 0);
                            }
                        }
                        return(false);
                    }
                }
            }
            if (ScattershotCount > 0 && Multishot && AMASettings.Instance.AllowMultiShot)
            {
                //    Log.Message(string.Format("AllowMultiShot: {0} Projectile Count: {1}", AMASettings.Instance.AllowMultiShot && Multishot, ScattershotCount));
                for (int i = 0; i < ScattershotCount; i++)
                {
                    //    Log.Message(string.Format("Launching extra projectile {0} / {1}", i+1, ScattershotCount));
                    //    AccessTools.Method(typeof(Verb_Shoot).BaseType, "TryCastShot", null, null).Invoke(__instance, null);
                    TryCastExtraShot(ref __instance);
                }
            }
            else
            if (TwinLinked)
            {
                TryCastExtraShot(ref __instance);
            }
            if (UserEffect && AMASettings.Instance.AllowUserEffects)
            {
                if (__instance.caster.def.category == ThingCategory.Pawn)
                {
                    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)
                    {
                        var rand = Rand.Value;       // This is a random percentage between 0% and 100%
                                                     //    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!
                        {
                            var randomSeverity = Rand.Range(0.05f, 0.15f);
                            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);
        }
Exemplo n.º 2
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);
        }