/// <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); }
/// <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 }