public static void ChooseBestWeaponForTarget(AbstractActor unit, ICombatant target, bool isStationary)
        {
            List <Weapon> ammoWeapons = new List <Weapon>();

            foreach (Weapon weapon in unit.Weapons)
            {
                if (CustomAmmoCategories.isWeaponHasDiffirentAmmo(weapon) == true)
                {
                    CustomAmmoCategoriesLog.Log.LogWrite(" " + weapon.UIName + " has ammo to choose\n");
                    ammoWeapons.Add(weapon);
                }
            }
            if (ammoWeapons.Count == 0)
            {
                CustomAmmoCategoriesLog.Log.LogWrite(" None choosable ammo\n");
                return;
            }
            ;
            if (target is Mech)
            {
                CustomAmmoCategoriesLog.Log.LogWrite(" Target is mech\n");
                Mech          targetMech      = (target as Mech);
                List <Weapon> ammoHeatWeapons = new List <Weapon>();
                foreach (Weapon weapon in ammoWeapons)
                {
                    if (CustomAmmoCategories.isWeaponHasHeatAmmo(weapon) == true)
                    {
                        CustomAmmoCategories.switchToMostHeatAmmo(weapon);
                        CustomAmmoCategoriesLog.Log.LogWrite(" " + weapon.UIName + " has hit ammo\n");
                        ammoHeatWeapons.Add(weapon);
                    }
                }
                float expectedHeat = CustomAmmoCategories.calcHeatCoeff(unit, target);
                CustomAmmoCategoriesLog.Log.LogWrite(" Expected heat " + expectedHeat + "\n");
                if ((targetMech.CurrentHeat + expectedHeat) > targetMech.OverheatLevel)
                {
                    foreach (Weapon weapon in ammoHeatWeapons)
                    {
                        CustomAmmoCategoriesLog.Log.LogWrite(" " + weapon.UIName + " - ammo choosed\n");
                        ammoWeapons.Remove(weapon);
                    }
                }
                List <int>    hitLocations      = targetMech.GetPossibleHitLocations(unit);
                List <Weapon> ammoClusterWeapon = new List <Weapon>();
                foreach (Weapon weapon in ammoWeapons)
                {
                    if (CustomAmmoCategories.isWeaponHasClusterAmmo(weapon))
                    {
                        CustomAmmoCategories.switchToMostClusterAmmo(weapon);
                        CustomAmmoCategoriesLog.Log.LogWrite(" " + weapon.UIName + " has cluster ammo\n");
                        ammoClusterWeapon.Add(weapon);
                    }
                }
                foreach (Weapon weapon in ammoClusterWeapon)
                {
                    float toHit = 0f;
                    if (weapon.parent.HasLOFToTargetUnit(target, weapon.MaxRange, CustomAmmoCategories.getIndirectFireCapable(weapon)))
                    {
                        toHit = weapon.GetToHitFromPosition(target, 1, unit.CurrentPosition, target.CurrentPosition, true, targetMech.IsEvasive, false);
                    }
                    if (toHit < 0.4f)
                    {
                        CustomAmmoCategoriesLog.Log.LogWrite(" " + weapon.UIName + " cluster toHit is too low " + toHit + "\n");
                        continue;
                    }
                    if (CustomAmmoCategories.hasHittableLocations(weapon, hitLocations, targetMech) == true)
                    {
                        CustomAmmoCategoriesLog.Log.LogWrite(" " + weapon.UIName + " can crit one of locations\n");
                        ammoWeapons.Remove(weapon);
                    }
                }
            }
            AbstractActor targetActor = (target as AbstractActor);

            foreach (Weapon weapon in ammoWeapons)
            {
                List <string> avaibleAmmo = CustomAmmoCategories.getAvaibleEffectiveAmmo(weapon);
                if (avaibleAmmo.Count == 0)
                {
                    continue;
                }
                ;
                CustomAmmoCategoriesLog.Log.LogWrite(" " + weapon.UIName + " choose ammo default algorithm\n");
                string bestAmmo       = "";
                float  expectedDamage = 0;
                foreach (string ammoId in avaibleAmmo)
                {
                    CustomAmmoCategories.SetWeaponAmmo(weapon, ammoId);
                    float toHit = 0f;
                    if (unit.HasLOFToTargetUnit(target, weapon.MaxRange, CustomAmmoCategories.getIndirectFireCapable(weapon)))
                    {
                        toHit = weapon.GetToHitFromPosition(target, 1, unit.CurrentPosition, target.CurrentPosition, true, (targetActor != null) ? targetActor.IsEvasive : false, false);
                    }
                    float nonClusterCoeff = 1f;
                    int   numberOfShots   = weapon.ShotsWhenFired * weapon.ProjectilesPerShot;
                    if ((toHit > 0.6f) && (numberOfShots == 1))
                    {
                        nonClusterCoeff = 1.2f;
                    }
                    float tempExpectedDamage = numberOfShots * weapon.DamagePerShot * toHit * nonClusterCoeff;
                    CustomAmmoCategoriesLog.Log.LogWrite(" " + weapon.UIName + " toHit " + toHit + " expectedDamage:" + tempExpectedDamage + "\n");
                    if (tempExpectedDamage > expectedDamage)
                    {
                        expectedDamage = tempExpectedDamage;
                        bestAmmo       = ammoId;
                    }
                }
                if (string.IsNullOrEmpty(bestAmmo) == false)
                {
                    CustomAmmoCategories.SetWeaponAmmo(weapon, bestAmmo);
                    CustomAmmoCategoriesLog.Log.LogWrite(" " + weapon.UIName + " best ammo choosed\n");
                }
            }
        }