private static short CalculateRemainingAmmo(Agent agent)
        {
            MissionWeapon weaponFromSlot0 = agent.Equipment[EquipmentIndex.Weapon0];
            short         ammoFromSlot0   = weaponFromSlot0.Equals(MissionWeapon.Invalid) || weaponFromSlot0.IsShield() ? (short)0 : weaponFromSlot0.Amount;
            MissionWeapon weaponFromSlot1 = agent.Equipment[EquipmentIndex.Weapon1];
            short         ammoFromSlot1   = weaponFromSlot1.Equals(MissionWeapon.Invalid) || weaponFromSlot1.IsShield() ? (short)0 : weaponFromSlot1.Amount;
            MissionWeapon weaponFromSlot2 = agent.Equipment[EquipmentIndex.Weapon2];
            short         ammoFromSlot2   = weaponFromSlot2.Equals(MissionWeapon.Invalid) || weaponFromSlot2.IsShield() ? (short)0 : weaponFromSlot2.Amount;
            MissionWeapon weaponFromSlot3 = agent.Equipment[EquipmentIndex.Weapon3];
            short         ammoFromSlot3   = weaponFromSlot3.Equals(MissionWeapon.Invalid) || weaponFromSlot3.IsShield() ? (short)0 : weaponFromSlot3.Amount;
            MissionWeapon weaponFromSlot4 = agent.Equipment[EquipmentIndex.Weapon4];
            short         ammoFromSlot4   = weaponFromSlot4.Equals(MissionWeapon.Invalid) || weaponFromSlot4.IsShield() ? (short)0 : weaponFromSlot4.Amount;

            return((short)(ammoFromSlot0 + ammoFromSlot1 + ammoFromSlot2 + ammoFromSlot3 + ammoFromSlot4));
        }
            static bool Prefix(Agent __instance)
            {
                ArrayList     stringRangedWeapons = new ArrayList();
                MissionWeapon arrow           = MissionWeapon.Invalid;
                bool          firstProjectile = true;

                for (EquipmentIndex equipmentIndex = EquipmentIndex.WeaponItemBeginSlot; equipmentIndex < EquipmentIndex.NumAllWeaponSlots; equipmentIndex++)
                {
                    if (__instance.Equipment != null && !__instance.Equipment[equipmentIndex].IsEmpty)
                    {
                        WeaponStatsData[] wsd = __instance.Equipment[equipmentIndex].GetWeaponStatsData();
                        if ((wsd[0].WeaponClass == (int)WeaponClass.Bow) || (wsd[0].WeaponClass == (int)WeaponClass.Crossbow))
                        {
                            stringRangedWeapons.Add(__instance.Equipment[equipmentIndex]);
                        }
                        if ((wsd[0].WeaponClass == (int)WeaponClass.Arrow) || (wsd[0].WeaponClass == (int)WeaponClass.Bolt))
                        {
                            if (firstProjectile)
                            {
                                arrow           = __instance.Equipment[equipmentIndex];
                                firstProjectile = false;
                            }
                        }
                        if ((wsd[0].WeaponClass == (int)WeaponClass.OneHandedPolearm) || (wsd[0].WeaponClass == (int)WeaponClass.LowGripPolearm))
                        {
                            for (int i = 0; i < wsd.Length; i++)
                            {
                                if (wsd[i].MissileSpeed != 0)
                                {
                                    Utilities.assignThrowableMissileSpeed(__instance.Equipment[equipmentIndex], i, 5);
                                }
                            }
                        }
                        if (wsd[0].WeaponClass == (int)WeaponClass.Javelin)
                        {
                            for (int i = 0; i < wsd.Length; i++)
                            {
                                if (wsd[i].MissileSpeed != 0)
                                {
                                    Utilities.assignThrowableMissileSpeed(__instance.Equipment[equipmentIndex], i, 10);
                                }
                            }
                        }
                        if ((wsd[0].WeaponClass == (int)WeaponClass.ThrowingAxe) || (wsd[0].WeaponClass == (int)WeaponClass.ThrowingKnife))
                        {
                            for (int i = 0; i < wsd.Length; i++)
                            {
                                if (wsd[i].MissileSpeed != 0)
                                {
                                    Utilities.assignThrowableMissileSpeed(__instance.Equipment[equipmentIndex], i, 0);
                                }
                            }
                        }
                        if (wsd[0].WeaponClass == (int)WeaponClass.Stone)
                        {
                            for (int i = 0; i < wsd.Length; i++)
                            {
                                if (wsd[i].MissileSpeed != 0)
                                {
                                    Utilities.assignStoneMissileSpeed(__instance.Equipment[equipmentIndex], i);
                                }
                            }
                        }
                    }
                }
                foreach (MissionWeapon missionWeapon in stringRangedWeapons)
                {
                    int calculatedMissileSpeed = 50;
                    if (!missionWeapon.Equals(MissionWeapon.Invalid) && !arrow.Equals(MissionWeapon.Invalid))
                    {
                        if (missionWeapon.ItemModifier != null)
                        {
                            FieldInfo field = typeof(ItemModifier).GetField("_missileSpeed", BindingFlags.NonPublic | BindingFlags.Instance);
                            field.DeclaringType.GetField("_missileSpeed");
                            int missileSpeedModifier = (int)field.GetValue(missionWeapon.ItemModifier);

                            _oldMissileSpeeds.Add(missionWeapon.GetModifiedMissileSpeedForUsage(0) - missileSpeedModifier);
                        }
                        else
                        {
                            _oldMissileSpeeds.Add(missionWeapon.GetModifiedMissileSpeedForUsage(0));
                        }
                        float ammoWeight = arrow.GetWeight() / arrow.Amount;
                        calculatedMissileSpeed = Utilities.calculateMissileSpeed(ammoWeight, missionWeapon, missionWeapon.GetModifiedMissileSpeedForUsage(0));

                        PropertyInfo property = typeof(WeaponComponentData).GetProperty("MissileSpeed");
                        property.DeclaringType.GetProperty("MissileSpeed");
                        property.SetValue(missionWeapon.CurrentUsageItem, calculatedMissileSpeed, BindingFlags.NonPublic | BindingFlags.SetProperty, null, null, null);
                    }
                    else if (!missionWeapon.Equals(MissionWeapon.Invalid))
                    {
                        if (missionWeapon.ItemModifier != null)
                        {
                            FieldInfo field = typeof(ItemModifier).GetField("_missileSpeed", BindingFlags.NonPublic | BindingFlags.Instance);
                            field.DeclaringType.GetField("_missileSpeed");
                            int missileSpeedModifier = (int)field.GetValue(missionWeapon.ItemModifier);

                            _oldMissileSpeeds.Add(missionWeapon.GetModifiedMissileSpeedForUsage(0) - missileSpeedModifier);
                        }
                        else
                        {
                            _oldMissileSpeeds.Add(missionWeapon.GetModifiedMissileSpeedForUsage(0));
                        }
                        PropertyInfo property = typeof(WeaponComponentData).GetProperty("MissileSpeed");
                        property.DeclaringType.GetProperty("MissileSpeed");
                        property.SetValue(missionWeapon.CurrentUsageItem, calculatedMissileSpeed, BindingFlags.NonPublic | BindingFlags.SetProperty, null, null, null);
                    }
                }

                return(true);
            }