예제 #1
0
        public static bool Prefix(ref MessageCenterMessage message, AttackDirector.AttackSequence __instance)
        {
            Logger.Debug("hit prefix");
            var attackSequenceResolveDamageMessage = (AttackSequenceResolveDamageMessage)message;

            var hitInfo = attackSequenceResolveDamageMessage.hitInfo;

            if (hitInfo.attackSequenceId != __instance.id)
            {
                return(true);
            }

            var messageCoordinator = Traverse.Create(__instance).Field("messageCoordinator").GetValue <MessageCoordinator>();

            if (!messageCoordinator.CanProcessMessage(attackSequenceResolveDamageMessage))
            {
                return(true);
            }

            var attackGroupIndex  = attackSequenceResolveDamageMessage.hitInfo.attackGroupIndex;
            var attackWeaponIndex = attackSequenceResolveDamageMessage.hitInfo.attackWeaponIndex;
            var weapon            = __instance.GetWeapon(attackGroupIndex, attackWeaponIndex);

            if (__instance.meleeAttackType != MeleeAttackType.DFA)
            {
                return(true);
            }

            var attacker = __instance.attacker;
            var rawDFASelfDamageValue = attacker.StatCollection.GetValue <float>("DFASelfDamage");
            var dfaSelfDamageValue    = rawDFASelfDamageValue;

            if (Core.ModSettings.PilotingSkillDFASelfDamageMitigation)
            {
                // TODO: hook up water physics
//                var superAlphaWaterFactor = 1f;
//                if ((attacker as Mech).occupiedDesignMask.Description.Id == "DesignMaskWater")
//                    superAlphaWaterFactor = 2f;

                var mitigation        = Calculator.PilotingMitigation(attacker);
                var mitigationPercent = Mathf.RoundToInt(mitigation * 100);
                dfaSelfDamageValue = rawDFASelfDamageValue - (rawDFASelfDamageValue * mitigation);
                Logger.Debug($"dfa miss numbers\n" +
                             $"pilotSkill: {attacker.SkillPiloting}\n" +
                             $"mitigation: {mitigation}\n" +
                             $"rawDFASelfDamageValue: {rawDFASelfDamageValue}\n" +
                             $"mitigationPercent: {mitigationPercent}\n" +
                             $"dfaSelfDamageValue: {dfaSelfDamageValue}");
                attacker.Combat.MessageCenter.PublishMessage(new AddSequenceToStackMessage(new ShowActorInfoSequence(attacker, $"Pilot Check: Avoided {mitigationPercent}% DFA Self-Damage!", FloatieMessage.MessageNature.Neutral, true)));
            }

            attacker.TakeWeaponDamage(attackSequenceResolveDamageMessage.hitInfo, (int)ArmorLocation.LeftLeg, weapon, dfaSelfDamageValue, 0, DamageType.DFASelf);
            attacker.TakeWeaponDamage(attackSequenceResolveDamageMessage.hitInfo, (int)ArmorLocation.RightLeg, weapon, dfaSelfDamageValue, 0, DamageType.DFASelf);
            if (AttackDirector.damageLogger.IsLogEnabled)
            {
                AttackDirector.damageLogger.Log($"@@@@@@@@ {attacker.DisplayName} takes {dfaSelfDamageValue} damage to its legs from the DFA attack!");
            }

            return(true);
        }
        public static bool Prefix(AttackDirector.AttackSequence __instance, ref MessageCenterMessage message)
        {
            AttackSequenceImpactMessage impactMessage = (AttackSequenceImpactMessage)message;

            if (impactMessage.hitInfo.attackSequenceId != __instance.id)
            {
                return(true);
            }
            int    attackGroupIndex  = impactMessage.hitInfo.attackGroupIndex;
            int    attackWeaponIndex = impactMessage.hitInfo.attackWeaponIndex;
            Weapon weapon            = __instance.GetWeapon(attackGroupIndex, attackWeaponIndex);
            float  rawDamage         = impactMessage.hitDamage;
            float  realDamage        = rawDamage;

            CustomAmmoCategoriesLog.Log.LogWrite("OnAttackSequenceImpact\n");
            CustomAmmoCategoriesLog.Log.LogWrite("  attacker = " + __instance.attacker.DisplayName + "\n");
            CustomAmmoCategoriesLog.Log.LogWrite("  target = " + __instance.target.DisplayName + "\n");
            CustomAmmoCategoriesLog.Log.LogWrite("  weapon = " + weapon.UIName + "\n");
            CustomAmmoCategoriesLog.Log.LogWrite("  damage = " + rawDamage + "\n");
            if (realDamage >= 1.0f)
            {
                if (CustomAmmoCategories.getWeaponDamageVariance(weapon) > CustomAmmoCategories.Epsilon)
                {
                    realDamage = CustomAmmoCategories.WeaponDamageSimpleVariance(weapon, rawDamage);
                }
                if (CustomAmmoCategories.getWeaponDistantVariance(weapon) > CustomAmmoCategories.Epsilon)
                {
                    if (CustomAmmoCategories.getWeaponDistantVarianceReversed(weapon))
                    {
                        realDamage = CustomAmmoCategories.WeaponDamageDistance(__instance.attacker, __instance.target, weapon, realDamage, rawDamage);
                    }
                    else
                    {
                        realDamage = CustomAmmoCategories.WeaponDamageRevDistance(__instance.attacker, __instance.target, weapon, realDamage, rawDamage);
                    }
                }
            }
            else
            {
                CustomAmmoCategoriesLog.Log.LogWrite("WARNING! raw damage is less than 1.0f. Variance calculation is forbidden with this damage value\n", true);
            }
            CustomAmmoCategoriesLog.Log.LogWrite("  real damage = " + realDamage + "\n");
            if (realDamage < CustomAmmoCategories.Epsilon)
            {
                CustomAmmoCategoriesLog.Log.LogWrite("WARNING! real damage is less than epsilon. May be negative. That is sad. Rounding to zero\n", true);
                realDamage = 0.0f;
            }
            impactMessage.hitDamage = realDamage;
            return(true);
        }
 public static bool Prefix(AttackDirector.AttackSequence __instance, MessageCenterMessage message)
 {
     CustomAmmoCategoriesLog.Log.LogWrite("AttackDirector.AttackSequence.OnAttackSequenceResolveDamage");
     try
     {
         AttackSequenceResolveDamageMessage resolveDamageMessage = (AttackSequenceResolveDamageMessage)message;
         WeaponHitInfo hitInfo = resolveDamageMessage.hitInfo;
         if (hitInfo.attackSequenceId != __instance.id)
         {
             return(true);
         }
         ;
         MessageCoordinator messageCoordinator = (MessageCoordinator)typeof(AttackDirector.AttackSequence).GetField("messageCoordinator", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance);
         if (!messageCoordinator.CanProcessMessage(resolveDamageMessage))
         {
             messageCoordinator.StoreMessage((MessageCenterMessage)resolveDamageMessage);
         }
         else
         {
             if (AttackDirector.AttackSequence.logger.IsLogEnabled)
             {
                 AttackDirector.AttackSequence.logger.Log((object)string.Format("[OnAttackSequenceResolveDamage]  ID {0}, Group {1}, Weapon {2}, AttackerId [{3}], TargetId [{4}]", (object)__instance.id, (object)hitInfo.attackGroupIndex, (object)hitInfo.attackWeaponIndex, (object)hitInfo.attackerId, (object)hitInfo.targetId));
             }
             Weapon weapon = __instance.GetWeapon(resolveDamageMessage.hitInfo.attackGroupIndex, resolveDamageMessage.hitInfo.attackWeaponIndex);
             if (__instance.meleeAttackType == MeleeAttackType.DFA)
             {
                 float damageAmount = __instance.attacker.StatCollection.GetValue <float>("DFASelfDamage");
                 __instance.attacker.TakeWeaponDamage(resolveDamageMessage.hitInfo, 64, weapon, damageAmount, 0, DamageType.DFASelf);
                 __instance.attacker.TakeWeaponDamage(resolveDamageMessage.hitInfo, 128, weapon, damageAmount, 0, DamageType.DFASelf);
                 if (AttackDirector.damageLogger.IsLogEnabled)
                 {
                     AttackDirector.damageLogger.Log((object)string.Format("@@@@@@@@ {0} takes {1} damage to its legs from the DFA attack!", (object)__instance.attacker.DisplayName, (object)damageAmount));
                 }
             }
             __instance.target.ResolveWeaponDamage(resolveDamageMessage.hitInfo);
             AbstractActor target      = __instance.target as AbstractActor;
             int           attackIndex = -1;
             int           num1        = 0;
             int           num2        = 65536;
             for (int index = 0; index < resolveDamageMessage.hitInfo.hitLocations.Length; ++index)
             {
                 int hitLocation = resolveDamageMessage.hitInfo.hitLocations[index];
                 if (hitLocation != num1 && hitLocation != num2 && attackIndex == -1)
                 {
                     attackIndex = index;
                 }
             }
             if (attackIndex > -1)
             {
                 //typeof(AttackDirector.AttackSequence).GetProperty("attackCompletelyMissed", BindingFlags.NonPublic).SetValue(__instance, (object)false);
                 PropertyInfo property = typeof(AttackDirector.AttackSequence).GetProperty("attackCompletelyMissed");
                 property.DeclaringType.GetProperty("attackCompletelyMissed");
                 property.GetSetMethod(true).Invoke(__instance, new object[1] {
                     (object)false
                 });
                 //__instance.attackCompletelyMissed = false;
             }
             if (attackIndex > -1 && !__instance.target.IsDead && target != null)
             {
                 foreach (EffectData statusEffect in CustomAmmoCategories.getWeaponStatusEffects(weapon))
                 {
                     if (statusEffect.targetingData.effectTriggerType == EffectTriggerType.OnHit)
                     {
                         string effectID = string.Format("OnHitEffect_{0}_{1}", (object)__instance.attacker.GUID, (object)resolveDamageMessage.hitInfo.attackSequenceId);
                         __instance.Director.Combat.EffectManager.CreateEffect(statusEffect, effectID, __instance.stackItemUID, (ICombatant)__instance.attacker, __instance.target, hitInfo, attackIndex, false);
                         if (__instance.target != null)
                         {
                             __instance.Director.Combat.MessageCenter.PublishMessage((MessageCenterMessage) new FloatieMessage(__instance.target.GUID, __instance.target.GUID, statusEffect.Description.Name, FloatieMessage.MessageNature.Debuff));
                         }
                     }
                 }
                 if (target != null)
                 {
                     List <EffectData> effectsForTriggerType = target.GetComponentStatusEffectsForTriggerType(EffectTriggerType.OnDamaged);
                     for (int index = 0; index < effectsForTriggerType.Count; ++index)
                     {
                         __instance.Director.Combat.EffectManager.CreateEffect(effectsForTriggerType[index], string.Format("OnDamagedEffect_{0}_{1}", (object)target.GUID, (object)resolveDamageMessage.hitInfo.attackSequenceId), __instance.stackItemUID, __instance.target, (ICombatant)__instance.attacker, hitInfo, attackIndex, false);
                     }
                 }
             }
             __instance.attacker.HandleDeath(__instance.attacker.GUID);
             __instance.attacker.HandleDeath(__instance.attacker.GUID);
             messageCoordinator.MessageComplete((MessageCenterMessage)resolveDamageMessage);
         }
     }
     catch (Exception e)
     {
         CustomAmmoCategoriesLog.Log.LogWrite("Exception " + e.ToString() + "\nFallback to default");
         return(true);
     }
     return(false);
 }