void GenNonLavaColumn(ushort x, ushort y, ushort z, Level Lvl, int index) { if (y > LiquidLevel) { int pos = x + Lvl.Width * (z + y * Lvl.Length); for (ushort yy = 0; y - yy >= 0; yy++) { if (genParams.SimpleColumns) { Lvl.blocks[pos] = Block.sand; } else if (overlay[index] < 0.72f) { if (genParams.IslandColumns) //increase sand height for island { if (y > LiquidLevel + 2) { if (yy == 0) { Lvl.blocks[pos] = Block.grass; //top layer } else if (yy < 3) { Lvl.blocks[pos] = Block.dirt; //next few } else { Lvl.blocks[pos] = Block.rock; //ten rock it } } else { Lvl.blocks[pos] = Block.sand; //SAAAND extra for islands } } else { if (yy == 0) { Lvl.blocks[pos] = Block.grass; } else if (yy < 3) { Lvl.blocks[pos] = Block.dirt; } else { Lvl.blocks[pos] = Block.rock; } } } else { Lvl.blocks[pos] = Block.rock; } pos -= Lvl.Width * Lvl.Length; } if (genParams.GenFlowers && overlay[index] < 0.25f) { switch (rand.Next(12)) { case 10: Lvl.SetTile(x, (ushort)(y + 1), z, Block.redflower); break; case 11: Lvl.SetTile(x, (ushort)(y + 1), z, Block.yellowflower); break; default: break; } } if (genParams.GenTrees && overlay[index] < 0.65f && overlay2[index] < treeDens) { if (Lvl.GetTile(x, (ushort)(y + 1), z) == Block.air) { if (Lvl.GetTile(x, y, z) == Block.grass || genParams.UseCactus) { if (rand.Next(13) == 0 && !TreeDrawOp.TreeCheck(Lvl, x, y, z, treeDist)) { treeDrawer.Type = genParams.UseCactus ? TreeDrawOp.T_Cactus : TreeDrawOp.T_Tree; treeCoords[0].X = x; treeCoords[0].Y = (ushort)(y + 1); treeCoords[0].Z = z; treeDrawer.Perform(treeCoords, null, Lvl, null); } } } } } else //Must be on/under the water line then { int pos = x + Lvl.Width * (z + LiquidLevel * Lvl.Length); for (ushort yy = 0; LiquidLevel - yy >= 0; yy++) { if (LiquidLevel - yy > y) { Lvl.blocks[pos] = Block.water; //better fill the water above me } else if (LiquidLevel - yy > y - 3) { byte block = overlay[index] < 0.75f ? Block.sand : Block.gravel; // sand on top Lvl.blocks[pos] = block; } else { Lvl.blocks[pos] = Block.rock; } pos -= Lvl.Width * Lvl.Length; } } }
void GenLavaColumn(ushort x, ushort y, ushort z, Level Lvl, int index) { if (y > LiquidLevel) { for (ushort yy = 0; y - yy >= 0; yy++) { if (y > (LiquidLevel - 1)) { if (yy == 0) { Lvl.SetTile(x, (ushort)(y - yy), z, Block.rock); //top layer } else if (yy < 3) { Lvl.SetTile(x, (ushort)(y - yy), z, Block.rock); } else if (yy < 2) { Lvl.SetTile(x, (ushort)(y - yy), z, Block.lava); //next few } else { Lvl.SetTile(x, (ushort)(y - yy), z, Block.obsidian); } } else { Lvl.SetTile(x, (ushort)(y - yy), z, Block.lava); } if (overlay[index] < 0.3f) { switch (rand.Next(13)) { case 9: case 10: case 11: case 12: Lvl.SetTile(x, (ushort)(y + 1), z, Block.lava); //change to lava when time break; default: break; } } Lvl.SetTile(x, (ushort)(y), z, (rand.Next(100) % 3 == 1 ? Block.darkgrey : Block.obsidian)); } } else { for (ushort yy = 0; LiquidLevel - yy >= 0; yy++) { if (LiquidLevel - yy > y - 1) { Lvl.SetTile(x, (ushort)(LiquidLevel - yy), z, Block.lava); //better fill the water above me } else if (LiquidLevel - yy > y - 3) { if (overlay[index] < 0.9f) { byte block = yy < y ? Block.lava : Block.rock; Lvl.SetTile(x, (ushort)(y - yy), z, block); } else { Lvl.SetTile(x, (ushort)(LiquidLevel - yy), (ushort)(z - 5), Block.lava); //killer lava } } else { Lvl.SetTile(x, (ushort)(LiquidLevel - yy), z, Block.stone); //and just make the rest cobblestone } } } }
public unsafe static void Generate(Level lvl, string type, int seed, bool useSeed) { int index = 0, width = lvl.Width, height = lvl.Height, length = lvl.Length; byte[] blocks = lvl.blocks; int half = height / 2; RealisticMapGen generator = new RealisticMapGen(); IModule module2D = null, module3D = null; switch (type) { case "flat": int grassHeight = height / 2; if (useSeed && seed >= 0 && seed < height) { lvl.EdgeLevel = (short)seed; grassHeight = seed; } fixed(byte *ptr = blocks) { if (grassHeight > 0) { MapSet(lvl.Width, lvl.Length, ptr, 0, grassHeight - 1, Block.dirt); } if (grassHeight < lvl.Height) { MapSet(lvl.Width, lvl.Length, ptr, grassHeight, grassHeight, Block.grass); } } return; case "pixel": for (int y = 0; y < height; ++y) { for (int z = 0; z < length; ++z) { for (int x = 0; x < width; ++x) { if (y == 0) { blocks[index] = Block.blackrock; } else if (x == 0 || x == width - 1 || z == 0 || z == length - 1) { blocks[index] = Block.white; } index++; } } } return; case "empty": for (int z = 0; z < length; ++z) { for (int x = 0; x < width; ++x) { blocks[index++] = Block.blackrock; } } return; case "space": Random random = useSeed ? new Random(seed) : new Random(); for (int y = 0; y < height; ++y) { for (int z = 0; z < length; ++z) { for (int x = 0; x < width; ++x) { if (y == 0) { blocks[index] = Block.blackrock; } else if (x == 0 || x == width - 1 || z == 0 || z == length - 1 || y == 1 || y == height - 1) { blocks[index] = random.Next(100) == 0 ? Block.iron : Block.obsidian; } index++; } } } break; case "rainbow": Random random2 = useSeed ? new Random(seed) : new Random(); for (int y = 0; y < height; ++y) { for (int z = 0; z < length; ++z) { for (int x = 0; x < width; ++x) { if (y == 0 || y == height - 1 || x == 0 || x == width - 1 || z == 0 || z == length - 1) { blocks[index] = (byte)random2.Next(Block.red, Block.white); } index++; } } } return; case "hell": Random random3 = useSeed ? new Random(seed) : new Random(); for (int y = 0; y < height; ++y) { for (int z = 0; z < length; ++z) { for (int x = 0; x < width; ++x) { if (y == 0) { blocks[index] = Block.blackrock; } else if (x == 0 || x == width - 1 || z == 0 || z == length - 1 || y == 0 || y == height - 1) { blocks[index] = Block.obsidian; } else if (x == 1 || x == width - 2 || z == 1 || z == length - 2) { if (random3.Next(1000) != 7) { index++; continue; } int colIndex = z * width + x; for (int i = 1; i < (height - y); ++i) { int yy = height - i; blocks[colIndex + yy * width * length] = Block.lava; } } index++; } } } generator.GenerateMap(lvl, type, seed, useSeed); return; case "billow": module2D = new Billow(); ((Billow)module2D).Seed = useSeed ? seed : new Random().Next(); break; case "ridgedmultifractal": module2D = new RidgedMultifractal(); ((RidgedMultifractal)module2D).Seed = useSeed ? seed : new Random().Next(); break; case "perlin": module2D = new Perlin(); ((Perlin)module2D).Seed = useSeed ? seed : new Random().Next(); break; case "checkerboard": module2D = new Checkerboard(); break; case "spheres": module2D = new Spheres(); break; case "cylinders": module2D = new Cylinders(); break; case "voronoi": module2D = new Voronoi(); ((Voronoi)module2D).Seed = useSeed ? seed : new Random().Next(); break; case "perlin3d": module3D = new Perlin(); ((Perlin)module3D).Seed = useSeed ? seed : new Random().Next(); break; case "perlin3dyadjust": Perlin adjNoise = new Perlin(); adjNoise.Seed = useSeed ? seed : new Random().Next(); for (int y = 0; y < height; y++) { for (int z = 0; z < length; ++z) { for (int x = 0; x < width; ++x) { double value = System.Math.Floor((adjNoise.GetValue(x / 100.0, y / 100.0, z / 100.0) + 2) * 10); if (value > 30 * y / height) { lvl.SetTile((ushort)x, (ushort)y, (ushort)z, Block.grass); } } } } break; case "billow3d": module3D = new Billow(); ((Billow)module3D).Seed = useSeed ? seed : new Random().Next(); break; case "island": case "mountains": case "ocean": case "forest": case "desert": generator.GenerateMap(lvl, type, seed, useSeed); return; } if (module2D != null) { int waterlvl = half - 1; for (int z = 0; z < length; ++z) { for (int x = 0; x < width; ++x) { double noise = module2D.GetValue(x / 100.0, 0.1, z / 100.0); int height2D = (int)System.Math.Floor((noise + 2) * 10) + (half - 20); int height2Dtex01 = (int)System.Math.Floor((noise + 2) * 15) + (half - 30); byte topBlock = height2D < height2Dtex01 ? Block.grass : Block.sand; lvl.SetTile((ushort)x, (ushort)height2D, (ushort)z, topBlock); if (height2D < waterlvl) { for (int y = waterlvl; y >= height2D; y--) { lvl.SetTile((ushort)x, (ushort)y, (ushort)z, Block.water); } } for (int y = height2D - 1; y >= 0; y--) { byte block = (y > height2D * 3 / 4) ? Block.dirt : Block.rock; lvl.SetTile((ushort)x, (ushort)y, (ushort)z, block); } } } } if (module3D != null) { for (int y = 0; y < height; y++) { for (int z = 0; z < length; ++z) { for (int x = 0; x < width; ++x) { double value = System.Math.Floor((module3D.GetValue(x / 100.0, y / 100.0, z / 100.0) + 2) * 10); if (value > 20) { lvl.SetTile((ushort)x, (ushort)y, (ushort)z, Block.grass); } } } } } }
public void AddCactus(Level Lvl, ushort x, ushort y, ushort z, Random Rand, bool blockChange = false, bool overwrite = true, Player p = null) { byte height = (byte)Rand.Next(3, 6); ushort yy; for (yy = 0; yy <= height; yy++) { if (overwrite || Lvl.GetTile(z, (ushort)(y + yy), z) == Block.air) if (blockChange) if (p == null) Lvl.Blockchange(x, (ushort)(y + yy), z, Block.green); else Lvl.Blockchange(p, x, (ushort)(y + yy), z, Block.green); else Lvl.SetTile(x, (ushort)(y + yy), z, Block.green); } int inX = 0, inZ = 0; switch (Rand.Next(1, 3)) { case 1: inX = -1; break; case 2: default: inZ = -1; break; } for (yy = height; yy <= Rand.Next(height + 2, height + 5); yy++) { if (overwrite || Lvl.GetTile((ushort)(x + inX), (ushort)(y + yy), (ushort)(z + inZ)) == Block.air) if (blockChange) if (p == null) Lvl.Blockchange((ushort)(x + inX), (ushort)(y + yy), (ushort)(z + inZ), Block.green); else Lvl.Blockchange(p, (ushort)(x + inX), (ushort)(y + yy), (ushort)(z + inZ), Block.green); else Lvl.SetTile((ushort)(x + inX), (ushort)(y + yy), (ushort)(z + inZ), Block.green); } for (yy = height; yy <= Rand.Next(height + 2, height + 5); yy++) { if (overwrite || Lvl.GetTile((ushort)(x + inX), (ushort)(y + yy), (ushort)(z + inZ)) == Block.air) if (blockChange) if (p == null) Lvl.Blockchange((ushort)(x - inX), (ushort)(y + yy), (ushort)(z - inZ), Block.green); else Lvl.Blockchange(p, (ushort)(x - inX), (ushort)(y + yy), (ushort)(z - inZ), Block.green); else Lvl.SetTile((ushort)(x - inX), (ushort)(y + yy), (ushort)(z - inZ), Block.green); } }
public void AddNotchSwampTree(Level Lvl, ushort x, ushort y, ushort z, Random Rand, bool blockChange = false, bool overwrite = true, Player p = null) { byte dist, tile; byte height = (byte)Rand.Next(4, 8); byte top = (byte)(height - 2); short xx, yy, zz; ushort xxx, yyy, zzz; for (yy = 0; yy <= height; yy++) { yyy = (ushort)(y + yy); tile = Lvl.GetTile(x, yyy, z); if (overwrite || tile == Block.air || (yyy == y && tile == Block.shrub)) if (blockChange) if (p == null) Lvl.Blockchange(x, yyy, z, Block.trunk); else Lvl.Blockchange(p, x, yyy, z, Block.trunk); else Lvl.SetTile(x, yyy, z, Block.trunk); } for (yy = top; yy <= height + 1; yy++) { dist = yy > height - 1 ? (byte)2 : (byte)3; for (xx = (short)-dist; xx <= dist; xx++) { for (zz = (short)-dist; zz <= dist; zz++) { xxx = (ushort)(x + xx); yyy = (ushort)(y + yy); zzz = (ushort)(z + zz); tile = Lvl.GetTile(xxx, yyy, zzz); //Server.s.Log(String.Format("{0} {1} {2}", xxx, yyy, zzz)); if ((xxx == x && zzz == z && yy <= height) || (!overwrite && tile != Block.air)) continue; if (Math.Abs(xx) == dist && Math.Abs(zz) == dist) { if (yy > height) continue; if (Rand.Next(2) == 0) { if (blockChange) if (p == null) Lvl.Blockchange(xxx, yyy, zzz, Block.leaf); else Lvl.Blockchange(p, xxx, yyy, zzz, Block.leaf); else Lvl.SetTile(xxx, yyy, zzz, Block.leaf); } } else { if (blockChange) if (p == null) Lvl.Blockchange(xxx, yyy, zzz, Block.leaf); else Lvl.Blockchange(p, xxx, yyy, zzz, Block.leaf); else Lvl.SetTile(xxx, yyy, zzz, Block.leaf); } } } } }
// public void AddTree(Level Lvl, ushort x, ushort y, ushort z, Random Rand, bool blockChange = false, bool overwrite = true, Player p = null) { byte height = (byte)Rand.Next(5, 8); short top = (short)(height - Rand.Next(2, 4)); ushort xxx, yyy, zzz; for (ushort yy = 0; yy < top + height - 1; yy++) { if (overwrite || Lvl.GetTile(x, (ushort)(y + yy), z) == Block.air || (y + yy == y && Lvl.GetTile(x, (ushort)(y + yy), z) == Block.shrub)) if (blockChange) if (p == null) Lvl.Blockchange(x, (ushort)(y + yy), z, Block.trunk); else Lvl.Blockchange(p, x, (ushort)(y + yy), z, Block.trunk); else Lvl.SetTile(x, (ushort)(y + yy), z, Block.trunk); } for (short xx = (short)-top; xx <= top; ++xx) { for (short yy = (short)-top; yy <= top; ++yy) { for (short zz = (short)-top; zz <= top; ++zz) { short Dist = (short)(Math.Sqrt(xx * xx + yy * yy + zz * zz)); if (Dist < top + 1) { if (Rand.Next((int)(Dist)) < 2) { try { xxx = (ushort)(x + xx); yyy = (ushort)(y + yy + height); zzz = (ushort)(z + zz); if ((xxx != x || zzz != z || yy >= top - 1) && (overwrite || Lvl.GetTile(xxx, yyy, zzz) == Block.air)) if (blockChange) if (p == null) Lvl.Blockchange(xxx, yyy, zzz, Block.leaf); else Lvl.Blockchange(p, xxx, yyy, zzz, Block.leaf); else Lvl.SetTile(xxx, yyy, zzz, Block.leaf); } catch { } } } } } } }
public bool GenerateMap(Level Lvl, string type, int seed = 0, bool useSeed = false) { DateTime startTime = DateTime.Now; Server.s.Log("Attempting map gen"); if (Inuse) { Server.s.Log("Generator in use"); return false; } Random rand = useSeed ? new System.Random(seed) : new System.Random(); try { Inuse = true; terrain = new float[Lvl.Width * Lvl.Length]; //hmm overlay = new float[Lvl.Width * Lvl.Length]; if (!type.Equals("ocean")) { overlay2 = new float[Lvl.Width * Lvl.Length]; } //float dispAux, pd; ushort WaterLevel = (ushort)(Lvl.Height / 2 + 2); ushort LavaLevel = 5; if (type.Equals("ocean")) { WaterLevel = (ushort)(Lvl.Height * 0.85f); } //Generate the level GenerateFault(terrain, Lvl, type, rand); //APPLY FILTER to terrain FilterAverage(Lvl); //CREATE OVERLAY //GenerateFault(overlay, Lvl, "overlay", rand); Server.s.Log("Creating overlay"); GeneratePerlinNoise(overlay, Lvl, "", rand); if (!type.Equals("ocean") && type != "desert") { Server.s.Log("Planning trees"); GeneratePerlinNoise(overlay2, Lvl, "", rand); } Server.s.Log("Converting height map"); Server.s.Log("And applying overlays"); float RangeLow = 0.2f; float RangeHigh = 0.8f; float TreeDens = 0.35f; short TreeDist = 3; //changes the terrain range based on type, also tree threshold switch (type) { case "hell": RangeLow = .3f; RangeHigh = 1.3f; break; case "island": RangeLow = 0.4f; RangeHigh = 0.75f; break; case "forest": RangeLow = 0.45f; RangeHigh = 0.8f; TreeDens = 0.7f; TreeDist = 2; break; case "mountains": RangeLow = 0.3f; RangeHigh = 0.9f; TreeDist = 4; break; case "ocean": RangeLow = 0.1f; RangeHigh = 0.6f; break; case "desert": RangeLow = 0.5f; RangeHigh = 0.85f; WaterLevel = 0; TreeDist = 24; break; default: break; } //loops though evey X/Z coordinate for (int bb = 0; bb < terrain.Length; bb++) { ushort x = (ushort)(bb % Lvl.Width); ushort y = (ushort)(bb / Lvl.Width); ushort z; if (type.Equals("island")) { z = Evaluate(Lvl, Range(terrain[bb], RangeLow - NegateEdge(x, y, Lvl), RangeHigh - NegateEdge(x, y, Lvl))); } else { z = Evaluate(Lvl, Range(terrain[bb], RangeLow, RangeHigh)); } if (type != "hell") { #region nonLavaWorld if (z > WaterLevel) { for (ushort zz = 0; z - zz >= 0; zz++) { if (type == "desert") { Lvl.SetTile(x, (ushort)(z - zz), y, Block.sand); } else if (overlay[bb] < 0.72f) //If not zoned for rocks or gravel { if (type.Equals("island")) //increase sand height for island { if (z > WaterLevel + 2) { if (zz == 0) { Lvl.SetTile(x, (ushort)(z - zz), y, Block.grass); } //top layer else if (zz < 3) { Lvl.SetTile(x, (ushort)(z - zz), y, Block.dirt); } //next few else { Lvl.SetTile(x, (ushort)(z - zz), y, Block.rock); } //ten rock it } else { Lvl.SetTile(x, (ushort)(z - zz), y, Block.sand); //SAAAND extra for islands } } else if (type == "desert") { Lvl.SetTile(x, (ushort)(z - zz), y, Block.sand); } else { if (zz == 0) { Lvl.SetTile(x, (ushort)(z - zz), y, Block.grass); } else if (zz < 3) { Lvl.SetTile(x, (ushort)(z - zz), y, Block.dirt); } else { Lvl.SetTile(x, (ushort)(z - zz), y, Block.rock); } } } else { Lvl.SetTile(x, (ushort)(z - zz), y, Block.rock); } } if (overlay[bb] < 0.25f && type != "desert") //Zoned for flowers { switch (rand.Next(12)) { case 10: Lvl.SetTile(x, (ushort)(z + 1), y, Block.redflower); break; case 11: Lvl.SetTile(x, (ushort)(z + 1), y, Block.yellowflower); break; default: break; } } if (!type.Equals("ocean")) { if (overlay[bb] < 0.65f && overlay2[bb] < TreeDens) { if (Lvl.GetTile(x, (ushort)(z + 1), y) == Block.air) { if (Lvl.GetTile(x, z, y) == Block.grass || type == "desert") { if (rand.Next(13) == 0) { if (!TreeCheck(Lvl, x, z, y, TreeDist)) { if (type == "desert") AddCactus(Lvl, x, (ushort)(z + 1), y, rand); else AddTree(Lvl, x, (ushort)(z + 1), y, rand); } } } } } } } else //Must be on/under the water line then { for (ushort zz = 0; WaterLevel - zz >= 0; zz++) { if (WaterLevel - zz > z) { Lvl.SetTile(x, (ushort)(WaterLevel - zz), y, Block.water); } //better fill the water aboce me else if (WaterLevel - zz > z - 3) { if (overlay[bb] < 0.75f) { Lvl.SetTile(x, (ushort)(WaterLevel - zz), y, Block.sand); //sand top } else { Lvl.SetTile(x, (ushort)(WaterLevel - zz), y, Block.gravel); //zoned for gravel } } else { Lvl.SetTile(x, (ushort)(WaterLevel - zz), y, Block.rock); } } } #endregion } else //all of lava world generation { if (z > LavaLevel) { for (ushort zz = 0; z - zz >= 0; zz++) { if (z > (LavaLevel - 1)) { if (zz == 0) { Lvl.SetTile(x, (ushort)(z - zz), y, Block.rock); } //top layer else if (zz < 3) { Lvl.SetTile(x, (ushort)(z - zz), y, Block.rock); } else if (zz < 2) { Lvl.SetTile(x, (ushort)(z - zz), y, Block.lava); }//next few else { Lvl.SetTile(x, (ushort)(z - zz), y, Block.obsidian); } } else { Lvl.SetTile(x, (ushort)(z - zz), y, Block.lava); } if (overlay[bb] < 0.3f) { switch (rand.Next(13)) { case 9: case 10: case 11: case 12: Lvl.SetTile(x, (ushort)(z + 1), y, Block.lava); //change to lava when time break; default: break; } } // if (zz == z) Lvl.skipChange(x, (ushort)(z - zz), y, Block.opsidian); Lvl.SetTile(x, (ushort)(z), y, (rand.Next(100) % 3 == 1 ? Block.darkgrey : Block.obsidian)); } } else { for (ushort zz = 0; LavaLevel - zz >= 0; zz++) { if (LavaLevel - zz > z - 1) { /*if (Lvl.GetTile(x, z, y) == Block.air)*/ Lvl.SetTile(x, (ushort)(LavaLevel - zz), y, Block.lava); } //better fill the water aboce me else if (LavaLevel - zz > z - 3) { if (overlay[bb] < .9f) { if (zz < z) Lvl.SetTile(x, (ushort)(z - zz), (ushort)(y), Block.lava); else Lvl.SetTile(x, (ushort)(z - zz), y, Block.rock); } else { Lvl.SetTile(x, (ushort)(LavaLevel - zz), (ushort)(y - 5), Block.lava); //killer lava } } else { Lvl.SetTile(x, (ushort)(LavaLevel - zz), y, Block.stone); //and just make the rest cobblestone } } } } } Server.s.Log("Total time was " + (DateTime.Now - startTime).TotalSeconds.ToString() + " seconds."); } catch (Exception e) { Server.ErrorLog(e); Server.s.Log("Gen Fail"); Inuse = false; return false; } terrain = new float[0]; //Derp overlay = new float[0]; //Derp overlay2 = new float[0]; //Derp Inuse = false; return true; }