internal static bool trySwapToMoreAccurateRangedWeapon(Pawn pawn, bool dropCurrent, float range, bool skipDangerous)
        {
            if (pawn.Dead)
                return false;
            Thing betterWeapon = null;
            float betterDPS;
            
            if (pawn.inventory.innerContainer.Any((Thing x) => x.def.IsRangedWeapon))
            {
                betterWeapon = GettersFilters.findBestRangedWeaponAtRanged(pawn, range, skipDangerous, out betterDPS);
            }
            else
            {
                return false;
            }
            if (betterWeapon == null)
                return false;

            float currentDPS = StatCalculator.RangedDPS(pawn.equipment.Primary, SpeedSelectionBiasRanged.Value, range);

            if (betterDPS < currentDPS + ANTI_OSCILLATION_FACTOR)
                return false;

            if (betterWeapon is ThingWithComps)
            {
                SetPrimary(pawn, betterWeapon, false, true, dropCurrent, false);

                return true;
            }
            return false;
        }
Esempio n. 2
0
        internal static ThingWithComps findBestRangedWeaponAtRanged(Pawn pawn, float range, bool skipDangerous, out float resultDPS)
        {
            List <Thing> weapons;

            weapons = getWeaponsOfType(pawn, WeaponSearchType.Ranged);

            float bestSoFar = float.MinValue;
            Thing best      = null;

            foreach (Thing thing in weapons)
            {
                if (!(thing is ThingWithComps))
                {
                    continue;
                }

                if (skipDangerous)
                {
                    if (isDangerousWeapon(thing as ThingWithComps))
                    {
                        continue;
                    }
                }

                float DPS = StatCalculator.RangedDPS(thing as ThingWithComps, SpeedSelectionBiasRanged.Value, range);

                if (DPS > bestSoFar)
                {
                    bestSoFar = DPS;
                    best      = thing;
                }
            }
            resultDPS = bestSoFar;
            return(best as ThingWithComps);
        }
        public static bool trySwapToMoreAccurateRangedWeapon(Pawn pawn, LocalTargetInfo target, bool dropCurrent, bool skipDangerous = true)
        {
            GoldfishModule pawnMemory = GoldfishModule.GetGoldfishForPawn(pawn);

            if (pawn == null || pawn.Dead || pawnMemory == null || pawn.equipment == null || pawn.inventory == null)
            {
                return(false);
            }

            if (pawnMemory.IsCurrentWeaponForced(false))
            {
                return(false);
            }

            (ThingWithComps weapon, float dps, float averageSpeed)bestWeapon = GettersFilters.findBestRangedWeapon(pawn, target, skipDangerous, true);

            if (bestWeapon.weapon == null)
            {
                return(false);
            }

            CellRect cellRect   = (!target.HasThing) ? CellRect.SingleCell(target.Cell) : target.Thing.OccupiedRect();
            float    range      = cellRect.ClosestDistSquaredTo(pawn.Position);
            float    currentDPS = StatCalculator.RangedDPS(pawn.equipment.Primary, SpeedSelectionBiasRanged.Value, bestWeapon.averageSpeed, range);

            if (bestWeapon.dps < currentDPS + ANTI_OSCILLATION_FACTOR)
            {
                return(false);
            }

            equipSpecificWeaponFromInventory(pawn, bestWeapon.weapon, dropCurrent, false);
            return(true);
        }
Esempio n. 4
0
        public static (ThingWithComps weapon, float dps, float averageSpeed) findBestRangedWeapon(Pawn pawn, LocalTargetInfo?target = null, bool skipDangerous = true, bool includeEquipped = true)
        {
            if (pawn == null || pawn.Dead || pawn.equipment == null || pawn.inventory == null)
            {
                return(null, -1, 0);
            }

            IEnumerable <ThingWithComps> options = pawn.getCarriedWeapons(includeEquipped).Where(t =>
            {
                return(t.def.IsRangedWeapon);
            });

            if (options.Count() == 0)
            {
                return(null, -1, 0);
            }

            float averageSpeed = AverageSpeedRanged(options);

            if (target.HasValue)
            {
                //TODO: handle DPS vs. armor?
                CellRect cellRect = (!target.Value.HasThing) ? CellRect.SingleCell(target.Value.Cell) : target.Value.Thing.OccupiedRect();
                float    range    = cellRect.ClosestDistSquaredTo(pawn.Position);
                (ThingWithComps thing, float dps, float averageSpeed)best = (null, -1, averageSpeed);
                foreach (ThingWithComps candidate in options)
                {
                    float dps = StatCalculator.RangedDPS(candidate, SpeedSelectionBiasRanged.Value, averageSpeed, range);
                    if (dps > best.dps)
                    {
                        best = (candidate, dps, averageSpeed);
                    }
                }
                return(best);
            }
            else
            {
                (ThingWithComps thing, float dps, float averageSpeed)best = (null, -1, averageSpeed);
                foreach (ThingWithComps candidate in options)
                {
                    float dps = StatCalculator.RangedDPSAverage(candidate, SpeedSelectionBiasRanged.Value, averageSpeed);
                    if (dps > best.dps)
                    {
                        best = (candidate, dps, averageSpeed);
                    }
                }
                return(best);
            }
        }
Esempio n. 5
0
        internal static bool trySwapToMoreAccurateRangedWeapon(Pawn pawn, bool dropCurrent, float range, bool skipDangerous)
        {
            //Log.Message("attempting swap");
            if (pawn.Dead)
            {
                return(false);
            }
            Thing betterWeapon = null;
            float betterDPS;

            //Log.Message("looking for ranged weapon in inventory");
            if (pawn.inventory.innerContainer.Any((Thing x) => x.def.IsRangedWeapon))
            {
                //Log.Message("found ranged weapon in inventory");
                betterWeapon = GettersFilters.findBestRangedWeaponAtRanged(pawn, range, skipDangerous, out betterDPS);
            }
            else
            {
                return(false);
            }
            if (betterWeapon == null)
            {
                return(false);
            }

            float currentDPS = StatCalculator.RangedDPS(pawn.equipment.Primary, SpeedSelectionBiasRanged.Value, range);

            //Log.Message("current DPS is "+currentDPS+ " ("+pawn.equipment.Primary.LabelShort+")");
            //Log.Message("best sidearm DPS is " + betterDPS + " (" + betterWeapon.LabelShort + ")");

            if (betterDPS < currentDPS + ANTI_OSCILLATION_FACTOR)
            {
                return(false);
            }

            //Log.Message("sorted out best (" + best.LabelShort + ")");

            if (betterWeapon is ThingWithComps)
            {
                //Log.Message("converted to ThingWithComps");

                SetPrimary(pawn, betterWeapon, false, true, dropCurrent, false);

                return(true);
            }
            return(false);
        }