public bool GenerateMap(Level Lvl, string type) { Server.s.Log("Attempting map gen"); if (Inuse) { Server.s.Log("Generator in use"); 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); 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 "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 (z > WaterLevel) { for (ushort zz = 0; z - zz >= 0; zz++) { if (type == "desert") { Lvl.skipChange(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.skipChange(x, (ushort)(z - zz), y, Block.grass); } //top layer else if (zz < 3) { Lvl.skipChange(x, (ushort)(z - zz), y, Block.dirt); } //next few else { Lvl.skipChange(x, (ushort)(z - zz), y, Block.rock); } //ten rock it } else { Lvl.skipChange(x, (ushort)(z - zz), y, Block.sand); //SAAAND extra for islands } } else if (type == "desert") { Lvl.skipChange(x, (ushort)(z - zz), y, Block.sand); } else { if (zz == 0) { Lvl.skipChange(x, (ushort)(z - zz), y, Block.grass); } else if (zz < 3) { Lvl.skipChange(x, (ushort)(z - zz), y, Block.dirt); } else { Lvl.skipChange(x, (ushort)(z - zz), y, Block.rock); } } } else { Lvl.skipChange(x, (ushort)(z - zz), y, Block.rock); //zoned for above sea level rock floor } } if (overlay[bb] < 0.25f && type != "desert") //Zoned for flowers { int temprand = rand.Next(12); switch (temprand) { case 10: Lvl.skipChange(x, (ushort)(z + 1), y, Block.redflower); break; case 11: Lvl.skipChange(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.skipChange(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.skipChange(x, (ushort)(WaterLevel - zz), y, Block.sand); //sand top } else { Lvl.skipChange(x, (ushort)(WaterLevel - zz), y, Block.gravel); //zoned for gravel } } else { Lvl.skipChange(x, (ushort)(WaterLevel - zz), y, Block.rock); } } } } } 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; }
//return true if tree is near private bool TreeCheck(Level Lvl, ushort x, ushort z, ushort y, short dist) { for (short xx = (short)-dist; xx <= +dist; ++xx) { for (short yy = (short)-dist; yy <= +dist; ++yy) { for (short zz = (short)-dist; zz <= +dist; ++zz) { byte foundTile = Lvl.GetTile((ushort)(x + xx), (ushort)(z + zz), (ushort)(y + yy)); if (foundTile == Block.trunk || foundTile == Block.green) { return true; } } } } return false; }
public PlayerBot(string n, Level l, ushort x, ushort y, ushort z, byte rotx, byte roty) { name = n; color = "&1"; id = FreeId(); level = l; pos = new ushort[3] { x, y, z }; rot = new byte[2] { rotx, roty }; GlobalSpawn(); foreach (Player p in Player.players) { if (p.level == level) { Player.SendMessage(p, color + name + Server.DefaultColor + ", the bot, has been added."); } } botTimer.Elapsed += delegate { int currentNum, foundNum = (32 * 75); Random rand = new Random(); x = (ushort)Math.Round((decimal)pos[0] / (decimal)32); y = (ushort)((pos[1] - 33) / 32); z = (ushort)Math.Round((decimal)pos[2] / (decimal)32); if (kill) { foreach (Player p in Player.players) { if ((ushort)(p.pos[0] / 32) == x) { if (Math.Abs((ushort)(p.pos[1] / 32) - y) < 2) { if ((ushort)(p.pos[2] / 32) == z) { p.HandleDeath(Block.Zero); } } } } } if (Waypoints.Count < 1) { if (hunt) Player.players.ForEach(delegate(Player p) { if (p.level == level && !p.invincible) { currentNum = Math.Abs(p.pos[0] - pos[0]) + Math.Abs(p.pos[1] - pos[1]) + Math.Abs(p.pos[2] - pos[2]); if (currentNum < foundNum) { foundNum = currentNum; foundPos = p.pos; foundRot = p.rot; movement = true; rot[1] = (byte)(255 - foundRot[1]); if (foundRot[0] < 128) rot[0] = (byte)(foundRot[0] + 128); else rot[0] = (byte)(foundRot[0] - 128); } } }); } else { bool skip = false; movement = false; retry: switch (Waypoints[currentPoint].type) { case "walk": foundPos[0] = Waypoints[currentPoint].x; foundPos[1] = Waypoints[currentPoint].y; foundPos[2] = Waypoints[currentPoint].z; movement = true; if ((ushort)(pos[0] / 32) == (ushort)(Waypoints[currentPoint].x / 32)) { if ((ushort)(pos[2] / 32) == (ushort)(Waypoints[currentPoint].z / 32)) { rot[0] = Waypoints[currentPoint].rotx; rot[1] = Waypoints[currentPoint].roty; currentPoint++; movement = false; if (currentPoint == Waypoints.Count) currentPoint = 0; if (!skip) { skip = true; goto retry; } } } break; case "teleport": pos[0] = Waypoints[currentPoint].x; pos[1] = Waypoints[currentPoint].y; pos[2] = Waypoints[currentPoint].z; rot[0] = Waypoints[currentPoint].rotx; rot[1] = Waypoints[currentPoint].roty; currentPoint++; if (currentPoint == Waypoints.Count) currentPoint = 0; return; case "wait": if (countdown != 0) { countdown--; if (countdown == 0) { currentPoint++; if (currentPoint == Waypoints.Count) currentPoint = 0; if (!skip) { skip = true; goto retry; } } } else { countdown = Waypoints[currentPoint].seconds; } return; case "nod": if (countdown != 0) { countdown--; if (nodUp) { if (rot[1] > 32 && rot[1] < 128) nodUp = !nodUp; else { if (rot[1] + (byte)Waypoints[currentPoint].rotspeed > 255) rot[1] = 0; else rot[1] += (byte)Waypoints[currentPoint].rotspeed; } } else { if (rot[1] > 128 && rot[1] < 224) nodUp = !nodUp; else { if (rot[1] - (byte)Waypoints[currentPoint].rotspeed < 0) rot[1] = 255; else rot[1] -= (byte)Waypoints[currentPoint].rotspeed; } } if (countdown == 0) { currentPoint++; if (currentPoint == Waypoints.Count) currentPoint = 0; if (!skip) { skip = true; goto retry; } } } else { countdown = Waypoints[currentPoint].seconds; } return; case "spin": if (countdown != 0) { countdown--; if (rot[0] + (byte)Waypoints[currentPoint].rotspeed > 255) rot[0] = 0; else if (rot[0] + (byte)Waypoints[currentPoint].rotspeed < 0) rot[0] = 255; else rot[0] += (byte)Waypoints[currentPoint].rotspeed; if (countdown == 0) { currentPoint++; if (currentPoint == Waypoints.Count) currentPoint = 0; if (!skip) { skip = true; goto retry; } } } else { countdown = Waypoints[currentPoint].seconds; } return; case "speed": movementSpeed = (int)Math.Round((decimal)((decimal)24 / (decimal)100 * (decimal)Waypoints[currentPoint].seconds)); if (movementSpeed == 0) movementSpeed = 1; currentPoint++; if (currentPoint == Waypoints.Count) currentPoint = 0; if (!skip) { skip = true; goto retry; } return; case "reset": currentPoint = 0; return; case "remove": removeBot(); return; case "linkscript": if (File.Exists("bots/" + Waypoints[currentPoint].newscript)) { Command.all.Find("botset").Use(null, this.name + " " + Waypoints[currentPoint].newscript); return; } currentPoint++; if (currentPoint == Waypoints.Count) currentPoint = 0; if (!skip) { skip = true; goto retry; } return; case "jump": jumpTimer.Elapsed += delegate { currentjump++; switch (currentjump) { case 1: case 2: pos[1] += 24; break; case 3: break; case 4: pos[1] -= 24; break; case 5: pos[1] -= 24; jumping = false; currentjump = 0; jumpTimer.Stop(); break; } }; jumpTimer.Start(); currentPoint++; if (currentPoint == Waypoints.Count) currentPoint = 0; if (!skip) { skip = true; goto retry; } break; } if (currentPoint == Waypoints.Count) currentPoint = 0; } if (!movement) { if (rot[0] < 245) rot[0] += 8; else rot[0] = 0; if (rot[1] > 32 && rot[1] < 64) rot[1] = 224; else if (rot[1] > 250) rot[1] = 0; else rot[1] += 4; } }; botTimer.Start(); moveTimer.Elapsed += delegate { moveTimer.Interval = Server.updateTimer.Interval / movementSpeed; if (!movement) return; int newNum; Random rand = new Random(); if ((pos[1] - 19) % 32 != 0 && !jumping) { pos[1] = (ushort)((pos[1] + 19) - (pos[1] % 32)); } x = (ushort)Math.Round((decimal)(pos[0] - 16) / (decimal)32); y = (ushort)((pos[1] - 64) / 32); z = (ushort)Math.Round((decimal)(pos[2] - 16) / (decimal)32); byte b = Block.Convert(level.GetTile(x, y, z)); byte b1, b2, b3;//, b4; if (Block.Walkthrough(b) && !jumping) { pos[1] = (ushort)(pos[1] - 32); } y = (ushort)((pos[1] - 64) / 32); //Block below feet newNum = level.PosToInt((ushort)(x + Math.Sign(foundPos[0] - pos[0])), y, (ushort)(z + Math.Sign(foundPos[2] - pos[2]))); b = Block.Convert(level.GetTile(newNum)); b1 = Block.Convert(level.GetTile(level.IntOffset(newNum, 0, 1, 0))); b2 = Block.Convert(level.GetTile(level.IntOffset(newNum, 0, 2, 0))); b3 = Block.Convert(level.GetTile(level.IntOffset(newNum, 0, 3, 0))); if (Block.Walkthrough(b2) && Block.Walkthrough(b3) && !Block.Walkthrough(b1)) { //Get ready to go up step pos[0] += (ushort)Math.Sign(foundPos[0] - pos[0]); pos[1] += (ushort)32; pos[2] += (ushort)Math.Sign(foundPos[2] - pos[2]); } else if (Block.Walkthrough(b1) && Block.Walkthrough(b2)) { //Stay on current level pos[0] += (ushort)Math.Sign(foundPos[0] - pos[0]); pos[2] += (ushort)Math.Sign(foundPos[2] - pos[2]); } else if (Block.Walkthrough(b) && Block.Walkthrough(b1)) { //Drop a level pos[0] += (ushort)Math.Sign(foundPos[0] - pos[0]); pos[1] -= (ushort)32; pos[2] += (ushort)Math.Sign(foundPos[2] - pos[2]); } x = (ushort)Math.Round((decimal)(pos[0] - 16) / (decimal)32); y = (ushort)((pos[1] - 64) / 32); z = (ushort)Math.Round((decimal)(pos[2] - 16) / (decimal)32); b1 = Block.Convert(level.GetTile(x, (ushort)(y + 1), z)); b2 = Block.Convert(level.GetTile(x, (ushort)(y + 2), z)); b3 = Block.Convert(level.GetTile(x, y, z)); /* if ((ushort)(foundPos[1] / 32) > y) { if (b1 == Block.water || b1 == Block.waterstill || b1 == Block.lava || b1 == Block.lavastill) { if (Block.Walkthrough(b2)) { pos[1] = (ushort)(pos[1] + (Math.Sign(foundPos[1] - pos[1]))); } } else if (b2 == Block.water || b2 == Block.waterstill || b2 == Block.lava || b2 == Block.lavastill) { pos[1] = (ushort)(pos[1] + (Math.Sign(foundPos[1] - pos[1]))); } } else if ((ushort)(foundPos[1] / 32) < y) { if (b3 == Block.water || b3 == Block.waterstill || b3 == Block.lava || b3 == Block.lavastill) { pos[1] = (ushort)(pos[1] + (Math.Sign(foundPos[1] - pos[1]))); } }*/ }; moveTimer.Start(); }