private IAmmunition CreateAmmo(IAmmunitionGetter a, AmmunitionMaterial am, AmmunitionType at, string ammoName,
                                       string?ammoDesc,
                                       Action <Ammunition>?ammoFn = null, Action <Projectile>?projectileFn = null)
        {
            var na = Patch.Ammunitions.DuplicateInAsNewRecord(a);

            na.EditorID = SPrefixPatcher + SPrefixAmmunition + a.EditorID + ammoName + a.FormKey;
            na.Name     = $"{a.NameOrThrow()} - {Storage.GetOutputString(ammoName)}";

            if (ammoDesc != null)
            {
                na.Description = Storage.GetOutputString(ammoDesc);
            }

            var p  = _projectiles[na.Projectile.FormKey];
            var np = Patch.Projectiles.DuplicateInAsNewRecord(p);

            _projectiles[np.FormKey] = np;
            np.EditorID = SPrefixPatcher + SPrefixProjectile + na.EditorID + a.FormKey;
            na.Projectile.SetTo(np);

            var amod = Storage.GetAmmunitionModifiers(na).ToArray();

            projectileFn?.Invoke(np);

            if (Storage.UseWarrior)
            {
                na.Damage = at.DamageBase + am.DamageModifier + amod.Sum(m => m.DamageModifier);
                PatchProjectile(na, am, at, amod);
            }

            return(na);
        }
        private void PatchProjectile(Ammunition na, AmmunitionMaterial am, AmmunitionType at, AmmunitionModifier[] amod)
        {
            var p = Patch.Projectiles.GetOrAddAsOverride(_projectiles[na.Projectile.FormKey]);

            p.Speed   = at.SpeedBase + am.SpeedModifier + amod.Sum(m => m.SpeedModifier);
            p.Gravity = at.GravityBase + am.GravityModifier + amod.Sum(m => m.GravityModifier);
            p.Range   = at.RangeBase + am.RangeModifier + amod.Sum(m => m.RangeModifier);
        }
        private void CreateBoltVariants(IAmmunitionGetter baseAmmo, AmmunitionMaterial am, AmmunitionType at)
        {
            var strongAmmo = CreateAmmo(baseAmmo, am, at, SAmmoStrong, null);

            CreateAmmoCraftingRecipeVariants(baseAmmo, strongAmmo, new[] { IngotIron }, new[] { xMARANAdvancedMissilecraft0 });

            var strongestAmmo = CreateAmmo(baseAmmo, am, at, SAmmoStrong, null);

            CreateAmmoCraftingRecipeVariants(strongAmmo, strongestAmmo, new[] { IngotSteel }, new[] { xMARANAdvancedMissilecraft0 });

            foreach (var a in new[] { baseAmmo, strongAmmo, strongestAmmo })
            {
                var newPoisonAmmo = CreateAmmo(a, am, at, SAmmoPoison, SAmmoPoisonDesc,
                                               projectileFn: p =>
                {
                    p.Flags.SetFlag(Projectile.Flag.Explosion, true);
                    p.Flags.SetFlag(Projectile.Flag.AltTrigger, false);
                    p.Explosion.SetTo(xMAALCPoisonBurstAmmoPoisonExplosion);
                });
                CreateAmmoCraftingRecipeVariants(a, newPoisonAmmo, new[] { deathBell }, new[] { xMAALCPoisonBurst });

                var newFireAmmo = CreateAmmo(a, am, at, SAmmoFire, SAmmoFireDesc,
                                             projectileFn: p =>
                {
                    p.Flags.SetFlag(Projectile.Flag.Explosion, true);
                    p.Flags.SetFlag(Projectile.Flag.AltTrigger, false);
                    p.Explosion.SetTo(xMAALCElementalBurstExplosionFire);
                });
                CreateAmmoCraftingRecipeVariants(a, newFireAmmo, new[] { FireSalts }, new[] { xMAALCElementalBombard });

                var newFrostAmmo = CreateAmmo(a, am, at, SAmmoFrost, SAmmoFrostDesc,
                                              projectileFn: p =>
                {
                    p.Flags.SetFlag(Projectile.Flag.Explosion, true);
                    p.Flags.SetFlag(Projectile.Flag.AltTrigger, false);
                    p.Explosion.SetTo(xMAALCElementalBurstExplosionFrost);
                });
                CreateAmmoCraftingRecipeVariants(a, newFrostAmmo, new[] { FrostSalts }, new[] { xMAALCElementalBombard });

                var newShockAmmo = CreateAmmo(a, am, at, SAmmoShock, SAmmoShockDesc,
                                              projectileFn: p =>
                {
                    p.Flags.SetFlag(Projectile.Flag.Explosion, true);
                    p.Flags.SetFlag(Projectile.Flag.AltTrigger, false);
                    p.Explosion.SetTo(xMAALCElementalBurstExplosionShock);
                });
                CreateAmmoCraftingRecipeVariants(a, newShockAmmo, new[] { VoidSalts }, new[] { xMAALCElementalBombard });

                var newBarbedAmmo = CreateAmmo(a, am, at, SAmmoBarbed, SAmmoBarbedDesc,
                                               projectileFn: p =>
                {
                    p.Flags.SetFlag(Projectile.Flag.Explosion, true);
                    p.Flags.SetFlag(Projectile.Flag.AltTrigger, false);
                    p.Explosion.SetTo(xMARANAdvancedMissilecraft1BarbedExplosion);
                });
                CreateAmmoCraftingRecipeVariants(a, newBarbedAmmo,
                                                 new IFormLink <IItemGetter>[] { IngotIron, IngotSteel },
                                                 new[] { xMARANAdvancedMissilecraft1 });

                var newExplosiveAmmo = CreateAmmo(a, am, at, SAmmoExplosive, SAmmoExplosiveDesc,
                                                  projectileFn: p =>
                {
                    p.Flags.SetFlag(Projectile.Flag.Explosion, true);
                    p.Flags.SetFlag(Projectile.Flag.AltTrigger, false);
                    p.Explosion.SetTo(xMAALCAdvancedExplosivesMissileExplosion);
                });
                CreateAmmoCraftingRecipeVariants(a, newExplosiveAmmo, new IFormLink <IItemGetter>[] { Ale, LeatherStrips },
                                                 new[] { xMAALCFuse });

                var newTimebombAmmo = CreateAmmo(a, am, at, SAmmoTimebomb, SAmmoTimebombDesc,
                                                 projectileFn: p =>
                {
                    p.Flags.SetFlag(Projectile.Flag.Explosion, true);
                    p.Flags.SetFlag(Projectile.Flag.AltTrigger, true);
                    p.ExplosionAltTriggerTimer = TimebombTimer;
                    p.Explosion.SetTo(xMAALCAdvancedExplosivesMissileExplosion);
                });
                CreateAmmoCraftingRecipeVariants(a, newTimebombAmmo,
                                                 new IFormLink <IItemGetter>[] { Ale, LeatherStrips, Charcoal },
                                                 new[] { xMAALCAdvancedExplosives });
            }
        }
        private void CreateArrowVariants(IAmmunitionGetter a, AmmunitionMaterial am, AmmunitionType at)
        {
            var newPoisonAmmo = CreateAmmo(a, am, at, SAmmoPoison, SAmmoPoisonDesc,
                                           projectileFn: p =>
            {
                p.Flags.SetFlag(Projectile.Flag.Explosion, true);
                p.Flags.SetFlag(Projectile.Flag.AltTrigger, false);
                p.Explosion.SetTo(xMAALCPoisonBurstAmmoPoisonExplosion);
            });

            CreateAmmoCraftingRecipeVariants(a, newPoisonAmmo, new[] { deathBell }, new[] { xMAALCPoisonBurst });

            var newFireAmmo = CreateAmmo(a, am, at, SAmmoFire, SAmmoFireDesc,
                                         projectileFn: p =>
            {
                p.Flags.SetFlag(Projectile.Flag.Explosion, true);
                p.Flags.SetFlag(Projectile.Flag.AltTrigger, false);
                p.Explosion.SetTo(xMAALCElementalBurstExplosionFire);
            });

            CreateAmmoCraftingRecipeVariants(a, newFireAmmo, new[] { FireSalts }, new[] { xMAALCElementalBombard });

            var newFrostAmmo = CreateAmmo(a, am, at, SAmmoFrost, SAmmoFrostDesc,
                                          projectileFn: p =>
            {
                p.Flags.SetFlag(Projectile.Flag.Explosion, true);
                p.Flags.SetFlag(Projectile.Flag.AltTrigger, false);
                p.Explosion.SetTo(xMAALCElementalBurstExplosionFrost);
            });

            CreateAmmoCraftingRecipeVariants(a, newFrostAmmo, new[] { FrostSalts }, new[] { xMAALCElementalBombard });

            var newShockAmmo = CreateAmmo(a, am, at, SAmmoShock, SAmmoShockDesc,
                                          projectileFn: p =>
            {
                p.Flags.SetFlag(Projectile.Flag.Explosion, true);
                p.Flags.SetFlag(Projectile.Flag.AltTrigger, false);
                p.Explosion.SetTo(xMAALCElementalBurstExplosionShock);
            });

            CreateAmmoCraftingRecipeVariants(a, newShockAmmo, new[] { VoidSalts }, new[] { xMAALCElementalBombard });

            var newLightsourceAmmo = CreateAmmo(a, am, at, SAmmoLightsource, SAmmoLightsourceDesc,
                                                projectileFn: p =>
            {
                p.Light.SetTo(xMASNEThiefsToolboxLightsourceArrowLight);
            });

            CreateAmmoCraftingRecipeVariants(a, newLightsourceAmmo, new IFormLink <IItemGetter>[] { FireflyThorax, LeatherStrips },
                                             new[] { xMASNEThiefsToolbox0 });

            var newExplosiveAmmo = CreateAmmo(a, am, at, SAmmoExplosive, SAmmoExplosiveDesc,
                                              projectileFn: p =>
            {
                p.Flags.SetFlag(Projectile.Flag.Explosion, true);
                p.Flags.SetFlag(Projectile.Flag.AltTrigger, false);
                p.Explosion.SetTo(xMAALCAdvancedExplosivesMissileExplosion);
            });

            CreateAmmoCraftingRecipeVariants(a, newExplosiveAmmo, new IFormLink <IItemGetter>[] { Ale, LeatherStrips },
                                             new[] { xMAALCFuse });

            var newTimebombAmmo = CreateAmmo(a, am, at, SAmmoTimebomb, SAmmoTimebombDesc,
                                             projectileFn: p =>
            {
                p.Flags.SetFlag(Projectile.Flag.Explosion, true);
                p.Flags.SetFlag(Projectile.Flag.AltTrigger, true);
                p.ExplosionAltTriggerTimer = TimebombTimer;
                p.Explosion.SetTo(xMAALCAdvancedExplosivesMissileExplosion);
            });

            CreateAmmoCraftingRecipeVariants(a, newTimebombAmmo, new IFormLink <IItemGetter>[] { Ale, LeatherStrips, Charcoal },
                                             new[] { xMAALCAdvancedExplosives });
        }