示例#1
0
        /// <summary>
        ///     returns true if 10% armor damage was incurred or any structure damage
        /// </summary>
        /// <param name="attackSequence"></param>
        /// <returns></returns>
        private static bool SufficientDamageWasDone(AttackDirector.AttackSequence attackSequence)
        {
            if (attackSequence == null)
            {
                return(false);
            }

            var id = attackSequence.chosenTarget.GUID;

            if (!attackSequence.GetAttackDidDamage(id))
            {
                LogDebug("No damage");
                return(false);
            }

            var previousArmor     = Patches.mechArmorBeforeAttack;
            var previousStructure = Patches.mechStructureBeforeAttack;

            LogDebug($"Damage >>> A: {attackSequence.GetArmorDamageDealt(id):#.###}" +
                     $" S: {attackSequence.GetStructureDamageDealt(id):#.###}" +
                     $" ({(attackSequence.GetArmorDamageDealt(id) + attackSequence.GetStructureDamageDealt(id)) / (previousArmor + previousStructure) * 100:#.##}%)  H: {Patches.heatDamage}");

            if (attackSequence.GetStructureDamageDealt(id) >= modSettings.MinimumStructureDamageRequired)
            {
                LogDebug("Structure damage requires panic save");
                return(true);
            }

            float heatTaken = 0;

            if (attackSequence.chosenTarget is Mech defender)
            {
                heatTaken = defender.CurrentHeat - Patches.mechHeatBeforeAttack;
                // LogDebug($"B {Patches.mechHeatBeforeAttack} A {defender.CurrentHeat}");
                LogDebug($"Took {Patches.heatDamage} heat");
            }

            LogDebug($"attackSequence.GetArmorDamageDealt(id) {attackSequence.GetArmorDamageDealt(id)}\nattackSequence.GetStructureDamageDealt(id) {attackSequence.GetStructureDamageDealt(id)}\nPatches.heatDamage * modSettings.HeatDamageModifier {Patches.heatDamage * modSettings.HeatDamageModifier}");
            if (attackSequence.GetArmorDamageDealt(id) + attackSequence.GetStructureDamageDealt(id) + Patches.heatDamage * modSettings.HeatDamageModifier /
                (previousArmor + previousStructure) +
                100 <= modSettings.MinimumDamagePercentageRequired)
            {
                LogDebug("Not enough damage");
                return(false);
            }

            LogDebug("Total damage requires a panic save");
            return(true);
        }
示例#2
0
        // returns true if enough damage was inflicted to trigger a panic save
        private static bool SufficientDamageWasDone(AttackDirector.AttackSequence attackSequence)
        {
            if (attackSequence == null)
            {
                return(false);
            }

            var id = attackSequence.chosenTarget.GUID;

            if (!attackSequence.GetAttackDidDamage(id))
            {
                LogReport("No damage");
                return(false);
            }

            var previousArmor     = AttackStackSequence_OnAttackBegin_Patch.armorBeforeAttack;
            var previousStructure = AttackStackSequence_OnAttackBegin_Patch.structureBeforeAttack;
            var armorDamage       = attackSequence.GetArmorDamageDealt(id);
            var structureDamage   = attackSequence.GetStructureDamageDealt(id);
            var percentDamageDone = (attackSequence.GetArmorDamageDealt(id) + attackSequence.GetStructureDamageDealt(id)) / (previousArmor + previousStructure) * 100;

            damageWithHeatDamage = percentDamageDone + Mech_AddExternalHeat_Patch.heatDamage * modSettings.HeatDamageFactor;

            // have to check structure here AFTER armor, despite it being the priority, because we need to set the global
            LogReport($"Damage >>> A: {armorDamage:F3} S: {structureDamage:F3} ({percentDamageDone:F2}%) H: {Mech_AddExternalHeat_Patch.heatDamage}");
            if (attackSequence.chosenTarget is Mech &&
                attackSequence.GetStructureDamageDealt(id) >= modSettings.MinimumMechStructureDamageRequired ||
                modSettings.VehiclesCanPanic &&
                attackSequence.chosenTarget is Vehicle &&
                attackSequence.GetStructureDamageDealt(id) >= modSettings.MinimumVehicleStructureDamageRequired)
            {
                LogReport("Structure damage requires panic save");
                return(true);
            }

            if (damageWithHeatDamage <= modSettings.MinimumDamagePercentageRequired)
            {
                LogReport("Not enough damage");
                Mech_AddExternalHeat_Patch.heatDamage = 0;
                return(false);
            }

            LogReport("Total damage requires a panic save");
            return(true);
        }
示例#3
0
        // returns true if enough damage was inflicted to trigger a panic save
        private static bool SufficientDamageWasDone(AttackDirector.AttackSequence attackSequence)
        {
            if (attackSequence == null)
            {
                return(false);
            }

            var id = attackSequence.chosenTarget.GUID;

            if (!attackSequence.GetAttackDidDamage(id))
            {
                LogReport("No damage");
                return(false);
            }

            // Account for melee attacks so separate panics are not triggered.
            if (attackSequence.isMelee && MechMeleeSequence_FireWeapons_Patch.meleeHasSupportWeapons)
            {
                initialArmorMelee     = AttackStackSequence_OnAttackBegin_Patch.armorBeforeAttack;
                initialStructureMelee = AttackStackSequence_OnAttackBegin_Patch.structureBeforeAttack;
                armorDamageMelee      = attackSequence.GetArmorDamageDealt(id);
                structureDamageMelee  = attackSequence.GetStructureDamageDealt(id);
                hadMeleeAttack        = true;
                LogReport("Stashing melee damage for support weapon firing");
                return(false);
            }

            var previousArmor     = AttackStackSequence_OnAttackBegin_Patch.armorBeforeAttack;
            var previousStructure = AttackStackSequence_OnAttackBegin_Patch.structureBeforeAttack;

            if (hadMeleeAttack)
            {
                LogReport("Adding stashed melee damage");
                previousArmor     = initialArmorMelee;
                previousStructure = initialStructureMelee;
            }
            else
            {
                armorDamageMelee     = 0;
                structureDamageMelee = 0;
            }

            var armorDamage     = attackSequence.GetArmorDamageDealt(id) + armorDamageMelee;
            var structureDamage = attackSequence.GetStructureDamageDealt(id) + structureDamageMelee;
            var heatDamage      = Mech_AddExternalHeat_Patch.heatDamage * modSettings.HeatDamageFactor;

            // used in SavingThrows.cs
            damageIncludingHeatDamage = armorDamage + structureDamage + heatDamage;
            var percentDamageDone =
                damageIncludingHeatDamage / (previousArmor + previousStructure) * 100;

            // clear melee values
            initialArmorMelee     = 0;
            initialStructureMelee = 0;
            armorDamageMelee      = 0;
            structureDamageMelee  = 0;
            hadMeleeAttack        = false;

            // have to check structure here AFTER armor, despite it being the priority, because we need to set the global
            LogReport($"Damage >>> A: {armorDamage:F3} S: {structureDamage:F3} ({percentDamageDone:F2}%) H: {Mech_AddExternalHeat_Patch.heatDamage}");
            if (modSettings.AlwaysPanic)
            {
                LogReport("AlwaysPanic");
                return(true);
            }

            if (attackSequence.chosenTarget is Mech &&
                attackSequence.GetStructureDamageDealt(id) > modSettings.MinimumMechStructureDamageRequired ||
                modSettings.VehiclesCanPanic &&
                attackSequence.chosenTarget is Vehicle &&
                attackSequence.GetStructureDamageDealt(id) > modSettings.MinimumVehicleStructureDamageRequired)
            {
                LogReport("Structure damage requires panic save");
                return(true);
            }

            if (percentDamageDone <= modSettings.MinimumDamagePercentageRequired)
            {
                LogReport("Not enough damage");
                Mech_AddExternalHeat_Patch.heatDamage = 0;
                return(false);
            }

            LogReport("Total damage requires a panic save");
            return(true);
        }
 static void Postfix(AbstractActor __instance, string sourceID, int sequenceID, int stackItemID, AttackDirection attackDirection)
 {
     try
     {
         AttackDirector.AttackSequence attackSequence = __instance.Combat.AttackDirector.GetAttackSequence(sequenceID);
         if (attackSequence != null && attackSequence.GetAttackDidDamage(__instance.GUID))
         {
             List <Effect> list = __instance.Combat.EffectManager.GetAllEffectsTargeting(__instance).FindAll((Effect x) => x.EffectData.targetingData.effectTriggerType == EffectTriggerType.OnDamaged);
             for (int i = 0; i < list.Count; i++)
             {
                 list[i].OnEffectTakeDamage(attackSequence.attacker, __instance);
             }
             if (attackSequence.isMelee)
             {
                 int value = attackSequence.attacker.StatCollection.GetValue <int>("MeleeHitPushBackPhases");
                 if (value > 0)
                 {
                     for (int j = 0; j < value; j++)
                     {
                         __instance.ForceUnitOnePhaseDown(sourceID, stackItemID, false);
                     }
                 }
             }
         }
         int   evasivePipsCurrent  = __instance.EvasivePipsCurrent;
         var   settings            = PermanentEvasion.Settings;
         float totalDamageReceived = 1;
         if (attackSequence.GetAttackDidDamage(__instance.GUID))
         {
             totalDamageReceived += attackSequence.GetArmorDamageDealt(__instance.GUID) + attackSequence.GetStructureDamageDealt(__instance.GUID);
             if ((totalDamageReceived > settings.MinDamageForEvasionStrip) && settings.AllowHitStrip)
             {
                 __instance.ConsumeEvasivePip(true);
                 Fields.LoosePip = false;
             }
             else if (Fields.LoosePip)
             {
                 __instance.ConsumeEvasivePip(true);
                 Fields.LoosePip = false;
             }
         }
         else if (Fields.LoosePip)
         {
             __instance.ConsumeEvasivePip(true);
             Fields.LoosePip = false;
         }
         int evasivePipsCurrent2 = __instance.EvasivePipsCurrent;
         if (evasivePipsCurrent2 < evasivePipsCurrent && (totalDamageReceived > settings.MinDamageForEvasionStrip) && settings.AllowHitStrip && !__instance.IsDead && !__instance.IsFlaggedForDeath)
         {
             __instance.Combat.MessageCenter.PublishMessage(new FloatieMessage(__instance.GUID, __instance.GUID, "HIT: -1 EVASION", FloatieMessage.MessageNature.Debuff));
         }
         else if (evasivePipsCurrent2 < evasivePipsCurrent && !__instance.IsDead && !__instance.IsFlaggedForDeath)
         {
             __instance.Combat.MessageCenter.PublishMessage(new FloatieMessage(__instance.GUID, __instance.GUID, "-1 EVASION", FloatieMessage.MessageNature.Debuff));
         }
         else if (evasivePipsCurrent2 > 0 && Fields.KeptPip && !__instance.IsDead && !__instance.IsFlaggedForDeath)
         {
             __instance.Combat.MessageCenter.PublishMessage(new FloatieMessage(__instance.GUID, __instance.GUID, "EVASION KEPT", FloatieMessage.MessageNature.Buff));
             Fields.KeptPip = false;
         }
     }
     catch (Exception e)
     {
         Logger.Error(e);
     }
 }