public static void AdjustedCooldown_RapidFire_Postfix(ref Verb_Shoot __instance, Verb ownerVerb, Pawn attacker, ref float __result)
        {
            bool RapidFire = false;

            if (ownerVerb.EquipmentSource != null)
            {
                //    Log.Message("ownerVerb.EquipmentSource");
                if (!ownerVerb.EquipmentSource.AllComps.NullOrEmpty())
                {
                    if (ownerVerb.EquipmentSource.GetComp <CompWeapon_GunSpecialRules>() != null)
                    {
                        if (ownerVerb.EquipmentSource.GetComp <CompWeapon_GunSpecialRules>() is CompWeapon_GunSpecialRules GunExt)
                        {
                            RapidFire = GunExt.RapidFire;
                        }
                    }
                }
            }
            if (ownerVerb.HediffCompSource != null && !ownerVerb.IsMeleeAttack)
            {
                //    Log.Message("ownerVerb.HediffCompSource");
                HediffComp_VerbGiverExtra _VGE = (HediffComp_VerbGiverExtra)ownerVerb.HediffCompSource;

                RapidFire = _VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(ownerVerb.verbProps)].RapidFire;
            }
            if (RapidFire && AMASettings.Instance.AllowRapidFire)
            {
                if (ownerVerb.caster.Position.InHorDistOf(((Pawn)ownerVerb.caster).TargetCurrentlyAimingAt.Cell, ownerVerb.verbProps.range / 2))
                {
                    __result = __result / 2;
                }
            }
        }
Пример #2
0
        public static void ShotsPerBurst_RapidFire_Postfix(ref Verb_Shoot __instance, ref int __result)
        {
            bool  RapidFire      = false;
            float RapidFireRange = 0;
            bool  BodyBurstSize  = false;

            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)
                        {
                            RapidFire      = GunExt.RapidFire;
                            RapidFireRange = __instance.verbProps.range / 2;

                            BodyBurstSize = GunExt.TyranidBurstBodySize;
                        }
                    }
                }
            }
            if (__instance.HediffCompSource != null)
            {
                HediffComp_VerbGiverExtra _VGE = (HediffComp_VerbGiverExtra)__instance.HediffCompSource;

                RapidFire      = _VGE.Props.verbEntrys[_VGE.VerbProperties.IndexOf(__instance.verbProps)].RapidFire;
                RapidFireRange = __instance.verbProps.range / 2;

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

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

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

            if (pawn.RaceProps.Humanlike)
            {
                return(true);
            }
            if (pawn.equipment != null)
            {
                if (pawn.equipment.Primary != null)
                {
                    if (pawn.equipment.PrimaryEq != null)
                    {
                        if (pawn.equipment.PrimaryEq.verbTracker.PrimaryVerb.verbProps.range > 1.5)
                        {
                            return(true);
                        }
                    }
                }
            }
            bool hasRangedVerb = false;


            List <Verb> verbList  = pawn.verbTracker.AllVerbs;
            List <Verb> rangeList = new List <Verb>();

            for (int i = 0; i < verbList.Count; i++)
            {
                //    Log.Warning("Checkity");
                //    Log.Warning(string.Format("verbList: {0}, Name: {1} RangeMax: {2}", i, verbList[i].verbProps.label, verbList[i].verbProps.range));
                //It corresponds with verbs anyway
                if (verbList[i].verbProps.range > 1.5f)
                {
                    rangeList.Add(verbList[i]);
                    hasRangedVerb = true;
                }
                //Log.Warning("Added Ranged Verb");
            }
            if (pawn.equipment?.PrimaryEq != null)
            {
                for (int i = 0; i < pawn.equipment.PrimaryEq.AllVerbs.Count; i++)
                {
                    //    Log.Warning("Checkity");
                    //    Log.Warning(string.Format("verbList: {0}, Name: {1} RangeMax: {2}", i, verbList[i].verbProps.label, verbList[i].verbProps.range));
                    //It corresponds with verbs anyway
                    if (pawn.equipment.PrimaryEq.AllVerbs[i].verbProps.range > 1.5f)
                    {
                        if (!rangeList.Contains(pawn.equipment.PrimaryEq.AllVerbs[i]))
                        {
                            rangeList.Add(pawn.equipment.PrimaryEq.AllVerbs[i]);
                            hasRangedVerb = true;
                        }
                    }
                    //Log.Warning("Added Ranged Verb");
                }
            }
            if (pawn.health.hediffSet.hediffs.Any(x => x.TryGetComp <HediffComp_VerbGiverExtra>() != null))
            {
                List <Hediff> list = pawn.health.hediffSet.hediffs.FindAll(x => x.TryGetComp <HediffComp_VerbGiverExtra>() != null);

                foreach (Hediff item in list)
                {
                    HediffComp_VerbGiverExtra _VerbGiver = item.TryGetComp <HediffComp_VerbGiverExtra>();
                    if (_VerbGiver != null)
                    {
                        for (int i = 0; i < _VerbGiver.verbTracker.AllVerbs.Count; i++)
                        {
                            //    Log.Warning("Checkity");
                            //    Log.Warning(string.Format("verbList: {0}, Name: {1} RangeMax: {2}", i, verbList[i].verbProps.label, verbList[i].verbProps.range));
                            //It corresponds with verbs anyway
                            if (_VerbGiver.verbTracker.AllVerbs[i].verbProps.range > 1.5f)
                            {
                                if (!rangeList.Contains(_VerbGiver.verbTracker.AllVerbs[i]))
                                {
                                    rangeList.Add(_VerbGiver.verbTracker.AllVerbs[i]);
                                    hasRangedVerb = true;
                                }
                            }
                            //Log.Warning("Added Ranged Verb");
                        }
                    }
                }
                if (hasRangedVerb == false)
                {
                    Log.Warning("I don't have range verb");
                    return(true);
                }
            }
            // this.SetCurMeleeVerb(updatedAvailableVerbsList.RandomElementByWeight((VerbEntry ve) => ve.SelectionWeight).verb);

            //    Log.Warning(string.Format("rangeVerbs: {0}", rangeList.Count));
            Verb rangeVerb;

            if (rangeList.Count > 1)
            {
                rangeVerb = rangeList.RandomElementByWeightWithDefault((Verb rangeItem) => rangeItem.verbProps.commonality, 0.5f);
            }
            else if (rangeList.Count == 1)
            {
                rangeVerb = rangeList.First();
            }
            else
            {
                rangeVerb = null;
            }

            if (rangeVerb == null)
            {
                //    Log.Warning("Can't get random range verb");
                return(true);
            }
            else
            {
                //    Log.Warning(string.Format("rangeVerb: {0}, Range Max: {1}, Min: {2}, Burst: {3}, Projectile: {4}", rangeVerb.verbProps.label, rangeVerb.verbProps.range, rangeVerb.verbProps.minRange, rangeVerb.verbProps.burstShotCount, rangeVerb.verbProps.defaultProjectile));
            }


            Thing enemyTarget = (Thing)AttackTargetFinder.BestAttackTarget((IAttackTargetSearcher)pawn, TargetScanFlags.NeedThreat, (Predicate <Thing>)(x =>
                                                                                                                                                        x is Pawn || x is Building), 0.0f, rangeVerb.verbProps.range, new IntVec3(), float.MaxValue, false);


            if (enemyTarget == null)
            {
                //    Log.Warning("I can't find anything to fight.");
                return(true);
            }
            bool useranged = Rand.Chance(rangeVerb.verbProps.commonality);

            //    Log.Warning(string.Format("useranged: {0}", useranged));
            if (!useranged)
            {
                //If adjacent melee attack
                if (enemyTarget.Position.AdjacentTo8Way(pawn.Position))
                {
                    __result = new Job(JobDefOf.AttackMelee, enemyTarget)
                    {
                        maxNumMeleeAttacks     = 1,
                        expiryInterval         = Rand.Range(420, 900),
                        attackDoorIfTargetLost = false
                    };
                    return(false);
                }
                //Only go if I am to be released. This prevent animal running off.
                if (pawn.CanReach(enemyTarget, PathEndMode.Touch, Danger.Deadly, false))
                {
                    //    Log.Warning("Melee Attack");
                    __result = new Job(JobDefOf.AttackMelee, enemyTarget)
                    {
                        maxNumMeleeAttacks     = 1,
                        expiryInterval         = Rand.Range(420, 900),
                        attackDoorIfTargetLost = false
                    };
                    return(false);
                }
                else
                {
                    return(true);
                }
            }

            //Log.Warning("got list of ranged verb");

            //    Log.Warning("Attempting flag");
            bool flag1 = (double)CoverUtility.CalculateOverallBlockChance(pawn.Position, enemyTarget.Position, pawn.Map) > 0.00999999977648258;
            bool flag2 = pawn.Position.Standable(pawn.Map);
            bool flag3 = rangeVerb.CanHitTarget(enemyTarget);
            bool flag4 = (pawn.Position - enemyTarget.Position).LengthHorizontalSquared < 25;



            if (flag1 && flag2 && flag3 || flag4 && flag3)
            {
                //    Log.Warning("Shooting");
                __result = new Job(DefDatabase <JobDef> .GetNamed("AnimalRangeAttack"), enemyTarget, JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, true)
                {
                    verbToUse = rangeVerb
                };
                return(false);
            }
            IntVec3 dest;
            bool    canShootCondition = false;

            //    Log.Warning("Try casting");

            //Animals with training seek cover

            /*
             *                  if (pawn.training.IsCompleted(TrainableDefOf.Release) && (double)verb.verbProps.range > 7.0)
             *                          Log.Warning("Attempting cover");
             *                  Log.Warning("Try get flag radius :" + Traverse.Create(__instance).Method("GetFlagRadius", pawn).GetValue<float>());
             *                  Log.Warning("Checking cast condition");
             */

            //Don't find new position if animal not released.


            canShootCondition = CastPositionFinder.TryFindCastPosition(new CastPositionRequest
            {
                caster              = pawn,
                target              = enemyTarget,
                verb                = rangeVerb,
                maxRangeFromTarget  = rangeVerb.verbProps.range,
                wantCoverFromTarget = (double)rangeVerb.verbProps.range > 7.0,
                locus               = pawn.Position,
                maxRangeFromLocus   = Traverse.Create(__instance).Method("GetFlagRadius", pawn).GetValue <float>(),
                maxRegions          = 50
            }, out dest);

            if (!canShootCondition)
            {
                //   Log.Warning("I can't move to shooting position");


                return(true);
            }

            if (dest == pawn.Position)
            {
                //   Log.Warning("I will stay here and attack");
                __result = new Job(DefDatabase <JobDef> .GetNamed("AnimalRangeAttack"), enemyTarget, JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange, true)
                {
                    verbToUse = rangeVerb
                };
                return(false);
            }
            //   Log.Warning("Going to new place");
            __result = new Job(JobDefOf.Goto, (LocalTargetInfo)dest)
            {
                expiryInterval        = JobGiver_AIFightEnemy.ExpiryInterval_ShooterSucceeded.RandomInRange,
                checkOverrideOnExpire = true
            };
            return(false);
        }
Пример #5
0
        public static void Projectile_ArmorPenetration_Rending_Postfix(Projectile __instance, ref LocalTargetInfo ___usedTarget, ref Thing ___launcher, ref float __result)
        {
            if (___usedTarget.HasThing)
            {
                bool  Rending       = false;
                float RendingChance = 0.167f;
                Pawn  caster        = ___launcher as Pawn;
                Thing hitThing      = ___usedTarget.Thing;
                Thing Launcher      = ___launcher;
                if (caster != null)
                {
                    if (caster.equipment != null)
                    {
                        //    Log.Warning(string.Format("___launcher: {0}", ___launcher));
                        if (caster.equipment.Primary != null)
                        {
                            //    Log.Warning(string.Format("caster.equipment != null"));
                            Launcher = caster.equipment.Primary;
                            //    Log.Warning(string.Format("Launcher = caster.equipment.Primary"));
                            CompWeapon_GunSpecialRules _GunSpecialRules = Launcher.TryGetComp <CompWeapon_GunSpecialRules>();
                            if (_GunSpecialRules != null)
                            {
                                //    Log.Warning(string.Format("_GunSpecialRules != null"));
                                Rending       = _GunSpecialRules.Rending;
                                RendingChance = _GunSpecialRules.RendingChance;
                            }
                        }
                        else
                        {
                            //    Log.Warning(string.Format("caster.equipment == null"));
                            if (caster.health.hediffSet.hediffs.Any(x => x.TryGetComp <HediffComp_VerbGiverExtra>() != null))
                            {
                                //    Log.Warning(string.Format("HediffComp_VerbGiverExtra: {0}", ___launcher));
                                HediffComp_VerbGiverExtra _VGE = caster.health.hediffSet.hediffs.Find(x => x.TryGetComp <HediffComp_VerbGiverExtra>() is HediffComp_VerbGiverExtra z && z.verbTracker.AllVerbs.Any(y => y.verbProps.defaultProjectile == __instance.def)).TryGetComp <HediffComp_VerbGiverExtra>();
                                if (_VGE != null)
                                {
                                    //    Log.Warning(string.Format("_VGE != null: {0}", _VGE.parent.LabelCap));
                                    GunVerbEntry entry = _VGE.Props.verbEntrys.Find(x => x.VerbProps.defaultProjectile == __instance.def);
                                    if (entry != null)
                                    {
                                        //    Log.Warning(string.Format("{0}, Rending: {1}, Chance: {2}", entry.VerbProps.label, entry.Rending, entry.RendingChance));
                                        Rending       = entry.Rending;
                                        RendingChance = entry.RendingChance;
                                    }
                                }
                            }
                        }
                    }
                }
                if (Rending)
                {
                    //    Log.Warning(string.Format("Rending: {0}", ___launcher));
                    bool RendingEffect = Rand.Chance(RendingChance);
                    if (RendingEffect)
                    {
                        //    Log.Warning(string.Format("RendingEffect: {0}", ___launcher));
                        DamageDef damageDef = __instance.def.projectile.damageDef;
                        //    Log.Warning(string.Format("damageDef: {0}", damageDef.LabelCap));
                        DamageArmorCategoryDef armorCategory = damageDef.armorCategory != null ? damageDef.armorCategory: null;
                        //    Log.Warning(string.Format("armorCategory: {0}", armorCategory));
                        StatDef armorcatdef = damageDef.armorCategory != null ? armorCategory.armorRatingStat : null;
                        //    Log.Warning(string.Format("armorcatdef: {0}", armorcatdef));
                        float num  = 0f;
                        float num2 = Mathf.Clamp01((armorcatdef != null ? hitThing.GetStatValue(armorcatdef, true) : 0f) / 2f);
                        //    Log.Warning(string.Format("num2: {0}", num2));
                        if (hitThing is Pawn hitPawn)
                        {
                            List <BodyPartRecord> allParts = hitPawn.RaceProps.body.AllParts;
                            //    Log.Warning(string.Format("allParts: {0}", allParts.Count));
                            List <Apparel> list = (hitPawn.apparel == null) ? null : hitPawn.apparel.WornApparel;
                            //    Log.Warning(string.Format("list: {0}", list.Count));
                            for (int i = 0; i < allParts.Count; i++)
                            {
                                float num3 = 1f - num2;
                                if (list != null)
                                {
                                    for (int j = 0; j < list.Count; j++)
                                    {
                                        if (list[j].def.apparel.CoversBodyPart(allParts[i]))
                                        {
                                            float num4 = Mathf.Clamp01((armorcatdef != null ? list[j].GetStatValue(armorcatdef, true) : 0f) / 2f);
                                            num3 *= 1f - num4;
                                        }
                                    }
                                }
                                num += allParts[i].coverageAbs * (1f - num3);
                            }
                        }
                        num = Mathf.Clamp(num * 2f, 0f, 2f);
                        float ArmorPenetration = num;

                        MoteMaker.ThrowText(hitThing.PositionHeld.ToVector3(), hitThing.MapHeld, "AMA_Rending_Shot".Translate(__instance.LabelCap, hitThing.LabelShortCap), 3f);
                        //    Log.Warning(string.Format("ArmorPenetration: {0}", ArmorPenetration));
                        __result = ArmorPenetration;
                    }
                }
            }
        }
Пример #6
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);
        }