예제 #1
0
        public void Generate(Map map)
        {
            this.map = map;

            map.Entities.Clear();
            map.Spawns.Clear();

            map.IsAutospawn = true;
            map.Music       = "Overworld";
            map.SeaLevel    = map.Height / 5;

            Utility.StatusMessage = "Let there be space.";
            map.Materials         = new byte[map.Width * map.Height];

            Utility.StatusMessage = "Let there be air.";
            map.Fill(Material.Air, new Rectangle(0, 0, map.Width, map.SeaLevel));

            Utility.StatusMessage = "Let there be dirt.";
            var dirtLevel       = map.SeaLevel;
            var clayHeight      = dirtLevel + 200;
            var sandstoneHeight = map.GetTierAltitude(2) / Map.BlockHeight;
            var sectionHeight   = (map.Height - sandstoneHeight) / 7;
            var limestoneHeight = map.GetTierAltitude(3) / Map.BlockHeight;
            var quartziteHeight = map.GetTierAltitude(4) / Map.BlockHeight;
            var graniteHeight   = map.GetTierAltitude(5) / Map.BlockHeight;
            var marbleHeight    = map.GetTierAltitude(6) / Map.BlockHeight;
            var rhyoliteHeight  = map.GetTierAltitude(7) / Map.BlockHeight;
            var basaltHeight    = map.GetTierAltitude(8) / Map.BlockHeight;

            map.Fill(Material.Dirt, new Rectangle(0, dirtLevel, map.Width, 200));

            Utility.StatusMessage = "Let there be clay.";
            map.Fill(Material.Clay, new Rectangle(0, clayHeight, map.Width, 300));
            Utility.StatusMessage = "Let there be sandstone.";
            map.Fill(Material.Sandstone, new Rectangle(0, sandstoneHeight, map.Width, sectionHeight));
            Utility.StatusMessage = "Let there be limestone.";
            map.Fill(Material.Limestone, new Rectangle(0, limestoneHeight, map.Width, sectionHeight));
            Utility.StatusMessage = "Let there be granite.";
            map.Fill(Material.Quartzite, new Rectangle(0, quartziteHeight, map.Width, sectionHeight));
            Utility.StatusMessage = "Let there be quartzite.";
            map.Fill(Material.Granite, new Rectangle(0, graniteHeight, map.Width, sectionHeight));
            Utility.StatusMessage = "Let there be marble.";
            map.Fill(Material.Marble, new Rectangle(0, marbleHeight, map.Width, sectionHeight));
            Utility.StatusMessage = "Let there be rhyolite.";
            map.Fill(Material.Rhyolite, new Rectangle(0, rhyoliteHeight, map.Width, sectionHeight));
            Utility.StatusMessage = "Let there be basalt.";
            map.Fill(Material.Basalt, new Rectangle(0, basaltHeight, map.Width, sectionHeight));

            Utility.StatusMessage = "Let there be rough terrain.";
            map.CreateHills(Material.Clay, Material.Dirt, clayHeight, 3 * VerticalScale);
            map.CreateHills(Material.Sandstone, Material.Clay, sandstoneHeight, 3 * VerticalScale);
            map.CreateHills(Material.Limestone, Material.Sandstone, limestoneHeight, 6 * VerticalScale);
            map.CreateHills(Material.Quartzite, Material.Limestone, quartziteHeight, 6 * VerticalScale);
            map.CreateHills(Material.Granite, Material.Quartzite, graniteHeight, 6 * VerticalScale);
            map.CreateHills(Material.Marble, Material.Granite, marbleHeight, 6 * VerticalScale);
            map.CreateHills(Material.Rhyolite, Material.Marble, rhyoliteHeight, 3 * VerticalScale);

            Utility.StatusMessage = "Let there be hills and lakes.";
            map.CreateHills(Material.Dirt, Material.Water, dirtLevel, 200, -200, 200, -200);

            map.SprinkleVeins(Material.Clay, dirtLevel - 500, clayHeight, 10000, 50, Brush.Size7);
            map.SprinkleVeins(Material.Sandstone, clayHeight, sandstoneHeight, 10000, 50, Brush.Size7);
            map.SprinkleVeins(Material.Limestone, sandstoneHeight, limestoneHeight, 10000, 50, Brush.Size7);
            map.SprinkleVeins(Material.Quartzite, limestoneHeight, quartziteHeight, 10000, 50, Brush.Size7);
            map.SprinkleVeins(Material.Granite, quartziteHeight, graniteHeight, 10000, 50, Brush.Size7);
            map.SprinkleVeins(Material.Marble, graniteHeight, marbleHeight, 10000, 50, Brush.Size7);
            map.SprinkleVeins(Material.Rhyolite, marbleHeight, rhyoliteHeight, 10000, 50, Brush.Size7);
            map.SprinkleVeins(Material.Basalt, rhyoliteHeight, basaltHeight, 10000, 50, Brush.Size7);
            map.SprinkleVeins(Material.Lava, basaltHeight, map.Height, 10000, 50, Brush.Size7);

            Utility.StatusMessage = "Let there be lava.";
            var topLavaHeight = basaltHeight - 5 * VerticalScale;

            map.LavaLevel = topLavaHeight;
            map.Fill(Material.Lava, new Rectangle(0, topLavaHeight, map.Width, 5 * VerticalScale));
            var bottomLavaHeight = map.Height - 5 * VerticalScale;

            map.Fill(Material.Lava, new Rectangle(0, bottomLavaHeight, map.Width, 5 * VerticalScale));
            map.CreateHills(Material.Lava, Material.Rhyolite, topLavaHeight, 4 * VerticalScale);
            map.CreateHills(Material.Basalt, Material.Lava, basaltHeight, 4 * VerticalScale);
            map.CreateHills(Material.Lava, Material.Basalt, bottomLavaHeight, 6 * VerticalScale);

            map.SprinkleVeins(Material.Water, clayHeight, rhyoliteHeight, 250000, 100, Brush.Size9);
            map.SprinkleVeins(Material.Gravel, map.SeaLevel + 100, rhyoliteHeight, 250000, 50, Brush.Size9);
            map.SprinkleVeins(Material.Lava, marbleHeight, map.Height, 150000, 100, Brush.Size9);

            map.SprinkleVeins(Material.PoisonGas, marbleHeight, map.Height, 150000, 300, Brush.Size9);
            map.SprinkleVeins(Material.Oil, marbleHeight, map.Height, 150000, 150, Brush.Size9);

            Utility.StatusMessage = "Let there be floating islands.";
            map.SprinkleVeins(Material.Dirt, 100, sectionHeight, 125000, 350, Brush.Size10,
                              (position) => {
                if (!Utility.Roll8())
                {
                    AddRandomSpawns(position, true);
                }

                if (Utility.Roll4())
                {
                    var chestPosition = map.FindGround(new Vector2(position.X, 0)) + new Vector2(0, -50);
                    var chest         = map.AddPlaceable(null, ItemBase.Get(ItemId.WorldHypercube), chestPosition);

                    var tier = 3;

                    chest.AddItem(GenerateRandomItem(tier));
                    chest.AddItem(GenerateRandomItem(tier));
                    chest.AddItem(GenerateRandomItem(tier));
                    chest.AddItem(GenerateRandomItem(tier));
                    chest.AddItem(GenerateRandomItem(tier));
                }
            },
                              false
                              );

            Utility.StatusMessage = "Let there be caves.";
            map.SprinkleVeins(Material.Air, map.SeaLevel - 300, map.Height, 50000, 450, Brush.Size9,
                              (position) => {
                if (Utility.Flip())
                {
                    map.AddPlaceable(null, ItemBase.Get(ItemId.LightOrb), position);
                }

                if (!Utility.Roll8())
                {
                    AddRandomSpawns(position);
                }

                if (Utility.Roll4())
                {
                    var chest = map.AddPlaceable(null, ItemBase.Get(ItemId.WorldHypercube), position);

                    var tier = map.GetTier(position);

                    chest.AddItem(GenerateRandomItem(tier));
                    chest.AddItem(GenerateRandomItem(tier));
                    chest.AddItem(GenerateRandomItem(tier));
                    chest.AddItem(GenerateRandomItem(tier));
                    chest.AddItem(GenerateRandomItem(tier));
                }
            }
                              );

            map.StartingPosition = new Vector2(map.PixelWidth / 2, (sectionHeight * Map.BlockHeight) + 1200); // add 1200 here so that spawn won't catch an island right in the center as it descends down.

            map.StartingPosition = map.FindGround(map.StartingPosition);
            map.StartingPosition = new Vector2(map.StartingPosition.X, map.StartingPosition.Y - 200f);
            AddPortal(map.StartingPosition, Material.Bone).Remove();

            var portal = AddPortal(new Vector2(map.StartingPosition.X, map.SeaLevelInPixels), Material.Bone);

            portal.Name  = "Dungeon Tier 2";
            portal.Value = "KrawnixLair";
            map.AddEntity(new Placeable()
            {
                TypeId = ItemId.Workbench, Position = portal.Position + new Vector2(-80, 50)
            });

            portal       = AddPortal(new Vector2(Utility.Next(1000, map.PixelWidth - 1000), map.GetTierAltitude(3) - Utility.Next(300, sectionHeight * Map.BlockHeight - 300)), Material.Bone);
            portal.Name  = "Dungeon Tier 3";
            portal.Value = "Botanica";

            var skyPortalIslandPosition = new Vector2(Utility.Next(1000, map.PixelWidth - 1000), Utility.Next(500, sectionHeight * Map.BlockHeight - 100));

            map.CreateVein(Material.Dirt, skyPortalIslandPosition, 350, Brush.Size10, false);
            skyPortalIslandPosition = map.FindGround(skyPortalIslandPosition);
            portal       = AddPortal(skyPortalIslandPosition + new Vector2(0, -50), Material.Bone);
            portal.Name  = "Dungeon Tier 4";
            portal.Value = "SkyRealm";

            portal       = AddPortal(new Vector2(Utility.Next(1000, map.PixelWidth - 1000), map.GetTierAltitude(5) - Utility.Next(300, sectionHeight * Map.BlockHeight - 300)), Material.Bone);
            portal.Name  = "Dungeon Tier 5";
            portal.Value = "Oberon";

            portal       = AddPortal(new Vector2(Utility.Next(1000, map.PixelWidth - 1000), map.GetTierAltitude(6) - Utility.Next(300, sectionHeight * Map.BlockHeight - 300)), Material.Bone);
            portal.Name  = "Dungeon Tier 6";
            portal.Value = "CaveDive";

            portal       = AddPortal(new Vector2(Utility.Next(1000, map.PixelWidth - 1000), map.GetTierAltitude(7) - Utility.Next(300, sectionHeight * Map.BlockHeight - 300)), Material.Bone);
            portal.Name  = "Dungeon Tier 7";
            portal.Value = "Burrower";

            portal       = AddPortal(new Vector2(Utility.Next(1000, map.PixelWidth - 1000), map.GetTierAltitude(8) - Utility.Next(300, sectionHeight * Map.BlockHeight - 300)), Material.Bone);
            portal.Name  = "Dungeon Tier 8";
            portal.Value = "Vesuvius";

            portal       = AddPortal(new Vector2(Utility.Next(1000, map.PixelWidth - 1000), map.GetTierAltitude(8) + Utility.Next(300, sectionHeight * Map.BlockHeight - 300)), Material.Bone);
            portal.Name  = "Dungeon Tier 9";
            portal.Value = "FinalBoss";

            Utility.StatusMessage = "Let there be grass, snow and thin strips of terrain to hold up the oceans.";
            for (var y = 0; y < map.Height; y++)
            {
                var levelMaterial = Material.Dirt;
                if (y > clayHeight)
                {
                    levelMaterial = Material.Clay;
                }
                if (y > sandstoneHeight)
                {
                    levelMaterial = Material.Sandstone;
                }
                if (y > limestoneHeight)
                {
                    levelMaterial = Material.Limestone;
                }
                if (y > quartziteHeight)
                {
                    levelMaterial = Material.Quartzite;
                }
                if (y > graniteHeight)
                {
                    levelMaterial = Material.Granite;
                }
                if (y > marbleHeight)
                {
                    levelMaterial = Material.Marble;
                }
                if (y > rhyoliteHeight)
                {
                    levelMaterial = Material.Rhyolite;
                }
                if (y > map.LavaLevel + 25)
                {
                    levelMaterial = Material.Basalt;
                }

                for (var x = 0; x < map.Width; x++)
                {
                    var material = map.GetMaterial(x, y);
                    if (MaterialInfo.IsLiquid(material))
                    {
                        if (MaterialInfo.IsGas(map.GetMaterial(x, y + 1)))
                        {
                            map.SetMaterial(x, y + 1, levelMaterial);
                        }
                        if (MaterialInfo.IsGas(map.GetMaterial(x - 1, y)))
                        {
                            map.SetMaterial(x - 1, y, levelMaterial);
                        }
                        if (MaterialInfo.IsGas(map.GetMaterial(x + 1, y)))
                        {
                            map.SetMaterial(x + 1, y, levelMaterial);
                        }
                    }
                    else
                    {
                        // this is my horrible attempt at erosion.
                        //var adjacent = IsAdjacent(x, y, Material.Air);
                        //if (adjacent != Direction.Up && adjacent != Direction.Left && adjacent != Direction.None)
                        //{
                        //    SetMaterial(x, y, Material.Air);
                        //    continue;
                        //}

                        switch (material)
                        {
                        case Material.Dirt:
                            if (map.GetMaterial(x, y - 1) == Material.Air)
                            {
                                if (y < map.SeaLevel + 15)
                                {
                                    map.SetMaterial(x, y, Material.Grass);
                                    if (y < map.SeaLevel - 50)
                                    {
                                        map.SetMaterial(x, y - 1, Material.Snow);
                                        if (Utility.Flip())
                                        {
                                            map.SetMaterial(x, y - 2, Material.Snow);
                                        }
                                    }
                                }
                            }
                            //else
                            //{
                            //    if (GetMaterial(x, y - 1) == Material.Water)
                            //        SetMaterial(x, y, Material.Mud);
                            //}
                            break;
                        }
                    }
                }
            }

            Utility.StatusMessage = "Let there be sandy beaches.";
            const int beachWidth  = 600;
            const int beachHeight = 10;

            for (int i = 0; i < beachWidth; i++)
            {
                var ground = map.FindGround(new Vector2(i * Map.BlockWidth, map.SeaLevelInPixels - sectionHeight / 2 * Map.BlockHeight));
                for (int y = 0; y < beachHeight; y++)
                {
                    map.SetMaterialAtPixel(ground + new Vector2(0, -Map.BlockHeight * y), Material.Sand);
                }
            }
            for (int i = map.Width - 420; i < map.Width; i++)
            {
                var ground = map.FindGround(new Vector2(i * Map.BlockWidth, map.SeaLevelInPixels - sectionHeight / 2 * Map.BlockHeight));
                for (int y = 0; y < beachHeight; y++)
                {
                    map.SetMaterialAtPixel(ground + new Vector2(0, -Map.BlockHeight * y), Material.Sand);
                }
            }

            map.WallMaterials = (byte[])map.Materials.Clone();
            for (int i = 0; i < map.WallMaterials.Length; i++)
            {
                if (map.WallMaterials[i] == (byte)Material.Water)
                {
                    map.WallMaterials[i] = (byte)Material.Dirt;
                }
            }

            Utility.StatusMessage = "Let there be coal.";
            map.SprinkleVeins(Material.Coal, map.SeaLevel - 300, map.Height, 50000, 50, Brush.Size4);
            Utility.StatusMessage = "Let there be iron.";
            map.SprinkleVeins(Material.IronOre, map.SeaLevel - 300, map.SeaLevel + sectionHeight * 5, 10000, 100);
            Utility.StatusMessage = "Let there be aluminum.";
            map.SprinkleVeins(Material.AluminumOre, sandstoneHeight, sandstoneHeight + sectionHeight * 5, 15000, 100);
            Utility.StatusMessage = "Let there be copper.";
            map.SprinkleVeins(Material.CopperOre, sandstoneHeight, sandstoneHeight + sectionHeight * 2, 15000, 100);
            Utility.StatusMessage = "Let there be silver.";
            map.SprinkleVeins(Material.SilverOre, limestoneHeight, limestoneHeight + sectionHeight * 2, 15000, 100);
            Utility.StatusMessage = "Let there be gold.";
            map.SprinkleVeins(Material.GoldOre, quartziteHeight, graniteHeight + sectionHeight * 2, 15000, 100);
            Utility.StatusMessage = "Let there be dilithium.";
            map.SprinkleVeins(Material.Dilithium, graniteHeight, quartziteHeight + sectionHeight * 2, 15000, 40);
            Utility.StatusMessage = "Let there be radium.";
            map.SprinkleVeins(Material.RadiumOre, marbleHeight, marbleHeight + sectionHeight * 2, 15000, 40);
            Utility.StatusMessage = "Let there be uranium.";
            map.SprinkleVeins(Material.UraniumOre, basaltHeight, map.Height, 10000, 20);

            Utility.StatusMessage = "Let there be sodium.";
            map.SprinkleVeins(Material.Sodium, map.SeaLevel - 300, map.SeaLevel + sectionHeight * 4, 20000, 30);

            Utility.StatusMessage = "Let there be sulpher.";
            map.SprinkleVeins(Material.Sulfur, clayHeight, clayHeight + sectionHeight * 3, 25000, 20);
            Utility.StatusMessage = "Let there be topaz.";
            map.SprinkleVeins(Material.Topaz, sandstoneHeight, sandstoneHeight + sectionHeight, 25000, 20);
            Utility.StatusMessage = "Let there be amethyst.";
            map.SprinkleVeins(Material.Amethyst, limestoneHeight, limestoneHeight + sectionHeight, 25000, 20);
            Utility.StatusMessage = "Let there be emerald.";
            map.SprinkleVeins(Material.Emerald, quartziteHeight, quartziteHeight + sectionHeight, 25000, 20);
            Utility.StatusMessage = "Let there be sapphire.";
            map.SprinkleVeins(Material.Sapphire, graniteHeight, graniteHeight + sectionHeight, 25000, 20);
            Utility.StatusMessage = "Let there be rubies.";
            map.SprinkleVeins(Material.Ruby, marbleHeight, marbleHeight + sectionHeight, 25000, 20);
            Utility.StatusMessage = "Let there be diamonds.";
            map.SprinkleVeins(Material.Diamond, rhyoliteHeight, rhyoliteHeight + sectionHeight * 2, 25000, 20);

            foreach (var player in map.Players)
            {
                map.Entities.Add(player);
                player.Respawn();
            }

            // so that entities actually get saved
            map.FlushEntities();

            Utility.StatusMessage = "";
        }
예제 #2
0
        public static void RegisterProjectiles()
        {
            ProjectileBase.AddType(new ProjectileType()
            {
                Id = ProjectileId.DigSmall, UseTierParticleColor = true, IsSlowBloom = true, InitialParticleBurst = 10, DigBrush = Brush.Size4, MaxAge = 600, Speed = 500, FireSound = Sound.MiningToolFire, TechName = "Mining Tool", UseTierTextures = true
            });
            ProjectileBase.AddType(new ProjectileType()
            {
                Id = ProjectileId.DigMedium, UseTierParticleColor = true, IsSlowBloom = true, InitialParticleBurst = 10, DigBrush = Brush.Size6, MaxAge = 600, Speed = 520, FireSound = Sound.MiningToolFire, TechName = "Mining Tool", UseTierTextures = true
            });
            ProjectileBase.AddType(new ProjectileType()
            {
                Id = ProjectileId.DigLarge, UseTierParticleColor = true, IsSlowBloom = true, InitialParticleBurst = 10, DigBrush = Brush.Size7, MaxAge = 600, Speed = 540, FireSound = Sound.MiningToolFire, TechName = "Mining Tool", UseTierTextures = true,
            });
            ProjectileBase.AddType(new ProjectileType()
            {
                Id = ProjectileId.DigExtraLarge, UseTierParticleColor = true, IsSlowBloom = true, InitialParticleBurst = 10, DigBrush = Brush.Size9, MaxAge = 600, Speed = 560, FireSound = Sound.MiningToolFire, TechName = "Mining Tool", UseTierTextures = true,
            });

            ProjectileBase.AddType(new ProjectileType()
            {
                Id                   = ProjectileId.Blaster,
                BaseDamage           = 5,
                MaxAge               = 600,
                Speed                = 750,
                InitialParticleBurst = 10,
                UseTierParticleColor = true,
                UseTierTextures      = true,
                ParticleStream       = true,
                FireSound            = Sound.BlasterFire,
                HitSound             = Sound.BlasterHit,
                Knockback            = 1000,
            });

            var blasterCharged = ProjectileBase.Get(ProjectileId.Blaster).Clone();

            blasterCharged.Name            = null;
            blasterCharged.Id              = ProjectileId.BlasterCharged;
            blasterCharged.BaseDamage      = 20;
            blasterCharged.Speed           = 1000;
            blasterCharged.Knockback       = 10;
            blasterCharged.UseTierTextures = true;
            blasterCharged.FireSound       = Sound.BlasterChargedFire;
            ProjectileBase.AddType(blasterCharged);

            var slowBlaster = ProjectileBase.Get(ProjectileId.Blaster).Clone();

            slowBlaster.TechName        = slowBlaster.Name;
            slowBlaster.Name            = null;
            slowBlaster.Id              = ProjectileId.SlowBlaster;
            slowBlaster.UseTierTextures = false;
            slowBlaster.BaseDamage      = 8;
            slowBlaster.Speed           = 300;
            slowBlaster.MaxAge          = 6000;
            ProjectileBase.AddType(slowBlaster);

            ProjectileBase.AddType(new ProjectileType()
            {
                Id                   = ProjectileId.LongRangeBlaster,
                BaseDamage           = 4,
                MaxAge               = 4000,
                Speed                = 650,
                Penetrate            = true,
                InitialParticleBurst = 10,
                UseTierParticleColor = true,
                //UseTierTextures = true,
                FireSound = Sound.BlasterFire,
                HitSound  = Sound.BlasterHit,
            });

            ProjectileBase.AddType(new ProjectileType()
            {
                Id                   = ProjectileId.BallLightning,
                BaseDamage           = 20,
                MaxAge               = 6000,
                Speed                = 500,
                Penetrate            = true,
                InitialParticleBurst = 10,
                ParticleColor        = Color.LightBlue,
                HitSound             = Sound.ElectricityHit,
            });

            ProjectileBase.AddType(new ProjectileType()
            {
                Id                   = ProjectileId.Disruptor,
                BaseDamage           = 6,
                MaxAge               = 200,
                Speed                = 750,
                InitialParticleBurst = 5,
                UseTierTextures      = true,
                UseTierParticleColor = true,
                FireSound            = Sound.DisruptorFire,
                HitSound             = Sound.DisruptorHit,
            });

            ProjectileBase.AddType(new ProjectileType()
            {
                Id         = ProjectileId.LaserRifle,
                BaseDamage = 13,
                MaxAge     = 1000,
                Speed      = 1000,
                //CoolDown = 500,
                InitialParticleBurst = 15,
                UseTierTextures      = true,
                UseTierParticleColor = true,
                FireSound            = Sound.LaserRifleFire,
                HitSound             = Sound.LaserRifleHit,
            });

            ProjectileBase.AddType(new ProjectileType()
            {
                Id                   = ProjectileId.PoisonDart,
                BaseDamage           = 5,
                MaxAge               = 2000,
                Speed                = 700,
                InitialParticleBurst = 10,
                ParticleColor        = Color.Green,
                FireSound            = Sound.Spike,
                HitSound             = Sound.BlasterHit,
            });

            ProjectileBase.AddType(new ProjectileType()
            {
                Id                   = ProjectileId.HomingMissile,
                BaseDamage           = 11,
                MaxAge               = 3000,
                Speed                = 500,
                IsHoming             = true,
                UseTierTextures      = true,
                InitialParticleBurst = 30,
                ParticleColor        = Color.LightGray,
                ParticleStream       = true,
                FireSound            = Sound.HomingMissileFire,
                HitSound             = Sound.HomingMissileHit,
                OnHitParticleBurst   = 75,
            });

            var acidSpit = ProjectileBase.Get(ProjectileId.HomingMissile).Clone();

            acidSpit.Id              = ProjectileId.AcidSpit;
            acidSpit.Name            = "AcidSpit";
            acidSpit.UseTierTextures = false;
            acidSpit.ParticleColor   = Color.FromNonPremultiplied(194, 245, 65, 200);
            acidSpit.FireSound       = Sound.FireBreath;
            acidSpit.HitSound        = Sound.AcidSplat;
            ProjectileBase.AddType(acidSpit);

            //var explosiveAcidSpit = ProjectileBase.Get(ProjectileId.HomingMissile).Clone();
            //explosiveAcidSpit.Id = ProjectileId.ExplosiveAcidSpit;
            //explosiveAcidSpit.Name = "Explosive AcidSpit";
            //explosiveAcidSpit.Penetrate = true;
            //explosiveAcidSpit.IsHoming = false;
            //explosiveAcidSpit.UseTierTextures = false;
            //explosiveAcidSpit.MaxAge = 6000;
            //explosiveAcidSpit.Speed = 400;
            //explosiveAcidSpit.ParticleColor = Color.FromNonPremultiplied(194, 245, 65, 200);
            //explosiveAcidSpit.FireSound = Sound.FireBreath;
            //explosiveAcidSpit.HitSound = Sound.AcidSplat;
            //explosiveAcidSpit.OnProjectileHitTerrain = (projectile, material) => {
            //        projectile.Map.RenderBrush(projectile.Position, Brush.Size4, Material.Acid, 0);
            //    };
            //explosiveAcidSpit.OnProjectileHit = (projectile, target, amount) => {
            //    projectile.Map.RenderBrush(projectile.Position, Brush.Size4, Material.Acid, 0);
            //};
            //ProjectileBase.AddType(explosiveAcidSpit);

            ProjectileBase.AddType(new ProjectileType()
            {
                Id               = ProjectileId.FlameThrower,
                Speed            = 1000,
                ParticleColor    = Color.Red,
                OnProjectileMove = (projectile, material) => {
                    if (material != Material.Fire && MaterialInfo.IsLiquid(material))
                    {
                        projectile.Remove();
                    }
                    else
                    {
                        if (projectile.Age > 150)
                        {
                            projectile.Map.RenderBrush(projectile.Position, Brush.Size4, Material.Fire, 0);
                        }
                    }
                },
                OnProjectileHitTerrain = (projectile, material) => {
                    projectile.Map.RenderBrush(projectile.Position, Brush.Size4, Material.Fire, 0);
                },
                OnProjectileHit = (projectile, target, amount) => {
                    projectile.Map.RenderBrush(projectile.Position, Brush.Size4, Material.Fire, 0);
                }
            });


            ProjectileBase.AddType(new ProjectileType()
            {
                Id                     = ProjectileId.Fireball,
                BaseDamage             = 25,
                Speed                  = 1000,
                MaxAge                 = 2000,
                DigBrush               = Brush.Size10,
                DigStrength            = 7,
                FireSound              = Sound.FireBreath,
                ParticleColor          = Color.FromNonPremultiplied(255, 113, 95, 200),
                ParticleStream         = true,
                InitialParticleBurst   = 20,
                OnProjectileHitTerrain = (projectile, material) => {
                    projectile.Map.RenderBrush(projectile.Position, Brush.Size5, Material.Fire, 0);
                },
                OnProjectileHit = (projectile, target, amount) => {
                    projectile.Map.RenderBrush(projectile.Position, Brush.Size5, Material.Fire, 0);
                }
            });

            ProjectileBase.AddType(new ProjectileType()
            {
                Id                   = ProjectileId.Fireball_2,
                BaseDamage           = 8,
                Speed                = 800,
                MaxAge               = 3000,
                Penetrate            = true,
                FireSound            = Sound.FireBreath,
                ParticleColor        = Color.FromNonPremultiplied(255, 113, 95, 200),
                ParticleStream       = true,
                InitialParticleBurst = 20,
                OnProjectileHit      = (projectile, target, amount) => {
                    projectile.Map.RenderBrush(projectile.Position, Brush.Size10, Material.Fire, 0);
                }
            });

            ProjectileBase.AddType(new ProjectileType()
            {
                Id                     = ProjectileId.Comet,
                BaseDamage             = 10,
                Speed                  = 500,
                ParticleColor          = Color.FromNonPremultiplied(255, 43, 61, 175),
                ParticleStream         = true,
                InitialParticleBurst   = 20,
                MaxAge                 = 2000,
                DigBrush               = Brush.Size10,
                DigStrength            = 7,
                HasGravity             = true,
                FireSound              = Sound.FireBreath,
                OnProjectileHitTerrain = (projectile, material) => {
                    projectile.Map.RenderBrush(projectile.Position, Brush.Size4, Material.Fire, 0);
                },
                OnProjectileHit = (projectile, target, amount) => {
                }
            });

            ProjectileBase.AddType(new ProjectileType()
            {
                Id                   = ProjectileId.Spike,
                BaseDamage           = 10,
                MaxAge               = 2000,
                Speed                = 750,
                InitialParticleBurst = 15,
                ParticleColor        = Color.FromNonPremultiplied(114, 118, 20, 255),
                ParticleStream       = true,
                FireSound            = Sound.Spike,
            });

            var project = ProjectileBase.Get(ProjectileId.Spike).Clone();

            project.TechName   = project.Name;
            project.Name       = null;
            project.Id         = ProjectileId.SproutSpike;
            project.BaseDamage = 7;
            ProjectileBase.AddType(project);

            ProjectileBase.AddType(new ProjectileType()
            {
                Id                   = ProjectileId.BoseEinsteinCondenser,
                BaseDamage           = 5,
                MaxAge               = 1000,
                Speed                = 500,
                FireSound            = Sound.BoseEinsteinCondenserFire,
                InitialParticleBurst = 5,
                ParticleColor        = Color.LightBlue,
                ParticleStream       = true,
                OnProjectileMove     = (projectile, material) => {
                    if (MaterialInfo.IsLiquid(material))
                    {
                        projectile.Map.RenderBrush(projectile.Position, Brush.Size9, Material.Ice, 0);
                        projectile.Remove();
                    }
                },
                OnProjectileHitTerrain = (projectile, material) => {
                    //if (projectile.Age > 150)
                    projectile.Map.RenderBrush(projectile.Position, Brush.Size9, Material.Ice, 0);
                },
                OnProjectileHit = (projectile, target, amount) => {
                    projectile.Map.RenderBrush(projectile.Position, Brush.Size9, Material.Ice, 0);
                }
            });

            ProjectileBase.AddType(new ProjectileType()
            {
                Id                     = ProjectileId.DiggingAndDamaging,
                BaseDamage             = 10,
                DigBrush               = Brush.Size7,
                DigStrength            = 7,
                ParticleColor          = Color.FromNonPremultiplied(248, 113, 241, 100),
                ParticleStream         = true,
                MaxAge                 = 3000,
                Speed                  = 600,
                FireSound              = Sound.SpaceShipBlaster,
                OnProjectileHitTerrain = (projectile, material) => {
                    projectile.Map.RenderBrush(projectile.Position, Brush.Size8, Material.Fire, 1);
                },
            });

            //Final Boss Grenades
            ProjectileBase.AddType(new ProjectileType()
            {
                Id                     = ProjectileId.Grenade,
                BaseDamage             = 5,
                ParticleColor          = Color.FromNonPremultiplied(109, 247, 27, 255),
                ParticleStream         = true,
                Speed                  = 500,
                MaxAge                 = 3000,
                FireSound              = Sound.HomingMissileFire,
                HitSound               = Sound.HomingMissileHit,
                OnProjectileHitTerrain = (projectile, material) => {
                    projectile.Map.Explode(projectile.Position, 250, 9);
                },
                OnProjectileHit = (projectile, target, amount) => {
                    projectile.Map.Explode(projectile.Position, 250, 9);
                }
            });

            ProjectileBase.AddType(new ProjectileType()
            {
                Id             = ProjectileId.Grenade_2,
                BaseDamage     = 1,
                Speed          = 1000,
                MaxAge         = 6000,
                HasGravity     = true,
                FireSound      = Sound.GrenadeFire,
                ParticleColor  = Color.FromNonPremultiplied(109, 247, 27, 255),
                ParticleStream = true,
                //OnProjectileMove = (projectile, material) =>
                //{
                //    if (projectile.Age > 2800)
                //        projectile.Map.Explode(projectile.Position, 5, 1);
                //},
                OnProjectileHitTerrain = (projectile, material) => {
                    projectile.Map.Explode(projectile.Position, 5, 1);
                },
                OnProjectileHit = (projectile, target, amount) => {
                    projectile.Map.Explode(projectile.Position, 5, 1);
                }
            });

            ProjectileBase.AddType(new ProjectileType()
            {
                Id                   = ProjectileId.MiniFlame,
                BaseDamage           = 5,
                DigBrush             = Brush.Size7,
                DigStrength          = 8,
                ParticleColor        = Color.FromNonPremultiplied(255, 80, 98, 255),
                ParticleStream       = true,
                InitialParticleBurst = 30,
                MaxAge               = 5000,
                Speed                = 300,
                Penetrate            = true
            });

            ProjectileBase.AddType(new ProjectileType()
            {
                Id                     = ProjectileId.MiniFlame_2,
                BaseDamage             = 5,
                ParticleColor          = Color.FromNonPremultiplied(255, 80, 98, 255),
                ParticleStream         = true,
                MaxAge                 = 5000,
                Speed                  = 650,
                FireSound              = Sound.MiniFlame,
                OnProjectileHitTerrain = (projectile, material) => {
                    projectile.Map.RenderBrush(projectile.Position, Brush.Size3, Material.Fire, 0);
                },
                OnProjectileHit = (projectile, target, amount) => {
                    projectile.Map.RenderBrush(projectile.Position, Brush.Size3, Material.Fire, 0);
                }
            });
        }