Example #1
0
        private static void Postfix(Mech __instance, WeaponHitInfo hitInfo, Weapon weapon, MeleeAttackType meleeAttackType)
        {
            AttackDirector.AttackSequence attackSequence = __instance.Combat.AttackDirector.GetAttackSequence(hitInfo.attackSequenceId);
            AbstractActor actor = __instance.Combat.FindActorByGUID(hitInfo.targetId);

            if (actor is Mech)
            {
                Mech target = actor as Mech;

                float stabilityDamage = hitInfo.ConsolidateInstability(weapon.Instability(), __instance.Combat.Constants.ResolutionConstants.GlancingBlowDamageMultiplier, __instance.Combat.Constants.ResolutionConstants.NormalBlowDamageMultiplier, __instance.Combat.Constants.ResolutionConstants.SolidBlowDamageMultiplier);
                stabilityDamage *= __instance.StatCollection.GetValue <float>("ReceivedInstabilityMultiplier");
                stabilityDamage *= __instance.EntrenchedMultiplier;

                if (AttackDirector.attackLogger.IsLogEnabled)
                {
                    AttackDirector.attackLogger.Log("[CBTPiloting] Checking Piloting Stability");
                    AttackDirector.attackLogger.Log(string.Format("[CBTPiloting] Is Mech: {0}", (actor is Mech)));
                    AttackDirector.attackLogger.Log(string.Format("[CBTPiloting] Weapon Stab Dmg: {0}", stabilityDamage));
                    AttackDirector.attackLogger.Log(string.Format("[CBTPiloting] Target Dead: {0}", target.IsDead));
                    AttackDirector.attackLogger.Log(string.Format("[CBTPiloting] Target Unsteady: {0}", target.IsUnsteady));
                    AttackDirector.attackLogger.Log(string.Format("[CBTPiloting] Target IsOrWillBeProne: {0}", target.IsOrWillBeProne));
                }

                if (stabilityDamage > 0 && !target.IsDead && target.IsUnsteady && !target.IsOrWillBeProne)
                {
                    float skillBonus = (float)target.SkillPiloting / __instance.Combat.Constants.PilotingConstants.PilotingDivisor;

                    float skillRoll  = __instance.Combat.NetworkRandom.Float();
                    float skillTotal = skillRoll + skillBonus;

                    if (AttackDirector.attackLogger.IsLogEnabled)
                    {
                        AttackDirector.attackLogger.Log(string.Format("[CBTPiloting] Skill Bonus: {0}", skillBonus));
                        AttackDirector.attackLogger.Log(string.Format("[CBTPiloting] Skill Roll: {0}", skillRoll));
                        AttackDirector.attackLogger.Log(string.Format("[CBTPiloting] Skill Roll Total: {0}", skillTotal));
                        AttackDirector.attackLogger.Log(string.Format("[CBTPiloting] Skill Target: {0}", CBTPiloting.Settings.PilotStabilityCheck));
                    }

                    if (skillTotal < CBTPiloting.Settings.PilotStabilityCheck)
                    {
                        if (AttackDirector.attackLogger.IsLogEnabled)
                        {
                            AttackDirector.attackLogger.Log(string.Format("[CBTPiloting] Skill Check Failed! Flagging for Knockdown"));
                        }

                        target.FlagForKnockdown();
                        target.Combat.MessageCenter.PublishMessage(new AddSequenceToStackMessage(new ShowActorInfoSequence(target, $"Stability Check: Failed!", FloatieMessage.MessageNature.Debuff, true)));
                    }
                    else
                    {
                        if (AttackDirector.attackLogger.IsLogEnabled)
                        {
                            AttackDirector.attackLogger.Log(string.Format("[CBTPiloting] Skill Check Succeeded!"));
                        }

                        target.Combat.MessageCenter.PublishMessage(new AddSequenceToStackMessage(new ShowActorInfoSequence(target, $"Stability Check: Passed!", FloatieMessage.MessageNature.Buff, true)));
                    }
                }
            }
        }
Example #2
0
            public static void Postfix(Mech __instance, WeaponHitInfo hitInfo, Weapon weapon, MeleeAttackType meleeAttackType)
            {
                Mod.Log.Trace("M:RWD entered.");

                AttackDirector.AttackSequence attackSequence = __instance.Combat.AttackDirector.GetAttackSequence(hitInfo.attackSequenceId);
                AbstractActor actor = __instance.Combat.FindActorByGUID(hitInfo.targetId);

                if (actor is Mech target)
                {
                    CombatResolutionConstantsDef crcd = __instance.Combat.Constants.ResolutionConstants;
                    float stabilityDamage             = hitInfo.ConsolidateInstability(hitInfo.targetId, weapon.Instability(),
                                                                                       crcd.GlancingBlowDamageMultiplier, crcd.NormalBlowDamageMultiplier, crcd.SolidBlowDamageMultiplier);

                    stabilityDamage *= __instance.StatCollection.GetValue <float>("ReceivedInstabilityMultiplier");
                    stabilityDamage *= __instance.EntrenchedMultiplier;

                    Mod.Log.Debug($" == Checking Piloting Stability");
                    Mod.Log.Debug($"   target:{CombatantHelper.LogLabel(target)} isMech:{(actor is Mech)} IsDead:{target.IsDead} IsUnsteady:{target.IsUnsteady} IsOrWillBeProne:{target.IsOrWillBeProne}");
                    Mod.Log.Debug($"   weapon stability damage:{stabilityDamage}");

                    if (stabilityDamage > 0 && !target.IsDead && target.IsUnsteady && !target.IsOrWillBeProne)
                    {
                        float skillBonus = (float)target.SkillPiloting / __instance.Combat.Constants.PilotingConstants.PilotingDivisor;

                        float skillRoll  = __instance.Combat.NetworkRandom.Float();
                        float skillTotal = skillRoll + skillBonus;

                        Mod.Log.Debug($" Skill check -> bonus: {skillBonus}  roll: {skillRoll}  rollTotal: {skillTotal}  target:{Mod.Config.PilotStabilityCheck}");

                        if (skillTotal < Mod.Config.PilotStabilityCheck)
                        {
                            Mod.Log.Debug(string.Format(" Skill Check Failed! Flagging for Knockdown"));
                            bool showMessage = !target.IsFlaggedForKnockdown;

                            target.FlagForKnockdown();
                            if (Mod.Config.ShowAllStabilityRolls || showMessage)
                            {
                                target.Combat.MessageCenter.PublishMessage(new AddSequenceToStackMessage(new ShowActorInfoSequence(target, $"Stability Check: Failed!", FloatieMessage.MessageNature.Debuff, true)));
                            }
                        }
                        else
                        {
                            Mod.Log.Debug(string.Format(" Skill Check Succeeded!"));
                            if (Mod.Config.ShowAllStabilityRolls)
                            {
                                target.Combat.MessageCenter.PublishMessage(new AddSequenceToStackMessage(new ShowActorInfoSequence(target, $"Stability Check: Passed!", FloatieMessage.MessageNature.Buff, true)));
                            }
                        }
                    }
                    else
                    {
                        Mod.Log.Debug($"  target has no stability damage, is not unsteady, or is dead or prone - skipping");
                    }
                }
            }
Example #3
0
        // The default method assumes an absractActor exists, and tries to draw a line of fire. We don't have that, so skip it.
        public static void ResolveSourcelessWeaponDamage(this Mech mech, WeaponHitInfo hitInfo, Weapon weapon, MeleeAttackType meleeAttackType)
        {
            AttackDirector.AttackSequence attackSequence = ModState.Combat.AttackDirector.GetAttackSequence(hitInfo.attackSequenceId);
            float damagePerShot          = weapon.DamagePerShot;
            float structureDamagePerShot = weapon.StructureDamagePerShot;

            LineOfFireLevel lineOfFireLevel = LineOfFireLevel.LOFClear;

            damagePerShot          = mech.GetAdjustedDamage(damagePerShot, weapon.WeaponCategoryValue, mech.occupiedDesignMask, lineOfFireLevel, false);
            structureDamagePerShot = mech.GetAdjustedDamage(structureDamagePerShot, weapon.WeaponCategoryValue, mech.occupiedDesignMask, lineOfFireLevel, false);
            foreach (KeyValuePair <int, float> keyValuePair in hitInfo.ConsolidateCriticalHitInfo(mech.GUID, damagePerShot))
            {
                if (keyValuePair.Key != 0 && keyValuePair.Key != 65536 && (mech.ArmorForLocation(keyValuePair.Key) <= 0f || structureDamagePerShot > 0f))
                {
                    ChassisLocations chassisLocationFromArmorLocation = MechStructureRules.GetChassisLocationFromArmorLocation((ArmorLocation)keyValuePair.Key);
                    if (!mech.IsLocationDestroyed(chassisLocationFromArmorLocation))
                    {
                        Traverse checkForCritT = Traverse.Create(mech).Method("CheckForCrit", new Type[] { typeof(WeaponHitInfo), typeof(ChassisLocations), typeof(Weapon) });
                        checkForCritT.GetValue(new object[] { hitInfo, chassisLocationFromArmorLocation, weapon });
                    }
                }
            }
            if (weapon.HeatDamagePerShot > 0f)
            {
                bool flag = false;
                for (int i = 0; i < hitInfo.numberOfShots; i++)
                {
                    if (hitInfo.DidShotHitTarget(mech.GUID, i) && hitInfo.ShotHitLocation(i) != 0 && hitInfo.ShotHitLocation(i) != 65536)
                    {
                        flag = true;
                        mech.AddExternalHeat(string.Format("Heat Damage from {0}", weapon.Description.Name), (int)weapon.HeatDamagePerShotAdjusted(hitInfo.hitQualities[i]));
                    }
                }
                if (flag && attackSequence != null)
                {
                    attackSequence.FlagAttackDidHeatDamage(mech.GUID);
                }
            }
            float num3 = hitInfo.ConsolidateInstability(mech.GUID, weapon.Instability(), mech.Combat.Constants.ResolutionConstants.GlancingBlowDamageMultiplier,
                                                        mech.Combat.Constants.ResolutionConstants.NormalBlowDamageMultiplier, mech.Combat.Constants.ResolutionConstants.SolidBlowDamageMultiplier);

            num3 *= mech.StatCollection.GetValue <float>("ReceivedInstabilityMultiplier");
            num3 *= mech.EntrenchedMultiplier;
            mech.AddAbsoluteInstability(num3, StabilityChangeSource.Attack, hitInfo.attackerId);
        }
            public static void Postfix(Mech __instance, WeaponHitInfo hitInfo, Weapon weapon, MeleeAttackType meleeAttackType)
            {
                Mod.Log.Trace("M:RWD entered.");

                AttackDirector.AttackSequence attackSequence = __instance.Combat.AttackDirector.GetAttackSequence(hitInfo.attackSequenceId);
                AbstractActor target = __instance.Combat.FindActorByGUID(hitInfo.targetId);

                if (target is Mech targetMech)
                {
                    // Feature: Piloting Skill Check from instability
                    // TODO: Let instability represent this?
                    CombatResolutionConstantsDef crcd = target.Combat.Constants.ResolutionConstants;
                    float stabilityDamage             = hitInfo.ConsolidateInstability(hitInfo.targetId, weapon.Instability(),
                                                                                       crcd.GlancingBlowDamageMultiplier, crcd.NormalBlowDamageMultiplier, crcd.SolidBlowDamageMultiplier);
                    stabilityDamage *= __instance.StatCollection.GetValue <float>("ReceivedInstabilityMultiplier");
                    stabilityDamage *= __instance.EntrenchedMultiplier;
                    MechHelper.PilotCheckOnInstabilityDamage(targetMech, stabilityDamage);
                }
            }