示例#1
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);
        }
        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;
        }
        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);
        }
示例#4
0
        internal static ThingWithComps findBestMeleeWeapon(Pawn pawn, bool skipDangerous /*, SelectionMode mode*/, Pawn target)
        {
            List <Thing> weapons = getWeaponsOfType(pawn, WeaponSearchType.MeleeCapable);

            if (pawn.equipment != null && pawn.equipment.Primary != null)
            {
                weapons.Add(pawn.equipment.Primary);
            }
            weapons.Add(null);  //for considering unarmed attacks

            /*string candList = "";
             * foreach (Thing thing in weapons)
             *  candList += (thing == null) ? " unarmed" : " " + thing.def.defName;
             * Log.Message("Considering melee swap, candidates:"+candList);*/

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

            foreach (Thing thing in weapons)
            {
                if (skipDangerous)
                {
                    if (isDangerousWeapon(thing as ThingWithComps))
                    {
                        continue;
                    }
                }

                float dpsAvg = -1f;

                dpsAvg = StatCalculator.MeleeDPS(pawn, thing as ThingWithComps, SpeedSelectionBiasMelee.Value, target);

                /*if(thing == null)
                 *  Log.Message("DPS for unarmed is " + dpsAvg);
                 * else
                 *  Log.Message("DPS for " + thing.def.defName + " is " + dpsAvg);*/

                if (dpsAvg > bestSoFar)
                {
                    bestSoFar = dpsAvg;
                    best      = thing;
                }
            }

            /*if (best == null)
             *  Log.Message("best: unarmed");
             * else
             *  Log.Message("best: " + best.def.defName);*/

            return(best as ThingWithComps);
        }
示例#5
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);
            }
        }
示例#6
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);
        }
示例#7
0
        public static float AverageSpeedMelee(IEnumerable <Thing> options, Pawn pawn)
        {
            int   i     = 0;
            float total = 0;

            foreach (Thing thing in options)
            {
                total += StatCalculator.MeleeSpeed(thing as ThingWithComps, pawn);
                i++;
            }
            if (i > 0)
            {
                return(total / i);
            }
            else
            {
                return(0);
            }
        }
示例#8
0
        internal static ThingWithComps findBestMeleeWeapon(Pawn pawn, bool skipDangerous /*, SelectionMode mode*/, Pawn target)
        {
            List <Thing> weapons = getWeaponsOfType(pawn, WeaponSearchType.Melee);

            Thing best      = pawn.equipment.Primary;
            float bestSoFar = best == null ? float.MinValue :
                              StatCalculator.MeleeDPS(pawn, best as ThingWithComps, SpeedSelectionBiasMelee.Value, target);

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

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

                float dpsAvg = -1f;

                dpsAvg = StatCalculator.MeleeDPS(pawn, thing as ThingWithComps, SpeedSelectionBiasMelee.Value, target);

                if (dpsAvg > bestSoFar)
                {
                    bestSoFar = dpsAvg;
                    best      = thing;
                }
            }

            if (StatCalculator.MeleeDPS(pawn, null, SpeedSelectionBiasMelee.Value, target) > bestSoFar)
            {
                best = null;
            }

            return(best as ThingWithComps);
        }
示例#9
0
        public static bool findBestMeleeWeapon(Pawn pawn, out ThingWithComps result, bool includeEquipped = true, bool includeRangedWithBash = true, Pawn target = null)
        {
            result = null;
            if (pawn == null || pawn.Dead || pawn.equipment == null || pawn.inventory == null)
            {
                return(false);
            }

            IEnumerable <Thing> options = pawn.getCarriedWeapons(includeEquipped).Where(t =>
            {
                return
                (t.def.IsMeleeWeapon ||
                 (includeRangedWithBash && t.def.IsWeapon && !t.def.tools.NullOrEmpty()));
            });

            if (options.Count() < 1)
            {
                return(false);
            }

            float averageSpeed = AverageSpeedMelee(options, pawn);

            /*if (target != null)
             * {
             *  //handle DPS vs. armor?
             * }
             * else*/
            {
                float resultDPS = options.Max(t => StatCalculator.getMeleeDPSBiased(t as ThingWithComps, pawn, SpeedSelectionBiasMelee.Value, averageSpeed));
                result = options.MaxBy(t => StatCalculator.getMeleeDPSBiased(t as ThingWithComps, pawn, SpeedSelectionBiasMelee.Value, averageSpeed)) as ThingWithComps;

                //check if pawn is better when punching
                if (pawn.GetStatValue(StatDefOf.MeleeDPS) > resultDPS)
                {
                    result = null;
                }

                return(true);
            }
        }
示例#10
0
        internal static ThingWithComps findBestRangedWeapon(Pawn pawn, bool skipDangerous /*, SelectionMode mode*/)
        {
            List <Thing> 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 dpsAvg = -1f;

                if (thing.def.IsRangedWeapon)
                {
                    dpsAvg = StatCalculator.RangedDPSAverage(thing as ThingWithComps, SpeedSelectionBiasRanged.Value);
                }
                if (dpsAvg > bestSoFar)
                {
                    bestSoFar = dpsAvg;
                    best      = thing;
                }
            }

            return(best as ThingWithComps);
        }
示例#11
0
        internal static ThingWithComps findBestMeleeWeapon(Pawn pawn, bool skipDangerous, out bool unarmedIsBetter /*, SelectionMode mode*/)
        {
            List <Thing> weapons = getWeaponsOfType(pawn, WeaponSearchType.Melee);

            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 dpsAvg = -1f;

                dpsAvg = StatCalculator.MeleeDPS(pawn, thing as ThingWithComps, SpeedSelectionBiasMelee.Value);

                if (dpsAvg > bestSoFar)
                {
                    bestSoFar = dpsAvg;
                    best      = thing;
                }
            }

            unarmedIsBetter = StatCalculator.UnarmedDPS(pawn, SpeedSelectionBiasMelee.Value) > bestSoFar;

            return(best as ThingWithComps);
        }
示例#12
0
 public static IEnumerable <ThingStuffPair> getValidSidearms()
 {
     return(getValidWeapons().Where(w => StatCalculator.isValidSidearm(w, out _)));
 }