Esempio n. 1
0
        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);
        }
Esempio n. 2
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);
            }
        }
Esempio n. 3
0
        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();
        }