public Room(IBot bot) : base(bot) { this.bot = bot; this.blockMap = new BlockMap(bot); this.blockDrawerPool = new BlockDrawerPool(bot, this); this.blockDrawer = blockDrawerPool.CreateBlockDrawer(15); this.blockDrawer.Start(); playerTickThread = new SafeThread(UpdatePhysics); EnableTick(50); }
public override void onCommand(string cmd, string[] args, ICmdSource cmdSource) { if (cmdSource is Player && ((Player)cmdSource).IsOp) { Player player = (Player)cmdSource; if (player.GetMetadata("editregion") == null) player.SetMetadata("editregion", new EditRegion()); EditRegion region = (EditRegion)player.GetMetadata("editregion"); BeginRecord(player); switch (cmd) { case "fill": if (args.Length >= 1) { int id = -1; int layer = 0; int.TryParse(args[0], out id); if (args.Length >= 2) int.TryParse(args[1], out layer); if (id != -1) { layer = (id >= 500 && id < 1000) ? 1 : layer; EditRegion region2 = new EditRegion(); region2.FirstCorner = new Point(1, 1); region2.SecondCorner = new Point(bot.Room.Width - 2, bot.Room.Height - 2); SetRegion(bot, region2, new NormalBlock(id, layer)); } else bot.ChatSayer.Say(player.Name + ": Invalid ID."); } else bot.ChatSayer.Say(player.Name + ": Usage: !fill <id> [layer]"); break; case "undo": if (player.HasMetadata("worldedithistory") && player.HasMetadata("worldedithistoryindex")) { List<IEditChange> history = (List<IEditChange>)player.GetMetadata("worldedithistory"); int index = (int)player.GetMetadata("worldedithistoryindex"); if (index >= 0 && index <= history.Count - 1 && (index != 0 || !history[index].IsUndone)) { history[index].Undo(blockDrawer); if (index - 1 >= 0) player.SetMetadata("worldedithistoryindex", ((int)player.GetMetadata("worldedithistoryindex")) - 1); } else player.Reply("Nothing left to undo."); } else player.Reply("No history."); break; case "redo": if (player.HasMetadata("worldedithistory") && player.HasMetadata("worldedithistoryindex")) { List<IEditChange> history = (List<IEditChange>)player.GetMetadata("worldedithistory"); int index = (int)player.GetMetadata("worldedithistoryindex"); if (index <= history.Count - 1 && (index != history.Count - 1 || !history[index].IsRedone)) { if (history.Count - 1 >= index + 1) history[index + 1].Redo(blockDrawer); else history[index].Redo(blockDrawer); if (index + 1 <= history.Count - 1) player.SetMetadata("worldedithistoryindex", ((int)player.GetMetadata("worldedithistoryindex")) + 1); } else player.Reply("Nothing left to redo."); } else player.Reply("No history."); break; case "set": if (region.Set) { if (args.Length >= 1) { int id = -1; int.TryParse(args[0], out id); if (id != -1) { int layer = ((id >= 500 && id < 1000) || id == 1337 ? 1 : 0); if (args.Length >= 2) int.TryParse(args[1], out layer); SetRegion(bot, region, new NormalBlock(id, layer)); } else bot.ChatSayer.Say(player.Name + ": Invalid ID."); } else bot.ChatSayer.Say(player.Name + ": Usage: !set <id> [layer]"); } else player.Send("You have to set a region."); break; case "replace": if (region.Set) { int blockToReplace; int blockToReplaceWith; if (args.Length >= 2 && int.TryParse(args[0], out blockToReplace) && int.TryParse(args[1], out blockToReplaceWith)) { SetRegion(bot, region, new NormalBlock(blockToReplaceWith), new NormalBlock(blockToReplace)); } else bot.ChatSayer.Say(player.Name + ": Usage: !replace <from> <to>"); } else player.Send("You have to set a region."); break; case "replacenear": { int range; int blockToReplace; int blockToReplaceWith; if (args.Length >= 3 && int.TryParse(args[0], out range) && int.TryParse(args[1], out blockToReplace) && int.TryParse(args[2], out blockToReplaceWith)) { EditRegion closeRegion = new EditRegion(); closeRegion.FirstCorner = new Point(player.BlockX - range, player.BlockY - range); closeRegion.SecondCorner = new Point(player.BlockX + range, player.BlockY + range); SetRegion(bot, closeRegion, new NormalBlock(blockToReplaceWith), new NormalBlock(blockToReplace)); } else bot.ChatSayer.Say(player.Name + ": Usage: !replacenear <range> <from> <to>"); } break; case "copy": if (region.FirstCornerSet) { BlockMap selection = new BlockMap(bot, region.Width, region.Height); foreach (Point pos in region) { selection.setBlock(pos.X - region.FirstCorner.X, pos.Y - region.FirstCorner.Y, bot.Room.getBlock(1, pos.X, pos.Y)); selection.setBlock(pos.X - region.FirstCorner.X, pos.Y - region.FirstCorner.Y, bot.Room.getBlock(0, pos.X, pos.Y)); } player.SetMetadata("selection", selection); } else player.Send("You have to place a region block."); break; case "paste": if (region.FirstCornerSet) { BlockMap selection = (BlockMap)player.GetMetadata("selection"); if (selection != null) { for (int x = 0; x < selection.Width; x++) { for (int y = 0; y < selection.Height; y++) { int blax = x + region.FirstCorner.X; int blay = y + region.FirstCorner.Y; RecordSetBlock(blax, blay, selection.getBackgroundBlock(x, y)); RecordSetBlock(blax, blay, selection.getForegroundBlock(x, y)); } } } else player.Send("You have to copy first."); } else player.Send("You have to place a region block."); break; case "line": { int tempBlock; if (args.Length >= 1 && int.TryParse(args[0], out tempBlock)) { if (region.Set) DrawLine(region.FirstCorner.X, region.FirstCorner.Y, region.SecondCorner.X, region.SecondCorner.Y, new NormalBlock(tempBlock, (tempBlock >= 500 && tempBlock < 1000) ? 1 : 0)); else player.Reply("You have to set a region."); } else player.Reply("Usage: !line <block>"); } break; case "circle": if (region.FirstCornerSet) { int radius; int block; if (args.Length >= 2 && int.TryParse(args[0], out radius) && int.TryParse(args[1], out block)) { DrawCircle(region.FirstCorner.X, region.FirstCorner.Y, radius, new NormalBlock(block, (block >= 500 && block < 1000) ? 1 : 0)); } else player.Send("Usage: !circle <radius> <block>"); } else player.Send("You have to place a region block."); break; case "square": if (region.FirstCornerSet) { int radius; int block; if (args.Length >= 2 && int.TryParse(args[0], out radius) && int.TryParse(args[1], out block)) { for (int x = region.FirstCorner.X - radius; x <= region.FirstCorner.X + radius; x++) { for (int y = region.FirstCorner.Y - radius; y <= region.FirstCorner.Y + radius; y++) { RecordSetBlock(x, y, new NormalBlock(block, (block >= 500 && block < 1000) ? 1 : 0)); } } } else player.Send("Usage: !square <radius> <block>"); } else player.Send("You have to place a region block."); break; case "fillexpand": { int toReplace = 0; int toReplaceLayer = 0; int toReplaceWith = 0; if (args.Length == 1) { if (!int.TryParse(args[0], out toReplaceWith)) { player.Reply("Usage: !fillexpand <from=0> <to>"); return; } } else if (args.Length >= 2) { if (!int.TryParse(args[1], out toReplaceWith) || !int.TryParse(args[0], out toReplace)) { player.Reply("Usage: !fillexpand <from=0> <to>"); return; } } else { player.Reply("Usage: !fillexpand <from=0> <to>"); break; } if (toReplace >= 500 && toReplace < 1000) toReplaceLayer = 1; IBlock startBlock = bot.Room.BlockMap.getBlock(toReplaceLayer, player.BlockX, player.BlockY); if (startBlock.Id == toReplace) { int total = 0; List<Point> closeBlocks = new List<Point> { new Point(1, 0), new Point(-1, 0), new Point(0, 1), new Point(0, -1) }; Queue<Point> blocksToCheck = new Queue<Point>(); List<Point> blocksToFill = new List<Point>(); blocksToCheck.Enqueue(new Point(player.BlockX, player.BlockY)); while (blocksToCheck.Count > 0) { Point parent = blocksToCheck.Dequeue(); for (int i = 0; i < closeBlocks.Count; i++) { Point current = new Point(closeBlocks[i].X + parent.X, closeBlocks[i].Y + parent.Y); IBlock currentBlock = bot.Room.BlockMap.getBlock(toReplaceLayer, current.X, current.Y); if (currentBlock.Id == toReplace && !blocksToCheck.Contains(current) && !blocksToFill.Contains(current) && current.X >= 0 && current.Y >= 0 && current.X <= bot.Room.Width && current.Y <= bot.Room.Height) { blocksToFill.Add(current); blocksToCheck.Enqueue(current); total++; } } } bot.ChatSayer.Say("total blocks: " + total + ". Filling.."); int layer = 0; if (toReplaceWith >= 500 && toReplaceWith < 1000) layer = 1; foreach (Point p in blocksToFill) { RecordSetBlock((int)p.X, (int)p.Y, new NormalBlock(toReplaceWith, layer)); } } } break; case "stop": blockDrawer.Stop(); break; case "start": blockDrawer.Start(); break; case "clearrepairblocks": //TODO: add function to blockdrawer break; case "write": if (region.FirstCornerSet) { int drawBlock = 0; if (args.Length >= 2 && int.TryParse(args[0], out drawBlock)) { List<char[]> letters = new List<char[]>(); foreach (string str in args.Skip(1)) letters.Add(str.ToLower().ToCharArray()); int spacing = 0; foreach (char[] array in letters) { for (int letterindex = 0; letterindex < array.Length; letterindex++) { string l = array[letterindex].ToString(); if (l != "_") { WriteLetter(spacing, l, region.FirstCorner.X, region.FirstCorner.Y, new NormalBlock(drawBlock, (drawBlock >= 500 && drawBlock < 1000) ? 1 : 0)); } if (l == @"@") spacing += 4; else if (l == "m" || l == "w" || l == "#" || l == "&") spacing += 2; else if (l == "n" || l == "%" || l == @"/" || l == @"\") spacing += 1; if (l == "|" || l == "." || l == "," || l == "'" || l == "!") { spacing -= 2; } else if (l == ",") { spacing -= 1; } spacing += 4; } spacing += array.Length; } } else player.Reply("Usage: !write <block> <text..>"); } else player.Reply("You have to set the first corner."); break; case "border": { int thickness; int block; if (args.Length >= 2 && int.TryParse(args[0], out thickness) && int.TryParse(args[1], out block)) { IBlock baseBlock = (bot.Room.getBlock(1, player.BlockX, player.BlockY).Id == 0 ? bot.Room.getBlock(0, player.BlockX, player.BlockY) : bot.Room.getBlock(0, player.BlockX, player.BlockY)); int layer = baseBlock.Layer; int x = player.BlockX; int y = player.BlockY; List<Point> closeBlocks = new List<Point> { new Point(1, 0), new Point(0, -1), new Point(-1, 0), new Point(0, 1) }; HashSet<Point> previouslySetBlocks = new HashSet<Point>(); for (int currentThickness = 0; currentThickness < thickness; currentThickness++) { int xx = x; while (bot.Room.getBlock(layer, xx + 1, y).Id == baseBlock.Id && !previouslySetBlocks.Contains(new Point(xx + 1, y)) && xx < 2000) xx++; List<Point> blocksToSet = new List<Point>(); HashSet<Point> blocksChecked = new HashSet<Point>(); Queue<Point> blocksToCheck = new Queue<Point>(); Point startPoint = new Point(xx, y); blocksToCheck.Enqueue(startPoint); blocksToSet.Add(startPoint); while (blocksToCheck.Count > 0) { Point parent = blocksToCheck.Dequeue(); for (int i = 0; i < closeBlocks.Count; i++) { Point current = new Point(closeBlocks[i].X + parent.X, closeBlocks[i].Y + parent.Y); IBlock currentBlock = bot.Room.BlockMap.getBlock(layer, current.X, current.Y); if (currentBlock.Id == baseBlock.Id && !previouslySetBlocks.Contains(current) && !blocksToCheck.Contains(current) && !blocksChecked.Contains(current)) { blocksToCheck.Enqueue(current); } else if ((currentBlock.Id != baseBlock.Id || previouslySetBlocks.Contains(current)) && !blocksToSet.Contains(parent)) { blocksToSet.Add(parent); } blocksChecked.Add(parent); } } foreach (Point p in blocksToSet) { RecordSetBlock(p.X, p.Y, new NormalBlock(block, (block >= 500 && block < 1000) ? 1 : 0)); previouslySetBlocks.Add(p); } } } else player.Reply("Usage: !border <thickness> <block>"); } break; case "worldborder": { int block; if (int.TryParse(args[0], out block)) { for (int x = 0; x < bot.Room.Width; x++) { for (int y = 0; y < bot.Room.Height; y++) { if (bot.Room.BlockMap.isOnBorder(x, y)) RecordSetBlock(x, y, new NormalBlock(block)); } } } else player.Reply("Usage: !worldborder <block>"); } break; default: return; } EndRecord(player); } }
private void Generate(int width, int height, int seed) { int centerHoleDiameter = 10; generatorDrawer = bot.Room.BlockDrawerPool.CreateBlockDrawer(1); Random random = new Random(); Graphics.Tools.Noise.Primitive.SimplexPerlin noise = new Graphics.Tools.Noise.Primitive.SimplexPerlin(seed, NoiseQuality.Best); BlockMap blockMap = new BlockMap(bot, width, height); for (int x = 1; x < width - 1; x++) { for (int y = 1; y < height - 1; y++) { double distanceFromCenter = Math.Sqrt(Math.Pow(x - width / 2, 2) + Math.Pow(y - height / 2, 2)) / ((width > height) ? width : height) * 2; double distanceFromCenterPow = Math.Pow(distanceFromCenter, 1.5); //if (noise.GetValue(x * 0.015625F, y * 0.015625F, 0) > 1 - 0.25F * distanceFromCenterPow) // slimy mud // blockMap.setBlock(x, y, new NormalBlock(21, 0)); //else if (noise.GetValue(x * 0.03125F, y * 0.03125F, 32) > 1 - 0.75 * distanceFromCenter) // slimy mud // blockMap.setBlock(x, y, new NormalBlock(21, 0)); //else if (noise.GetValue(x * 0.015625F, y * 0.015625F, 48) > 1 - 0.5 * distanceFromCenter) // Water // blockMap.setBlock(x, y, new NormalBlock(197, 0)); //else if (noise.GetValue(x * 0.03125F, y * 0.03125F, 64) > 1 - 0.75 * distanceFromCenter) //wet stones // blockMap.setBlock(x, y, new NormalBlock(197, 0)); if (noise.GetValue(x * 0.0078125F, y * 0.0078125F, 96) > 1 - 0.75 * distanceFromCenterPow) blockMap.setBlock(x, y, new NormalBlock((int)Blocks.Stone, 0)); else if (noise.GetValue(x * 0.015625F, y * 0.015625F, 128) > 1 - 0.75 * distanceFromCenter) blockMap.setBlock(x, y, new NormalBlock((int)Blocks.Stone, 0)); else if (distanceFromCenter + 0.33 * noise.GetValue(x * 0.015625F, y * 0.015625F, 48) > 1) blockMap.setBlock(x, y, new NormalBlock((int)1022, 0)); else if (distanceFromCenter + 0.33 * noise.GetValue(x * 0.015625F, y * 0.015625F, 48) > 0.5) blockMap.setBlock(x, y, new NormalBlock((int)Skylight.BlockIds.Blocks.Sand.GRAY, 0)); else// if (noise.GetValue(x * 0.015625F, y * 0.015625F, 160) > 0) blockMap.setBlock(x, y, new NormalBlock(Skylight.BlockIds.Blocks.Sand.BROWN, 0)); } } Queue<BlockWithPos> blockQueue = new Queue<BlockWithPos>(); for (int i = 0; i < 64; i++) blockQueue.Enqueue(new BlockWithPos(random.Next(1, width - 1), random.Next(1, height - 1), new NormalBlock((int)Blocks.Stone, 0))); for (int i = 0; i < 64; i++) blockQueue.Enqueue(new BlockWithPos(random.Next(1, width - 1), random.Next(1, height - 1), new NormalBlock((int)Blocks.Copper, 0))); for (int i = 0; i < 32; i++) blockQueue.Enqueue(new BlockWithPos(random.Next(1, width - 1), random.Next(1, height - 1), new NormalBlock((int)Blocks.Iron, 0))); for (int i = 0; i < 16; i++) blockQueue.Enqueue(new BlockWithPos(random.Next(1, width - 1), random.Next(1, height - 1), new NormalBlock((int)Blocks.Gold, 0))); for (int i = 0; i < 8; i++) blockQueue.Enqueue(new BlockWithPos(random.Next(1, width - 1), random.Next(1, height - 1), new NormalBlock((int)Blocks.Emerald, 0))); int amount = 1536;//2048 later while (blockQueue.Count > 0 && amount > 0) { BlockWithPos block = blockQueue.Dequeue(); blockMap.setBlock(block.X, block.Y, block.Block); if (random.Next(8) == 0) { BlockWithPos block2 = null; switch (random.Next(4)) { case 0: block2 = new BlockWithPos(block.X + 1, block.Y, block.Block); break; case 1: block2 = new BlockWithPos(block.X, block.Y + 1, block.Block); break; case 2: block2 = new BlockWithPos(block.X - 1, block.Y, block.Block); break; case 3: block2 = new BlockWithPos(block.X, block.Y - 1, block.Block); break; } Console.WriteLine("s"); if (block2 != blockMap.getBlock(0, block2.X, block2.Y) && block2.X > 1 && block2.Y > 1 && block2.X < width - 1 && block2.Y < height - 1) { blockQueue.Enqueue(block2); blockMap.setBlock(block2.X, block2.Y, block2.Block); amount--; } } blockQueue.Enqueue(block); } //Make hole in center for the shop for (int x = width / 2 - (centerHoleDiameter / 2 + 1); x < width / 2 + centerHoleDiameter / 2; x++) { for (int y = height / 2 - (centerHoleDiameter / 2 + 1); y < height / 2 + centerHoleDiameter / 2; y++) { blockMap.setBlock(x, y, new NormalBlock(414, 0)); } } blockMap.setBlock(width / 2 - 1, height / 2 - 1, new NormalBlock(255, 0)); Shop.SetLocation(width / 2 - 1, height / 2 - 2); blockMap.setBlock(width / 2 - 1, height / 2 - 2, new NormalBlock(Skylight.BlockIds.Blocks.Pirate.CHEST, 0)); for (int x = 1; x < width - 1; x++) { for (int y = 1; y < height - 1; y++) { if (blockMap.getBlock(0, x, y) != null) { IBlock block = blockMap.getBlock(0, x, y); generatorDrawer.PlaceBlock(x, y, block); IBlock background = null; switch (block.Id) { case 197: background = new NormalBlock(574, 1); break; case 21: background = new NormalBlock(630, 1); break; default: background = new NormalBlock(584, 1); break; } //generatorDrawer.PlaceBlock(x, y, background); resetBlockHardness(x, y, blockMap.getBlock(0, x, y).Id); } } } generatorDrawer.Start(); }