Пример #1
0
        public bool IsOpaque(BlockData.Blocks blockType)
        {
            byte opacity;

            _blocksOpacity.TryGetValue((byte)blockType, out opacity);
            return(opacity == 0xF);
        }
Пример #2
0
        public byte Opacity(BlockData.Blocks blockType)
        {
            byte opacity;

            _blocksOpacity.TryGetValue((byte)blockType, out opacity);
            return(opacity);
        }
Пример #3
0
        public short BurnEfficiency(BlockData.Blocks blockType)
        {
            short burnEfficiency;

            _blocksBurnEfficiency.TryGetValue((byte)blockType, out burnEfficiency);
            return(burnEfficiency);
        }
Пример #4
0
        public byte Luminance(BlockData.Blocks blockType)
        {
            byte luminance;

            _blocksLuminance.TryGetValue((byte)blockType, out luminance);
            return(luminance);
        }
Пример #5
0
        public bool IsIgnitable(BlockData.Blocks blockType)
        {
            short burnEfficiency;

            _blocksBurnEfficiency.TryGetValue((byte)blockType, out burnEfficiency);
            return(burnEfficiency > 0);
        }
Пример #6
0
        public static void Open(Player player, UniversalCoords coords)
        {
            PersistentContainer container = Instance(player.World, coords);

            if (container == null)
            {
                return;
            }

            Chunk chunk = player.World.GetChunk(coords) as Chunk;

            if (chunk == null)
            {
                return;
            }
            BlockData.Blocks block = chunk.GetType(coords);
            switch (block)
            {
            case BlockData.Blocks.Furnace:
            case BlockData.Blocks.Burning_Furnace:
                player.CurrentInterface = new FurnaceInterface(player.World, coords);
                break;

            case BlockData.Blocks.Dispenser:
                player.CurrentInterface = new DispenserInterface(player.World, coords);
                break;

            case BlockData.Blocks.Chest:
                if (container is LargeChestContainer)
                {
                    UniversalCoords[] doubleChestCoords = GetDoubleChestCoords(player.World, coords);
                    if (doubleChestCoords == null)
                    {
                        return;
                    }
                    if (container.Coords == doubleChestCoords[0])
                    {
                        player.CurrentInterface = new LargeChestInterface(player.World, doubleChestCoords[0], doubleChestCoords[1]);
                    }
                    else
                    {
                        player.CurrentInterface = new LargeChestInterface(player.World, doubleChestCoords[1], doubleChestCoords[0]);
                    }
                }
                else
                {
                    player.CurrentInterface = new SmallChestInterface(player.World, coords);
                }
                break;

            default:
                return;
            }
            player.CurrentInterface.Associate(player);
            container.AddInterface((PersistentContainerInterface)player.CurrentInterface);
            player.CurrentInterface.Open();
        }
Пример #7
0
        public void Interact(EntityBase entity, StructBlock block)
        {
            Player player = entity as Player;
            if (player == null)
                return;
            if (player.CurrentInterface != null)
                return;

            byte? blockId = block.World.GetBlockId(block.Coords);

            if (blockId == null || !BlockHelper.Instance((byte)blockId).IsAir)
            {
                // Cannot open a chest if no space is above it
                return;
            }

            Chunk chunk = GetBlockChunk(block);

            // Double chest?
            if (chunk.IsNSEWTo(block.Coords, block.Type))
            {
                // Is this chest the "North or East", or the "South or West"
                BlockData.Blocks[] nsewBlocks = new BlockData.Blocks[4];
                UniversalCoords[] nsewBlockPositions = new UniversalCoords[4];
                int nsewCount = 0;
                chunk.ForNSEW(block.Coords, (uc) =>
                {
                    nsewBlocks[nsewCount] = (BlockData.Blocks)block.World.GetBlockId(uc);
                    nsewBlockPositions[nsewCount] = uc;
                    nsewCount++;
                });

                if ((byte)nsewBlocks[0] == block.Type) // North
                {
                    player.CurrentInterface = new LargeChestInterface(block.World, nsewBlockPositions[0], block.Coords);
                }
                else if ((byte)nsewBlocks[2] == block.Type) // East
                {
                    player.CurrentInterface = new LargeChestInterface(block.World, nsewBlockPositions[2], block.Coords);
                }
                else if ((byte)nsewBlocks[1] == block.Type) // South
                {
                    player.CurrentInterface = new LargeChestInterface(block.World, block.Coords, nsewBlockPositions[1]);
                }
                else if ((byte)nsewBlocks[3] == block.Type) // West
                {
                    player.CurrentInterface = new LargeChestInterface(block.World, block.Coords, nsewBlockPositions[3]);
                }
            }
            else
            {
                player.CurrentInterface = new SmallChestInterface(block.World, block.Coords);
            }

            player.CurrentInterface.Associate(player);
            player.CurrentInterface.Open();
        }
Пример #8
0
        public void Interact(EntityBase entity, StructBlock block)
        {
            Player player = entity as Player;
            if (player == null)
                return;
            if (player.CurrentInterface != null)
                return;

            if (!block.World.BlockHelper.Instance(block.World.GetBlockId(block.X, block.Y, block.Z)).IsAir)
            {
                // Cannot open a chest if no space is above it
                return;
            }

            Chunk chunk = player.World.GetBlockChunk(block.X, block.Y, block.Z);

            // Double chest?
            // TODO: simplify chunk API so that no bit shifting is required
            if (chunk.IsNSEWTo(block.X & 0xf, block.Y, block.Z & 0xf, block.Type))
            {
                // Is this chest the "North or East", or the "South or West"
                BlockData.Blocks[] nsewBlocks = new BlockData.Blocks[4];
                PointI[] nsewBlockPositions = new PointI[4];
                int nsewCount = 0;
                chunk.ForNSEW(block.X & 0xf, block.Y, block.Z & 0xf, (x1, y1, z1) =>
                {
                    nsewBlocks[nsewCount] = (BlockData.Blocks)block.World.GetBlockId(x1, y1, z1);
                    nsewBlockPositions[nsewCount] = new PointI(x1, y1, z1);
                    nsewCount++;
                });

                if ((byte)nsewBlocks[0] == block.Type) // North
                {
                    player.CurrentInterface = new LargeChestInterface(block.World, nsewBlockPositions[0], new PointI(block.X, block.Y, block.Z));
                }
                else if ((byte)nsewBlocks[2] == block.Type) // East
                {
                    player.CurrentInterface = new LargeChestInterface(block.World, nsewBlockPositions[2], new PointI(block.X, block.Y, block.Z));
                }
                else if ((byte)nsewBlocks[1] == block.Type) // South
                {
                    player.CurrentInterface = new LargeChestInterface(block.World, new PointI(block.X, block.Y, block.Z), nsewBlockPositions[1]);
                }
                else if ((byte)nsewBlocks[3] == block.Type) // West
                {
                    player.CurrentInterface = new LargeChestInterface(block.World, new PointI(block.X, block.Y, block.Z), nsewBlockPositions[3]);
                }
            }
            else
            {
                player.CurrentInterface = new SmallChestInterface(block.World, block.X, block.Y, block.Z);
            }

            player.CurrentInterface.Associate(player);
            player.CurrentInterface.Open();
        }
Пример #9
0
        protected override byte GetDirection(LivingEntity living, StructBlock block, StructBlock targetBlock, BlockFace face)
        {
            Chunk chunk = GetBlockChunk(block);
            // Load the blocks surrounding the position (NSEW) not diagonals
            var nsewBlocks = new BlockData.Blocks[4];
            var nsewBlockPositions = new UniversalCoords[4];
            int nsewCount = 0;

            int secondChestIndex = -1;
            chunk.ForNSEW(block.Coords, uc =>
            {
                byte? nearbyBlockId = block.World.GetBlockId(uc);

                if (nearbyBlockId == null)
                    return;

                if (nearbyBlockId == (byte)BlockData.Blocks.Chest)
                    secondChestIndex = nsewCount;

                nsewBlocks[nsewCount] = (BlockData.Blocks)nearbyBlockId;
                nsewBlockPositions[nsewCount] = uc;
                nsewCount++;
            });
            byte direction = base.GetDirection(living, block, targetBlock, face);
            if (secondChestIndex != -1)
            {
                var secondChestCoords = nsewBlockPositions[secondChestIndex];
                byte secondChestDirection = chunk.GetData(secondChestCoords);
                if (secondChestDirection != direction)
                {
                    if (secondChestCoords.WorldX == block.Coords.WorldX)
                    {
                        if (direction != (byte)MetaData.Container.South && direction != (byte)MetaData.Container.North)
                            direction = (byte)MetaData.Container.South;                          
                    }
                    else
                    {
                        if (direction != (byte)MetaData.Container.East && direction != (byte)MetaData.Container.West)
                            direction = (byte)MetaData.Container.West;
                    }
                }
                else
                {

                    if (secondChestCoords.WorldX == block.Coords.WorldX && block.MetaData != (byte)MetaData.Container.North && block.MetaData != (byte)MetaData.Container.South)
                        direction = (byte)MetaData.Container.South;
                    else
                        if (block.MetaData != (byte)MetaData.Container.West && block.MetaData != (byte)MetaData.Container.East)
                            direction = (byte)MetaData.Container.West;
                }
            }

            return direction;
        }
Пример #10
0
        public static void HandlePacketUpdateSign(Client client, UpdateSignPacket packet)
        {
            BlockData.Blocks blockId = (BlockData.Blocks)client.Owner.World.GetBlockId(packet.X, packet.Y, packet.Z);

            UniversalCoords coords = UniversalCoords.FromWorld(packet.X, packet.Y, packet.Z);

            if (blockId == BlockData.Blocks.Sign_Post)
            {
                BlockSignPost sign = (BlockSignPost)BlockHelper.Instance.CreateBlockInstance((byte)blockId);
                sign.SaveText(coords, client.Owner, packet.Lines);
            }
        }
Пример #11
0
        public static UniversalCoords[] GetDoubleChestCoords(WorldManager world, UniversalCoords coords)
        {
            Chunk chunk = world.GetChunk(coords) as Chunk;

            if (chunk == null || !IsDoubleChest(chunk, coords))
            {
                return(null);
            }
            // Is this chest the "North or East", or the "South or West"
            BlockData.Blocks[] nsewBlocks         = new BlockData.Blocks[4];
            UniversalCoords[]  nsewBlockPositions = new UniversalCoords[4];
            int  nsewCount = 0;
            byte?blockId;

            chunk.ForNSEW(coords, uc =>
            {
                blockId = world.GetBlockId(uc) ?? 0;
                nsewBlocks[nsewCount]         = (BlockData.Blocks)blockId;
                nsewBlockPositions[nsewCount] = uc;
                nsewCount++;
            });
            UniversalCoords firstCoords;
            UniversalCoords secondCoords;

            if ((byte)nsewBlocks[0] == (byte)BlockData.Blocks.Chest) // North
            {
                firstCoords  = nsewBlockPositions[0];
                secondCoords = coords;
            }
            else if ((byte)nsewBlocks[2] == (byte)BlockData.Blocks.Chest) // East
            {
                firstCoords  = nsewBlockPositions[2];
                secondCoords = coords;
            }
            else if ((byte)nsewBlocks[1] == (byte)BlockData.Blocks.Chest) // South
            {
                firstCoords  = coords;
                secondCoords = nsewBlockPositions[1];
            }
            else// if ((byte)nsewBlocks[3] == (byte)BlockData.Blocks.Chest) // West
            {
                firstCoords  = coords;
                secondCoords = nsewBlockPositions[3];
            }
            return(new UniversalCoords[] { firstCoords, secondCoords });
        }
Пример #12
0
        public static UniversalCoords[] GetDoubleChestCoords(WorldManager world, UniversalCoords coords)
        {
            Chunk chunk = world.GetChunk(coords);
            if (chunk == null || !IsDoubleChest(chunk, coords))
                return null;
            // Is this chest the "North or East", or the "South or West"
            BlockData.Blocks[] nsewBlocks = new BlockData.Blocks[4];
            UniversalCoords[] nsewBlockPositions = new UniversalCoords[4];
            int nsewCount = 0;
            byte? blockId;
            chunk.ForNSEW(coords, uc =>
            {
                blockId = world.GetBlockId(uc) ?? 0;
                nsewBlocks[nsewCount] = (BlockData.Blocks)blockId;
                nsewBlockPositions[nsewCount] = uc;
                nsewCount++;
            });
            UniversalCoords firstCoords;
            UniversalCoords secondCoords;

            if ((byte)nsewBlocks[0] == (byte)BlockData.Blocks.Chest) // North
            {
                firstCoords = nsewBlockPositions[0];
                secondCoords = coords;
            }
            else if ((byte)nsewBlocks[2] == (byte)BlockData.Blocks.Chest) // East
            {
                firstCoords = nsewBlockPositions[2];
                secondCoords = coords;
            }
            else if ((byte)nsewBlocks[1] == (byte)BlockData.Blocks.Chest) // South
            {
                firstCoords = coords;
                secondCoords = nsewBlockPositions[1];
            }
            else// if ((byte)nsewBlocks[3] == (byte)BlockData.Blocks.Chest) // West
            {
                firstCoords = coords;
                secondCoords = nsewBlockPositions[3];
            }
            return new UniversalCoords[] { firstCoords, secondCoords };
        }
Пример #13
0
 public bool IsLiquid(BlockData.Blocks blockType)
 {
     return(_liquidBlocks.ContainsKey((byte)blockType));
 }
Пример #14
0
 public bool IsAir(BlockData.Blocks blockType)
 {
     return(_airBlocks.ContainsKey((byte)blockType));
 }
Пример #15
0
 public bool IsPlowed(BlockData.Blocks blockType)
 {
     return(_plowedBlocks.ContainsKey((byte)blockType));
 }
Пример #16
0
 public bool IsFertile(BlockData.Blocks blockType)
 {
     return(_fertileBlocks.ContainsKey((byte)blockType));
 }
Пример #17
0
 public bool IsGrowable(BlockData.Blocks blockType)
 {
     return(_growableBlocks.ContainsKey((byte)blockType));
 }
Пример #18
0
        protected override byte GetDirection(LivingEntity living, StructBlock block, StructBlock targetBlock, BlockFace face)
        {
            Chunk chunk = GetBlockChunk(block);
            // Load the blocks surrounding the position (NSEW) not diagonals
            var nsewBlocks         = new BlockData.Blocks[4];
            var nsewBlockPositions = new UniversalCoords[4];
            int nsewCount          = 0;

            int secondChestIndex = -1;

            chunk.ForNSEW(block.Coords, uc =>
            {
                byte?nearbyBlockId = block.World.GetBlockId(uc);

                if (nearbyBlockId == null)
                {
                    return;
                }

                if (nearbyBlockId == (byte)BlockData.Blocks.Chest)
                {
                    secondChestIndex = nsewCount;
                }

                nsewBlocks[nsewCount]         = (BlockData.Blocks)nearbyBlockId;
                nsewBlockPositions[nsewCount] = uc;
                nsewCount++;
            });
            byte direction = base.GetDirection(living, block, targetBlock, face);

            if (secondChestIndex != -1)
            {
                var  secondChestCoords    = nsewBlockPositions[secondChestIndex];
                byte secondChestDirection = chunk.GetData(secondChestCoords);
                if (secondChestDirection != direction)
                {
                    if (secondChestCoords.WorldX == block.Coords.WorldX)
                    {
                        if (direction != (byte)MetaData.Container.South && direction != (byte)MetaData.Container.North)
                        {
                            direction = (byte)MetaData.Container.South;
                        }
                    }
                    else
                    {
                        if (direction != (byte)MetaData.Container.East && direction != (byte)MetaData.Container.West)
                        {
                            direction = (byte)MetaData.Container.West;
                        }
                    }
                }
                else
                {
                    if (secondChestCoords.WorldX == block.Coords.WorldX && block.MetaData != (byte)MetaData.Container.North && block.MetaData != (byte)MetaData.Container.South)
                    {
                        direction = (byte)MetaData.Container.South;
                    }
                    else
                    if (block.MetaData != (byte)MetaData.Container.West && block.MetaData != (byte)MetaData.Container.East)
                    {
                        direction = (byte)MetaData.Container.West;
                    }
                }
            }

            return(direction);
        }
Пример #19
0
        public static void HandlePacketPlayerItemPlacement(Client client, PlayerBlockPlacementPacket packet)
        {
            Player player = client.Owner;

            // if(!Permissions.CanPlayerBuild(Username)) return;
            if (player.Inventory.Slots[player.Inventory.ActiveSlot].Type <= 255)
            {
                return;
            }

            UniversalCoords baseBlockCoords = UniversalCoords.FromWorld(packet.X, packet.Y, packet.Z);

            Chunk chunk = player.World.GetChunk(baseBlockCoords) as Chunk;

            if (chunk == null)
            {
                return;
            }

            BlockData.Blocks baseBlockType = chunk.GetType(baseBlockCoords); // Get block being built against.
            byte             baseBlockData = chunk.GetData(baseBlockCoords);

            StructBlock baseBlock = new StructBlock(baseBlockCoords, (byte)baseBlockType, (byte)baseBlockData, player.World);

            // Placed Item Info
            short pType     = player.Inventory.Slots[player.Inventory.ActiveSlot].Type;
            short pMetaData = player.Inventory.Slots[player.Inventory.ActiveSlot].Durability;

            UniversalCoords newBlockCoords = player.World.FromFace(baseBlockCoords, packet.Face);
            StructBlock     newBlock;
            byte            newBlockId = 0;

            switch (packet.Face)
            {
            case BlockFace.Held:
                return;     // TODO: Process buckets, food, etc.
            }

            switch (baseBlockType)
            {
            case BlockData.Blocks.Air:
            case BlockData.Blocks.Water:
            case BlockData.Blocks.Lava:
            case BlockData.Blocks.Still_Water:
            case BlockData.Blocks.Still_Lava:
                return;
            }

            switch ((BlockData.Items)pType)
            {
            case BlockData.Items.Diamond_Hoe:
            case BlockData.Items.Gold_Hoe:
            case BlockData.Items.Iron_Hoe:
            case BlockData.Items.Stone_Hoe:
            case BlockData.Items.Wooden_Hoe:
                if (baseBlockType == BlockData.Blocks.Dirt || baseBlockType == BlockData.Blocks.Grass)
                {
                    // Think the client has a Notch bug where hoe's durability is not updated properly.
                    BlockHelper.Instance.CreateBlockInstance((byte)BlockData.Blocks.Soil).Spawn(baseBlock);
                }
                return;

            case BlockData.Items.Ink_Sack:
                if (pMetaData != 15)
                {
                    return;
                }
                if (baseBlockType == BlockData.Blocks.Red_Mushroom || baseBlockType == BlockData.Blocks.Brown_Mushroom)
                {
                    BlockBaseMushroom baseMushroom = (BlockBaseMushroom)BlockHelper.Instance.CreateBlockInstance((byte)baseBlockType);
                    baseMushroom.Fertilize(player, baseBlock);
                }
                return;

            case BlockData.Items.Minecart:
            case BlockData.Items.Boat:
            case BlockData.Items.Storage_Minecart:
            case BlockData.Items.Powered_Minecart:
                // TODO: Create new object
                break;

            case BlockData.Items.Sign:
                if (packet.Face == BlockFace.Up)
                {
                    newBlockId = (byte)BlockData.Blocks.Sign_Post;
                }
                else
                {
                    newBlockId = (byte)BlockData.Blocks.Wall_Sign;
                }
                break;

            case BlockData.Items.Seeds:
                newBlockId = (byte)BlockData.Blocks.Crops;
                break;

            case BlockData.Items.Reeds:
                newBlockId = (byte)BlockData.Blocks.Reed;
                break;

            case BlockData.Items.Redstone:
                newBlockId = (byte)BlockData.Blocks.Redstone_Wire;
                break;

            case BlockData.Items.Iron_Door:
                newBlockId = (byte)BlockData.Blocks.Iron_Door;
                break;

            case BlockData.Items.Wooden_Door:
                newBlockId = (byte)BlockData.Blocks.Wooden_Door;
                break;
            }

            if (newBlockId != 0)
            {
                newBlock = new StructBlock(newBlockCoords, newBlockId, 0, player.World);
                BlockHelper.Instance.CreateBlockInstance(newBlockId).Place(player, newBlock, baseBlock, packet.Face);
            }
        }
Пример #20
0
        public static void HandlePacketPlayerBlockPlacement(Client client, PlayerBlockPlacementPacket packet)
        {
            /*
             * Scenarios:
             *
             * 1) using an item against a block (e.g. stone and flint)
             * 2) placing a new block
             * 3) using a block: e.g. open/close door, open chest, open workbench, open furnace
             *
             * */

            //  if (!Permissions.CanPlayerBuild(Username)) return;
            // Using activeslot provides current item info wtihout having to maintain ActiveItem

            UniversalCoords coords = UniversalCoords.FromWorld(packet.X, packet.Y, packet.Z);

            if (packet.X == -1 && packet.Y == -1 && packet.Z == -1 && packet.Face == BlockFace.Held)
            {
                // TODO: Implement item usage - food etc
                return;
            }

            Player player = client.Owner;

            Chunk chunk = player.World.GetChunk(coords) as Chunk;

            if (chunk == null)
            {
                return;
            }

            BlockData.Blocks type        = chunk.GetType(coords); // Get block being built against.
            byte             metadata    = chunk.GetData(coords);
            StructBlock      facingBlock = new StructBlock(coords, (byte)type, metadata, player.World);

            UniversalCoords coordsFromFace = player.World.FromFace(coords, packet.Face);

            if (BlockHelper.Instance.CreateBlockInstance((byte)type) is IBlockInteractive)
            {
                (BlockHelper.Instance.CreateBlockInstance((byte)type) as IBlockInteractive).Interact(player, facingBlock);
                return;
            }

            if (player.Inventory.Slots[player.Inventory.ActiveSlot].Type <= 0 || player.Inventory.Slots[player.Inventory.ActiveSlot].Count < 1)
            {
                return;
            }

            // TODO: Neaten this out, or address via handler?
            if (player.Inventory.Slots[player.Inventory.ActiveSlot].Type > 255 || packet.Face == BlockFace.Held) // Client is using an Item.
            {
                HandlePacketPlayerItemPlacement(client, packet);
                return;
            }

            // Built Block Info

            byte bType     = (byte)player.Inventory.Slots[player.Inventory.ActiveSlot].Type;
            byte bMetaData = (byte)player.Inventory.Slots[player.Inventory.ActiveSlot].Durability;

            StructBlock bBlock = new StructBlock(coordsFromFace, bType, bMetaData, player.World);

            BlockHelper.Instance.CreateBlockInstance(bType).Place(player, bBlock, facingBlock, packet.Face);
        }
Пример #21
0
 public bool IsInteractive(BlockData.Blocks blockType)
 {
     return(_interactiveBlocks.ContainsKey((byte)blockType));
 }
Пример #22
0
        public bool CanGrow(IStructBlock block, IChunk iChunk)
        {
            Chunk chunk = iChunk as Chunk;

            if (chunk == null)
            {
                return(false);
            }

            // BlockMeta = 0x0 is a freshly planted cactus.
            // The data value is incremented at random intervals.
            // When it becomes 15, a new cactus block is created on top as long as the total height does not exceed 3.
            int maxHeight = 3;

            if (block.Coords.WorldY == 127)
            {
                return(false);
            }

            UniversalCoords oneUp = UniversalCoords.FromWorld(block.Coords.WorldX, block.Coords.WorldY + 1, block.Coords.WorldZ);

            BlockData.Blocks blockId = chunk.GetType(oneUp);
            if (blockId != BlockData.Blocks.Air)
            {
                return(false);
            }

            // Calculating the cactus length below this block
            int cactusHeightBelow = 0;

            for (int i = block.Coords.WorldY - 1; i >= 0; i--)
            {
                blockId = chunk.GetType(UniversalCoords.FromWorld(block.Coords.WorldX, i, block.Coords.WorldZ));
                if (blockId != BlockData.Blocks.Cactus)
                {
                    break;
                }
                cactusHeightBelow++;
            }

            if ((cactusHeightBelow + 1) >= maxHeight)
            {
                return(false);
            }

            bool isAir = true;

            chunk.ForNSEW(oneUp,
                          delegate(UniversalCoords uc)
            {
                byte?nearbyBlockId = block.WorldInterface.GetBlockId(uc);
                if (nearbyBlockId == null || nearbyBlockId != (byte)BlockData.Blocks.Air)
                {
                    isAir = false;
                }
            });

            if (!isAir)
            {
                return(false);
            }

            return(true);
        }
Пример #23
0
        public override void Fertilize(EntityBase entity, StructBlock block)
        {
            Chunk chunk = GetBlockChunk(block);

            if (chunk == null)
            {
                return;
            }

            BlockData.Blocks blockBelow = chunk.GetType(block.Coords.BlockX, block.Coords.BlockY - 1,
                                                        block.Coords.BlockZ);

            if (blockBelow != BlockData.Blocks.Dirt && blockBelow != BlockData.Blocks.Grass && blockBelow != BlockData.Blocks.Mycelium)
            {
                return;
            }

            int stemHeight = block.World.Server.Rand.Next(3) + 4;
            int capY       = block.Coords.WorldY + stemHeight + 1;

            if (capY > 127)
            {
                return;
            }

            for (int dY = block.Coords.WorldY + 1; dY < capY - 1; dY++)
            {
                BlockData.Blocks blockUp = chunk.GetType(block.Coords.BlockX, dY, block.Coords.BlockZ);

                if (blockUp != BlockData.Blocks.Air && blockUp != BlockData.Blocks.Leaves)
                {
                    return;
                }
            }

            int  absdX, absdZ;
            byte?blockId;

            for (int dX = -3; dX < 4; dX++)
            {
                for (int dZ = -3; dZ < 4; dZ++)
                {
                    absdX = Math.Abs(dX);
                    absdZ = Math.Abs(dZ);
                    if (absdX == 3 && absdZ == 3)
                    {
                        continue;
                    }
                    blockId = block.World.GetBlockId(block.Coords.WorldX + dX, capY, block.Coords.WorldZ + dZ);
                    if (blockId == null || (blockId != (byte)BlockData.Blocks.Air && blockId != (byte)BlockData.Blocks.Leaves))
                    {
                        return;
                    }
                }
            }


            byte metaData = (byte)MetaData.HugeMushroom.NorthWeastSouthEast;

            for (int dY = block.Coords.WorldY; dY < capY; dY++)
            {
                if (chunk.GetType(block.Coords.BlockX, dY, block.Coords.BlockZ) != BlockData.Blocks.Leaves)
                {
                    chunk.SetBlockAndData(block.Coords.BlockX, dY, block.Coords.BlockZ, (byte)BlockData.Blocks.BrownMushroomCap, metaData);
                }
            }

            for (int dX = -3; dX < 4; dX++)
            {
                for (int dZ = -3; dZ < 4; dZ++)
                {
                    Chunk currentChunk = block.World.GetChunkFromWorld(block.Coords.WorldX + dX, block.Coords.WorldZ + dZ) as Chunk;
                    if (currentChunk == null)
                    {
                        continue;
                    }

                    absdX = Math.Abs(dX);
                    absdZ = Math.Abs(dZ);
                    if (absdX == 3 && absdZ == 3)
                    {
                        continue;
                    }

                    BlockData.Blocks nearbyBlockId = currentChunk.GetType(block.Coords.BlockX + dX, capY, block.Coords.BlockZ + dZ);
                    if (nearbyBlockId == BlockData.Blocks.Leaves)
                    {
                        continue;
                    }

                    if (absdX < 3 && absdZ < 3)
                    {
                        metaData = (byte)MetaData.HugeMushroom.Top;
                    }
                    else if ((dX == -3 && dZ == -2) || (dZ == -3 && dX == -2))
                    {
                        metaData = (byte)MetaData.HugeMushroom.TopNorthWest;
                    }
                    else if ((dX == -3 && dZ == 2) || (dZ == 3 && dX == -2))
                    {
                        metaData = (byte)MetaData.HugeMushroom.TopSouthWest;
                    }
                    else if ((dX == 3 && dZ == -2) || (dZ == -3 && dX == 2))
                    {
                        metaData = (byte)MetaData.HugeMushroom.TopNorthEast;
                    }
                    else if ((dX == 3 && dZ == 2) || (dZ == 3 && dX == 2))
                    {
                        metaData = (byte)MetaData.HugeMushroom.TopSouthEast;
                    }
                    else if (dX == -3 && absdZ < 2)
                    {
                        metaData = (byte)MetaData.HugeMushroom.TopWest;
                    }
                    else if (dX == 3 && absdZ < 2)
                    {
                        metaData = (byte)MetaData.HugeMushroom.TopEast;
                    }
                    else if (dZ == -3 && absdX < 2)
                    {
                        metaData = (byte)MetaData.HugeMushroom.TopNorth;
                    }
                    else if (dZ == 3 && absdX < 2)
                    {
                        metaData = (byte)MetaData.HugeMushroom.TopSouth;
                    }

                    currentChunk.SetBlockAndData(block.Coords.BlockX + dX, capY, block.Coords.BlockZ + dZ, (byte)BlockData.Blocks.BrownMushroomCap, metaData);
                }
            }
        }
Пример #24
0
        public override void Place(EntityBase entity, StructBlock block, StructBlock targetBlock, BlockFace face)
        {
            Chunk chunk = GetBlockChunk(block);
            Chunk targetChunk = GetBlockChunk(targetBlock);

            if (chunk == null || targetChunk == null)
                return;

            // Load the blocks surrounding the position (NSEW) not diagonals
            BlockData.Blocks[] nsewBlocks = new BlockData.Blocks[4];
            UniversalCoords[] nsewBlockPositions = new UniversalCoords[4];
            int nsewCount = 0;

            chunk.ForNSEW(block.Coords, (uc) =>
            {
                byte? nearbyBlockId = block.World.GetBlockId(uc);

                if(nearbyBlockId == null)
                    return;

                nsewBlocks[nsewCount] = (BlockData.Blocks)nearbyBlockId;
                nsewBlockPositions[nsewCount] = uc;
                nsewCount++;
            });

            // Count chests in list
            if (nsewBlocks.Where((b) => b == BlockData.Blocks.Chest).Count() > 1)
            {
                // Cannot place next to two chests
                return;
            }

            for (int i = 0; i < 4; i++)
            {
                UniversalCoords p = nsewBlockPositions[i];
                if (nsewBlocks[i] == BlockData.Blocks.Chest && chunk.IsNSEWTo(p, (byte)BlockData.Blocks.Chest))
                {
                    // Cannot place next to a double chest
                    return;
                }
            }
            base.Place(entity, block, targetBlock, face);
        }
Пример #25
0
 public bool IsSolid(BlockData.Blocks blockType)
 {
     return(_solidBlocks.ContainsKey((byte)blockType));
 }
Пример #26
0
 public void SetType(int x, int y, int z, BlockData.Blocks value)
 {
     this[x, y, z] = (byte)value;
 }
Пример #27
0
 public bool IsSingleHit(BlockData.Blocks blockType)
 {
     return(_singleHitBlocks.ContainsKey((byte)blockType));
 }
Пример #28
0
 public static ItemInventory GetInstance(BlockData.Blocks blockType)
 {
     return(GetInstance((short)blockType));
 }
Пример #29
0
        public override void Place(EntityBase entity, StructBlock block, StructBlock targetBlock, BlockFace face)
        {
            // Load the blocks surrounding the position (NSEW) not diagonals
            BlockData.Blocks[] nsewBlocks = new BlockData.Blocks[4];
            PointI[] nsewBlockPositions = new PointI[4];
            int nsewCount = 0;
            block.Chunk.ForNSEW(block.X & 0xf, block.Y, block.Z & 0xf, (x1, y1, z1) =>
            {
                nsewBlocks[nsewCount] = (BlockData.Blocks)block.World.GetBlockId(x1, y1, z1);
                nsewBlockPositions[nsewCount] = new PointI(x1, y1, z1);
                nsewCount++;
            });

            // Count chests in list
            if (nsewBlocks.Where((b) => b == BlockData.Blocks.Chest).Count() > 1)
            {
                // Cannot place next to two chests
                return;
            }

            for (int i = 0; i < 4; i++)
            {
                PointI p = nsewBlockPositions[i];
                if (nsewBlocks[i] == BlockData.Blocks.Chest && block.Chunk.IsNSEWTo(p.X & 0xf, p.Y, p.Z & 0xf, (byte)BlockData.Blocks.Chest))
                {
                    // Cannot place next to a double chest
                    return;
                }
            }
            base.Place(entity, block, targetBlock, face);
        }
Пример #30
0
        private void PacketHandler_PlayerBlockPlacement(object sender, PacketEventArgs<PlayerBlockPlacementPacket> e)
        {
            /*
             * Scenarios:
             *
             * 1) using an item against a block (e.g. stone and flint)
             * 2) placing a new block
             * 3) using a block: e.g. open/close door, open chest, open workbench, open furnace
             *
             * */

            //  if (!Permissions.CanPlayerBuild(Username)) return;
            // Using activeslot provides current item info wtihout having to maintain ActiveItem

            int x = e.Packet.X;
            int y = e.Packet.Y;
            int z = e.Packet.Z;

            BlockData.Blocks type = (BlockData.Blocks)World.GetBlockId(x, y, z); // Get block being built against.

            int bx, by, bz;
            World.FromFace(x, y, z, e.Packet.Face, out bx, out by, out bz);

            if (type == BlockData.Blocks.Chest)
            {
                if (!BlockData.Air.Contains((BlockData.Blocks)World.GetBlockId(bx, by, bz)))
                {
                    // Cannot open a chest if no space is above it
                    return;
                }

                Chunk chunk = World.GetBlockChunk(x, y, z);

                // Double chest?
                // TODO: simplify chunk API so that no bit shifting is required
                if (chunk.IsNSEWTo(x & 0xf, y, z & 0xf, (byte)type))
                {
                    // Is this chest the "North or East", or the "South or West"
                    BlockData.Blocks[] nsewBlocks = new BlockData.Blocks[4];
                    PointI[] nsewBlockPositions = new PointI[4];
                    int nsewCount = 0;
                    chunk.ForNSEW(x & 0xf, y, z & 0xf, (x1, y1, z1) =>
                    {
                        nsewBlocks[nsewCount] = (BlockData.Blocks)World.GetBlockId(x1, y1, z1);
                        nsewBlockPositions[nsewCount] = new PointI(x1, y1, z1);
                        nsewCount++;
                    });

                    if (nsewBlocks[0] == type) // North
                    {
                        CurrentInterface = new LargeChestInterface(World, nsewBlockPositions[0], new PointI(x, y, z));
                    }
                    else if (nsewBlocks[2] == type) // East
                    {
                        CurrentInterface = new LargeChestInterface(World, nsewBlockPositions[2], new PointI(x, y, z));
                    }
                    else if (nsewBlocks[1] == type) // South
                    {
                        CurrentInterface = new LargeChestInterface(World, new PointI(x, y, z), nsewBlockPositions[1]);
                    }
                    else if (nsewBlocks[3] == type) // West
                    {
                        CurrentInterface = new LargeChestInterface(World, new PointI(x, y, z), nsewBlockPositions[3]);
                    }
                }
                else
                {
                    CurrentInterface = new SmallChestInterface(World, x, y, z);
                }

                if (CurrentInterface != null)
                {
                    CurrentInterface.Associate(this);
                    CurrentInterface.Open();
                }
                return;
            }
            else if (type == BlockData.Blocks.Workbench)
            {
                CurrentInterface = new WorkbenchInterface();
                CurrentInterface.Associate(this);
                ((WorkbenchInterface)CurrentInterface).Open(bx, by, bz);
                return;
            }
            else if (type == BlockData.Blocks.Furnace || type == BlockData.Blocks.Burning_Furnace)
            {
                CurrentInterface = new FurnaceInterface(World, x, y, z);
                CurrentInterface.Associate(this);
                CurrentInterface.Open();
                return;
            }

            if (Inventory.Slots[Inventory.ActiveSlot].Type <= 0 || Inventory.Slots[Inventory.ActiveSlot].Count < 1)
                return;

            // TODO: Neaten this out, or address via handler?
            if (Inventory.Slots[Inventory.ActiveSlot].Type > 255 || e.Packet.Face == BlockFace.Held) // Client is using an Item.
            {
                PacketHandler_PlayerItemPlacement(sender, e);
                return;
            }

            // Built Block Info

            byte bType = (byte)Inventory.Slots[Inventory.ActiveSlot].Type;
            byte bMetaData = (byte)Inventory.Slots[Inventory.ActiveSlot].Durability;

            switch (type) // Can't build against these blocks.
            {
                case BlockData.Blocks.Air:
                case BlockData.Blocks.Water:
                case BlockData.Blocks.Lava:
                case BlockData.Blocks.Still_Water:
                case BlockData.Blocks.Still_Lava:
                    return;
            }

            switch ((BlockData.Blocks)bType)
            {

                case BlockData.Blocks.Cactus:
                    {
                        BlockData.Blocks uType = (BlockData.Blocks)World.GetBlockId(bx, by - 1, bz);
                        if (uType != BlockData.Blocks.Sand && uType != BlockData.Blocks.Cactus)
                            return;
                    }
                    break;

                case BlockData.Blocks.Crops:
                    {
                        BlockData.Blocks uType = (BlockData.Blocks)World.GetBlockId(bx, by - 1, bz);
                        if (uType != BlockData.Blocks.Soil)
                            return;
                    }
                    break;

                case BlockData.Blocks.Chest:
                    // Load the blocks surrounding the position (NSEW) not diagonals
                    Chunk chunk = World.GetBlockChunk(x, y, z);
                    BlockData.Blocks[] nsewBlocks = new BlockData.Blocks[4];
                    PointI[] nsewBlockPositions = new PointI[4];
                    int nsewCount = 0;
                    chunk.ForNSEW(bx & 0xf, by, bz & 0xf, (x1, y1, z1) =>
                    {
                        nsewBlocks[nsewCount] = (BlockData.Blocks)World.GetBlockId(x1, y1, z1);
                        nsewBlockPositions[nsewCount] = new PointI(x1, y1, z1);
                        nsewCount++;
                    });

                    // Count chests in list
                    if (nsewBlocks.Where((b) => b == BlockData.Blocks.Chest).Count() > 1)
                    {
                        // Cannot place next to two chests
                        return;
                    }

                    // A chest cannot be surrounded by two blocks on the same axis when placed
                    //if (BlockData.IsSolid(nsewBlocks[0]) && BlockData.IsSolid(nsewBlocks[1]))
                    //{
                    //    return;
                    //}
                    //if (BlockData.IsSolid(nsewBlocks[2]) && BlockData.IsSolid(nsewBlocks[3]))
                    //{
                    //    return;
                    //}

                    for (int i = 0; i < 4; i++)
                    {
                        PointI p = nsewBlockPositions[i];
                        if (nsewBlocks[i] == BlockData.Blocks.Chest && chunk.IsNSEWTo(p.X & 0xf, p.Y, p.Z & 0xf, (byte)BlockData.Blocks.Chest))
                        {
                            // Cannot place next to a double chest
                            return;
                        }
                    }

                    break;
                case BlockData.Blocks.Furnace:
                case BlockData.Blocks.Dispenser:
                    switch (e.Packet.Face) //Bugged, as the client has a mind of its own for facing
                    {
                        case BlockFace.East: bMetaData = (byte)MetaData.Furnace.East;
                            break;
                        case BlockFace.West: bMetaData = (byte)MetaData.Furnace.West;
                            break;
                        case BlockFace.North: bMetaData = (byte)MetaData.Furnace.North;
                            break;
                        case BlockFace.South: bMetaData = (byte)MetaData.Furnace.South;
                            break;
                        default:
                            switch (FacingDirection(4)) // Built on floor, set by facing dir
                            {
                                case "N":
                                    bMetaData = (byte)MetaData.Furnace.North;
                                    break;
                                case "W":
                                    bMetaData = (byte)MetaData.Furnace.West;
                                    break;
                                case "S":
                                    bMetaData = (byte)MetaData.Furnace.South;
                                    break;
                                case "E":
                                    bMetaData = (byte)MetaData.Furnace.East;
                                    break;
                                default:
                                    return;

                            }
                            break;
                    }
                    break;

                case BlockData.Blocks.Rails:
                    // TODO: Rail Logic
                    break;

                case BlockData.Blocks.Reed:
                    // TODO: Check there is water nearby before placing.
                    break;

                case BlockData.Blocks.Stair:
                    // TODO : If (Block  Y - 1 = Stair && Block Y = Air) Then DoubleStair
                    // Else if (Buildblock = Stair) Then DoubleStair
                    break;

                case BlockData.Blocks.Wooden_Stairs:
                case BlockData.Blocks.Cobblestone_Stairs:
                    switch (FacingDirection(4))
                    {
                        case "N":
                            bMetaData = (byte)MetaData.Stairs.South;
                            break;
                        case "E":
                            bMetaData = (byte)MetaData.Stairs.West;
                            break;
                        case "S":
                            bMetaData = (byte)MetaData.Stairs.North;
                            break;
                        case "W":
                            bMetaData = (byte)MetaData.Stairs.East;
                            break;
                        default:
                            return;
                    }
                    break;

                case BlockData.Blocks.Torch:
                    switch (e.Packet.Face)
                    {
                        case BlockFace.Down: return;
                        case BlockFace.Up: bMetaData = (byte)MetaData.Torch.Standing;
                            break;
                        case BlockFace.West: bMetaData = (byte)MetaData.Torch.West;
                            break;
                        case BlockFace.East: bMetaData = (byte)MetaData.Torch.East;
                            break;
                        case BlockFace.North: bMetaData = (byte)MetaData.Torch.North;
                            break;
                        case BlockFace.South: bMetaData = (byte)MetaData.Torch.South;
                            break;
                    }
                    break;
                case BlockData.Blocks.Sapling:
                    // We can place a sapling only on the top of the dirt or soil block
                    if (e.Packet.Face != BlockFace.Up || type != BlockData.Blocks.Dirt || type != BlockData.Blocks.Soil)
                        return;
                    break;
            }

            World.SetBlockAndData(bx, by, bz, bType, bMetaData);
            World.Update(bx, by, bz, false);

            if(GameMode == 0)
                Inventory.RemoveItem(Inventory.ActiveSlot);
        }
Пример #31
0
        private void Burn(object state)
        {
            lock (_containerLock)
            {
                Chunk chunk = World.GetChunk(Coords) as Chunk;

                if (chunk == null)
                {
                    StopBurning();
                    return;
                }

                if (_fuelTicksLeft <= 0)
                {
                    if (HasIngredient() && HasFuel())
                    {
                        if (!OutputSlot.IsVoid() && !GetSmeltingRecipe(InputSlot).Result.StacksWith(OutputSlot))
                        {
                            StopBurning();
                            return;
                        }

                        _fuelTicksFull = GetFuelEfficiency();
                        _fuelTicksLeft = _fuelTicksFull;

                        SendFurnaceProgressPacket(_progressTicks);
                        RemoveFuel();

                        BlockData.Blocks blockId = chunk.GetType(Coords);

                        if (blockId == BlockData.Blocks.Furnace)
                        {
                            chunk.SetType(Coords, BlockData.Blocks.Burning_Furnace);
                        }
                    }
                    else
                    {
                        StopBurning();
                    }

                    return;
                }

                _fuelTicksLeft--;
                if (InputSlot.IsVoid() || (!OutputSlot.IsVoid() && (!GetSmeltingRecipe(InputSlot).Result.StacksWith(OutputSlot) || OutputSlot.Count == 64)))
                {
                    _progressTicks = 0;
                }
                else
                {
                    if (_progressTicks >= FullProgress)
                    {
                        _progressTicks = 0;
                        AddOutput();
                        RemoveIngredient();
                    }
                    _progressTicks++;
                }

                double fuelTickCost = ((double)(_fuelTicksFull)) / FullFire;
                short  fireLevel    = (short)(_fuelTicksLeft / fuelTickCost);

                if (fireLevel % 10 == 0 || fireLevel == FullFire)
                {
                    SendFurnaceFirePacket(fireLevel);
                }

                if (_progressTicks % 10 == 0 || _progressTicks == FullProgress)
                {
                    SendFurnaceProgressPacket(_progressTicks);
                }
            }
        }
Пример #32
0
        public static PersistentContainer Instance(WorldManager world, UniversalCoords coords)
        {
            PersistentContainer container;
            Chunk chunk = world.GetChunk(coords) as Chunk;

            if (chunk == null)
            {
                return(null);
            }
            BlockData.Blocks block = chunk.GetType(coords);
            if (!chunk.Containers.ContainsKey(coords.BlockPackedCoords))
            {
                switch (block)
                {
                case BlockData.Blocks.Furnace:
                case BlockData.Blocks.Burning_Furnace:
                    container = new FurnaceContainer();
                    container.Initialize(world, coords);
                    (container as FurnaceContainer).StartBurning();
                    break;

                case BlockData.Blocks.Dispenser:
                    container = new DispenserContainer();
                    container.Initialize(world, coords);
                    break;

                case BlockData.Blocks.Chest:
                    // Double chest?
                    if (IsDoubleChest(chunk, coords))
                    {
                        UniversalCoords[] doubleChestCoords = GetDoubleChestCoords(world, coords);
                        if (doubleChestCoords == null)
                        {
                            return(null);
                        }
                        chunk.Containers.TryRemove(doubleChestCoords[0].BlockPackedCoords, out container);
                        chunk.Containers.TryRemove(doubleChestCoords[1].BlockPackedCoords, out container);

                        container = new LargeChestContainer(doubleChestCoords[1]);
                        container.Initialize(world, doubleChestCoords[0]);
                        chunk.Containers.TryAdd(doubleChestCoords[0].BlockPackedCoords, container);
                        chunk.Containers.TryAdd(doubleChestCoords[1].BlockPackedCoords, container);
                    }
                    else
                    {
                        container = new SmallChestContainer();
                        container.Initialize(world, coords);
                    }
                    break;

                default:
                    return(null);
                }
                chunk.Containers.TryAdd(coords.BlockPackedCoords, container);
            }
            else
            {
                chunk.Containers.TryGetValue(coords.BlockPackedCoords, out container);
            }
            return(container);
        }
Пример #33
0
 public bool IsWaterProof(BlockData.Blocks blockType)
 {
     return(_waterProofBlocks.ContainsKey((byte)blockType));
 }
Пример #34
0
        public override void Fertilize(EntityBase entity, StructBlock block)
        {
            Chunk chunk = GetBlockChunk(block);

            if (chunk == null)
            {
                return;
            }

            BlockData.Blocks blockBelow = chunk.GetType(block.Coords.BlockX, block.Coords.BlockY - 1,
                                                        block.Coords.BlockZ);

            if (blockBelow != BlockData.Blocks.Dirt && blockBelow != BlockData.Blocks.Grass &&
                blockBelow != BlockData.Blocks.Mycelium)
            {
                return;
            }

            int stemHeight = block.World.Server.Rand.Next(3) + 4;
            int capY       = block.Coords.WorldY + stemHeight + 1;

            if (capY > 127)
            {
                return;
            }

            BlockData.Blocks blockId;
            for (int dY = block.Coords.WorldY + 1; dY < capY - 1; dY++)
            {
                blockId = chunk.GetType(block.Coords.BlockX, dY, block.Coords.BlockZ);
                if (blockId != BlockData.Blocks.Air && blockId != BlockData.Blocks.Leaves)
                {
                    return;
                }
            }

            int absdX, absdZ;

            byte?nullableBlockId;

            for (int dX = -2; dX < 3; dX++)
            {
                for (int dZ = -2; dZ < 3; dZ++)
                {
                    for (int dY = block.Coords.WorldY + 1; dY <= capY; dY++)
                    {
                        absdX = Math.Abs(dX);
                        absdZ = Math.Abs(dZ);
                        if (absdX == 2 && absdZ == 2)
                        {
                            continue;
                        }
                        if (dY == capY && absdX > 1 && absdZ > 1)
                        {
                            continue;
                        }
                        if (dY < capY && absdX < 2 && absdZ < 2)
                        {
                            continue;
                        }

                        nullableBlockId = block.World.GetBlockId(block.Coords.WorldX + dX, dY, block.Coords.WorldZ + dZ);
                        if (nullableBlockId == null || (nullableBlockId != (byte)BlockData.Blocks.Leaves && nullableBlockId != (byte)BlockData.Blocks.Air))
                        {
                            return;
                        }
                    }
                }
            }

            byte metaData = (byte)MetaData.HugeMushroom.NorthWeastSouthEast;

            for (int dY = block.Coords.WorldY; dY < capY; dY++)
            {
                if (chunk.GetType(block.Coords.BlockX, dY, block.Coords.BlockZ) != BlockData.Blocks.Leaves)
                {
                    chunk.SetBlockAndData(block.Coords.BlockX, dY, block.Coords.BlockZ, (byte)BlockData.Blocks.BrownMushroomCap, metaData);
                }
            }

            for (int dX = -2; dX < 3; dX++)
            {
                for (int dZ = -2; dZ < 3; dZ++)
                {
                    Chunk currentChunk = block.World.GetChunkFromWorld(block.Coords.WorldX + dX,
                                                                       block.Coords.WorldZ + dZ) as Chunk;

                    if (currentChunk == null)
                    {
                        continue;
                    }

                    for (int dY = capY - 3; dY <= capY; dY++)
                    {
                        absdX = Math.Abs(dX);
                        absdZ = Math.Abs(dZ);
                        if (absdX == 2 && absdZ == 2)
                        {
                            continue;
                        }
                        if (dY == capY && (absdX > 1 || absdZ > 1))
                        {
                            continue;
                        }
                        if (dY < capY && absdX < 2 && absdZ < 2)
                        {
                            continue;
                        }
                        blockId = currentChunk.GetType(block.Coords.BlockX + dX, dY, block.Coords.BlockZ + dZ);
                        if (blockId == BlockData.Blocks.Leaves)
                        {
                            continue;
                        }

                        if (dY == capY)
                        {
                            // Draw cap
                            if (dX == 0 && dZ == 0)
                            {
                                metaData = (byte)MetaData.HugeMushroom.Top;
                            }
                            else if (dX == -1 && dZ == 0)
                            {
                                metaData = (byte)MetaData.HugeMushroom.TopWest;
                            }
                            else if (dX == 1 && dZ == 0)
                            {
                                metaData = (byte)MetaData.HugeMushroom.TopEast;
                            }
                            else if (dX == 0 && dZ == -1)
                            {
                                metaData = (byte)MetaData.HugeMushroom.TopNorth;
                            }
                            else if (dX == 0 && dZ == 1)
                            {
                                metaData = (byte)MetaData.HugeMushroom.TopSouth;
                            }
                            else if (dX == -1 && dZ == -1)
                            {
                                metaData = (byte)MetaData.HugeMushroom.TopNorthWest;
                            }
                            else if (dX == -1 && dZ == 1)
                            {
                                metaData = (byte)MetaData.HugeMushroom.TopSouthWest;
                            }
                            else if (dX == 1 && dZ == -1)
                            {
                                metaData = (byte)MetaData.HugeMushroom.TopNorthEast;
                            }
                            else if (dX == 1 && dZ == 1)
                            {
                                metaData = (byte)MetaData.HugeMushroom.TopSouthEast;
                            }
                        }
                        else
                        {
                            // Draw sides
                            if (dX == -2 && dZ == -1)
                            {
                                metaData = (byte)MetaData.HugeMushroom.TopNorthWest;
                            }
                            else if (dX == -2 && dZ == 0)
                            {
                                metaData = (byte)MetaData.HugeMushroom.TopWest;
                            }
                            else if (dX == -2 && dZ == 1)
                            {
                                metaData = (byte)MetaData.HugeMushroom.TopSouthWest;
                            }
                            else if (dX == 2 && dZ == -1)
                            {
                                metaData = (byte)MetaData.HugeMushroom.TopNorthEast;
                            }
                            else if (dX == 2 && dZ == 0)
                            {
                                metaData = (byte)MetaData.HugeMushroom.TopEast;
                            }
                            else if (dX == 2 && dZ == 1)
                            {
                                metaData = (byte)MetaData.HugeMushroom.TopSouthEast;
                            }
                            else if (dX == -1 && dZ == 2)
                            {
                                metaData = (byte)MetaData.HugeMushroom.TopSouthWest;
                            }
                            else if (dX == 0 && dZ == 2)
                            {
                                metaData = (byte)MetaData.HugeMushroom.TopSouth;
                            }
                            else if (dX == 1 && dZ == 2)
                            {
                                metaData = (byte)MetaData.HugeMushroom.TopSouthEast;
                            }
                            else if (dX == -1 && dZ == -2)
                            {
                                metaData = (byte)MetaData.HugeMushroom.TopNorthWest;
                            }
                            else if (dX == 0 && dZ == -2)
                            {
                                metaData = (byte)MetaData.HugeMushroom.TopNorth;
                            }
                            else if (dX == 1 && dZ == -2)
                            {
                                metaData = (byte)MetaData.HugeMushroom.TopNorthEast;
                            }
                        }

                        currentChunk.SetBlockAndData(block.Coords.BlockX + dX, dY, block.Coords.BlockZ + dZ,
                                                     (byte)BlockData.Blocks.RedMushroomCap, metaData);
                    }
                }
            }
        }