Пример #1
0
        /// <summary>
        /// Generates a broken temple pillar. Only places between vitric sand. Automatically scans for crystals, and returns false if a crystal is in the way.
        /// </summary>
        /// <param name="x">Center X position.</param>
        /// <param name="y">Y position. Can be anywhere between a ceiling and floor; will generate appropriately.</param>
        /// <returns>True if a pillar was successfully placed within an area</returns>
        public static bool GenPillar(int x, int y)
        {
            int ceil  = FindTypeUp(x, y, VitricBiome.Y - 20, TileType <VitricSand>(), TileType <VitricSoftSand>());
            int floor = FindType(x, y, VitricBiome.Bottom + 20, TileType <VitricSand>(), TileType <VitricSoftSand>());

            if (ceil == -1 || floor == -1 || ceil >= floor)
            {
                return(false);         //If there's an invalid ceiling or floor, or if the floor is above or on the ceiling, kill
            }
            int height = floor - ceil; //Height of pillar

            if (height < 7 || height > 50)
            {
                return(false);            //If it's too short or too tall
            }
            int wid = genRand.Next(3, 6); //Width of pillar

            int GetHeight(int xPos) => Math.Abs(ceil - FindTypeUp(xPos, y, VitricBiome.Y - 20, TileType <VitricSand>(), TileType <VitricSoftSand>()));
            int GetDepth(int xPos) => Math.Abs(floor - FindType(xPos, y, VitricBiome.Y - 20, TileType <VitricSand>(), TileType <VitricSoftSand>()));

            for (int i = -wid; i < wid + 1; ++i) //Checks for crystals. If there's a crystal, kill this pillar before it gens
            {
                if (Helper.ScanForTypeDown(x + i, y, TileType <VitricLargeCrystal>(), 100) || Helper.ScanForTypeDown(x + i, y, TileType <VitricSmallCrystal>(), 100))
                {
                    return(false); //Crystal found, can't place here
                }
                if (GetHeight(x + i) - 30 > GetHeight(x - wid) || GetHeight(x + i) - 30 > GetHeight(x + wid))
                {
                    return(false);                                                                                          //Large height differencial found, can't place
                }
                if (GetDepth(x + i) + 30 < GetDepth(x - wid) || GetDepth(x + i) + 30 < GetDepth(x + wid))
                {
                    return(false);                                                                                      //Large height differencial found, can't place
                }
            }

            for (int i = -wid; i < wid + 1; ++i)
            {
                //Tile placement
                int depth = genRand.Next(2) + 1;
                if (Math.Abs(i) == wid || Math.Abs(i) == wid - 2)
                {
                    depth = (int)Math.Ceiling(height / 4f) + genRand.Next((int)Math.Ceiling(-height / 6f), (int)Math.Ceiling(height / 6f));
                }
                if (Math.Abs(i) == wid - 1)
                {
                    depth = (int)Math.Ceiling(height / 3f) + genRand.Next((int)Math.Ceiling(-height / 6f), (int)Math.Ceiling(height / 6f));
                }
                int ceilingY = FindTypeUp(x + i, y, VitricBiome.Y - 20, TileType <VitricSand>(), TileType <VitricSoftSand>());
                int floorY   = FindType(x + i, y, VitricBiome.Bottom + 20, TileType <VitricSand>(), TileType <VitricSoftSand>());

                for (int j = 0; j < depth; ++j)
                {
                    KillTile(x + i, ceilingY + j, false, false, true);
                    PlaceTile(x + i, ceilingY + j, TileType <AncientSandstone>(), true, false);
                    KillTile(x + i, floorY - j, false, false, true);
                    PlaceTile(x + i, floorY - j, TileType <AncientSandstone>(), true, false);
                }

                //Wall placement
                depth = (int)Math.Ceiling(height / 2f) + 2;
                if (Math.Abs(i) >= wid)
                {
                    depth = genRand.Next(2) + 1;
                }
                if (Math.Abs(i) == wid - 2)
                {
                    depth = (int)Math.Ceiling(height / 3f) + genRand.Next((int)Math.Ceiling(-height / 6f), (int)Math.Ceiling(height / 4f));
                }
                if (Math.Abs(i) == wid - 1)
                {
                    depth = (int)Math.Ceiling(height / 4f) + genRand.Next((int)Math.Ceiling(-height / 6f), (int)Math.Ceiling(height / 6f));
                }

                for (int j = 0; j < depth; ++j)
                {
                    KillWall(x + i, ceilingY + j, false);
                    PlaceWall(x + i, ceilingY + j, WallType <AncientSandstoneWall>(), true);
                    KillWall(x + i, floorY - j, false);
                    PlaceWall(x + i, floorY - j, WallType <AncientSandstoneWall>(), true);
                }
            }
            RuinedPillarPositions.Add(new Point(x, y));
            return(true);
        }
Пример #2
0
        /// <summary>Generates the Vitric Desert under the Underground Desert.</summary>
        /// <param name="progress"></param>
        public static void VitricGen(GenerationProgress progress)
        {
            progress.Message = "Digging Vitric Desert";

            int vitricHeight = 140;

            ValidGround = new int[] { TileType <VitricSand>(), TileType <VitricSoftSand>() };
            //Basic biome information
            VitricBiome = new Rectangle(UndergroundDesertLocation.X - 80, UndergroundDesertLocation.Y + UndergroundDesertLocation.Height, UndergroundDesertLocation.Width + 150, vitricHeight);

            int minCeilingDepth = (int)((VitricBiome.Y + (VitricBiome.Height / 2)) - (17f * Math.Log(VitricSlopeOffset - 8))); //Various informational variables - not to be changed
            int maxCeilingDepth = minCeilingDepth + 7;
            int minFloorDepth   = (int)(VitricBiome.Y + (13f * Math.Log(VitricSlopeOffset - 8))) + (VitricBiome.Height / 2);

            GenerateBase(minCeilingDepth, maxCeilingDepth, minFloorDepth);

            for (int x = VitricBiome.Center.X - 35; x <= VitricBiome.Center.X + 36; x++) //Entrance from Desert
            {
                for (int y = VitricBiome.Y - 6; y < VitricBiome.Y + 20; y++)
                {
                    KillTile(x, y);
                    if (y > VitricBiome.Y + 5 && y < VitricBiome.Y + 9)
                    {
                        PlaceTile(x, y, TileType <VitricBossBarrier>(), true, true);
                    }
                }
            }

            for (int y = VitricBiome.Y + 9; y < VitricBiome.Y + VitricBiome.Height - 77; y++) //collision for pillars
            {
                PlaceTile(VitricBiome.X + VitricBiome.Width / 2 - 40, y, TileType <VitricBossBarrier>(), false, false);
                PlaceTile(VitricBiome.X + VitricBiome.Width / 2 + 41, y, TileType <VitricBossBarrier>(), false, false);
            }

            VitricIslandLocations = new List <Point>(); //List for island positions
            int fail = 0;

            for (int i = 0; i < (VitricBiome.Width / 40) - 1; ++i)
            {
                int  x;
                int  y;
                bool repeat = false;

                do
                {
                    x = genRand.Next(2) == 0 ? genRand.Next(VitricBiome.X + VitricSlopeOffset + 20, VitricBiome.Center.X - 61) : genRand.Next(VitricBiome.Center.X + 62, VitricBiome.Right - VitricSlopeOffset - 20);
                    y = (maxCeilingDepth + 18) + (genRand.Next((int)(VitricBiome.Height / 2.8f)));

                    if (VitricIslandLocations.Any(v => Vector2.Distance(new Vector2(x, y), v.ToVector2()) < 32) || (x > VitricBiome.X + VitricBiome.Width / 2 - 71 && x < VitricBiome.X + VitricBiome.Width / 2 + 70))
                    {
                        repeat = true;
                        if (fail++ >= 50)
                        {
                            break;
                        }
                    }
                    else
                    {
                        repeat = false;
                    }
                }while (repeat); //Gets a valid island position

                if (fail >= 50)
                {
                    break;             //Could not get a valid position, stop trying
                }
                VitricIslandLocations.Add(new Point(x, y));
                CreateIsland(x, y); //Adds island pos to list and places island
            }

            for (int i = 0; i < 8; ++i) //Mini islands v2, outer only
            {
                int x = i <= 2 ? VitricBiome.X + 6 + genRand.Next((int)(VitricSlopeOffset * 1.3f)) : VitricBiome.Right - 6 - genRand.Next((int)(VitricSlopeOffset * 1.3f));
                if (i <= 2 && forgeSide == 0)
                {
                    x += 10;
                }
                if (i > 2 && forgeSide == 1)
                {
                    x -= 10;
                }
                int y = genRand.Next(VitricBiome.Y + 22, VitricBiome.Bottom - 50);
                if (ScanRectangle(x - 13, y - 4, 26, 14) < 8)
                {
                    CreateIsland(x, y, true);
                }
                else
                {
                    i--;
                }
            }

            //Mini islands throughout main area
            List <Point> MiniIslandLocations = new List <Point>();

            for (int i = 0; i < 20;)  //I may or may not be doing this because I find this form of a for loop neat.
            {
                int x = genRand.Next(2) == 0 ? genRand.Next(VitricBiome.X + VitricSlopeOffset + 20, VitricBiome.Center.X - 61) : genRand.Next(VitricBiome.Center.X + 62, VitricBiome.Right - VitricSlopeOffset - 20);
                int y = (maxCeilingDepth + 18) + (genRand.Next((int)(VitricBiome.Height / 2.8f)));

                if (MiniIslandLocations.Any(v => Vector2.Distance(v.ToVector2(), new Vector2(x, y)) < 1) || ScanRectangle(x - 13, y - 4, 26, 14) > 8)
                {
                    i++;
                    continue;
                }
                else
                {
                    MiniIslandLocations.Add(new Point(x, y));
                }
            }
            for (int i = 0; i < MiniIslandLocations.Count; ++i)
            {
                if (genRand.NextFloat() > 0.7f)
                {
                    CreateIsland(MiniIslandLocations[i].X, MiniIslandLocations[i].Y, true);
                }
            }

            fail = 0;
            for (int i = 0; i < VitricBiome.Width / 160; ++i)
            {
                if (fail > 40)
                {
                    break;
                }

                int x = genRand.Next(2) == 0 ? genRand.Next(VitricBiome.X + VitricSlopeOffset + 20, VitricBiome.Center.X - 61) : genRand.Next(VitricBiome.Center.X + 62, VitricBiome.Right - VitricSlopeOffset - 20);
                int y = (maxCeilingDepth + 20) + (genRand.Next((int)(VitricBiome.Height / 3.2f)));

                if (Helper.ScanForTypeDown(x, y, TileType <VitricSpike>(), 120))
                {
                    y = FindType(x, y, VitricBiome.Bottom + 20, TileType <VitricSpike>());
                }
                else
                {
                    i--;
                    fail++;
                    continue;
                }

                if (!FloorCrystal(x, y))
                {
                    i--;
                    fail++;
                    continue;
                }
            } //Mini islands

            progress.Message = "Populating the Vitric";

            GenConsistentMiniIslands();
            GenSandstonePillars();
            RuinedPillarPositions = new List <Point>();
            GenRuins();
            GenForge();
            GenDecoration();
            //GenMoss();
            GenTemple();

            VitricBiome.Y -= 8; //Adjust a bit
        }