Beispiel #1
0
 public void Set(IBot bot, int x1, int y1, int x2, int y2, IBlock replaceWith, IBlock replace = null)
 {
     EditRegion region = new EditRegion();
     region.FirstCorner = new Point(x1, y1);
     region.SecondCorner = new Point(x2, y2);
     SetRegion(bot, region, replaceWith, replace);
 }
Beispiel #2
0
 public void SetRegion(IBot bot, EditRegion region, IBlock replaceWith, IBlock replace = null)
 {
     if (replace == null)
     {
         foreach (Point pos in region)
         {
             RecordSetBlock(pos.X, pos.Y, replaceWith);
         }
     }
     else
     {
         foreach (Point pos in region)
         {
             if (bot.Room.getBlock(replaceWith.Layer, pos.X, pos.Y).Id == replace.Id)
                 RecordSetBlock(pos.X, pos.Y, replaceWith);
         }
     }
 }
Beispiel #3
0
        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);
            }
        }