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

            if (!meleeCondition.CanUsePhysicalAttack())
            {
                Mod.MeleeLog.Info?.Write($"Attacker cannot make a physical attack, skipping.");
                return(false);
            }

            // If no punch - we're not a valid attack.
            if (!validAnimations.Contains(MeleeAttackType.Punch))
            {
                Mod.MeleeLog.Info?.Write("Animations do not include a punch, cannot use physical weapon.");
                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("PHYSICAL WEAPON ATTACK validated");
            return(true);
        }
        public static float PhysicalWeaponInstability(this Mech mech)
        {
            ActorMeleeCondition attackerCondition = ModState.GetMeleeCondition(mech);

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

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

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

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

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

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

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

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

            return(attackerCondition.CanUsePhysicalAttack());
        }