private static List <WeaponAttackEval> FilterForBreachingShot(List <WeaponAttackEval> attacks, AttackDetails details)
        {
            if (!details.Attacker.HasBreachingShotAbility)
            {
                return(attacks);
            }

            List <WeaponAttackEval> filteredList = new List <WeaponAttackEval>();

            // TODO: Sort by chance to hit / weight weapons with a higher chance to hit?
            attacks.Sort((wae1, wae2) => (wae1.EVDirectDmg + wae1.EVStructDam).CompareTo(wae2.EVDirectDmg + wae2.EVStructDam));

            WeaponAttackEval bShotWAE = attacks.First();
            float            bShotDmg = (bShotWAE.EVDirectDmg + bShotWAE.EVStructDam) * Mod.Config.Weights.BreachingShot.Multi;
            float            sumDmg   = attacks.Sum(x => x.EVDirectDmg + x.EVStructDam);

            Mod.Log.Debug?.Write($" breachingShotDmg: {bShotDmg} vs. sumEVDmg: {sumDmg}");

            // TODO: Normalize toHit chance of sumDmg vs. toHit of bShotDmg before comparing damage
            if (bShotDmg > sumDmg)
            {
                Mod.Log.Debug?.Write($"Breaching shot has more damage, returning a list of one item.");
                filteredList.Add(bShotWAE);
            }
            else
            {
                Mod.Log.Debug?.Write($"Full attack has more damage, returning the entire list.");
                filteredList.AddRange(attacks);
            }

            return(filteredList);
        }
        // Iterate the ammoModePairs on the weapon to find the highest direct damage, heat damage, and stab damage
        private static (WeaponAttackEval damage, WeaponAttackEval heat, WeaponAttackEval stab) OptimizeAmmoPairForAttack(Weapon weapon, AttackDetails details)
        {
            WeaponAttackEval damage = new WeaponAttackEval()
            {
                Weapon = weapon
            };
            WeaponAttackEval heat = new WeaponAttackEval()
            {
                Weapon = weapon
            };
            WeaponAttackEval stab = new WeaponAttackEval()
            {
                Weapon = weapon
            };

            BehaviorTree bTree = details.Attacker.BehaviorTree;

            try
            {
                float attackTypeWeight = AIHelper.GetCachedBehaviorVariableValue(bTree, BehaviorVariableName.Float_ShootingDamageMultiplier).FloatVal;;

                // Damage prediction assumes an attack quality of Solid. It doesn't apply targetMultis either
                Dictionary <AmmoModePair, WeaponFirePredictedEffect> damagePredictions = CleverGirlHelper.gatherDamagePrediction(weapon, details.AttackPosition, details.Target);
                foreach (KeyValuePair <AmmoModePair, WeaponFirePredictedEffect> kvp in damagePredictions)
                {
                    AmmoModePair ammoModePair = kvp.Key;
                    WeaponFirePredictedEffect weaponFirePredictedEffect = kvp.Value;
                    Mod.Log.Debug?.Write($" - Evaluating ammoId: {ammoModePair.ammoId} with modeId: {ammoModePair.modeId}");

                    WeaponAttackEval wae = new WeaponAttackEval()
                    {
                        Weapon = weapon, AmmoMode = ammoModePair
                    };
                    foreach (DamagePredictionRecord dpr in weaponFirePredictedEffect.predictDamage)
                    {
                        Hostility targetHostility = SharedState.Combat.HostilityMatrix.GetHostility(details.Attacker.team, dpr.Target.team);
                        if (targetHostility == Hostility.FRIENDLY)
                        {
                            // Friendly and self damage weights directly into a self damage, and doesn't contribute to any attacks
                            float damageMulti;
                            if (details.Attacker.GUID == dpr.Target.GUID)
                            {
                                damageMulti = Mod.Config.Weights.DamageMultis.Self;
                            }
                            else
                            {
                                damageMulti = Mod.Config.Weights.DamageMultis.Friendly;
                            }

                            wae.EVFriendlyDmg += dpr.ToHit * dpr.Normal * damageMulti;
                            wae.EVFriendlyDmg += dpr.ToHit * dpr.AP * damageMulti;
                            wae.EVFriendlyDmg += dpr.ToHit * dpr.Heat * damageMulti;
                            wae.EVFriendlyDmg += dpr.ToHit * dpr.Instability * damageMulti;
                        }
                        else if (targetHostility == Hostility.NEUTRAL)
                        {
                            // Neutrals are weighted lower, to emphasize attacking enemies more directly
                            wae.EVDirectDmg += dpr.ToHit * dpr.Normal * Mod.Config.Weights.DamageMultis.Neutral;
                            wae.EVStructDam += dpr.ToHit * dpr.AP * Mod.Config.Weights.DamageMultis.Neutral;
                            wae.EVHeat      += dpr.ToHit * dpr.Heat * Mod.Config.Weights.DamageMultis.Neutral;
                            wae.EVStab      += dpr.ToHit * dpr.Instability * Mod.Config.Weights.DamageMultis.Neutral;
                        }
                        else
                        {
                            wae.EVDirectDmg += dpr.ToHit * dpr.Normal;
                            wae.EVStructDam += dpr.ToHit * dpr.AP;
                            wae.EVHeat      += dpr.ToHit * dpr.Heat;
                            wae.EVStab      += dpr.ToHit * dpr.Instability;
                        }
                        if (!dpr.isAoE && dpr.ToHit > wae.ToHit)
                        {
                            wae.ToHit = dpr.ToHit;
                        }
                    }

                    if ((wae.EVDirectDmg + wae.EVStructDam) >= (damage.EVDirectDmg + damage.EVStructDam))
                    {
                        damage = wae;
                    }
                    if (wae.EVHeat >= heat.EVHeat)
                    {
                        heat = wae;
                    }
                    if (wae.EVStructDam >= stab.EVStructDam)
                    {
                        stab = wae;
                    }
                }
            }
            catch (Exception e)
            {
                Mod.Log.Error?.Write(e, "Failed to calculate weapon damageEV!");
            }

            return(damage, heat, stab);
        }