public static void CriticalOverheatExplosion(ref AbilitesExtended.Verb_EquipmentLaunchProjectile __instance)
        {
            Map map = __instance.caster.Map;

            if (__instance.Projectile.projectile.explosionEffect != null)
            {
                Effecter effecter = __instance.Projectile.projectile.explosionEffect.Spawn();
                effecter.Trigger(new TargetInfo(__instance.EquipmentSource.Position, map, false), new TargetInfo(__instance.EquipmentSource.Position, map, false));
                effecter.Cleanup();
            }
            IntVec3   position         = __instance.caster.Position;
            Map       map2             = map;
            float     explosionRadius  = __instance.Projectile.projectile.explosionRadius;
            DamageDef damageDef        = __instance.Projectile.projectile.damageDef;
            Thing     launcher         = __instance.EquipmentSource;
            int       DamageAmount     = __instance.Projectile.projectile.GetDamageAmount(__instance.EquipmentSource, null);
            float     ArmorPenetration = __instance.Projectile.projectile.GetArmorPenetration(__instance.EquipmentSource, null);
            SoundDef  soundExplode     = __instance.Projectile.projectile.soundExplode;
            ThingDef  equipmentDef     = __instance.EquipmentSource.def;
            ThingDef  def   = __instance.EquipmentSource.def;
            Thing     thing = __instance.EquipmentSource;
            ThingDef  postExplosionSpawnThingDef   = __instance.Projectile.projectile.postExplosionSpawnThingDef;
            float     postExplosionSpawnChance     = __instance.Projectile.projectile.postExplosionSpawnChance;
            int       postExplosionSpawnThingCount = __instance.Projectile.projectile.postExplosionSpawnThingCount;
            ThingDef  preExplosionSpawnThingDef    = __instance.Projectile.projectile.preExplosionSpawnThingDef;

            GenExplosion.DoExplosion(position, map2, explosionRadius, damageDef, launcher, DamageAmount, ArmorPenetration, soundExplode);//, equipmentDef, def, thing, postExplosionSpawnThingDef, postExplosionSpawnChance, postExplosionSpawnThingCount, EquipmentSource.def.projectile.applyDamageToExplosionCellsNeighbors, preExplosionSpawnThingDef, EquipmentSource.def.projectile.preExplosionSpawnChance, EquipmentSource.def.projectile.preExplosionSpawnThingCount, EquipmentSource.def.projectile.explosionChanceToStartFire, EquipmentSource.def.projectile.explosionDamageFalloff);
            return;
        }
示例#2
0
        public static void Postfix(ref AbilitesExtended.Verb_EquipmentLaunchProjectile __instance, ref ThingDef __result)
        {
            if (__instance.EquipmentSource != null)
            {
                CompUpgradeableProjectile upgradeableProjectile = __instance.EquipmentSource.TryGetCompFast <CompUpgradeableProjectile>();
                if (upgradeableProjectile != null && __instance.verbProps.defaultProjectile == __result)
                {
                    bool inFaction     = __instance.CasterPawn?.Faction != null;
                    bool playerFaction = false;
                    if (inFaction)
                    {
                        playerFaction = __instance.CasterPawn.Faction == Faction.OfPlayer;
                        if (playerFaction)
                        {
                            if (upgradeableProjectile.ResearchDef != null)
                            {
                                if (upgradeableProjectile.ResearchDef.IsFinished)
                                {
                                    __result = upgradeableProjectile.ProjectileDef;
                                }
                            }
                            return;
                        }
                        else
                        {
                            if (upgradeableProjectile.FactionDefs.Contains(__instance.CasterPawn.Faction.def))
                            {
                                __result = upgradeableProjectile.ProjectileDef;
                                return;
                            }
                        }
                    }
                }

                /*
                 * if (__instance.EquipmentSource.GetComp<CompSlotLoadable.CompSlotLoadable>() != null && __instance.verbProps.defaultProjectile == __result)
                 * {
                 * //    log.message(string.Format("{0} CompSlotLoadable != null", __instance.EquipmentSource));
                 *  if (__instance.EquipmentSource.GetComp<CompSlotLoadable.CompSlotLoadable>() is CompSlotLoadable.CompSlotLoadable slotLoadable)
                 *  {
                 *      if (!slotLoadable.Slots.NullOrEmpty())
                 *      {
                 *      //    log.message(string.Format("{0} Slots, Occupied: {1} Empty: {2}, Total: {3}", __instance.EquipmentSource, slotLoadable.Slots.FindAll(x => x.SlotOccupant != null).Count, slotLoadable.Slots.FindAll(x => x.SlotOccupant == null).Count, slotLoadable.Slots.Count));
                 *          foreach (CompSlotLoadable.SlotLoadable slot in slotLoadable.Slots.FindAll(x => x.SlotOccupant != null))
                 *          {
                 *              CompSlotLoadable.CompSlottedBonus slottedBonus = slot.SlotOccupant.TryGetCompFast<CompSlotLoadable.CompSlottedBonus>();
                 *          //    log.message(string.Format("{0}'s Slot at {1} with: {2} slottedBonus: {3}", __instance.EquipmentSource, slotLoadable.Slots.IndexOf(slot), slot.SlotOccupant, slottedBonus!=null));
                 *              if (slottedBonus != null)
                 *              {
                 *              //    log.message(string.Format("{0} slottedBonus: {1}", __instance.EquipmentSource, slottedBonus));
                 *                  __result = slottedBonus.Props.projectileReplacer;
                 *                  break;
                 *              }
                 *          }
                 *      }
                 *  }
                 * }
                 */
            }
        }
        // Token: 0x0600651E RID: 25886 RVA: 0x001B8BC0 File Offset: 0x001B6FC0
        public static bool TryCastExtraShot(ref AbilitesExtended.Verb_EquipmentLaunchProjectile __instance, LocalTargetInfo currentTarget, bool canHitNonTargetPawnsNow)
        {
            if (currentTarget.HasThing && currentTarget.Thing.Map != __instance.caster.Map)
            {
                return(false);
            }
            ThingDef projectile = __instance.Projectile;

            if (projectile == null)
            {
                return(false);
            }
            ShootLine shootLine;
            bool      flag = __instance.TryFindShootLineFromTo(__instance.caster.Position, currentTarget, out shootLine);

            if (__instance.verbProps.stopBurstWithoutLos && !flag)
            {
                return(false);
            }
            if (__instance.EquipmentSource != null)
            {
                CompChangeableProjectile comp = __instance.EquipmentSource.GetComp <CompChangeableProjectile>();
                if (comp != null)
                {
                    comp.Notify_ProjectileLaunched();
                }
            }
            Thing        launcher     = __instance.caster;
            Thing        equipment    = __instance.EquipmentSource;
            CompMannable compMannable = __instance.caster.TryGetCompFast <CompMannable>();

            if (compMannable != null && compMannable.ManningPawn != null)
            {
                launcher  = compMannable.ManningPawn;
                equipment = __instance.caster;
            }
            Vector3    drawPos     = __instance.caster.DrawPos;
            Projectile projectile2 = (Projectile)GenSpawn.Spawn(projectile, shootLine.Source, __instance.caster.Map, WipeMode.Vanish);

            if (__instance.verbProps.forcedMissRadius > 0.5f)
            {
                float num = VerbUtility.CalculateAdjustedForcedMiss(__instance.verbProps.forcedMissRadius, currentTarget.Cell - __instance.caster.Position);
                if (num > 0.5f)
                {
                    int max = GenRadial.NumCellsInRadius(num);
                    Rand.PushState();
                    int num2 = Rand.Range(0, max);
                    Rand.PopState();
                    if (num2 > 0)
                    {
                        IntVec3 c = currentTarget.Cell + GenRadial.RadialPattern[num2];

                        ProjectileHitFlags projectileHitFlags = ProjectileHitFlags.NonTargetWorld;
                        Rand.PushState();
                        if (Rand.Chance(0.5f))
                        {
                            projectileHitFlags = ProjectileHitFlags.All;
                        }
                        Rand.PopState();
                        if (!canHitNonTargetPawnsNow)
                        {
                            projectileHitFlags &= ~ProjectileHitFlags.NonTargetPawns;
                        }
                        projectile2.Launch(launcher, drawPos, c, currentTarget, projectileHitFlags, equipment, null);
                        return(true);
                    }
                }
            }
            ShotReport shotReport            = ShotReport.HitReportFor(__instance.caster, __instance, currentTarget);
            Thing      randomCoverToMissInto = shotReport.GetRandomCoverToMissInto();
            ThingDef   targetCoverDef        = randomCoverToMissInto?.def;

            Rand.PushState();
            bool f1 = !Rand.Chance(shotReport.AimOnTargetChance_IgnoringPosture);

            Rand.PopState();
            if (f1)
            {
                shootLine.ChangeDestToMissWild(shotReport.AimOnTargetChance_StandardTarget);
                ProjectileHitFlags projectileHitFlags2 = ProjectileHitFlags.NonTargetWorld;
                Rand.PushState();
                if (Rand.Chance(0.5f) && canHitNonTargetPawnsNow)
                {
                    projectileHitFlags2 |= ProjectileHitFlags.NonTargetPawns;
                }
                Rand.PopState();
                projectile2.Launch(launcher, drawPos, shootLine.Dest, currentTarget, projectileHitFlags2, equipment, targetCoverDef);
                return(true);
            }
            Rand.PushState();
            bool f2 = !Rand.Chance(shotReport.PassCoverChance);

            Rand.PopState();
            if (currentTarget.Thing != null && currentTarget.Thing.def.category == ThingCategory.Pawn && f2)
            {
                ProjectileHitFlags projectileHitFlags3 = ProjectileHitFlags.NonTargetWorld;
                if (canHitNonTargetPawnsNow)
                {
                    projectileHitFlags3 |= ProjectileHitFlags.NonTargetPawns;
                }
                projectile2.Launch(launcher, drawPos, randomCoverToMissInto, currentTarget, projectileHitFlags3, equipment, targetCoverDef);
                return(true);
            }
            ProjectileHitFlags projectileHitFlags4 = ProjectileHitFlags.IntendedTarget;

            if (canHitNonTargetPawnsNow)
            {
                projectileHitFlags4 |= ProjectileHitFlags.NonTargetPawns;
            }
            if (!currentTarget.HasThing || currentTarget.Thing.def.Fillage == FillCategory.Full)
            {
                projectileHitFlags4 |= ProjectileHitFlags.NonTargetWorld;
            }
            if (currentTarget.Thing != null)
            {
                projectile2.Launch(launcher, drawPos, currentTarget, currentTarget, projectileHitFlags4, equipment, targetCoverDef);
            }
            else
            {
                projectile2.Launch(launcher, drawPos, shootLine.Dest, currentTarget, projectileHitFlags4, equipment, targetCoverDef);
            }
            return(true);
        }
        public static bool Prefix(ref AbilitesExtended.Verb_EquipmentLaunchProjectile __instance)
        {
            //    Log.Warning("TryCastShot");
            bool          GetsHot                    = __instance.verbProperties.GetsHot;
            bool          Jams                       = __instance.verbProperties.Jams;
            bool          GetsHotCrit                = __instance.verbProperties.GetsHotCrit;
            float         GetsHotCritChance          = __instance.verbProperties.GetsHotCritChance;
            bool          GetsHotCritExplosion       = __instance.verbProperties.GetsHotCritExplosion;
            float         GetsHotCritExplosionChance = __instance.verbProperties.GetsHotCritExplosionChance;
            bool          canDamageWeapon            = __instance.verbProperties.HotDamageWeapon || __instance.verbProperties.JamsDamageWeapon;
            float         extraWeaponDamage          = (Jams && __instance.verbProperties.JamsDamageWeapon) ? __instance.verbProperties.JamDamage : (GetsHot && __instance.verbProperties.HotDamageWeapon) ? __instance.verbProperties.HotDamage : 0f;
            bool          TwinLinked                 = __instance.verbProperties.TwinLinked;
            bool          Multishot                  = __instance.verbProperties.Multishot;
            int           ScattershotCount           = __instance.verbProperties.ScattershotCount;
            bool          UserEffect                 = __instance.verbProperties.EffectsUser;
            HediffDef     UserHediff                 = __instance.verbProperties.UserEffect;
            float         AddHediffChance            = __instance.verbProperties.EffectsUserChance;
            List <string> Immunitylist               = __instance.verbProperties.UserEffectImmuneList;

            if ((GetsHot && AMSettings.Instance.AllowGetsHot) || (Jams && AMSettings.Instance.AllowJams))
            {
                string msg = string.Format("");
                string reliabilityString;
                float  failChance;
                AbilitesExtended.StatPart_Reliability.GetReliability(__instance.verbProperties, out reliabilityString, out failChance);
                failChance = GetsHot ? (failChance / 10) : (failChance / 100);
                Rand.PushState();
                bool fails = Rand.Chance(failChance);
                Rand.PopState();
                if (fails)
                {
                    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;
                        Rand.PushState();
                        bool getshotcrit = Rand.Chance(GetsHotCritChance);
                        Rand.PopState();
                        if (getshotcrit)
                        {
                            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);
                            Rand.PushState();
                            if (GetsHotCritExplosion && Rand.Chance(GetsHotCritExplosionChance))
                            {
                                CriticalOverheatExplosion(ref __instance);
                            }
                            Rand.PopState();
                        }
                        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;
                                Rand.PushState();
                                float severity = Rand.Range(Math.Min(0.1f, DamageAmount), Math.Min(DamageAmount, maxburndmg));
                                Rand.PopState();
                                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 && AMSettings.Instance.AllowMultiShot || TwinLinked)
            {
                Traverse        traverse                = Traverse.Create(__instance);
                LocalTargetInfo currentTarget           = (LocalTargetInfo)Verb_Shoot_TryCastShot_WeaponSpecialRules_Patch.currentTarget.GetValue(__instance);
                bool            canHitNonTargetPawnsNow = (bool)Verb_Shoot_TryCastShot_WeaponSpecialRules_Patch.canHitNonTargetPawnsNow.GetValue(__instance);
                //    Log.Message(string.Format("AllowMultiShot: {0} Projectile Count: {1}", AMASettings.Instance.AllowMultiShot && Multishot, ScattershotCount));
                if (TwinLinked)
                {
                    TryCastExtraShot(ref __instance, currentTarget, canHitNonTargetPawnsNow);
                }
                else
                {
                    for (int i = 0; i < ScattershotCount; i++)
                    {
                        TryCastExtraShot(ref __instance, currentTarget, canHitNonTargetPawnsNow);
                    }
                }
            }

            if (UserEffect && AMSettings.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)
                    {
                        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);
        }