public override void onTick()
        {
            if (!bot.Room.HasCode)
            {
                return;
            }

            DigPlayer digPlayer = null;

            lock (playersToSave)
            {
                if (playersToSaveQueue.Count > 0)
                {
                    IPlayer player = playersToSaveQueue.Dequeue();
                    playersToSave.Remove(player);

                    digPlayer = (DigPlayer)player.GetMetadata("digplayer");
                }
            }
            if (digPlayer != null)
            {
                digPlayer.Save();
            }

            lock (dugBlocksToPlaceQueueLock)
            {
                while (dugBlocksToPlaceQueue.Count > bot.Room.Width * bot.Room.Height / 5)
                {
                    BlockWithPos block = dugBlocksToPlaceQueue.Dequeue();
                    if (digHardness[block.X, block.Y] == 0f)
                    {
                        bot.Room.setBlock(block.X, block.Y, block.Block);
                    }
                }
            }

            Pair <BlockPos, ItemDynamite> toRemove = null;

            List <Pair <BlockPos, ItemDynamite> > .Enumerator e = dynamites.GetEnumerator();
            while (e.MoveNext())
            {
                if ((DateTime.Now - e.Current.second.DatePlaced).Seconds >= 5)
                {
                    Random r        = new Random();
                    int    x        = e.Current.first.X;
                    int    y        = e.Current.first.Y;
                    float  strength = e.Current.second.Strength;
                    List <Pair <BlockWithPos, double> > blocksToRemove = new List <Pair <BlockWithPos, double> >();
                    for (int xx = (int)(x - strength); xx < x + strength; xx++)
                    {
                        for (int yy = (int)(y - strength); yy < y + strength; yy++)
                        {
                            double distanceFromCenter = Math.Sqrt(Math.Pow(x - xx, 2) + Math.Pow(y - yy, 2));
                            if (distanceFromCenter <= strength)
                            {
                                bool shouldRemove = (r.Next((int)((distanceFromCenter / strength) * 100)) <= 50 ? true : false);
                                if (shouldRemove)
                                {
                                    blocksToRemove.Add(new Pair <BlockWithPos, double>(new BlockWithPos(xx, yy, new NormalBlock(414, 0)), distanceFromCenter));

                                    if (e.Current.second.Placer != null)
                                    {
                                        int           blockIdReplaced = bot.Room.getBlock(0, xx, yy).Id;
                                        InventoryItem oreItem         = ItemManager.GetItemFromOreId(blockIdReplaced);
                                        if (oreItem != null && r.Next(4) == 0)
                                        {
                                            e.Current.second.Placer.Inventory.AddItem(oreItem, 1);
                                        }
                                    }
                                }
                            }
                        }
                    }

                    blocksToRemove.Sort((s1, s2) => s1.second.CompareTo(s2.second));
                    bot.Room.setBlock(e.Current.first.X, e.Current.first.Y, new NormalBlock(414, 0));
                    foreach (var block in blocksToRemove)
                    {
                        DigBlock(block.first.X, block.first.Y, null, (int)Math.Floor(1 / block.second * 50) * ((float)r.Next(100) / 100 + 1), false, true);
                    }
                    blocksToRemove.Clear();


                    toRemove = e.Current;
                    break;
                }
            }
            if (toRemove != null)
            {
                dynamites.Remove(toRemove);
            }
        }
        public override void onCommand(string cmd, string[] args, ICmdSource cmdSource)
        {
            if (cmdSource is IPlayer && (IPlayer)cmdSource != null)
            {
                IPlayer   player    = (IPlayer)cmdSource;
                DigPlayer digPlayer = DigPlayer.FromPlayer(player);

                AddUnsavedPlayer(player);

                switch (cmd)
                {
                case "dynamite":
                {
                    ItemDynamite dynamite = new ItemDynamite();
                    dynamite.Placer = digPlayer;
                    if (digPlayer.Inventory.RemoveItem(dynamite, 1) || player.IsGod)
                    {
                        bot.ChatSayer.Say(player.Name + " has placed a big barrel of dynamite! Hide!!");
                        bot.Room.setBlock(player.BlockX, player.BlockY, new NormalBlock(163, 0));
                        dynamites.Add(
                            new Pair <BlockPos, ItemDynamite>(new BlockPos(0, player.BlockX, player.BlockY), dynamite)
                            );
                    }
                    else
                    {
                        player.Reply("You have no dynamite! Buy it at the shop.");
                    }
                }
                break;

                case "dig":
                case "help":
                case "commands":
                case "digcommands":
                    player.Reply("Here are the commands: !xp, !level, !inventory, !xpleft, !buy, !sell, !money, !levelforores, !save");
                    break;

                case "levelforores":
                {
                    string total = "";
                    foreach (Ore ore in ItemManager.GetOres())
                    {
                        total += ore.Name + ": " + ore.LevelRequired + (ItemManager.GetOres().Last().Name.Equals(ore.Name) ? "" : ", ");
                    }
                    player.Reply(total);
                }
                break;

                case "generate":
                    if (player.IsOp)
                    {
                        int seed = -1;

                        if (args.Length >= 1)
                        {
                            Int32.TryParse(args[0], out seed);
                        }
                        if (seed == -1)
                        {
                            seed = random.Next();
                        }

                        bot.ChatSayer.Say("Generating new map with seed " + seed + ".");
                        digHardness = new float[bot.Room.Width, bot.Room.Height];
                        Generate(bot.Room.Width, bot.Room.Height, seed);
                    }
                    break;

                case "worm":
                    if (player.IsOp)
                    {
                        zombies.SpawnZombie(player.BlockX, player.BlockY);
                        player.Reply("Worm spawned.");
                    }
                    break;

                case "givexp":
                    if (player.IsOp && args.Length >= 2)
                    {
                        IPlayer receiver = bot.Room.getPlayer(args[0]);
                        if (receiver != null)
                        {
                            int xp = Int32.Parse(args[1]);
                            if (!receiver.HasMetadata("digplayer"))
                            {
                                receiver.SetMetadata("digplayer", new DigPlayer(receiver));
                            }
                            DigPlayer receiverDigPlayer = (DigPlayer)receiver.GetMetadata("digplayer");
                            receiverDigPlayer.digXp += xp;
                            AddUnsavedPlayer(receiver);
                        }
                        else
                        {
                            player.Reply("That player doesn't exist.");
                        }
                    }
                    else
                    {
                        player.Reply("Usage: !givexp <player> <xp>");
                    }
                    break;

                case "setxp":
                    if (player.IsOp && args.Length >= 2)
                    {
                        IPlayer receiver = bot.Room.getPlayer(args[0]);
                        if (receiver != null)
                        {
                            int xp = Int32.Parse(args[1]);
                            if (!receiver.HasMetadata("digplayer"))
                            {
                                receiver.SetMetadata("digplayer", new DigPlayer(receiver));
                            }
                            DigPlayer receiverDigPlayer = (DigPlayer)receiver.GetMetadata("digplayer");
                            receiverDigPlayer.digXp = xp;
                            AddUnsavedPlayer(receiver);
                        }
                        else
                        {
                            player.Reply("That player doesn't exist.");
                        }
                    }
                    else
                    {
                        player.Reply("Usage: !setxp <player> <xp>");
                    }
                    break;

                case "givemoney":
                    if (player.IsOp && args.Length >= 2)
                    {
                        IPlayer receiver = bot.Room.getPlayer(args[0]);
                        if (receiver != null)
                        {
                            int money = Int32.Parse(args[1]);
                            if (!receiver.HasMetadata("digplayer"))
                            {
                                receiver.SetMetadata("digplayer", new DigPlayer(receiver));
                            }
                            DigPlayer receiverDigPlayer = (DigPlayer)receiver.GetMetadata("digplayer");
                            receiverDigPlayer.digMoney += money;
                            AddUnsavedPlayer(receiver);
                        }
                        else
                        {
                            player.Reply("That player doesn't exist.");
                        }
                    }
                    else
                    {
                        player.Reply("Usage: !givemoney <player> <money>");
                    }
                    break;

                case "setmoney":
                    if (player.IsOp && args.Length >= 2)
                    {
                        IPlayer receiver = bot.Room.getPlayer(args[0]);
                        if (receiver != null)
                        {
                            int money = Int32.Parse(args[1]);
                            if (!receiver.HasMetadata("digplayer"))
                            {
                                receiver.SetMetadata("digplayer", new DigPlayer(receiver));
                            }
                            DigPlayer receiverDigPlayer = (DigPlayer)receiver.GetMetadata("digplayer");
                            receiverDigPlayer.digMoney = money;
                            AddUnsavedPlayer(receiver);
                        }
                        else
                        {
                            player.Reply("That player doesn't exist.");
                        }
                    }
                    else
                    {
                        player.Reply("Usage: !setmoney <player> <money>");
                    }
                    break;

                case "xp":
                    player.Reply("XP: " + digPlayer.digXp);
                    break;

                case "xpleft":
                    player.Reply("You need " + (digPlayer.xpRequired_ - digPlayer.digXp).ToString() + " XP for level " + (digPlayer.digLevel + 1).ToString());
                    break;

                case "level":
                    player.Reply("Level: " + digPlayer.digLevel);
                    break;

                case "inventory":
                    player.Reply(digPlayer.Inventory.ToString());
                    break;

                case "save":
                    player.Reply("Saved!");
                    digPlayer.Save();
                    break;

                case "setshop":
                    if (player.IsOp)
                    {
                        Shop.SetLocation(player.BlockX, player.BlockY);
                        player.Reply("Shop set at X:" + player.BlockX + " Y:" + player.BlockY);
                    }
                    break;

                case "money":
                    player.Reply("Money: " + digPlayer.digMoney);
                    break;

                case "buy":
                    if (Shop.IsPlayerClose(player))
                    {
                        if (args.Length >= 1)
                        {
                            string itemName = args[0].ToLower();
                            int    amount   = 1;

                            if (args.Length >= 2)
                            {
                                if (!int.TryParse(args[1], out amount))
                                {
                                    amount = 1;
                                }
                            }

                            if (amount < 1)
                            {
                                player.Reply("You can't buy a negative amount of items.");
                                break;
                            }

                            Shop.BuyItem(digPlayer, itemName, amount);
                        }
                        else
                        {
                            player.Reply("Usage: !buy <item> [amount=1]");
                            Shop.BuyItem(digPlayer, "", 0);
                        }
                    }
                    else
                    {
                        player.Reply("You aren't near the shop.");
                    }
                    break;

                case "sell":
                    if (Shop.IsPlayerClose(player))
                    {
                        if (args.Length >= 1)
                        {
                            string itemName = args[0].ToLower();
                            int    amount   = 1;

                            if (args.Length >= 2)
                            {
                                if (!int.TryParse(args[1], out amount))
                                {
                                    amount = 1;
                                }
                            }

                            if (amount < 1)
                            {
                                player.Reply("You can't buy a negative amount of items.");
                                break;
                            }

                            Shop.SellItem(digPlayer, itemName, amount);
                        }
                        else
                        {
                            player.Reply("Usage: !sell <item> [amount=1]");
                            Shop.SellItem(digPlayer, "", 0);
                        }
                    }
                    else
                    {
                        player.Reply("You aren't near the shop.");
                    }
                    break;
                }
            }
        }