/// <summary>
        /// this one reverses the direction offset and returns the block id that was clicked
        /// this does not always need to be used, only if the direction offset has already been applied
        /// in the packet handling.
        /// </summary>
        /// <param name="p"></param>
        /// <param name="a"></param>
        /// <returns></returns>
        public static byte Blockclicked(Player p, BCS a)
        {
            int x = (int)a.pos.x;
            int y = (int)a.pos.y;
            int z = (int)a.pos.z;

            switch (a.Direction)
            {
                case 0: y++; break;
                case 1: y--; break;
                case 2: z++; break;
                case 3: z--; break;
                case 4: x++; break;
                case 5: x--; break;
            }

            return p.level.GetBlock(x, y, z);
        }
 public static bool EatCookie(Player a, BCS b)
 {
     return false;
 }
 public static bool PlaceFence(Player a, BCS b)
 {
     return false;
 }
 public static bool PlaceCake(Player a, BCS b)
 {
     if (a.level.GetBlock((int)b.pos.x, (int)b.pos.y - 1, (int)b.pos.z) != 0)
     {
         a.level.BlockChange((int)b.pos.x, (int)b.pos.y, (int)b.pos.z, (byte)Blocks.CakeBlock, 0);
         return true;
     }
     return false;
 }
        public static bool PlaceButtonStone(Player a, BCS b)
        {
            if (!BlockData.CanPlaceAgainst(Blockclicked(a, b))) return false;
            if (a.level.GetBlock((int)b.pos.x, (int)b.pos.y, (int)b.pos.z) != 0) return false;

            switch (b.Direction)
            {
                case (0):
                case (1):
                    return false;
                case ((byte)Directions.East):
                    b.Direction = (byte)Buttons.North;
                    break;
                case ((byte)Directions.West):
                    b.Direction = (byte)Buttons.South;
                    break;
                case ((byte)Directions.North):
                    b.Direction = (byte)Buttons.East;
                    break;
                case ((byte)Directions.South):
                    b.Direction = (byte)Buttons.West;
                    break;

                default:
                    return false;
            }

            a.level.BlockChange((int)b.pos.x, (int)b.pos.y, (int)b.pos.z, (byte)b.ID, b.Direction);
            if (Server.mode == 0) a.inventory.Remove(a.inventory.current_index, 1);
            return false;
        }
        public static bool PlaceBed(Player a, BCS b)
        {
            if (b.Direction != 1) return false;
            Point3 pos2 = b.pos;
            byte rot = DirectionByRotFlat(a, b);

            switch (rot)
            {
                case (byte)Directions.North:
                    rot = (byte)Bed.North;
                    break;
                case (byte)Directions.East:
                    rot = (byte)Bed.East;
                    break;
                case (byte)Directions.South:
                    rot = (byte)Bed.South;
                    break;
                case (byte)Directions.West:
                    rot = (byte)Bed.West;
                    break;
            }
            switch (rot)
            {
                case (byte)Bed.North:
                    pos2.x--;
                    break;
                case (byte)Bed.East:
                    pos2.z--;
                    break;
                case (byte)Bed.South:
                    pos2.x++;
                    break;
                case (byte)Bed.West:
                    pos2.z++;
                    break;
            }

            if (!BlockData.CanPlaceAgainst(a.level.GetBlock((int)b.pos.x, (int)b.pos.y - 1, (int)b.pos.z)) || !BlockData.CanPlaceAgainst(a.level.GetBlock((int)pos2.x, (int)pos2.y - 1, (int)pos2.z))) return false;
            a.level.BlockChange((int)b.pos.x, (int)b.pos.y, (int)b.pos.z, (byte)Blocks.Bed, rot);
            a.level.BlockChange((int)pos2.x, (int)pos2.y, (int)pos2.z, (byte)Blocks.Bed, (byte)(rot | 0x8));

            return true;
        }
 public static bool OpenFurnace(Player a, BCS b)
 {
     a.OpenWindow(WindowType.Furnace, b.pos);
     return false;
 }
 public static bool OpenDoor(Player a, BCS b)
 {
     byte type = a.level.GetBlock((int)b.pos.x, (int)b.pos.y, (int)b.pos.z);
     byte meta = a.level.GetMeta((int)b.pos.x, (int)b.pos.y, (int)b.pos.z);
     if ((meta & 0x8) == 0)
     {
         a.level.BlockChange((int)b.pos.x, (int)b.pos.y, (int)b.pos.z, type, (byte)(meta ^ 0x4));
         if (a.level.GetBlock((int)b.pos.x, (int)b.pos.y + 1, (int)b.pos.z) == type)
             a.level.BlockChange((int)b.pos.x, (int)b.pos.y + 1, (int)b.pos.z, type, (byte)((meta | 0x8) ^ 0x4));
     }
     else
     {
         a.level.BlockChange((int)b.pos.x, (int)b.pos.y, (int)b.pos.z, type, (byte)(meta ^ 0x4));
         if (a.level.GetBlock((int)b.pos.x, (int)b.pos.y - 1, (int)b.pos.z) == type)
             a.level.BlockChange((int)b.pos.x, (int)b.pos.y - 1, (int)b.pos.z, type, (byte)((meta ^ 0x8) ^ 0x4));
     }
     Player.GlobalSoundEffect(b.pos, 1003, a.level, a);
     return false;
 }
 public static bool EjectCd(Player a, BCS b)
 {
     return false;
 }
 public static bool EatSoup(Player a, BCS b)
 {
     return false;
 }
 public static bool EatPorkchopRaw(Player a, BCS b)
 {
     return false;
 }
 public static bool EatPorkchopCooked(Player a, BCS b)
 {
     return false;
 }
 public static bool EatGoldenApple(Player a, BCS b)
 {
     return false;
 }
 public static bool EatFishRaw(Player a, BCS b)
 {
     return false;
 }
 public static bool EatFishCooked(Player a, BCS b)
 {
     return false;
 }
 public static bool OpenCraftingTable(Player a, BCS b)
 {
     a.OpenWindow(WindowType.Workbench, b.pos);
     return false;
 }
 public static bool OpenDispenser(Player a, BCS b)
 {
     a.OpenWindow(WindowType.Dispenser, b.pos);
     return false;
 }
 public static bool FireBow(Player a, BCS b)
 {
     return false;
 }
 public static bool OpenEnchantmentTable(Player a, BCS b)
 {
     a.OpenWindow(WindowType.EnchantmentTable, b.pos);
     return false;
 }
 public static bool GetInBed(Player a, BCS b)
 {
     return false;
 }
 public static bool OpenTrapdoor(Player a, BCS b)
 {
     byte meta = a.level.GetMeta((int)b.pos.x, (int)b.pos.y, (int)b.pos.z);
     a.level.BlockChange((int)b.pos.x, (int)b.pos.y, (int)b.pos.z, (byte)Blocks.Trapdoor, (byte)(meta ^ 0x4));
     Player.GlobalSoundEffect(b.pos, 1003, a.level, a);
     return false;
 }
 public static bool GreenMusicDisk(Player a, BCS b)
 {
     return false;
 }
 public static bool PlaceBoat(Player a, BCS b)
 {
     return false;
 }
 public static bool HitButton(Player a, BCS b)
 {
     byte meta = a.level.GetMeta((int)b.pos.x, (int)b.pos.y, (int)b.pos.z);
     a.level.BlockChange((int)b.pos.x, (int)b.pos.y, (int)b.pos.z, (byte)Blocks.ButtonStone, (byte)(meta | 0x8));
     return false;
 }
 public static bool PlaceCactus(Player a, BCS b)
 {
     if (a.level.GetBlock((int)b.pos.x, (int)b.pos.y - 1, (int)b.pos.z) != (byte)Blocks.Sand) return false;
     // TODO: Adjacent block checks!
     return true;
 }
        public static bool LightFire(Player a, BCS b)
        {
            /*Point3 firePos = new Point3();
            switch (b.Direction)
            {
                case 0:
                    firePos = new Point3(b.pos.x, b.pos.y - 1, b.pos.z);
                    break;
                case 1:
                    firePos = new Point3(b.pos.x, b.pos.y + 1, b.pos.z);
                    break;
                case 2:
                    firePos = new Point3(b.pos.x, b.pos.y, b.pos.z - 1);
                    break;
                case 3:
                    firePos = new Point3(b.pos.x, b.pos.y, b.pos.z + 1);
                    break;
                case 4:
                    firePos = new Point3(b.pos.x - 1, b.pos.y, b.pos.z);
                    break;
                case 5:
                    firePos = new Point3(b.pos.x + 1, b.pos.y, b.pos.z);
                    break;
                default:
                    return false;
            }*/

            if (a.level.GetBlock((int)b.pos.x, (int)b.pos.y, (int)b.pos.z) == (byte)Blocks.Air)
            {
                a.level.BlockChange((int)b.pos.x, (int)b.pos.y, (int)b.pos.z, (byte)Blocks.Fire, 0);
                a.inventory.current_item.meta++;
            }
            return false;
        }
 public static bool PlaceDirt(Player a, BCS b)
 {
     return true;
 }
 public static bool OpenBrewingStand(Player a, BCS b)
 {
     a.OpenWindow(WindowType.BrewingStand, b.pos);
     return false;
 }
        public static bool PlaceFurnace(Player a, BCS b)
        {
            switch (b.Direction)
            {
                case (0):
                case (1):
                    b.Direction = DirectionByRotFlat(a, b);
                    break;
                case ((byte)Directions.East):
                    b.Direction = (byte)Furnace.East;
                    break;
                case ((byte)Directions.West):
                    b.Direction = (byte)Furnace.West;
                    break;
                case ((byte)Directions.North):
                    b.Direction = (byte)Furnace.North;
                    break;
                case ((byte)Directions.South):
                    b.Direction = (byte)Furnace.South;
                    break;

                default:
                    return false;
            }

            a.level.BlockChange((int)b.pos.x, (int)b.pos.y, (int)b.pos.z, (byte)b.ID, b.Direction);
            if (Server.mode == 0) a.inventory.Remove(a.inventory.current_index, 1);
            return false;
        }
 public static bool OpenChest(Player a, BCS b)
 {
     a.OpenWindow(WindowType.Chest, b.pos);
     return false;
 }