예제 #1
0
        private bool ValidateAttack(Mech attacker, AbstractActor target, HashSet <MeleeAttackType> validAnimations)
        {
            ActorMeleeCondition meleeCondition = ModState.GetMeleeCondition(attacker);

            if (!meleeCondition.CanPunch())
            {
                Mod.MeleeLog.Info?.Write($"Attacker cannot punch, skipping.");
                return(false);
            }

            // If we cannot punch - not a valid attack
            if (!validAnimations.Contains(MeleeAttackType.Punch) && !(validAnimations.Contains(MeleeAttackType.Tackle)))
            {
                Mod.MeleeLog.Info?.Write("Animations do not include a punch or tackle, attacker cannot punch!");
                return(false);
            }

            if (target.UnaffectedPathing())
            {
                Mod.MeleeLog.Info?.Write($"Target is unaffected by pathing, likely a VTOL or LAM in flight. Cannot melee it!");
                return(false);
            }

            // If distance > walkSpeed, disable kick/physical weapon/punch
            if (!state.HasWalkAttackNodes)
            {
                Mod.MeleeLog.Info?.Write($"No walking nodes found for melee attack!");
                return(false);
            }

            Mod.MeleeLog.Info?.Write("PUNCH ATTACK validated");
            return(true);
        }
        public static float PunchInstability(this Mech mech)
        {
            ActorMeleeCondition attackerCondition = ModState.GetMeleeCondition(mech);

            if (!attackerCondition.CanPunch())
            {
                return(0);
            }

            // 0 is a signal that there's no divisor
            float tonnageMulti = mech.StatCollection.ContainsStatistic(ModStats.PunchTargetInstability) &&
                                 mech.StatCollection.GetValue <float>(ModStats.PunchTargetInstability) > 0 ?
                                 mech.StatCollection.GetValue <float>(ModStats.PunchTargetInstability) :
                                 Mod.Config.Melee.Punch.TargetInstabilityPerAttackerTon;

            float raw = (float)Math.Ceiling(tonnageMulti * mech.tonnage);

            Mod.MeleeLog.Debug?.Write($"PUNCH instability => tonnageMulti: {tonnageMulti} x attacker tonnage: {mech.tonnage} = raw: {raw}");

            // Modifiers
            float mod = mech.StatCollection.ContainsStatistic(ModStats.PunchTargetInstabilityMod) ?
                        mech.StatCollection.GetValue <int>(ModStats.PunchTargetInstabilityMod) : 0f;
            float multi = mech.StatCollection.ContainsStatistic(ModStats.PunchTargetInstabilityMulti) ?
                          mech.StatCollection.GetValue <float>(ModStats.PunchTargetInstabilityMulti) : 1f;

            // Leg actuator damage
            float leftReductionMulti = 1f;
            int   damagedLeftCount   = 2 - attackerCondition.LeftArmActuatorsCount;

            for (int i = 0; i < damagedLeftCount; i++)
            {
                leftReductionMulti *= Mod.Config.Melee.Punch.ArmActuatorDamageReduction;
            }
            Mod.MeleeLog.Debug?.Write($" - Left actuator damage multi is: {leftReductionMulti}");

            float rightReductionMulti = 1f;
            int   damagedRightCount   = 2 - attackerCondition.RightArmActuatorsCount;

            for (int i = 0; i < damagedRightCount; i++)
            {
                rightReductionMulti *= Mod.Config.Melee.Punch.ArmActuatorDamageReduction;
            }
            Mod.MeleeLog.Debug?.Write($" - Right actuator damage multi is: {rightReductionMulti}");

            float actuatorMulti = leftReductionMulti >= rightReductionMulti ? leftReductionMulti : rightReductionMulti;

            Mod.MeleeLog.Debug?.Write($" - Using actuator damage multi of: {actuatorMulti}");

            // Roll up instability
            float final = (float)Math.Ceiling((raw + mod) * multi * actuatorMulti);

            Mod.MeleeLog.Info?.Write($" - Target instability => final: {final} = (raw: {raw} + mod: {mod}) x " +
                                     $"multi: {multi} x actuatorMulti: {actuatorMulti}");

            return(final);
        }
        public static float PunchDamage(this Mech mech)
        {
            ActorMeleeCondition attackerCondition = ModState.GetMeleeCondition(mech);

            if (!attackerCondition.CanPunch())
            {
                return(0);
            }

            float tonnageMulti = mech.StatCollection.ContainsStatistic(ModStats.PunchTargetDamage) &&
                                 mech.StatCollection.GetValue <float>(ModStats.PunchTargetDamage) > 0 ?
                                 mech.StatCollection.GetValue <float>(ModStats.PunchTargetDamage) :
                                 Mod.Config.Melee.Punch.TargetDamagePerAttackerTon;

            float raw = (float)Math.Ceiling(tonnageMulti * mech.tonnage);

            Mod.MeleeLog.Debug?.Write($"PUNCH damage => tonnageMulti: {tonnageMulti} x attacker tonnage: {mech.tonnage} = raw: {raw}");

            // Modifiers
            float mod = mech.StatCollection.ContainsStatistic(ModStats.PunchTargetDamageMod) ?
                        mech.StatCollection.GetValue <int>(ModStats.PunchTargetDamageMod) : 0f;
            float multi = mech.StatCollection.ContainsStatistic(ModStats.PunchTargetDamageMulti) ?
                          mech.StatCollection.GetValue <float>(ModStats.PunchTargetDamageMulti) : 1f;

            // Actuator damage
            float leftReductionMulti   = 1f;
            int   damagedLeftActuators = 2 - attackerCondition.LeftArmActuatorsCount;

            for (int i = 0; i < damagedLeftActuators; i++)
            {
                leftReductionMulti *= Mod.Config.Melee.Punch.ArmActuatorDamageReduction;
            }
            Mod.MeleeLog.Debug?.Write($" - Left arm actuator damage is: {leftReductionMulti}");

            float rightReductionMulti   = 1f;
            int   damagedRightActuators = 2 - attackerCondition.RightArmActuatorsCount;

            for (int i = 0; i < damagedRightActuators; i++)
            {
                rightReductionMulti *= Mod.Config.Melee.Punch.ArmActuatorDamageReduction;
            }
            Mod.MeleeLog.Debug?.Write($" - Right arm actuator damage is: {rightReductionMulti}");

            float reductionMulti = leftReductionMulti >= rightReductionMulti ? leftReductionMulti : rightReductionMulti;

            Mod.MeleeLog.Debug?.Write($" - Using arm actuator damage reduction of: {reductionMulti}");

            // Roll up final damage
            float final = (float)Math.Ceiling((raw + mod) * multi * reductionMulti);

            Mod.MeleeLog.Debug?.Write($" - Target damage per strike => final: {final} = (raw: {raw} + mod: {mod}) x " +
                                      $"multi: {multi} x reductionMulti: {reductionMulti}");

            return(final);
        }