public bool GenerateMap(Level Lvl, string type) { Logger.Log("Attemping to generate a map. Type: " + type); if (Inuse) { Logger.Log("Generator in use", LogType.Warning); return false; } Random rand = new System.Random(); try { Inuse = true; terrain = new float[Lvl.width * Lvl.height]; overlay = new float[Lvl.width * Lvl.height]; if (!type.Equals("ocean")) { overlay2 = new float[Lvl.width * Lvl.height]; } //float dispAux, pd; ushort WaterLevel = (ushort)(Lvl.depth / 2 + 2); if (type.Equals("ocean")) { WaterLevel = (ushort)(Lvl.depth * 0.85f); } //Generate the level GenerateFault(terrain, Lvl, type, rand); //APPLY FILTER to terrain FilterAverage(Lvl); //CREATE OVERLAY //GenerateFault(overlay, Lvl, "overlay", rand); Logger.Log("Creating overlay", LogType.Debug); GeneratePerlinNoise(overlay, Lvl, "", rand); if (!type.Equals("ocean")) { Logger.Log("Planning trees", LogType.Debug); GeneratePerlinNoise(overlay2, Lvl, "", rand); } Logger.Log("Converting height map", LogType.Debug); Logger.Log("And applying overlays", LogType.Debug); 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 "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; 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")) //apply the edge dip { 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 (z > WaterLevel) { for (ushort zz = 0; z - zz >= 0; zz++) { 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.Blockchange(x, (ushort)(z - zz), y, Block.grass); } //top layer else if (zz < 3) { Lvl.Blockchange(x, (ushort)(z - zz), y, Block.dirt); } //next few else { Lvl.Blockchange(x, (ushort)(z - zz), y, Block.rock); } //ten rock it } else { Lvl.Blockchange(x, (ushort)(z - zz), y, Block.sand); //SAAAND extra for islands } } else { if (zz == 0) { Lvl.Blockchange(x, (ushort)(z - zz), y, Block.grass); } else if (zz < 3) { Lvl.Blockchange(x, (ushort)(z - zz), y, Block.dirt); } else { Lvl.Blockchange(x, (ushort)(z - zz), y, Block.rock); } } } else { Lvl.Blockchange(x, (ushort)(z - zz), y, Block.rock); //zoned for above sea level rock floor } } if (overlay[bb] < 0.25f) //Zoned for flowers { int temprand = rand.Next(12); switch (temprand) { case 10: Lvl.Blockchange(x, (ushort)(z + 1), y, Block.redflower); break; case 11: Lvl.Blockchange(x, (ushort)(z + 1), y, Block.yellowflower); break; default: break; } } if (!type.Equals("ocean")) //Oceans dont have trees { if (overlay[bb] < 0.65f && overlay2[bb] < TreeDens) //If not a rock zoned area and is zoned for possible trees { if (Lvl.GetTile(x, (ushort)(z + 1), y) == Block.air) //No flowers here right? { if (Lvl.GetTile(x, z, y) == Block.grass) //Im not on sand am I either? { if (rand.Next(13) == 0) { if (!TreeCheck(Lvl, x, z, y, TreeDist)) //Am I too close to other trees? { 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.Blockchange(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.Blockchange(x, (ushort)(WaterLevel - zz), y, Block.sand); //sand top } else { Lvl.Blockchange(x, (ushort)(WaterLevel - zz), y, Block.gravel); //zoned for gravel } } else {Lvl.Blockchange(x, (ushort)(WaterLevel - zz), y, Block.rock);} } } } } catch { Logger.Log("Map Generator Failed", LogType.Error); Inuse = false; return false; } terrain = new float[0]; //Derp overlay = new float[0]; //Derp overlay2 = new float[0]; //Derp Inuse = false; return true; }
// void AddTree(Level Lvl, ushort x, ushort z, ushort y, Random Rand) { byte height = (byte)Rand.Next(4, 7); for (ushort zz = 0; zz < height; zz++) { if (Lvl.GetTile(x, (ushort)(z + zz), y) == Block.air) //Not likly to trigger anyway { Lvl.Blockchange(x, (ushort)(z + zz), y, Block.trunk); } else { height = (byte)zz; } } short top = (short)(height - 3); for (short xx = (short)-top; xx <= top; ++xx) { for (short yy = (short)-top; yy <= top; ++yy) { for (short zz = (short)-top; zz <= top; ++zz) { if (Lvl.GetTile((ushort)(x + xx), (ushort)(z + zz + height), (ushort)(y + yy)) == Block.air) //Not likly to trigger anyway { //short Dist = (short)(Math.Abs(xx) + Math.Abs(yy) + Math.Abs(zz)); short Dist = (short)(Math.Sqrt(xx * xx + yy * yy + zz * zz)); if (Dist < top + 1) { if (Rand.Next((int)(Dist)) < 2) { Lvl.Blockchange((ushort)(x + xx), (ushort)(z + zz + height), (ushort)(y + yy), Block.leaf); } } } } } } }