public CandidateWeapons(AbstractActor attacker, ICombatant target)
        {
            Mod.Log.Debug?.Write($"Calculating candidate weapons");

            for (int i = 0; i < attacker.Weapons.Count; i++)
            {
                Weapon weapon = attacker.Weapons[i];

                CondensedWeapon cWeapon = new CondensedWeapon(weapon);

                if (cWeapon.First.CanFire)
                {
                    Mod.Log.Debug?.Write($" -- '{cWeapon.First.defId}' included");
                    string cWepKey = cWeapon.First.weaponDef.Description.Id;
                    if (condensed.ContainsKey(cWepKey))
                    {
                        condensed[cWepKey].AddWeapon(weapon);
                    }
                    else
                    {
                        condensed[cWepKey] = cWeapon;
                    }
                }
                else
                {
                    Mod.Log.Debug?.Write($" -- '{cWeapon.First.defId}' excluded (disabled or out of ammo)");
                }
            }
            Mod.Log.Debug?.Write("  -- DONE");

            // TODO: Can fire only evaluates ammo once... check for enough ammo for all shots?
            float distance = (target.CurrentPosition - attacker.CurrentPosition).magnitude;

            Mod.Log.Debug?.Write($" Checking range {distance} and LOF from attacker: ({attacker.CurrentPosition}) to " +
                                 $"target: ({target.CurrentPosition})");
            foreach (KeyValuePair <string, CondensedWeapon> kvp in condensed)
            {
                CondensedWeapon cWeapon = kvp.Value;
                // Evaluate being able to hit the target
                bool willFireAtTarget = cWeapon.First.WillFireAtTargetFromPosition(target, attacker.CurrentPosition, attacker.CurrentRotation);
                bool withinRange      = distance <= cWeapon.First.MaxRange;
                if (willFireAtTarget && withinRange)
                {
                    Mod.Log.Debug?.Write($" ({cWeapon.First.defId}) has LOF and is within range, adding ");
                    RangedWeapons.Add(cWeapon);
                }
                else
                {
                    Mod.Log.Debug?.Write($" ({cWeapon.First.defId}) is out of range (MaxRange: {cWeapon.First.MaxRange} vs {distance}) " +
                                         $"or has no LOF, skipping.");
                }

                if (cWeapon.First.WeaponCategoryValue.IsSupport)
                {
                    Mod.Log.Debug?.Write($" ({cWeapon.First.defId}) is anti-personnel, adding to melee and DFA sets.");
                    MeleeWeapons.Add(cWeapon);
                    DFAWeapons.Add(cWeapon);
                }
            }
        }
        // === CLONE METHODS BELOW ==

        // CLONE OF HBS CODE - LIKELY BRITTLE!
        public static List <List <CondensedWeapon> > MakeWeaponSets(List <CondensedWeapon> potentialWeapons)
        {
            List <List <CondensedWeapon> > list = new List <List <CondensedWeapon> >();

            if (potentialWeapons.Count > 0)
            {
                CondensedWeapon                item  = potentialWeapons[0];
                List <CondensedWeapon>         range = potentialWeapons.GetRange(1, potentialWeapons.Count - 1);
                List <List <CondensedWeapon> > list2 = MakeWeaponSets(range);
                for (int i = 0; i < list2.Count; i++)
                {
                    List <CondensedWeapon> list3 = list2[i];
                    list.Add(list3);
                    list.Add(new List <CondensedWeapon>(list3)
                    {
                        item
                    });
                }
            }
            else
            {
                List <CondensedWeapon> item2 = new List <CondensedWeapon>();
                list.Add(item2);
            }
            return(list);
        }
Beispiel #3
0
        public static int HeatForAttack(List <CondensedWeapon> weaponList)
        {
            int num = 0;

            for (int i = 0; i < weaponList.Count; i++)
            {
                CondensedWeapon cWeapon = weaponList[i];
                num += ((int)cWeapon.First.HeatGenerated * cWeapon.weaponsCondensed);
            }
            return(num);
        }
Beispiel #4
0
        public static float LowestHitChance(List <CondensedWeapon> weaponList, ICombatant target, Vector3 attackPosition, Vector3 targetPosition, bool targetIsEvasive)
        {
            float num = float.MaxValue;

            for (int i = 0; i < weaponList.Count; i++)
            {
                CondensedWeapon cWeapon           = weaponList[i];
                float           toHitFromPosition = cWeapon.First.GetToHitFromPosition(target, 1, attackPosition, targetPosition, true, targetIsEvasive, false);
                num = Mathf.Min(num, toHitFromPosition);
            }
            return(num);
        }
        // CLONE OF HBS CODE - LIKELY BRITTLE!
        public static List <List <CondensedWeapon> > MakeWeaponSetsForEvasive(List <CondensedWeapon> potentialWeapons, float toHitFrac, ICombatant target, Vector3 shooterPosition)
        {
            List <CondensedWeapon> likelyToHitWeapons     = new List <CondensedWeapon>();
            List <CondensedWeapon> unlikelyNonAmmoWeapons = new List <CondensedWeapon>();
            List <CondensedWeapon> unlikelyAmmoWeapons    = new List <CondensedWeapon>();

            // Separate weapons into likely to hit, and unlikely to hit. Add only a single unlikely to hit weapon to the sets to be created.
            // TODO: Make this multi-step marginal... don't fire 9% weapons, but do fire 30%?
            for (int i = 0; i < potentialWeapons.Count; i++)
            {
                CondensedWeapon weapon = potentialWeapons[i];
                if (weapon.First.CanFire)
                {
                    float toHitFromPosition = weapon.First.GetToHitFromPosition(target, 1, shooterPosition, target.CurrentPosition, true, true, false);
                    if (toHitFromPosition < toHitFrac)
                    {
                        if (weapon.First.AmmoCategoryValue.Is_NotSet)
                        {
                            unlikelyNonAmmoWeapons.Add(weapon);
                        }
                        else
                        {
                            unlikelyAmmoWeapons.Add(weapon);
                        }
                    }
                    else
                    {
                        likelyToHitWeapons.Add(weapon);
                    }
                }
            }

            float           unlikelyWeaponChanceToHit = float.MinValue;
            CondensedWeapon weapon2 = null;

            for (int j = 0; j < unlikelyNonAmmoWeapons.Count; j++)
            {
                CondensedWeapon nonAmmoWeapon      = unlikelyNonAmmoWeapons[j];
                float           toHitFromPosition2 = nonAmmoWeapon.First.GetToHitFromPosition(target, 1, shooterPosition, target.CurrentPosition, true, true, false);
                float           weaponChanceToHit  = toHitFromPosition2 * (float)nonAmmoWeapon.First.ShotsWhenFired * nonAmmoWeapon.First.DamagePerShot;
                if (weaponChanceToHit > unlikelyWeaponChanceToHit)
                {
                    unlikelyWeaponChanceToHit = weaponChanceToHit;
                    weapon2 = nonAmmoWeapon;
                }
            }

            if (weapon2 == null)
            {
                for (int k = 0; k < unlikelyAmmoWeapons.Count; k++)
                {
                    CondensedWeapon weapon4            = unlikelyAmmoWeapons[k];
                    float           toHitFromPosition3 = weapon4.First.GetToHitFromPosition(target, 1, shooterPosition, target.CurrentPosition, true, true, false);
                    float           weaponChanceToHit  = toHitFromPosition3 * (float)weapon4.First.ShotsWhenFired * weapon4.First.DamagePerShot;
                    if (weaponChanceToHit > unlikelyWeaponChanceToHit)
                    {
                        unlikelyWeaponChanceToHit = weaponChanceToHit;
                        weapon2 = weapon4;
                    }
                }
            }

            if (weapon2 != null)
            {
                likelyToHitWeapons.Add(weapon2);
            }

            return(MakeWeaponSets(likelyToHitWeapons));
        }